Sticky Director — AI 電影導演手冊
此儲存庫是一個本機動畫與無聲電影引擎。一個穿著灰色連帽衫的黑色剪影角色,在照片背景前表演(例如 Google Flow 圖片),搭配音樂、環境音、鏡頭運動與字幕。您可以透過 MCP 工具(.mcp.json 註冊 sticky-studio → node mcp-server.js)或 CLI(node cli.js …)來導演。兩者皆會自動啟動 server.js,畫布操作會開啟工作室(無顯示器時以無頭 Chromium 執行)。
務必傳遞絕對檔案路徑。所有 ID 均經過驗證。未知值會以
warnings傳回且不會套用,因此請務必閱讀警告訊息。
從 Antigravity 執行: 若
sticky-studioMCP 工具不可用,請從儲存庫根目錄使用 CLI。每個 MCP 工具都有對應的 CLI(見下方表格);node cli.js snapshot <t> <abs.png>會寫出 PNG 檔案,可使用視覺功能開啟。所有指令皆會自動啟動工作室伺服器。
工具 (MCP) ↔ CLI
| MCP 工具 | CLI | 功能 |
|---|---|---|
sticky_status | node cli.js status | 模式、長寬比、時長、BPM/節拍數、連線標籤、場景列表 |
sticky_get_project | node cli.js get-project [out.json] | 以平鋪代理格式輸出完整專案(場景、fxMarkers、mediaCards、audio.beats/strongBeats、背景 + lightProfile) |
sticky_load_audio | node cli.js load-audio <path> --mode silent | 載入音樂/旁白 → {duration, bpm, beats[], strongBeats[]} |
sticky_import_photos | node cli.js import-photos <p1> <p2> … [--auto-build] | 註冊照片 → [{bgId, name, path, width, height, lightProfile}] |
sticky_apply_template | node cli.js template <id> [--no-photos] | 載入符合音訊和照片的無聲電影故事板 |
sticky_set_project | node cli.js set-project <file.json | '{…}'> | 推送完整或部分故事板(只會套用您傳送的鍵) |
sticky_update_scene | node cli.js update-scene <index|id> '{…}' | 修改一個場景 |
sticky_split_scene | node cli.js split <timeSec> [--no-snap] | 在指定時間分割,會吸附到最近的節拍(±0.35 秒) |
sticky_add_fx | node cli.js add-fx <type> <timeSec> [--duration s] | 鏡頭撞擊 / 音效 / card |
sticky_render_frame | node cli.js snapshot <timeSec> [out.png] | 輸出該時間點的 PNG 畫面(MCP 也會以圖片形式傳回) |
sticky_export_mp4 | node cli.js export | 即時渲染 → exports/sticky_video_*.mp4(60 fps H.264 + AAC) |
get_status、get_project、set_project 和 update_scene 也可在未開啟工作室分頁時運作:它們會讀寫 projects/live_state.json,工作室連線時會載入該檔案。
參考 ID
情緒 (10 種)
| id | 用途 |
|---|---|
neutral | 預設、平靜 |
happy | 溫暖、釋懷、小確幸 |
tired | 凌晨三點、倦怠、 exhaustion |
crying | 悲傷、崩潰(搭配 silentMouth: quiver) |
angry | 挫折 |
shocked | 驚慌、醒悟 |
skeptical | 懷疑、側目 |
confused | 「?」的時刻 |
excited | 興奮(星星眼) |
deadpan | 空洞、麻木 |
手勢 (18 種) — gesture
| id | 描述 | 最佳視角 |
|---|---|---|
pocket | 雙手插在連帽衫口袋(放鬆預設) | 任意 |
idle | 放鬆手臂(走路時擺動) | 任意 |
talking | 根據音訊節奏擺動手(旁白) | 正面 |
explain | 雙手攤開 | 正面 |
point_screen | 指向側面(朝向媒體卡片) | 正面 |
point_viewer | 指向鏡頭 | 正面 / 3/4 |
crossed | 雙手交叉 | 正面 |
facepalm | 手遮臉 | 正面 |
hands_head | 雙手抱頭(驚慌) | 正面 |
shrug | 聳肩,手掌朝上 | 正面 |
wave | 揮手打招呼 | 正面 |
typing | 坐在桌前打字(自動繪製桌子 + 凳子) | 自動 3/4–側面 |
slouch_lonely | 深度癱坐,頭垂低,緩慢沉重呼吸 | 正面 / 3/4 |
heavy_sigh | 4.5 秒週期:吸氣 → 屏息 → 癱軟(自動呼吸音效) | 正面 / 3/4 |
check_phone_dark | 手持發光手機;藍色光線照在臉和連帽衫上 | 正面 / 3/4 |
sit_curb_hug_knees | 坐在地上抱膝,頭低垂 | 自動 3/4 |
look_back_horizon | 站著凝視遠景,風吹動連帽衫 | 背面 / 3/4 |
pull_hood_up | 動作:手臂向後拉帽子(從場景開始約 2.3 秒) | 正面 |
身體與姿勢參數
| 鍵 | 值 |
|---|---|
pose | rig(關節式,預設)· v1 精靈:front、bust、side、back |
view | front、threeQuarter、side、back |
hoodUp | true / false(每個視角皆會繪製帽子;背面視角預設為拉起) |
walkSpeed | 0 靜止 · 0.1–1.0 走路 · 1.1–2.5 慢跑 → 衝刺 |
walkDir | left、right |
walkInPlace | true(原地走路)/ false(橫跨畫面,會循環) |
wind | 0..1(衣襬、拉繩、帽子) |
silentMouth | closed(預設)· sigh · quiver(哭泣 / 焦慮) |
handLeft、handRight | auto、relaxed、open_palm、pointing、fist、holding_prop、in_pocket |
prop | none、phone、mug、mic、controller、book |
spineLean、headTilt、headNod | 度數(≈ −25…25;headNod + = 向下看) |
ikPins | { rightHand|leftHand|rightFoot|leftFoot|head: {x, y} },單位為骨架單位(原點為雙腳之間的地面,+x = 面朝方向,向上為負 y;頭部 y 約 −300,手部 y 約 −130)。{} 會清除 |
x、y、scale、flipX | 位置 0..1(x 0.5 = 置中;y ≈ 0.55 = 站立於下三分之一)、大小(1 = 預設)、鏡像 |
motion | breathe(無聲模式預設)、talk_bounce、walk、shake(顫抖)、float、none |
emotion | 見上方表格 |
背景 — background
內建:paper_sketch、cozy_night、rainy_window、streetlight(午夜路燈)、classroom(日落課桌)、dark_spotlight、rooftop_dusk、green_screen。
照片:使用 sticky_import_photos 傳回的 bgId,或直接在 background 中使用絕對照片路徑(會自動匯入)。
照片相機與深度
| 鍵 | 值 |
|---|---|
kenBurns | none、push_in、pull_out、drift_left、drift_right、breathing(照片移動 100%,角色移動 30% → 視差效果) |
foreground | none、bokeh、rain_streaks、window_reflection |
camera | static、zoom_in、zoom_out、pan_right、handheld(疊加在 kenBurns 之上) |
atmosphere | dust(隨著音樂節拍發光)、rain、none |
dutchScene / spotlightScene | 整個場景傾斜地平線 / 背景調暗 60% |
光線匹配(照片和諧化) — lightMatch
true = 建議(tint 0.35, rim 0.55, exposure 0.5)· false = 關閉 · 數字 0..1 = 整體強度 · 或 { tint, rim, exposure, side },其中 side = auto(根據照片自動判斷) | left | right | back(背光,雙側邊緣)。
每個照片場景都建議使用 true。 對日落和背光地平線調高 rim(0.7–0.9);對 look_back_horizon 使用 side: "back"。
轉場(場景進入方式) — transitionType、transitionDur(0–2 秒)
cut · dissolve(兩個鏡頭即時渲染並混合)· fade_black(時間流逝、孤獨)· fade_white(回憶、醒悟、希望)。第一個場景若使用 dissolve 或 fade_black,會從黑畫面淡入。fadeOutEnd: true 會讓電影在結尾淡出至黑畫面。
環境聲(連續、每場景) — ambientBed、ambientVol 0..1
| id | 情緒 |
|---|---|
none | — |
rain_window | 輕柔雨聲 + 遠處雷聲(也會讓腳步聲潮濕) |
night_wind | 孤獨的午夜風聲 |
vinyl_crackle | 溫暖的 lo-fi 灰塵感 |
clock_ticking | 60 BPM 迴響的滴答聲:凌晨三點、失眠、空虛 |
heartbeat | 低沉的心跳聲:焦慮、恐慌 |
crowd_muffle | 低通濾波的嗡嗡聲:在擁擠房間中孤獨一人 |
FX 標記 — sticky_add_fx / fxMarkers: [{type, timeSec, …}]
- 鏡頭撞擊:
snap_zoom(1.0→1.25× 彈性縮放到臉部)、dutch_tilt、shake、spotlight(+duration、intensity0..3、dir±1 表示荷蘭角方向) - 音效 / 擬音 (10 種):
whoosh、pop、vine_boom、record_scratch、shutter、typing、footstep_wet、heavy_sigh_breath、phone_vibrate、door_close_echo(+volume) - 場景也可設定
transitionSfx(在剪輯點播放的音效)和foley: true(自動在每次腳跟著地時播放腳步聲,並加入嘆息呼吸;無聲模式預設開啟) - 媒體卡片:
type: "card",搭配card: {kind: image|meme|post|note, text, imagePath, side: auto|left|right, hold, size}
專案層級參數(sticky_set_project)
| 鍵 | 值 |
|---|---|
mode | silent(只有音樂,嘴巴永遠不會對嘴)· voiceover |
aspectRatio | 16:9 · 16:9-letterbox(2.35:1 電影黑邊)· 9:16(Shorts / Reels / TikTok,720×1280) |
fadeOutEnd | true 或秒數 |
masterAmbientVol | 0..1 |
captionStyle | cinematic(無聲電影襯線體)、pop、karaoke、classic、off、或 {mode, highlight, position: bottom|middle|top, chunk, uppercase, size} |
snapToBeats | 預設 true:剪輯點會吸附到最近的節拍 |
scenes | 平鋪場景物件。時間設定:在所有場景中給定 start/end,或全不給,使用 duration / weight(根據音樂長度分配) |
fxMarkers | 見上方 |
mediaCards | [{sceneIndex | timeSec, kind, text, imagePath, appear, hold, side}] |
模板 — sticky_apply_template
loneliness_3am(黑暗中看手機 → 戴帽雨中行走 → 路邊抱膝 → 黎明地平線)· social_anxiety(癱坐角落 + 人群嗡嗡聲 → 心跳加速的恐慌 → 走出門外迎風 → 釋懷的嘆息)· burnout(桌前打字 → 空洞凝視時鐘 → 淡出至黑畫面 → 雨中行走)· discipline(疲憊起床 → 拉起帽子 → 1.2 倍慢跑 → 2.0 倍衝刺迎向日出)。
導演工作流程
- 觀察與聆聽。 使用視覺功能查看使用者的照片(讀取圖檔),決定情緒弧線(例如隔離 → 崩潰點 → 釋放 → 希望)。使用
sticky_load_audio {path, mode: "silent"}載入音樂,並記下duration、bpm和strongBeats(最佳剪輯點)。 - 匯入並對應照片。 按故事順序使用
sticky_import_photos {paths: [...]}。利用每個lightProfile(tone溫暖/冷色、brightness、lightFrom)來選擇節拍。暗冷色調的房間適合check_phone_dark/slouch_lonely+clock_ticking。雨天的街道適合戴帽pocket行走 +rain_window+rain_streaks。日落和天際線適合look_back_horizon(背面視角、lightMatch {rim: 0.8, side: "back"})+night_wind。 - 建構故事板,使用一次
sticky_set_project呼叫:mode: "silent"、captionStyle: "cinematic"、fadeOutEnd: true,每個照片一個場景。為每個場景設定background(路徑或 bgId)、gesture、emotion、view、hoodUp、kenBurns、lightMatch: true、ambientBed、transitionType(第一個場景用fade_black,多數用dissolve1.0–1.5 秒,時間跳躍用fade_black,轉向希望用fade_white)、簡短詩意subtitle(≤ 8 個字或留空)、以及強調用的weight。加入幾個fxMarkers(phone_vibrate、door_close_echo、在情緒高峰用snap_zoom)。檢查結果中的warnings。 - 視覺檢查。 在 2–3 個關鍵時間點使用
sticky_render_frame:第一個場景內部(淡入後約 1.5 秒)、影片中段、以及高潮處。確認角色完全在畫面內且接地(調整y、scale、x)、邊光與色調與照片相符(調整lightMatch)、字幕可讀且未被遮蓋、臉部未被卡片遮擋。使用sticky_update_scene修正並重新渲染。 - 匯出,當使用者準備好時使用
sticky_export_mp4。耗時約等於影片長度加上編碼時間。回報mp4Path。
無聲情緒短片的品味指南
- 使用較少但較長的鏡頭(4–8 秒)。在
strongBeats上剪輯。讓heavy_sigh和slouch_lonely至少維持一個完整週期(≥ 4.5 秒)。 hoodUp: true= 退縮 / 下雨 / 焦慮;帽子放下 = 開放、釋懷。walkSpeed保持 0.4–0.6 給憂鬱的步行,1.2 給堅定的慢跑,2.0 以上僅用於高潮衝刺。- 搭配情緒和嘴巴:
crying+quiver、tired+sigh。在無聲模式中永不使用talking。 - 每個場景使用一種環境聲,音量 0.4–0.8。在剪輯點更換環境聲以標記新場景。
- 對於
9:16,保持x≈ 0.5 和scale0.9–1.1。字幕和卡片會自動重新定位。
故事板範例
{
"mode": "silent", "aspectRatio": "16:9-letterbox", "captionStyle": "cinematic", "fadeOutEnd": true,
"scenes": [
{ "title": "3 AM", "background": "/abs/photos/bedroom.jpg", "gesture": "check_phone_dark", "emotion": "tired",
"kenBurns": "push_in", "lightMatch": true, "ambientBed": "clock_ticking", "transitionType": "fade_black", "transitionDur": 1.2, "subtitle": "3:07 AM." },
{ "title": "Rain Walk", "background": "/abs/photos/street.jpg", "gesture": "pocket", "view": "threeQuarter", "hoodUp": true,
"walkSpeed": 0.55, "walkInPlace": false, "x": 0.25, "foreground": "rain_streaks", "ambientBed": "rain_window",
"lightMatch": true, "transitionType": "dissolve", "transitionDur": 1.2, "weight": 1.2 },
{ "title": "Dawn", "background": "/abs/photos/sunset.jpg", "gesture": "look_back_horizon", "view": "back", "wind": 0.6,
"lightMatch": { "rim": 0.8, "side": "back" }, "kenBurns": "pull_out", "ambientBed": "night_wind",
"transitionType": "fade_white", "subtitle": "但太陽還是升起了。" }
],
"fxMarkers": [ { "type": "phone_vibrate", "timeSec": 0.8 } ]
}