/motion — 劇本 → 動態圖形影片(含旁白)
輸入:一份劇本(貼上的文字或 .txt/.md/.docx 檔案)。無實拍影片;全部為全螢幕動畫場景。
輸出:<資料夾>/<NAME>_MOTION/ 內含 <NAME>.mp4(H.264 + AAC,−14 LUFS)、<NAME>.srt、<NAME>_premiere.xml(可編輯專案)、Assets/{Escenas,Subtitulos,Overlay,Voz,Musica,SFX}、LEEME.md 與 .work/(可保留,供 v2 使用)。
與使用者使用阿根廷西班牙語(voseo)溝通。在長時間步驟之間告知進度。
路徑:SK = 此技能資料夾(Claude Code:~/.claude/skills/motion;Codex:~/.codex/skills/motion)。
PY = 技能的 Python 直譯器:$SK/.venv/bin/python -I(Windows:$SK\.venv\Scripts\python.exe -I)。所有 .py 腳本皆使用此直譯器。
場景目錄:$SK/reference/escenas.md · 完整範例:$SK/reference/ejemplo/(script.json + story.js)。
若 doctor.py 標示 ✗:執行 bash $SK/scripts/install.sh(Windows:powershell -ExecutionPolicy Bypass -File $SK\scripts\install.ps1)。
0 · 初始問題(務必在製作前執行)
先讀取劇本,並執行 $PY $SK/scripts/brand.py list(已儲存的品牌)。然後一次性詢問所有問題(在 Claude Code 中使用 AskUserQuestion 工具;在 Codex 或其他平台則使用單一編號訊息)。使用者已提供的資訊則無需再問。
- 語音 — 女聲 或 男聲。預設為 阿根廷腔(edge-tts:
es-AR-ElenaNeural/es-AR-TomasNeural)。若使用者要求其他口音,則使用該國家的語音(tts.py voices es可列出所有語音:es-UY、es-MX、es-ES、es-CL、es-CO…)。若有ELEVENLABS_API_KEY且使用者追求更真實的效果,則提供 ElevenLabs 選項(tts.py voices eleven argentine)。 - 品牌 — 從已儲存品牌中選擇(顯示名稱),或選擇 新品牌。
- 格式 — 垂直 9:16(Reels/TikTok/Shorts,預設)· 正方形 1:1 · 4:5(動態消息)· 橫向 16:9(YouTube)。
- 音樂 — 充滿活力(Upbeat 110–140 BPM)· 溫暖/啟發性(Medium 90–110)· 企業/平靜 · 自備音樂(要求提供路徑)。
若為新品牌,則進行第二輪詢問(同樣一次性提出):
- 品牌名稱與 Logo(PNG/SVG 路徑,或「無 Logo」)和社群媒體帳號(例如
@consultorio)。若有 Logo:執行$PY $SK/scripts/brand.py colors <logo>並根據產生的顏色建議色票。 - 顏色 — 選項:從 Logo 提取 · 黑色 + 橘色(編輯風格)· 深藍 + 淺藍(健康/信任)· 綠色 + 奶油色(健康);或自行輸入十六進位色碼。需要 4 種:
dark(深色背景)、light(淺色背景)、accent(主要強調色)、accent2(次要強調色,可選)。 - 字體 —
brand.py fonts列出組合:Editorial condensed · Moderna geométrica · Impacto · Elegante(或直接輸入任何 Google Fonts 字體系列名稱)。 - 風格 — 字幕 是/否(預設為是),背景裝飾:顆粒 + 網格 + 色塊(預設)· 圓環 · 點狀 · 簡潔。
建立 $SK/brands/<slug>/brand.json:複製 brands/editorial/brand.json(每種字體僅保留 family、weight,標題則加上 upper/stretch/tracking/leading;強調字型則加上 italic),將 logo 設為絕對路徑,然後執行 $PY $SK/scripts/brand.py setup <slug>(下載字體、複製 Logo、檢查對比度:修正 ⚠️ 警告)。顯示預覽:node $SK/scripts/render.js --brand-preview=<slug> --out=<work>/marca.jpg --format=<格式> → 檢視圖片並展示給使用者;確認後再繼續(調整起來很快)。品牌會儲存供下次使用。
1 · 準備
NAME根據主題轉換為大寫底線連接形式。資料夾:劇本檔案所在位置,若為貼上文字則使用工作目錄。work=<資料夾>/<NAME>_MOTION/.work。$PY $SK/scripts/timing.py start "<work>"(計時器)與$PY $SK/scripts/doctor.py。config.json:
{ "name": "NAME", "out_dir": "/abs/<資料夾>/NAME_MOTION", "edit_dir": "/abs/<資料夾>/NAME_MOTION",
"format": "9:16", "fps": 30, "brand": "<slug>", "tail": 1.6, "keywords": ["單字","關鍵"], "sfx_max": 6,
"music": {} }
keywords = 劇本中 3–6 個會在字幕中強調的單字。可選:"captions": false、"logo_corner": false。
2 · 劇本 → 節拍 → 語音
劇本屬於使用者:請勿改寫內容。 僅拆分並調整發音。
- 將劇本拆分為節拍(1 個句子或想法,每個 2–6 秒;1 分鐘約 10–18 個節拍)。每個節拍通常對應一個場景。
say(可選)=當文字寫法會混淆語音時,標示實際發音方式:大數字("70 %" → "setenta por ciento")、縮寫("OMS" → "o eme ese")、符號、年份、縮寫。text保持原樣。pause=節拍後的靜音時間(預設:若結尾為句號/問號則 0.38 秒,否則 0.18 秒)。在重點或 CTA 前增加停頓(0.6 秒)。<work>/script.json:{"voice":{"engine":"edge","id":"es-AR-ElenaNeural","rate":"+5%"},"lead":0.35,"target":60,"beats":[{"id":"b01","text":"…"},…]}$PY $SK/scripts/tts.py "<work>"→ 產生voice.wav+words.json(每個單字的時間戳記)以及總時長。目標時長 ≈ 60 秒:- 超過 66 秒 → 調高
rate(最高+15%);若仍超時,向使用者提出具體的刪減建議並等待回覆。 - 時長較短 → 沒問題,無需拉長劇本(若語速顯得太趕,可將
rate降至-5%)。
- 超過 66 秒 → 調高
- 在心中聆聽節奏:若某個節拍過長(> 7 秒),則將其拆分。僅重新生成有變動的節拍(使用快取)。
3 · 音樂
- 若使用者提供音樂:
"music": {"path": "/abs/tema.mp3", "offset": 0}。 - 若無,則使用 Envato(一律為純音樂):
$PY $SK/scripts/envato.py search "<work>" music "<英文風格>" --mood <情緒> --tempo "<速度>" [--genre <類型>]。根據音調和能量曲線選擇(平穩,前 1 分鐘無長時間低谷),然後執行$PY $SK/scripts/envato.py use "<work>" music <搜尋結果>#<編號>。設定offset(能量部分開始的秒數;參考曲線 ▁▂▃█)。 mix.py自動調整音量:片頭(intro−8 dB)、語音期間(bed−21 dB)、片尾(outro−10 dB)並淡出。可在config.music中調整。- Envato 預覽音訊含浮水印:交付時需告知使用者需取得授權。使用已登入 Envato 的瀏覽器:詢問一次確認,以影片名稱授權並下載 WAV;否則提供連結給使用者。之後執行
$PY $SK/scripts/envato.py collect "<work>",然後僅重新執行mix.py(無需重新渲染)。
4 · 分鏡腳本 → <work>/story.js
參考 reference/escenas.md 與 reference/ejemplo/story.js。每個場景依序呼叫一次 S(type, start, params):
start:節拍 ID('b03')或w('單字')(從該單字開始)。場景持續至下一個場景開始;第一個場景從 0 開始。- 在 params 中,所有內部時間皆與語音同步,使用
w('單字')(若為該單字第二次出現則使用w('單字', 1)):列表項目、計數、印章、訊息、CTA 按鈕。 - 通用參數:
bg('dark'|'light'|'accent'|'accent2';若省略則交替使用)、tr('wipe'|'slide'|'circle'|'push'|'zoom'|'cut';若省略則輪流使用)、cap:false(無字幕)、sfx(null= 無音效 ·'pop'·[['ding',1.2]])。 - 文字輔助函數:
H('文字')= 色塊中凸顯的文字 ·A('文字')= 強調色文字。
導演準則(強制遵守):
- 開場 2 秒內吸引目光:使用
question、bigword、kinetic或強烈title,背景為accent。第一個場景切換應在 3–4 秒內發生。 - 節奏:每 3–5 秒一個場景(每分鐘 12–18 個場景)。靜止時間不超過約 5 秒:若場景較長,應逐步建構(同步項目)。
- 多樣性:避免連續重複相同場景類型;最多連續 2 個
kinetic;在文字場景與圖形場景(stat、bars、donut、icons、steps、compare、phone)之間交替。 - 展示,而非重複:螢幕上顯示的文字應為關鍵字、數據與結構,而非完整句子(但
kinetic/quote例外,它們在朗讀時顯示完整句子並關閉字幕)。 - 數據 →
stat/bars/donut。列舉 →list/steps/icons。對比(迷思/現實、之前/之後)→compare。提問 →question。對話/訊息 →phone。結尾 →bigword。使用者照片 →image。 - 以
cta結尾(追蹤/評論特定單字/儲存/連結),並與劇本說詞同步。 - 簡短文字:每行標題 1–3 個單字,項目 ≤ 6 個單字。
5 · 規劃、測試與渲染
node $SK/scripts/render.js "<work>" --plan→ 顯示場景時間、音效與導演提示。修正所有 ⚠️ 警告並重複。node $SK/scripts/render.js "<work>" --test --at=0.3,mid,end→ 產生<work>/sheet.jpg(每個場景 3 幀:進入時、中間、完成時)。檢視此圖表並修正:文字縮放過小(提示「縮小至 N %」)、裁切、與字幕重疊、對比度不足的顏色、中間空白的場景(內容需快速出現)。- 最終渲染(背景執行,約每分鐘影片需 1 分鐘):
node $SK/scripts/render.js "<work>"→ 產生<work>/video.mp4。 $PY $SK/scripts/mix.py "<work>"→ 在out_dir中產生<NAME>.mp4+<NAME>.srt。- Premiere 專案(預設始終產生;僅當
config.premiere為false時跳過):node $SK/scripts/render.js "<work>" --premiere(背景執行,約 2–3 分鐘)與$PY $SK/scripts/build_xml.py "<work>"。軌道:V1 場景(每個剪輯一個,已合成入場轉場)· V2 字幕(含 Alpha)· V3 Logo · A1 語音(每個句子一個剪輯)· A2 音樂(含音量關鍵影格)· A3+ 音效。每個場景加入標記。 - 檢視最終 MP4 的 3–4 幀(
ffmpeg -ss <t> -i <mp4> -frames:v 1 x.jpg)以確認。
6 · 交付
$PY $SK/scripts/timing.py report "<work>"。- 在
out_dir中產生LEEME.md:如何在 Premiere 中開啟(檔案 → 匯入 →<NAME>_premiere.xml;請勿移動或重新命名資料夾;軌道表格;可在 Premiere 中編輯的內容 — 剪下/移動/刪除場景、重新調整語音句子時間、更換音樂與音量、移除音效、使用.srt作為原生字幕 — 以及不可編輯的內容:每個圖形中的文字,需透過 Claude 修改)、使用的語音、品牌、格式、時長、結構(場景 → 文字 → 時間表格)、音樂(使用envato.py report並標示是否需授權)、音效、處理時間、如何要求修改。 - 簡短回覆:MP4 與 XML 路徑、時長、選擇的語音與音樂(若音樂為未授權預覽則告知)、重點場景、總處理時間。
版本(v2、調整)
重複使用 .work:修改 script.json(語音/文字:僅重新生成有變動的節拍)及/或 story.js,將 out_dir 指向 <NAME>_MOTION_v2,並從對應步驟開始重複(僅更換音樂或音量 → 僅執行 mix.py + build_xml.py;視覺變更 → 渲染 + mix + render.js --premiere --only=<場景編號> + build_xml.py;文字變更 → tts + 全部重新執行)。
在已匯入 Premiere 的圖形中更改文字:編輯 story.js 並執行 render.js --premiere --only=N(僅重新渲染該場景,保持相同檔案名稱),若需要 MP4 則一併渲染,並告知使用者在 Premiere 中對該剪輯按右鍵 → 取代/連結媒體(或關閉並重新開啟專案)以查看變更。若場景時長改變,需重新產生 XML 並重新匯入。新增場景:按照 escenas.md 將其加入 engine/engine.html。
技術備註
- Premiere 圖層:場景使用 ProRes 422 HQ(不透明);字幕與 Logo 使用 ProRes 4444(含 Alpha)。Premiere 中的音訊約比 MP4 低 2 dB(MP4 已進行最終 −14 LUFS 標準化)。
- 引擎:
engine/engine.html使用 Chrome(puppeteer-core)逐幀渲染,並行處理,輸出 H.264 yuv420p。所有場景均為時間的純函數。 - 每個場景的內容會自動縮放以適應安全區域(依格式而定),不超出範圍;若縮放過多則發出警告。
- 音效:若已安裝技能
edicion,則使用其音效庫(或使用自身assets/sfx搭配相同catalog.json);若無音效,則略過。 - 語音:edge-tts 使用 Microsoft Edge 語音服務(需網路,無需金鑰)。ElevenLabs:
{"engine":"eleven","id":"<voice_id>"}+ 環境變數ELEVENLABS_API_KEY。 - 請勿使用
rm -rf搭配相對路徑的 glob 模式。