Communitygithub.com

igm61799-cloud/voiceover-to-animation

將口白或旁白音檔轉換為完整的、完全以程式碼繪製的 2D 動畫影片 (MP4),不使用任何影片生成模型或素材庫。每一幀皆由程式碼 (Canvas 2D) 繪製、依據旁白逐字時間點剪輯,並透過無頭 Chromium 與 ffmpeg 渲染輸出。

voiceover-to-animation 是什麼?

此技能可將使用者提供的任何語音或旁白音檔(例如 voiceover.mp3、講座錄音、Podcast 片段)自動轉換為一支完全由程式碼繪製的 2D 動畫短片(MP4 格式)。整個流程完全確定性:每個場景都是時間的純函數,因此任何影格都可以獨立渲染,支援平行渲染與完美的音訊同步。技能首先使用 faster-whisper 進行逐字時間戳記辨識,然後透過 Playwright 驅動的無頭 Chromium 在 Canvas 2D 上繪製每一幀畫面,最後以 ffmpeg 合成輸出。它特別適合製作「Kurzgesagt 風格」的解釋型動畫、動態圖像或教學短片,但強調每一幀都由程式碼繪製,不使用任何影片生成模型或素材庫。支援的平台包括任何可以執行 Python、ffmpeg 和 Playwright 的環境,但主要設計用於 Claude Code 等 AI 代理工具。運作流程包含:轉錄音檔、建立專案、決定美術方向與分鏡、逐步編寫場景、透過靜態畫面預覽檢視、完整渲染並驗證輸出。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/igm61799-cloud/voiceover-to-animation/tree/HEAD

在你喜歡的 AI 中提問

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

說明文件

Voiceover -> coded 2D animated short

你正在製作一部短片,而不是投影片。旁白是固定的;你的工作是為每一刻發明觀眾看到的內容,用程式碼繪製出來,並提供一部剪輯和視覺節拍精準對應到指定詞語的 MP4 影片。

整個管線是確定性的:每個場景都是時間的純函數,因此任何影格都可以獨立渲染。這一個特性賦予了你其他一切——即時靜態畫面供審閱、平行渲染、完美的音訊同步。

機器上需要的東西

開始前請先檢查這些;它們是唯幾會動的零件。

python -c "import faster_whisper, playwright, PIL; print('ok')"
ffmpeg -version

缺少的部分:pip install faster-whisper playwright pillow,然後 python -m playwright install chromium。ffmpeg 必須在 PATH 中。如果無法安裝某項東西,請告訴使用者缺少什麼,而不是改用較弱的方法。

工作流程

保持使用者的視角簡單:他們給了你音訊並想要一部影片。依序完成這些步驟,並保持一個可見的任務清單。

1. 先聽:字詞時間點

python <skill>/scripts/transcribe.py voiceover.mp3 work

它會列印出帶有開始/結束時間的句子以及每個 word@start,並儲存 work/words.json。下游的一切都根據這些數字規劃。注意總時長。

2. 在音檔旁邊設置專案

將 <skill>/assets/template/ 複製到工作資料夾,使其看起來像這樣:

voiceover.mp3
render.py
src/index.html  src/engine.js  src/scenes.js  src/main.js

閱讀 src/engine.js 一次(它很短),並瀏覽 references/engine-api.md 以便了解你已經有什麼:緩動、隨機種子、攝影機、部分路徑繪製,以及版畫風格的主題(雲、雨、閃電、煙、天際線)。

3. 決定美術方向,然後根據文字製作分鏡表

為整部影片選擇一個視覺語言並保持一致:一個小調色板(五或六種顏色)、一種邊緣和紋理的處理方式、一種繪製人物的方法。範本附帶一個版畫/雕刻風格(骨色紙張、海軍藍墨、朱紅、金色、搖晃的手工邊緣)。使用它,或透過更改 scenes.js 中的調色板和 POST 開關來重新設計風格——但不要在場景之間混合風格。多樣性來自於哪種顏色在每個場景中佔主導地位(夜晚場景、紙張場景、紅色場景),而不是改變規則。

然後在寫程式碼之前寫分鏡表:一個包含鏡頭絕對開始/結束時間、每個鏡頭涵蓋的文字、螢幕上顯示的內容以及每個節拍對應的確切詞語的表格。閱讀 references/storyboarding.md 了解如何將旁白轉化為圖像——這是決定影片好壞的部分。

簡短版本:

  • 每個片語一個想法。一個有三個子句的句子通常是三個鏡頭或一個鏡頭內的三個節拍。
  • 顯示事物,不要加標題。重複旁白的螢幕文字會讓觀眾閱讀而不是觀看。預設完全不加文字;名稱、真實數據和圖表上的簡短中性標籤是例外。如果使用者已說明文字偏好,則以那些為準。
  • 給影片一個主幹:一個重複出現的角色或主題,以及在結尾回顧開頭某個事物的設計。
  • 有目的地改變景別和攝影機:廣角、特寫、圖表、地圖、剖面圖。連續兩個鏡頭不應有相同的構圖。
  • 如果旁白以一個妙句結尾,在最後一個詞之後添加 1-2 秒的無聲尾部,以便最終圖像能夠落地。render.py 會填充音訊。

