explainer-video-pipeline(自動產生)
使用時機
使用者想要一段 1-3 分鐘的旁白解說影片,主題可以是科學、產品或技術,最終產出為一個包含語音、字幕、音樂和音效的 MP4 檔案。
參數與預設值
只詢問主題;除非使用者指定其他值,否則使用所有預設值。在第一行中說明你使用了哪些值。
| 參數 | 預設值 | 其他數值 |
|---|---|---|
topic | 必要 | — |
storyboard_model | claude-opus-5.5 負責撰寫腳本、旁白與故事板 | 任何來自 kiro-cli chat --list-models 的模型 ID |
video_engine | opus-5.5:claude-opus-5.5 為每個場景撰寫繪製影格的程式碼 | 其他程式碼模型,例如 claude-sonnet-5.5;seedance(BytePlus ModelArk API,需要 ARK_API_KEY);hybrid(在程式繪製場景中嵌入 Seedance 片段) |
renderer | remotion(React/SVG;Remotion 逐幀驅動無頭 Chromium) | html(Canvas 2D / SVG / GSAP / p5.js 頁面,透過 Playwright 捕捉);manim(Manim Community 場景;最適合幾何、圖表、向量與逐步推導) |
seedance_model | seedance-1-5-pro-251215 | 使用者的 ModelArk 帳戶中啟用的任何 Seedance 模型 |
tts | polly,神經語音 Zhiyu,cmn-CN,us-east-1 | gtts(免費,無需金鑰,語調較平);任何其他 Polly 語音/語言 |
captions | 開啟:Whisper 逐字時間戳,燒錄為逐字高亮的字幕 | 關閉 |
whisper_model | small(CPU,int8;約 5 秒處理 10 秒語音) | base(更快),medium(時間更準確) |
music | synth(使用 ffmpeg 製作的免版稅振盪器背景音樂) | none;使用者擁有的音樂檔案路徑 |
sfx | 開啟:scenes.json 中列出的音效事件會被合成並放置到對應影格 | 關閉:從每個場景中移除 sfx |
language | 國語旁白 | Polly 與 Whisper 皆支援的任何語言 |
size、fps | 1920×1080、30 fps | 1080×1920 垂直畫面 |
「使用 Opus 5.5 製作」表示 Opus 5.5 是作者:它負責撰寫腳本與繪圖程式碼,然後由渲染器將程式碼轉換為像素。沒有任何文字模型直接輸出影片;只有 Seedance 可以。在首次回覆中說明一次。
如果當前 session 已在 claude-opus-5.5 上執行,則由你自行撰寫。否則,使用 model="claude-opus-5.5" 和 keep=true 啟動一個任務來處理故事板(步驟 2),然後使用 spawn_continue 在同一個執行中繼續場景程式碼(步驟 5),最後由你審查其輸出。
設置(每台機器一次)
將工具放在穩定的快取目錄中(例如 ~/.cache/explainer-video/),絕對不要放在 $KIROCREW_SCRATCH 中,因為該目錄會在 session 之間被回收。
- ffmpeg:一個完整的靜態建置,需包含
aevalsrc、anoisesrc、tremolo、sidechaincompress和ass/libass。Remotion 內建的 ffmpeg 缺少這些功能。將FFMPEG/FFPROBE指向該建置。 - Python venv(
boto3 gTTS playwright faster-whisper pillow numpy),然後在該 venv 中執行python -m playwright install chromium-headless-shell。faster-whisper 1.2.x 在 PyAV 19 上會出錯(unexpected keyword argument 'metadata_errors'):將av==16.1.0固定住。將HF_HOME設定為快取目錄,以便 Whisper 模型只下載一次。 - Manim(僅用於
renderer=manim):pip 無法在 aarch64 上建置它(沒有 pycairo、manimpango、moderngl 的 wheels)。在沒有 root 權限的情況下,使用 micromamba:micromamba create -p <cache>/manim-env -c conda-forge python=3.12 manim。Text()可以使用 CJK 字型。MathTex/Tex需要 LaTeX 發行版與dvisvgm;conda-forge 的texlive-core在 aarch64 上沒有latex.fmt,因此在該平台上公式會失敗。使用Text()(Unicode:F = m·a、x²、√、→)來撰寫公式,或在使用者可以的地方安裝系統 TeX Live。
步驟
輔助工具位於此技能的 scripts/ 資料夾中。
- 專案。 在使用者的工作區中建立一個 git 儲存庫的專案資料夾。對於
renderer=remotion,手動建立package.json、tsconfig.json(resolveJsonModule: true)、src/index.ts、src/Root.tsx,然後執行npm i remotion @remotion/cli react react-dom。 - 腳本與故事板(由
storyboard_model負責)。撰寫scenes.json:每個場景一個物件,包含id、narration(口述台詞)、visual(螢幕上的內容)、可選的manim(Scene 類別名稱)以及可選的sfx:[{"at": FRAME_IN_SCENE, "kind": "whoosh|hiss|pop|rise|thud|PATH"}]。使用 6-10 個場景,每個場景一個概念,包含一個標題場景和一個結尾卡。使用網路搜尋檢查事實,並在 README 中引用來源。 - 參考圖片。 當影片顯示真實物體時,要求或找到一張清晰的照片,並將其保存在
ref/中。永遠不要憑記憶繪製真實物體的形狀:對照片執行邊緣偵測,測量關鍵點,然後使用儲存在儲存庫中的小腳本從這些點生成形狀。 - 旁白驅動時間。 執行
narrate.py scenes.json . --tts polly。它會寫入durations.json(每個場景的影格數,根據實際語音長度加上填充時間計算)、narration.wav和audio/sNN.mp3。場景程式碼會讀取durations.json,因此每個場景的長度會與其台詞完全一致。 - 場景程式碼(由
video_engine負責)。remotion:每個場景一個 React 元件,使用useCurrentFrame和相對於場景起始點的interpolate/spring進行動畫。html:一個index.html,包含window.seek = async (frame) => {...},它會根據影格編號和durations.json陣列繪製出精確的影格。不要使用requestAnimationFrame、不要使用牆上時鐘、不要使用未設定種子的Math.random。將durations.json陣列作為常數貼到頁面中:以file://方式開啟的頁面無法fetch()本機檔案,而且失敗是靜默的。GSAP:暫停時間軸 +tl.seek(frame / fps)。p5.js:noLoop()+seek中的redraw()。manim:一個scenes.py,每個場景一個 Scene 類別。從os.environ["SCENE_SECONDS"]讀取目標長度,並以self.wait(max(0.04, secs - self.renderer.time))結束;動畫的長度也要根據secs來調整。保持影格底部 15% 的區域空白以顯示字幕。seedance:在設定了ARK_API_KEY的情況下執行seedance_clips.py scenes.json .;它會下載clips/<id>.mp4(URL 在 24 小時後過期)。
- 在完整渲染前檢查靜止畫面。 渲染 4-6 個影格,每個關鍵場景一個,將它們組合成一個縮小的聯絡表(contact sheet),然後查看該單一圖像。若要進行獨立檢查,請啟動一個新的審查者,只提供聯絡表和
scenes.json。 - 音效。 如果任何場景有
sfx,則執行sfx.py scenes.json .。然後執行mix_bgm.py . --music <music>:它會在語音下降低音樂音量,加入sfx.wav,寫入narration_bgm.wav,並列印 RMS 電平。僅音樂的開頭部分應約為 −20 至 −30 dB;−55 dB 或更低表示聽不見。 - 字幕。
captions.py scenes.json . --size <WxH>使用 faster-whisper 逐字時間戳轉錄每一行,並將其對應到腳本本身的字元,因為 Whisper 會聽錯同音字(它曾將「氣體」聽成「漆體」)。它會寫入captions.ass(每個字元在發音時高亮顯示)和words.json(每個字元的時間,可用於步驟 5 的螢幕強調效果)。 - 渲染(無聲畫面)。
remotion:npx remotion render src/index.ts <Comp> out/silent.mp4。html:capture_html.py index.html out/silent.mp4 --frames <durations.json 的總和>。manim:manim_scenes.py scenes.py . --manim <manim-env>/bin/manim --quality h。它會渲染每個類別,並將其填充或修剪至精確的影格數。
- 使用 FFmpeg 合成。 若有字幕:
ffmpeg -i silent.mp4 -i narration_bgm.wav -vf "ass=captions.ass" -c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac -b:a 192k -shortest final.mp4(無字幕時,使用-c:v copy並省略-vf)。檢查影片與音訊的長度相差在約 0.1 秒內,然後從最終的 MP4 中提取 4-5 個影格並查看,其中一個影格應在句子中間,以檢查字幕高亮。 - 發布。 提交到一個功能分支,開啟一個 PR,在合併後使用
gh api repos/<o>/<r>/git/trees/<base>?recursive=1確認檔案已正確上傳。
常見陷阱
- 永遠不要在 SVG 路徑
d=字串內放入/* */註解;Chromium 會在/處停止解析。使用 6 位十六進位顏色。 - 使用硬編碼絕對影格編號的程式碼可能會在高潮發生時,其場景已經結束。
- 在 Manim 中,請在物體移動後放置標籤和箭頭(或使用
always_redraw/add_updater附加它們),否則它們會停留在原來的位置。DashedVMobject本身沒有點:從一個普通的形狀取得位置。 - 透過 pip 安裝的 Playwright 可能需要比已快取版本更新的 Chromium 建置。
- 不要同時使用多個
strReplace調用編輯同一個檔案;編輯內容可能會遺失。不要透過 shell heredocs 撰寫程式碼;防護措施可能會封鎖它們。 - Seedance 2.x 模型需要帳戶啟用,並且會拒絕包含真實人臉的參考圖片。Seedance 1.5 pro 片段長度為 4-12 秒。
- Remotion 授權:個人及 3 人以下的公司免費;較大的公司需要付費的公司授權。
html和manim可以避免這個授權問題。