手工舞台影片
萬聖節夜晚,無所事事:一位留著黑色鮑伯頭的女孩坐在手繪紙板沙發上,手拿粉紅色飲料,按下紙板遙控器。紙板電視機開啟雪花雜訊,螢幕上一個小幽靈跳起舞來,然後從螢幕剝離飄走。它飄到她的杯子旁(「它想喝一口。」),落在棋盤格桌面上,一支巨叉刺向一盤手繪莓果(「梔子花。莓果。優格。」),喝了一口後,她坐在一頂巨大的女巫帽上,周圍星星蹦跳而出(「……完全魔法。」)。杯子以潦草字跡寫著「魔法漂亮水」和箭頭,最後一張卡片有品牌字標、杯子、幽靈、「萬聖節限定」和販售地點。每一幀都來自該品牌自己的七張宣傳照片。
它以四個部分組成:
scripts/generate.mjs將靜態照片轉為素材:9:16 關鍵影格(Nano Banana 2 繪製額外背景,原始像素疊回其上)、Kling 短片片段、切割出的道具、重新放置的標籤和品牌字標。scripts/reel.mjs將片段按影片時間線剪輯為一個連續片段。scripts/sfx.mjs合成音效:一首原創音樂盒華爾滋以及每個事件對應的聲音。scripts/render.mjs以舞台秀方式播放所有內容:每秒 12 幀的步進動作、手持抖動、移動噪點、紙偶、撕紙字幕、附箭頭的標籤、開啟的電視螢幕以及最後一張卡片。它使用 headless Chrome 和 FFmpeg 在本機渲染。
設定(每台機器一次)
在此技能資料夾內執行:
npm install
這會安裝 puppeteer-core 和 ffmpeg-static。必須已安裝 Google Chrome,或設定 CHROME_PATH 指向 Chrome/Chromium 執行檔(npx @puppeteer/browsers install chrome-headless-shell@stable 會顯示一個)。
影片素材需要 Nano Banana 2 和 Kling 2.5 Turbo 的 API 金鑰;腳本透過模型 API 閘道呼叫它們,金鑰於此建立(https://fal.ai/dashboard/keys)。使用者在其終端機中設定為 FAL_KEY(例如在其 shell 設定檔中)。切勿要求使用者將金鑰貼入對話中,也切勿印出金鑰。
成本
模型使用費,計入使用者自己的 API 金鑰:每張靜態照片擴展為 9:16 需 $0.08(每次 edit 亦同),每個 5 秒片段需 $0.35,每個切割道具幾分之一美分(2026 年 10 月價格)。七張靜態照片、五個片段的一部影片約需 $2.30。連續片段、道具、字幕、音效和最終 MP4 在使用者機器上免費製作。在生成前告知使用者成本。
成功關鍵
- 他們自己的照片,關鍵處未經更動。 擴展和每個片段都從品牌的真實靜態照片開始;
extend將原始像素疊回 AI 的版本上,relabel將清晰的標籤疊回任何片段中標籤模糊的畫格上。 - 一個故事,而非幻燈片。 規劃一個小情節貫穿各張照片,並有一個物件在之間移動(此處為從電視逃出的小幽靈紙偶)。字幕是簡短的故事節拍,而非口號。
- 刻意笨拙。 所有內容以 1/12 秒的步伐移動,帶有細微抖動,紙偶在關鍵影格上搖晃,字幕以三步驟彈出,箭頭以三筆畫繪製。不要讓它平滑。
- 一半產品,一半品牌。 產品出現在大部分鏡頭中,並有一個特寫加上標籤;最後一張卡片是品牌字標、產品、名稱和購買地點。
工作流程
- 收集 4-8 張同一次拍攝的靜態照片(3:4、4:5 或 9:16)、產品名稱、一句話(口味、材質)、一則備註(「萬聖節限定」)和行動呼籲。詢問靜態照片底部是否帶有印刷的品牌字標或徽章(這些會在畫格中被塗掉,並為最後一張卡片進行去背)。
- 分鏡腳本(在生成前顯示):鏡頭順序、情節、每個片段中移動的內容(一到兩個小動作,產品保持靜止)、哪些道具要切割為紙偶及其動作、字幕和標籤,以及成本。控制在 15-20 秒內。
- 關鍵影格:對每張非 9:16 的靜態照片執行
node scripts/generate.mjs extend --in still.jpg --out keys/<shot>.png --cover <rows>(--cover= 原始照片底部印刷品牌字標頻寬的畫素高度,若有的話)。以全尺寸檢視每個關鍵影格:若模型在新頻帶中留下鏡像或重複的物件,則用同一張照片中的單純紋理覆蓋它。 - 試拍:一個片段,包含情節鉤子的鏡頭:
node scripts/generate.mjs clip --start keys/<shot>.png --prompt "…" --out clips/<shot>.mp4。提示詞僅描述移動的內容(「她用手指按下遙控器上的一個按鈕;杯子保持直立不動」);固定後綴保持攝影機鎖定,且場景、臉部和產品不變。展示結果,然後執行其餘部分。 - 其他動態鏡頭的片段。逐格觀看每個片段:記下動作發生的位置(以放置音效和紙偶),以及產品上小字體模糊的位置。使用
relabel --clip … --key keys/<shot>.png --box x,y,w,h(關鍵影格中的標籤方框)修正標籤,或僅使用產品移動前的畫格。並非每個鏡頭都需要片段:帶有緩慢推近的靜態特寫鏡頭(still、box、boxTo)通常更適合產品。 - 道具:對每個紙偶(角色、星星、花朵、莓果、手中的產品)執行
cutout --in keys/<shot>.png --box x,y,w,h --out props/<name>.png;對移除某物(例如沒有幽靈的電視螢幕)的盤子執行edit。品牌字標:wordmark --in still.jpg --box x,y,w,h --out props/wordmark.png。最後一張卡片的背景是從某個關鍵影格中裁切的彩繪牆壁。 - 建立
effect.json從examples/example.json(參見鏡頭和最後一張卡片),然後執行node scripts/reel.mjs effect.json --out reel.mp4並設定"reel": "reel.mp4"。 - 音效:
node scripts/sfx.mjs effect.json --out stage.m4a,然後設定"music": "stage.m4a"。計時有任何變更後重新執行。--no-bed --music track.mp3可將華爾滋替換為使用者已取得授權的音樂曲目。 - 驗證:
node scripts/validate.mjs effect.json— 修正所有錯誤,並向使用者讀出所有警告。 - 草稿:
node scripts/render.mjs effect.json --quality draft --width 540 --out draft.mp4,並檢查每個鏡頭的一格畫面:確認無字幕、標籤或紙偶蓋住臉部或產品,且所有內容避開右側 14% 的平台按鈕區域。 - 最終版:
node scripts/render.mjs effect.json --out film.mp4 --poster poster.png。針對小紅書,裁切 3:4 版本:ffmpeg -i film.mp4 -vf crop=720:960:0:160 -c:a copy film-3x4.mp4(預設寬度 720;確認重要內容未位於頂部或底部 160 畫素內)。
鏡頭
所有位置以 1080 × 1920 畫格畫素為單位。每個鏡頭為下列之一:
- 片段鏡頭:
clip(reel.mjs 剪輯的檔案)、from和to(片段中的秒數)、speed(0.5 = 半速,配合 12 步播放可充分利用短暫良好片段中的每一格)、hold(動作開始前第一格停留的秒數)。 - 靜態鏡頭:
still(影像)、len、box和boxTo(影像畫素中的[x, y, width]9:16 視窗;視角從一個移動到另一個)。
每個鏡頭可以包含:
captions:{ "text", "at", "out", "x", "y", "rot", "size" }— 帶有手寫文字的撕紙碎片;\n換行。tags:{ "text", "at", "x", "y", "to": [x, y], "ink": "dark" | "light", "rot", "size" }— 帶有自行繪製箭頭的手寫文字,指向to。puppets:{ "image", "path": [[t, x, y, width, rotation], …], "sound", "exit", "flip", "wobble" }— 在關鍵影格之間移動的切割道具(t 為鏡頭內的秒數,x、y 為中心)。一個寬度為 0 的關鍵影格緊接一個全寬的關鍵影格即為彈出。除非"exit": true,否則道具會停留在最後一個關鍵影格。sound在其第一個關鍵影格播放。screen:{ "rect": [x, y, w, h], "off", "static", "plate", "plateAt" }— 電視或手機螢幕,在off之前為黑色,static之前為雪花雜訊,並從plateAt開始顯示plate(同一關鍵影格但螢幕已清空),以便紙偶可從中爬出。sounds:[[t, "kind"], …]—click、tvon、static、ghost、boing、tap、pop、whoosh、land、stab、sip、sparkle、chime、paper、scribble、cut。剪輯、字幕、標籤、螢幕和有sound的紙偶會自動獲得對應音效。
最後一張卡片
end:len、bg(9:16 彩繪牆壁)、wordmark(wordmarkY、wordmarkWidth)、name(nameY、nameSize)、line(lineY)、note 在撕紙碎片上(noteX、noteY)、cta 在膠囊形按鈕上(ctaY),以及 puppets 如鏡頭般(從邊緣滑入手中的產品、角色、星星)。每個都有對應的 …At 時間。
欄位
| 欄位 | 必要 | 備註 |
|---|---|---|
reel | 是 | 相對於 JSON 檔案的影片檔案路徑 — 所有片段鏡頭由 scripts/reel.mjs 剪輯為一個無聲的 9:16 連續片段(reel.mp4) |
shots | 是 | 2-10 個項目的列表:clip、from、to、speed、hold、still、len — 按順序排列的影片:片段鏡頭(靜態照片的 AI 片段)和靜態鏡頭(帶有緩慢移動的靜態照片);另請參閱 SKILL.md、鏡頭 |
end.bg | 否 | 相對於 JSON 檔案的圖片路徑 — 最後一張卡片的背景:來自照片的彩繪牆壁或背景,9:16 |
end.wordmark | 否 | 相對於 JSON 檔案的圖片路徑 — 透明背景上的品牌字標(scripts/generate.mjs wordmark) |
end.name | 否 | 文字,少於 4 個單詞 — 產品名稱,最後一張卡片上手寫字體 |
end.line | 否 | 文字,少於 6 個單詞 — 名稱下方的一行簡短說明,例如口味 |
end.note | 否 | 文字,少於 4 個單詞 — 在撕紙碎片上,例如「萬聖節限定」 |
end.cta | 否 | 文字,少於 12 個單詞 |
music | 否 | 相對於 JSON 檔案的音訊檔案路徑 — 來自 scripts/sfx.mjs 的配樂(stage.m4a) |
palette | 否 | 顏色為 #RRGGBB;鍵值:ink(字幕和深色標籤)、paper(撕紙碎片和淺色標籤)和 accent(行動呼籲膠囊按鈕) |
提示
- 撰寫緊湊的片段提示詞:一或兩個小動作、面無表情的臉、「杯子保持直立不動,標籤朝向攝影機」。大動作會模糊臉部和標籤。
- Kling 自行選擇時機:觀察動作落點,並將點擊、剪輯和紙偶放在該畫格上,而非整數時間點。
- 為故事提供一個旅行者:從一張照片切割出的紙偶,出現在後續鏡頭中,可將七張靜態照片連結成一部影片。
- 從照片本身切割紙偶,而非使用新的美術素材:相同的顏料、紙張和光線使它們具有歸屬感。
- 保持字幕在三四個單詞內;圖片講述了大部分故事。
輸出
H.264 MP4,1080 × 1920,30 fps(畫面以每秒 12 步移動),15-20 秒含音效,外加一個宣傳幀(PNG)。