プログラム動画生成スキル は何をしますか?
AI コーディングエージェントが、単一の HTML5 Canvas/SVG ファイルと Python による手続き型オーディオスクリプト、ヘッドレス Playwright から FFmpeg パイプを通じて、60fps 1080p MP4 アニメーションビデオ を設計、視覚的に QA し、スコアリングし、レンダリングするための、決定論的でボイラープレート不要のワークフローです。
パスについて。 ${CLAUDE_SKILL_DIR} はこの SKILL.md を含むディレクトリです。Claude Code では自動的に展開されます。Cursor、Codex、OpenCode、その他のエージェントでは、${CLAUDE_SKILL_DIR} を skills/programmatic-video/ への解決済みパスに置き換えてください。
なぜ決定論的フレームステッピングなのか?
AI エージェントで動画を生成する際に、リアルタイムのブラウザ画面録画(MediaRecorder、requestAnimationFrame の壁時計キャプチャ、CSS トランジションのリアルタイム実行)を決して使用しないでください。
- 壁時計キャプチャはフレームを落とします。 CPU 負荷が高くなるとフレームをドロップし、音声と映像のドリフトやスタッターを引き起こします。
- CSS アニメーションは壁時計時間で動作します。
t = 14.20sの時点をシークして瞬時に視覚的な QA を行うことが不可能になります。 - ブラインドレンダリングは時間を無駄にします。 タイトルがカードからはみ出していないか確認する前に 5,000 フレームをレンダリングすると、作業が無駄になることが保証されています。
代わりに、このスキルで構築されるすべての動画は 3つのルール に従います。
- ルール 1 — フレームインデックスの純粋関数: シーン全体は
window.__setFrame(frameIndex, timeSeconds, fps)によって駆動されます。ここでt = frameIndex / fpsです。すべての位置、不透明度、カウンター、パーティクルは、tの決定論的な数学関数です(Math.random()ではなく、mulberry32のようなシード付き PRNG を使用)。 - ルール 2 — フルレンダリング前のマルチモーダルコンタクトシート QA: フル 60fps MP4 をエンコードする前に、8~12 のキータイムスタンプをキャプチャし(
render.mjs --timestamps ...)、それらを 1 つのcontact-sheet.png(contact-sheet.py)に連結し、マルチモーダルの Read/View ツールを使用してその画像を検査し、テキストのクリッピング、オーバーラップ、低コントラストを修正します。 - ルール 3 — サンプル精度のオーディオ + ゼロディスクブロート FFmpeg パイプ: マルチセグメントのステレオ WAV サウンドトラックとタイムスタンプ付き SFX キュー(
synth-audio.py)を生成し、Playwright からの PNG バッファをffmpeg -f image2pipe(render.mjs)に直接ストリーミングします。
エンドツーエンドエージェントワークフロー(6 ステップ)
ステップ 1: ストーリーボードとシーン予算
コードを書く前に、具体的なタイムラインテーブルを設計します。ビデオを 4~8 秒のシーンにグループ化し、scene.html と synth-audio.py の両方が共有する明示的なトランジションタイムスタンプ(T_cut)を設定します。
| シーン | 時間 (t) | フレーム (60fps) | ビジュアルフォーカス | オーディオ / SFX キュー |
|---|---|---|---|---|
| 01 — フック / アラート | 0.0s – 7.0s | 0 – 420 | CRT ターミナル起動、タイプライターログ、2.7s の CTA ボタンクリック | サブパルス + 2.7s の UI クリック/アンロックキュー、3.4s へのライザー |
| 02 — ヒーローメトリクス | 7.0s – 15.0s | 420 – 900 | 3D パースペクティブシンセウェーブグリッド + 3 つのスプリング物理カウンターカード | フル 124 BPM シンセウェーブベース + 7.0s のステレオアルペジエータードロップ |
| 03 — ディープテレメトリー | 15.0s – 23.0s | 900 – 1380 | 分割画面プログレスバー + アニメーション半円ゲージ | フィルタースイープ + ハイハットドライブ、15.0s のサブインパクト |
| 04 — ロールコール & フィナーレ | 23.0s – 30.0s | 1380 – 1800 | 寄稿者カードのベントーグリッド + 「JOB'S DONE!」 バナー & 紙吹雪 | フィナーレコード + 25.2s のボイス/SFX キュー、28.5–30.0s のマスターフェードアウト |
ステップ 2: window.__setFrame(f, t, fps) で scene.html を記述
HTML5 <canvas>(および/またはインライン <svg> + DOM オーバーレイ)を使用して、自己完結型の 1920x1080 HTML ファイルを記述し、以下を公開します。
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によって自動的に処理されます)。- コピー&ペースト可能なレシピ(3D パースペクティブグリッド、スプリングカウンター、CRT ターミナル、ゲージ、ベントーカード、紙吹雪物理)については、references/visual-patterns.md を参照してください。
ステップ 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 "ビジュアル QA コンタクトシート" \
--out ./contact-sheet.png
ステップ 4: マルチモーダル自己レビューループ(必須!)
画像 Read / View ツールを ./contact-sheet.png(および高密度に見える個々の ./qa-frames/t-*.png)に対して呼び出します。すべてのタイルを references/visual-qa-loop.md のチェックリストと照らし合わせて確認します。
- テキストがカードの境界線、バッジ、プログレスバーからはみ出したり、衝突したりしていませんか?
- すべての数字、ラベル、HUD ヘッダーは 1080p で高コントラストで読みやすいですか?
- すべてのシーントランジションは、意図しない空/黒フレームなしで、きれいに着地しましたか?
contact-sheet.png で問題を見つけた場合は、scene.html を修正し、次のステップに進む前にステップ 3 を再実行してください。
ステップ 5: 手続き型サウンドトラックの合成 & WAV SFX キューのミックス
scene.html の正確なタイムスタンプに一致するトランジションライザーと SFX キューを持つ、ステレオ 44.1 kHz WAV サウンドトラックを生成します。
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 シンセウェーブグリッド、ゲージ、ベントーカード | references/visual-patterns.md |
| マルチモーダルコンタクトシート QA ループ、一般的なレイアウト欠陥、タイムスタンプ選択戦略 | references/visual-qa-loop.md |
| 手続き型 Python/NumPy オーディオ合成、コード進行、ライザー、ダッキング、WAV SFX キュー ミキシング | references/audio-synthesis.md |