動畫影片
你正在根據一個故事製作一部短篇卡通電影。使用者會提供你一個故事、一句故事梗概、一個場景列表或一個腳本。你需要交付一個完成的 mp4 檔案以及一段 Instagram 貼文說明。你必須獨立完成所有步驟,並且過程中不得停下來請求批准。
此技能製作的影片看起來像是手繪動畫:角色會擠壓、拉伸、眨眼和做出反應,鏡頭從不靜止,帶有紙墨質感,且畫面與旁白精準同步。它們絕對不能看起來像是一串由靜態圖片與文字組成的幻燈片。此技能中的所有一切都是為了可靠地達成這個成果而設計,因此請依序執行步驟,並使用提供的工具包,而不是發明你自己的系統。
以下SK代表此技能的資料夾:~/.claude/skills/animation-video。
運作方式(請閱讀一次)
- 整部電影是一個你編寫的 JavaScript 檔案
film.js。它描述了在任何時間點t螢幕上顯示的內容。一個腳本會在無頭瀏覽器 (headless Chrome) 中逐幀渲染,然後 ffmpeg 將其製作成 mp4 檔案。過程中不會使用影片編輯器或影像生成工具。 - 旁白會先被逐行產生。其真實的時間點會被寫入
timeline.js中。影片中的每個時刻都是相對於旁白來定義(例如「第 4 行開始前 0.2 秒」),這樣畫面與旁白就不會不同步。 - 工具包為你準備好了困難的部分:一個引擎(包含緩動、鏡頭、場景、字幕)、兩種完整的藝術風格(含角色、姿勢與道具),以及 25 個經過測試的動畫配方。
- 你必須透過渲染靜態幀並仔細查看來檢查你的工作成果。這不是一個可選步驟。你無法判斷一部你沒看過的電影的好壞。
步驟
根據這些步驟建立待辦事項清單,並依序完成。
| # | 步驟 | 結果 |
|---|---|---|
| 0 | 預檢 | 所有工具就緒,VoiceStudio 正在執行 |
| 1 | 閱讀故事,選擇風格 | 做出決定,建立專案資料夾 |
| 2 | 編寫腳本 | vo/script.json,最多 130 個口語詞 |
| 3 | 產生旁白 | 每行一個已檢查的 wav 檔案 |
| 4 | 建立時間軸 | timeline.js,影片長度 35-45 秒 |
| 5 | 規劃鏡頭 | 一個鏡頭規劃的註解區塊,放在 film.js 頂部 |
| 6 | 編寫電影 | 逐場景編寫 film.js,邊進行邊檢查靜態幀 |
| 7 | 審查整部電影 | 查看連續幀圖,修正缺陷 |
| 8 | 匯出 | mp4 檔案 |
| 9 | 交付 | mp4 + 含旁白腳本 + Instagram 貼文說明 + 誠實的備註 |
步驟 0 - 預檢
bash ~/.claude/skills/animation-video/scripts/preflight.sh
每一行都必須顯示 OK。如果 VoiceStudio 狀態為 MISSING,請要求使用者開啟 VoiceStudio 應用程式並等待;切勿改用其他語音或跳過旁白。對於其他任何問題,請使用腳本列印的指令來修復。
步驟 1 - 閱讀故事並選擇風格
除非完全沒有故事,否則不要問使用者問題。請自行決定以下事項:
- 風格。 有兩種風格可供選擇。請查看
SK/references/characters-ink.jpg和characters-paper.jpg(使用 Read 工具開啟影像)來了解它們的樣子。ink:粗獷搖擺的墨水輪廓線、厚實的襯線招牌、溫暖復古的卡通風格。最適合有反派、鬧劇、商店、街道、肢體搞笑元素的故事。paper:剪紙拼貼風格,沒有輪廓線,柔和的陰影,優雅的襯線字體。最適合關於電話、應用程式、連結、自然、較柔和或較現代氛圍的故事。- 如果使用者指定了風格,就使用它。否則,如果工作資料夾中已經有較早的單集,請使用另一種風格(執行
head -3 */style.js 2>/dev/null查看之前使用的是哪一種)。否則,根據故事內容挑選。
- 角色。 誰是英雄(小企業主或主要角色)?誰或什麼是阻礙(一個反派、一個困惑的顧客、一個迷宮)?兩個主要角色就足夠了。
- 專案資料夾。 根據故事取一個簡短的名稱,放在使用者的工作資料夾中。
bash ~/.claude/skills/animation-video/scripts/new_project.sh "./film-<short-name>" ink # 或 paper
這會建立一個專案,裡面有一個可運作的起始 film.js。現在就閱讀這個起始檔案:它很短,並展示了你需要遵循的明確結構。
步驟 2 - 編寫腳本
首先閱讀 SK/references/story.md。裡面有結構、字數限制以及工作範例。最重要的規則如下:
- 總共最多 130 個口語詞。 旁白大約每秒說 3.2 個詞,所以 130 個詞大約是 43 秒。如果使用者的腳本更長,請自行刪減,保留他們最好的台詞和故事的順序。不要問;在最後告訴他們你刪減了什麼。一部節奏明快的短片總是比一部冗長拖沓的短片好。
- 每個節拍一行,每行 5-16 個詞,編號為
l01、l02……。每行會變成一個音訊片段,通常也是一個視覺創意。 - 為聽覺而寫:數字用文字表示(「四十」而非「40」),不用表情符號,不用符號,品牌名稱按照發音拼寫(例如 "Site Keep" 而非 "SiteKeep")。
- 最後一行是一個鉤子,鼓勵觀眾留言(請參閱下方的品牌預設值)。
將其寫入 <project>/vo/script.json:
{"l01": "Meet Maya. She makes custom treats from scratch.",
"l02": "So she set up shop inside a giant online marketplace."}
步驟 3 - 產生旁白
python3 ~/.claude/skills/animation-video/scripts/voice.py "./film-<short-name>"
這大約需要每行 20 秒(完整腳本約 4-5 分鐘):設定 10 分鐘的超時時間來執行它。如果中途停止,再次執行同一個指令;已經產生的行會被保留。它會使用使用者的語音(設定檔 3a02464e,「ep1 D sample-locked」,英語,steps 16,speed 1.0,無指示文字;這些是預設值,除非使用者要求,否則不要更改)為每一行產生語音,然後再次聆聽,並為每一行列印 OK 或 DIFF 以及它聽到的內容。
閱讀每個 DIFF 行並決定:
- 沒問題: 相同的詞但寫法不同(「SiteKeep」/「Site Keep」、「40」/「forty」、「two」/「to」、標點符號)。
- 有問題: 一個詞遺漏、新增,或是一個不同的詞(「her menu」聽成「our menu」)。只重新產生那些有問題的行:
voice.py <project> --only l05 l11。如果一行在再嘗試兩次後仍然失敗,請在script.json中稍微修改那一行的措辭,然後重新產生。
絕對不要交付任何有遺漏、新增或錯誤詞語的行。
步驟 4 - 建立時間軸
python3 ~/.claude/skills/animation-video/scripts/audio.py timeline "./film-<short-name>"
它會列印總長度以及每行的開始時間和持續時間。然後在 <project>/film.json 中調整暫停時間,並再次執行它:
{"lead": 0.55, "gap": 0.4, "tail": 1.6, "gaps": {"l04": 0.7, "l09": 0.9}}
gap是行與行之間的預設暫停時間。對於視覺上需要更多時間來呈現效果的行,例如一個搞笑橋段、一次墜落、一個重大揭露、故事轉折點,給予較長的暫停時間(0.6-0.9 秒)。- 對於屬於同一個思路的幾行,使用 0.25-0.35 秒的暫停時間。
tail是最後一個詞說完後,片尾卡片的停留時間(1.4-1.8 秒)。- 目標總長度:35-45 秒。超過 46 秒:從腳本中刪除一行,並為這一行重做步驟 3-4。
每當你稍後重新為某行配音時,請再次執行 audio.py timeline。因為每個提示點都是相對於旁白的,影片會自動重新同步。
步驟 5 - 規劃鏡頭
閱讀 SK/references/story.md 中的「從腳本到鏡頭」章節。然後將規劃寫成一個註解區塊,放在 film.js 頂部(不是一個單獨的文件)。每個場景一行:
/* 鏡頭規劃
A l01-l02 街道,白天 Maya 從她的攤位後面突然出現,揮手。鏡頭:緩慢推近。
B l03-l04 同一街道 房東的影子籠罩她,招牌砰地一聲砸下(震動,灰塵)。她跳起來。
C l05 地下室 地板門打開,她懸在半空中,墜落。鏡頭跟著向下。
...
Z l12 片尾卡片 圓圈擦除。問題 + 「在留言區分享你的看法」。英雄探頭進來。
*/
一個好的規劃包含:5-8 個場景;至少每 6 秒更換一次畫面;每個場景都有一個明確的視覺搞笑橋段或驚喜;每個抽象概念都轉化為具體的實物(費用變成收費站,演算法變成陷阱門,令人困惑的連結變成叢林);情緒從困境轉向找到解決方案的寬慰;以及一個片尾卡片。
步驟 6 - 編寫電影
在開始編寫之前,請先閱讀以下文件(它們很短,並且是優秀影片與失敗影片的區別所在):
SK/references/engine.md- 你可以呼叫的所有函式。SK/references/kit-ink.md或kit-paper.md- 你所用風格的角色、姿勢和道具。SK/references/recipes.js- 25 個經過測試、可以複製的動作。也可以看看recipes-<style>.jpg。SK/references/craft.md- 使其看起來像手繪動畫的時間數字和規則。
然後在起始結構的四個部分中編寫 film.js:設定、提示點時間、音效提示點、場景。
一次處理一個場景。 編寫場景 A,渲染該場景的兩到三個靜態幀,查看它們,修正,然後再進行場景 B:
node ~/.claude/skills/animation-video/scripts/render.mjs "./film-<short-name>" stills 1.2 3.5 6.0
然後使用 Read 工具開啟 <project>/check/sheet-1.jpg。如果指令列印 PAGE ERROR,表示電影有 JavaScript 錯誤:修正第一個列印的錯誤,然後再次執行。
film.js 的十個規則(每一條都防止了一個實際發生過的失敗情況):
- 只編輯
film.js(以及style.js中的顏色,如有需要)。絕對不要編輯engine.js或index.html。 - 絕對不要直接輸入原始時間。每個提示點都必須從旁白建構而來:
L('l04')(行開始)、E('l04')(行結束)、wt('l04', 'three rival')(當一個片語被說出時),加上或減去一個小的偏移量。為每個提示點命名:const tSlam = L('l04') + 0.25;。 - 在一個詞被說出前 0.1-0.3 秒開始動作,使其精準地落在該詞上。
- 姿勢和物體使用
q(時間以每秒 12 幀離散化:營造手繪動畫的感覺)。鏡頭、震動和擦除使用t(平滑)。 - 在提示點之前,任何東西都不可見。使用
pop(...)或if (q < tCue) ...讓物件在旁白提到它們時才出現,而不是更早。 - 不要使用
Math.random()、Date、CSS 動畫或setTimeout。使用h(n)來獲取隨機性。對於同一個t,電影必須每次都能給出相同的畫面。 - 繪製背景時,要比螢幕大得多(例如 x 從 -1000 到 2080),這樣鏡頭移動和震動就不會露出空白邊緣。
- 繪製順序即深度:後繪製的東西在前。背景優先,然後是遠距離物體、角色、近距離物體,最後是特效。
- 保持重要元素在 x 70-1010 和 y 180-1400 的範圍內。字幕位於 y 1420-1560,而 Instagram 自身的按鈕會覆蓋 y 1600 以下以及右邊緣的所有區域。
- 每個音效都屬於一個可見事件,並使用
sfx(time, name)在與事件相同的提示點時間宣告。在困境部分使用一個music(...)背景音樂,在寬慰部分使用另一個。
品質標準。 在你認為一個場景完成之前,它必須具備以下所有條件:
- 每一幀都有生命力。 英雄會眨眼和呼吸 (
POSE.idle(q)),背景中有東西在移動(雲、搖曳的招牌、漂浮的形狀),並且鏡頭至少有一個緩慢的推近動作。任何超過一秒沒有東西移動的幀都是缺陷。 - 進場和退場是動畫化的, 而不是簡單的剪接:使用帶有 overshoot 效果的彈出、帶有 bounce 效果的掉落、跳入、帶有預備動作的快速移出(配方 1-6)。
- 撞擊效果同時發生在同一幀: 擠壓 + 螢幕震動 + 灰塵或爆發效果 + 音效(配方 3)。這個單一元素比其他任何東西都更能提升「感覺」。
- 角色要會「演戲」。 他們會看向正在發生的事件 (
look),在事件發生後延遲一個節拍做出反應(配方 9),並在故事情緒改變時變換姿勢和表情。絕對不要讓一個角色在整個場景中保持一個姿勢。 - 每個場景都有一個搞笑橋段, 讓概念變得具體且稍微有趣。
- 文字可讀。 標誌和標籤至少要有 40 像素高,1-4 個單詞,高對比度,在螢幕上至少停留 1 秒鐘,並且絕對不能被角色或字幕遮擋。
- 場景之間有真實的轉場效果(配方 19-20,或在同一個世界內的快速鏡頭移動),而不是僅僅一個畫面取代另一個。
步驟 7 - 審查整部電影
node ~/.claude/skills/animation-video/scripts/render.mjs "./film-<short-name>" check 36
使用 Read 工具開啟兩個連續幀圖(check/sheet-1.jpg、sheet-2.jpg)。每個圖按時間順序顯示 18 幀,從左到右,從上到下;時間點會由指令列印出來。對每一幀檢查以下清單,並在修正任何問題之前先記錄下來:
- 文字被截斷、與其他文字重疊,或被角色或道具遮擋
- 字幕遮擋了重要元素,或品牌名稱被拆分或拼寫錯誤
(設定
CAPTION.replace,或將動作上移) - 有大片空白區域(超過三分之一畫面沒有任何東西):將鏡頭拉近,或移動物件,或添加背景細節
- 在旁白提到之前就有東西可見,或應該消失後仍然存在
- 角色或關鍵道具部分超出畫面、太小(低於 250 像素高)或被隱藏
- 手、手臂或物體穿過了它應該在其前面或後面的東西
- 連續兩幀(相隔 2+ 秒)看起來完全相同:添加動作或鏡頭移動
- 對於故事當下時刻,角色臉上的表情錯誤
- 片尾卡片:問題可讀,留言提示可見,無重疊
修正你發現的問題,然後只渲染那些時間點的靜態幀來確認(render.mjs <project> stills 4.2 11.8)。當連續幀圖太小難以判斷時,請以全尺寸查看單個幀(check/f003.jpg)。最多進行兩輪完整的審查;不要無止境地打磨,但也不要跳過審查步驟。
步驟 8 - 匯出
bash ~/.claude/skills/animation-video/scripts/build.sh "./film-<short-name>" "./<short-name>.mp4"
這需要 2-10 分鐘(紙張風格較慢):在背景執行,或設定一個 10 分鐘的超時時間。它會渲染每一幀,混合旁白、音效和音樂,並列印一個檢查結果。確認:h264 1080x1920 30 fps,aac 音訊,長度等於時間軸總長度,平均音量在 -16 到 -19 dB 之間。如果渲染列印 PAGE ERROR,修正它並再次執行。
步驟 9 - 交付
以這個確切格式給使用者(只需替換 {...} 中的文字):
🎬 你的動畫短片,{story-name}
影片:{output.mp4}
腳本(含旁白):{script}
IG 貼文說明:
{一段引人入勝的貼文說明,<50 個中文字。結尾用 3-5 個相關的 hashtag。}。
備註:{如果腳本被縮短了,這是腳本原本的長度以及你刪減的內容。}
品牌預設值
使用這個,除非使用者有他們自己的。
- 故事背景: 小企業主在大型線上市場中
- 英雄: 充滿創意、盡心盡力的店鋪老闆
- 反派: 複雜的規則、隱藏費用、令人困惑的演算法
- 語氣: 溫暖,帶點淘氣
- 結尾問題: 「你遇過最奇怪的市場規則是什麼?」
- 呼籲行動: 「在留言區分享你的故事 👇」
- Hashtag: #SmallBizStruggles #MarketplaceLife #EcommerceTips