Communitygithub.com

liangruibupt/explainer-video-pipeline

製作帶旁白的解說影片(Opus 故事板、程式繪製影格、Polly 語音、字幕、音樂、音效),並可切換不同的渲染器。

explainer-video-pipeline 是什麼?

這是一個 AI 代理技能,用於自動化產出 1-3 分鐘的旁白解說影片,涵蓋科學、產品或技術等主題。使用者只需提供主題,系統便會使用 Claude Opus 5.5 撰寫劇本與故事板,並透過程式碼繪製每個影格,再交由 Remotion、HTML/Playwright 或 Manim 等渲染器輸出影片。技能支援多種語音合成(Amazon Polly、gTTS)、逐字字幕(Whisper)、背景音樂與音效合成,且所有參數皆可自訂。此技能定義了從專案建立、腳本產生、場景繪製、音訊處理到最終合成的完整步驟,並涵蓋了許多實作細節與常見陷阱,適合開發者與 AI 代理使用。

相容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/liangruibupt/explainer_video_platform/tree/HEAD/skills/explainer-video-pipeline

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

explainer-video-pipeline(自動產生)

使用時機

使用者想要一段 1-3 分鐘的旁白解說影片,主題可以是科學、產品或技術,最終產出為一個包含語音、字幕、音樂和音效的 MP4 檔案。

參數與預設值

只詢問主題;除非使用者指定其他值,否則使用所有預設值。在第一行中說明你使用了哪些值。

參數預設值其他數值
topic必要—
storyboard_modelclaude-opus-5.5 負責撰寫腳本、旁白與故事板任何來自 kiro-cli chat --list-models 的模型 ID
video_engineopus-5.5:claude-opus-5.5 為每個場景撰寫繪製影格的程式碼其他程式碼模型,例如 claude-sonnet-5.5;seedance(BytePlus ModelArk API,需要 ARK_API_KEY);hybrid(在程式繪製場景中嵌入 Seedance 片段)
rendererremotion(React/SVG;Remotion 逐幀驅動無頭 Chromium)html(Canvas 2D / SVG / GSAP / p5.js 頁面,透過 Playwright 捕捉);manim(Manim Community 場景;最適合幾何、圖表、向量與逐步推導)
seedance_modelseedance-1-5-pro-251215使用者的 ModelArk 帳戶中啟用的任何 Seedance 模型
ttspolly,神經語音 Zhiyu,cmn-CN,us-east-1gtts(免費,無需金鑰,語調較平);任何其他 Polly 語音/語言
captions開啟:Whisper 逐字時間戳,燒錄為逐字高亮的字幕關閉
whisper_modelsmall(CPU,int8;約 5 秒處理 10 秒語音)base(更快),medium(時間更準確)
musicsynth(使用 ffmpeg 製作的免版稅振盪器背景音樂)none;使用者擁有的音樂檔案路徑
sfx開啟:scenes.json 中列出的音效事件會被合成並放置到對應影格關閉:從每個場景中移除 sfx
language國語旁白Polly 與 Whisper 皆支援的任何語言
size、fps1920×1080、30 fps1080×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/ 資料夾中。

  1. 專案。 在使用者的工作區中建立一個 git 儲存庫的專案資料夾。對於 renderer=remotion,手動建立 package.json、tsconfig.json(resolveJsonModule: true)、src/index.ts、src/Root.tsx,然後執行 npm i remotion @remotion/cli react react-dom。
  2. 腳本與故事板(由 storyboard_model 負責)。撰寫 scenes.json:每個場景一個物件,包含 id、narration(口述台詞)、visual(螢幕上的內容)、可選的 manim(Scene 類別名稱)以及可選的 sfx:[{"at": FRAME_IN_SCENE, "kind": "whoosh|hiss|pop|rise|thud|PATH"}]。使用 6-10 個場景,每個場景一個概念,包含一個標題場景和一個結尾卡。使用網路搜尋檢查事實,並在 README 中引用來源。
  3. 參考圖片。 當影片顯示真實物體時,要求或找到一張清晰的照片,並將其保存在 ref/ 中。永遠不要憑記憶繪製真實物體的形狀:對照片執行邊緣偵測,測量關鍵點,然後使用儲存在儲存庫中的小腳本從這些點生成形狀。
  4. 旁白驅動時間。 執行 narrate.py scenes.json . --tts polly。它會寫入 durations.json(每個場景的影格數,根據實際語音長度加上填充時間計算)、narration.wav 和 audio/sNN.mp3。場景程式碼會讀取 durations.json,因此每個場景的長度會與其台詞完全一致。
  5. 場景程式碼(由 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 小時後過期)。
  6. 在完整渲染前檢查靜止畫面。 渲染 4-6 個影格,每個關鍵場景一個,將它們組合成一個縮小的聯絡表(contact sheet),然後查看該單一圖像。若要進行獨立檢查,請啟動一個新的審查者,只提供聯絡表和 scenes.json。
  7. 音效。 如果任何場景有 sfx,則執行 sfx.py scenes.json .。然後執行 mix_bgm.py . --music <music>:它會在語音下降低音樂音量,加入 sfx.wav,寫入 narration_bgm.wav,並列印 RMS 電平。僅音樂的開頭部分應約為 −20 至 −30 dB;−55 dB 或更低表示聽不見。
  8. 字幕。 captions.py scenes.json . --size <WxH> 使用 faster-whisper 逐字時間戳轉錄每一行,並將其對應到腳本本身的字元,因為 Whisper 會聽錯同音字(它曾將「氣體」聽成「漆體」)。它會寫入 captions.ass(每個字元在發音時高亮顯示)和 words.json(每個字元的時間,可用於步驟 5 的螢幕強調效果)。
  9. 渲染(無聲畫面)。
    • 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。它會渲染每個類別,並將其填充或修剪至精確的影格數。
  10. 使用 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 個影格並查看,其中一個影格應在句子中間,以檢查字幕高亮。
  11. 發布。 提交到一個功能分支,開啟一個 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 可以避免這個授權問題。

相關技能