Communitygithub.com

jblxo/programmatic-video-skill

使用 HTML5 Canvas、SVG、Playwright 逐幀渲染 (window.__setFrame)、多模態聯繫表視覺自我審查、程序化 Python/NumPy 音頻合成、WAV 音效提示混合與 FFmpeg,構建並渲染確定性 60fps 1080p MP4 動畫影片、動態圖形、版本回顧、產品演示與數據驅動的「年度回顧」影片。

programmatic-video-skill 是什麼?

此技能為 AI 編碼代理提供了一個確定性、零模板的端到端工作流程,用於設計、視覺品質保證 (QA)、評分和渲染 60fps 1080p MP4 動畫影片。它基於三個核心規則:將整個場景建構為幀索引的純函數 (透過 `window.__setFrame`)、在完整渲染前使用多模態聯繫表進行視覺自我審查,以及透過管道將 Playwright 的 PNG 緩衝區直接輸入 FFmpeg 以生成零磁碟膨脹的影片。此技能支援 Claude Code、Cursor、Codex 和 OpenCode 等平台,並內建腳本 (`render.mjs`、`synth-audio.py`、`contact-sheet.py`),可處理從故事板規劃、場景編寫、音頻合成到最終 H.264 編碼的整個過程。它旨在當使用者要求「製作動畫影片」、「從程式碼生成 MP4」、「構建版本回顧」或「使用音效創建演示影片」等情境下被自動調用,通過結構化的 6 步流程取代 Remotion 等繁重的庫,確保高效且可重現的影片生成。

相容平台✓Claude Code✓Codex CLI✓Cursor✓Gemini CLI✓OpenCode
npx skills add https://github.com/jblxo/programmatic-video-skill/tree/HEAD/skills/programmatic-video

在你喜歡的 AI 中提問

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

說明文件

程式化影片生成技能

一個確定性、零模板的工作流程,適用於 AI 編碼代理,可直接從單一 HTML5 Canvas/SVG 檔案、Python 程序化音頻腳本以及無頭 Playwright → FFmpeg 管道,設計、視覺 QA、評分和渲染 60fps 1080p MP4 動畫影片。

路徑。 ${CLAUDE_SKILL_DIR} 是包含此 SKILL.md 的目錄。在 Claude Code 中它會自動展開;在 Cursor、Codex、OpenCode 或其他代理中,請將 ${CLAUDE_SKILL_DIR} 替換為 skills/programmatic-video/ 的解析路徑。


為什麼需要確定性逐幀渲染?

永遠不要使用即時瀏覽器螢幕錄製(MediaRecorder、requestAnimationFrame 掛鐘時間捕獲,或 CSS 轉場以即時時間運行)來製作影片:

  1. 掛鐘時間捕獲會丟幀,只要 CPU 負載飆升,就會導致音視頻不同步和卡頓。
  2. CSS 動畫以掛鐘時間運行,使得無法直接跳轉到 t = 14.20s 進行即時視覺 QA。
  3. 盲目渲染浪費時間:在檢查標題是否超出卡片邊界之前就渲染 5,000 幀,保證浪費工作。

相反,使用此技能構建的每個影片都遵守三個規則:

  • 規則 1 — 幀索引的純函數: 整個場景由 window.__setFrame(frameIndex, timeSeconds, fps) 驅動,其中 t = frameIndex / fps。每個位置、透明度、計數器和粒子都是 t 的確定性數學函數(使用種子 PRNG,如 mulberry32,絕不使用 Math.random())。
  • 規則 2 — 完整渲染前的多模態聯繫表 QA: 在對完整的 60fps MP4 進行編碼之前,捕獲 8–12 個關鍵時間戳(render.mjs --timestamps ...),將它們拼接成一個 contact-sheet.png(contact-sheet.py),然後使用你的多模態閱讀/查看工具檢查該圖像,以修復文字裁剪、重疊或對比度低的問題。
  • 規則 3 — 樣本精確音頻 + 零磁碟膨脹 FFmpeg 管道: 生成多段立體聲 WAV 音軌 + 時間戳音效提示(synth-audio.py),然後將 Playwright 的 PNG 緩衝區直接透過管道輸入 ffmpeg -f image2pipe(render.mjs)。

端到端代理工作流程(6 個步驟)

步驟 1:故事板與場景預算

在編寫程式碼之前設計一個具體的時間線表。將影片分組為 4–8 秒的場景,並帶有 scene.html 和 synth-audio.py 共享的明確轉換時間戳 (T_cut):