4. 在編寫其餘場景之前,先完整建立一個場景

在 src/scenes.js 中編寫第一個鏡頭,將其註冊到 SHOTS,並查看它:

python render.py stills 0.3,1.5,2.9 first

然後用 Read 工具打開 work/first.png。在編寫其他場景之前執行此操作:它驗證了管線,更重要的是,讓你在更換風格成本還低的時候判斷風格。

5. 每次編寫幾個剩餘場景

維持系統運作的規則(每一條都存在,因為違反它會導致特定的失敗):

  • 時間的純函數。 一個鏡頭是 function name(g, t, u),其中 t 是絕對秒數,u 是自該鏡頭開始以來的秒數。沒有在影格之間累積的變數,沒有 Math.random(),沒有 Date。使用 hash(n)、noise1(x)、rng(seed)。影格由多個瀏覽器同時亂序渲染;任何有狀態的東西都會顯示為閃爍或無法匹配的區塊。
  • 使用絕對時間進行動畫。 編寫 E.out(seg(t, 12.62, 13.1)),直接使用文字列表中的數字。當剪輯改變時,節拍仍會停留在它們的詞語上。
  • 萬物皆微動。 一個靜止的畫面會被視為錯誤。為每個鏡頭添加緩慢的攝影機漂移(1 + u * .01 縮放就足夠了)和一些次要運動(雨、煙、擺動的物體)。
  • 萬物皆緩動。 用 E.out 讓東西到達,用 E.inOut 做攝影機移動,用 E.back 做彈出,用 E.bounce 做落地。線性運動看起來很機械。
  • 當攝影機拉遠或搖晃時,繪製比畫面更大的世界;將背景和地面的填充範圍遠遠超出 0..1920,這樣任何邊緣都不會暴露。
  • 衝擊需要三件事:一個 2-3 影格的全面 flash、一個衰減的 shake,以及一個反應(一股煙、一個後座力、一個顏色翻轉)。
  • 將場景程式碼拆分到多個檔案(s1.js、s2.js、...),一旦檔案超過幾百行,並在 scenes.js 之前將它們添加到 index.html。

編寫兩三個鏡頭,渲染它們的縮印版,查看,修正,繼續。不要盲目地編寫整部影片。

6. 用靜態畫面審查——這是你的眼睛

你無法觀看影片,因此縮印版就是你的審查。對於每個鏡頭,至少取樣開始、主要動作的中間、結束,以及每個節拍的確切影格:

python render.py stills 12.2,13.3,14.3,15.4,16.5 act2     # 每個縮印版最多約 16 個時間戳
python render.py sheet 4                                   # 整部影片,每 4 秒一幀

讀取 PNG 並逐鏡頭檢查:主體是否大到一眼就能看清?是否有任何東西被裁剪、重疊或懸浮?重要的事物與其背景是否有對比?它看起來是否經過設計,還是畫面的一半是空的?然後修正並重新渲染相同的時間戳。references/pitfalls.md 列出了容易犯且難以察覺的錯誤。

頁面錯誤由 render.py 以 PAGE ERROR: 行打印——一個黑色或半繪製的影格通常表示該鏡頭中發生了異常。

7. 渲染並驗證

python render.py full --workers 8

在背景執行它;一部 70 秒的影片大約有 2,100 幀,需要幾分鐘。它會輸出 output.mp4(1920x1080,H.264 + AAC,音訊填充至完整長度)。然後驗證檔案本身,而不僅僅是靜態畫面:

ffprobe -v error -show_entries format=duration:stream=codec_name,width,height -of default=nw=1 output.mp4
python render.py sheet 6

確認持續時間、有音訊串流,且總覽縮印版沒有空白影格。在你的報告中清楚地說明你檢查了靜態畫面和檔案屬性,但沒有觀看其動態——使用者應該觀看一次。

8. 交付

提供使用者 output.mp4 的路徑、總覽縮印版,以及一行關於如何在編輯後重新渲染的說明。src/index.html 在瀏覽器中打開時是一個帶有音訊的即時播放器,這是他們檢查時間點最快的方式。

聲音

除非使用者要求音樂或音效,否則僅提供旁白。如果他們要求,將它們作為額外的 ffmpeg 輸入添加到最終的混流中,時間點與你用於視覺效果的節拍列表相同。

參考檔案

  • references/storyboarding.md - 將旁白轉化為鏡頭;節拍放置;視覺隱喻;什麼讓場景感覺經過設計。在第 3 步之前閱讀。
  • references/engine-api.md - engine.js 中的每個輔助函數及其一行說明用途。在第 5 步之前閱讀。
  • references/pitfalls.md - 經由困難方式發現的失敗模式,以及修正方法。在第 6 步之前閱讀。
  • references/example-bells/ - 一個完整的 71 秒影片(16 個鏡頭,約 900 行程式碼)及其分鏡表。閱讀 storyboard.md 以了解預期的規劃層級;當你想了解特定效果(跟隨攀爬角色的攝影機、爆炸、地圖、畫線的羽毛筆、眯起的眼睛)是如何建構時,打開 src/s*.js 檔案。

相關技能