場景時間 (t)幀數 (60fps)視覺重點音頻 / 音效提示
01 — 鉤子/警報0.0s – 7.0s0 – 420CRT 終端啟動、打字機日誌、2.7s 處的 CTA 按鈕點擊子音脈衝 + UI 點擊/解鎖提示在 2.7s,漸強音進入 3.4s
02 — 英雄指標7.0s – 15.0s420 – 9003D 透視合成波網格 + 3 個彈簧物理計數器卡片在 7.0s 處完整的 124 BPM 合成波貝斯 + 立體聲琶音器落點
03 — 深度遙測15.0s – 23.0s900 – 1380分割畫面進度條 + 動畫半圓形儀表濾波器掃掠 + 高帽子鼓,在 15.0s 處的子音衝擊
04 — 點名與結局23.0s – 30.0s1380 – 1800貢獻者卡片的 Bento 網格 + "JOB'S DONE!" 橫幅與五彩紙屑在 25.2s 處的最後和弦 + 語音/音效提示,主輸出淡出 28.5–30.0s

步驟 2:使用 window.__setFrame(f, t, fps) 編寫 scene.html

編寫一個自包含的 1920x1080 HTML 檔案,使用 HTML5 <canvas>(和/或內聯 <svg> + DOM 覆蓋層),並公開:

window.__setFrame = function(frameIndex, timeSeconds, fps = 60) {
  if (window.__rafId) {
    cancelAnimationFrame(window.__rafId);
    window.__rafId = null;
  }
  const t = typeof timeSeconds === 'number' ? timeSeconds : frameIndex / fps;
  renderSceneAtTime(frameIndex, t);
};
  • 始終包含一個種子 PRNG(mulberry32(seed))用於星星、粒子、五彩紙屑或雜訊,以便幀 f 在多次運行中完全相同。
  • 等待 document.fonts.ready(由 render.mjs 自動處理)。
  • 請參閱 references/visual-patterns.md 以獲取可複製的配方(3D 透視網格、彈簧計數器、CRT 終端、儀表、Bento 卡片、五彩紙屑物理)。

步驟 3:執行快速時間戳快照並構建 contact-sheet.png

永遠不要先執行完整的 60fps 渲染。每個場景採樣 1–2 個時間戳(加上轉換中點)並構建一個聯繫表:

# 1. 在約 3 秒內捕獲 9 個關鍵幀 PNG
node "${CLAUDE_SKILL_DIR}/scripts/render.mjs" \
  --html ./scene.html \
  --timestamps 1.8,3.0,5.2,8.5,12.5,16.5,20.5,24.5,28.0 \
  --out-dir ./qa-frames

# 2. 將它們拼接成一個帶標籤的網格圖像
python3 "${CLAUDE_SKILL_DIR}/scripts/contact-sheet.py" \
  --dir ./qa-frames \
  --cols 3 \
  --thumb-width 560 \
  --title "VISUAL QA CONTACT SHEET" \
  --out ./contact-sheet.png

步驟 4:多模態自我審查循環(必做!)

在你的 ./contact-sheet.png(以及任何看起來密集的 ./qa-frames/t-*.png)上調用你的圖像「閱讀」/「查看」工具。根據 references/visual-qa-loop.md 中的清單檢查每個圖塊:

  • 是否有任何文字溢出或與卡片邊框、徽章或進度條碰撞?
  • 所有數字、標籤和 HUD 標題在 1080p 解析度下是否高對比度且清晰可讀?
  • 每個場景轉換是否乾淨落地,沒有出現意外的空白/黑色幀?

如果你在 contact-sheet.png 中發現任何問題,請修正 scene.html 並在繼續之前重新執行步驟 3。

步驟 5:合成程序化音軌並混合 WAV 音效提示

生成一個立體聲 44.1 kHz WAV 音軌,其轉換漸強音和音效提示與 scene.html 中的確切時間戳匹配:

python3 "${CLAUDE_SKILL_DIR}/scripts/synth-audio.py" \
  --duration 30.0 \
  --bpm 124 \
  --style synthwave \
  --transitions 3.4,7.0,15.0,23.0,25.2 \
  --cue "25.2:./sfx/jobs-done.wav:+1.5" \
  --out ./soundtrack.wav

對於自定義多段合成或整合主題音樂包(例如 jblxo/claude-code-sound-packs),請閱讀 references/audio-synthesis.md。

步驟 6:通過 FFmpeg 管道渲染最終 60fps H.264 MP4

一旦視覺 QA 和音頻合成通過,以完整管道模式執行 render.mjs:

node "${CLAUDE_SKILL_DIR}/scripts/render.mjs" \
  --html ./scene.html \
  --duration 30 \
  --fps 60 \
  --audio ./soundtrack.wav \
  --crf 18 \
  --out ./final-video.mp4

使用 ffprobe 驗證輸出容器:

ffprobe -v error -show_entries format=duration,size:stream=codec_name,width,height,r_frame_rate -of default=noprint_wrappers=1 ./final-video.mp4

參考手冊(按需載入)

主題參考文件
Canvas/SVG 視覺基本元素、緩動函數、種子 PRNG、3D 合成波網格、儀表、Bento 卡片references/visual-patterns.md
多模態聯繫表 QA 循環、常見佈局缺陷、時間戳選擇策略references/visual-qa-loop.md
程序化 Python/NumPy 音頻合成、和弦進行、漸強音、閃避、WAV 音效提示混合references/audio-synthesis.md

相關技能