Communitygithub.com

製品動画をコードで作成

コードから製品動画を生成 — アニメーションHTMLデッキ、AIナレーション、スクリーンレコーディング、決定論的なMP4レンダリング。

製品動画をコードで作成 とは?

このスキルは、製品動画を完全にコードとして構築するためのパイプラインです。HTML/CSSで作られたアニメーションデッキ、AIによる音声ナレーション、実際の製品のスクリーンキャプチャ、そしてffmpegによる音声マスタリングを統合し、再現可能で差分管理可能なMP4を出力します。最大の特徴は「オーディオファースト」のアプローチで、まずナレーションを生成し、その長さを測定してから各シーンのタイミングを決定することで、音声と映像の同期を保証します。Claude Code、Cursor、Codexなど、任意のAIエージェント環境で利用可能で、スクリプトはPythonとPlaywrightに依存しています。ビデオ編集ソフトではなく、あくまでコードベースのパイプラインであるため、修正は再編集ではなく再レンダリングで完了し、数分で反映されます。製品説明、機能ローンチ、デモ、チュートリアル、リリースノート、オンボーディング、ソーシャルカットなど、多様な動画タイプに対応し、ブランド情報を製品のコードベースから自動検出する機能も備えています。

対応✓Claude Code~Codex CLI~Cursor
npx skills add A19235972428/product-video-as-code

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

製品動画をコードで作成 は何をしますか?

製品動画をコードとして構築します。決定論的なタイムラインで駆動されるHTMLデッキ、AIによるナレーション、実際の製品のスクリーンレコーディング、そしてffmpegによるオーディオマスタリング。すべてが再現可能で、差分管理可能、再レンダリング可能なので、修正にかかる時間は再構築ではなく数分です。

これはビデオエディタではありません。パイプラインです。出力はMP4です。

重要なアイデア

音声を先に、次にタイミング、最後に映像。

画面上の何かをどれだけ表示するかを決める前に、ナレーションを生成します。各クリップの長さを測定し、その測定値からシーンの長さを導き出し、その後にフレームをレンダリングします。代替手段(長さを推測する、または固定のストーリーボードに合わせてナレーションを書く)では、映像が音声と同期しなくなり、台詞を書き直すたびに再レンダリングが必要になります。

script.json ──► TTS ──► measure ──► timings.json ──► render ──► composite ──► mux ──► MP4
                              ▲                          ▲            ▲
                        assemble.py                 render.py    composite.py

ナレーションなしの動画(タイトルスティング、無音ループ、ミュートソーシャルクリップ)の場合は、ステージ1をスキップしてtimings.jsonを手動で作成してください。後続の処理は変わりません。

パイプライン

ステージスクリプト生成物
1. ナレーションお好みのTTSツールaudio/vo_NN.mp3(シーンごとに1つ)
2. タイミング+音声トラックscripts/assemble.pytimings.json、out/voice.wav
3. 映像scripts/render.pyout/silent.mp4
4. スクリーン映像 (オプション)scripts/capture/tour.pycapture/clips/*.mp4
5. コンポジット (オプション)scripts/composite.pyout/composited.mp4
6. オーディオマスタリングscripts/mux.py最終MP4

references/PIPELINE.mdでウォークスルー、references/AUDIO.mdで音声と音楽、references/SCREEN-CAPTURE.mdで製品映像、references/PITFALLS.mdでデバッグ前に確認すべき実際に発生した失敗例を参照してください。

動画の種類

パイプラインは同じ。変わるのは構成、ペース、そしてフレーム内の実際の製品の量です。1行も書く前に、どの種類の動画を作るのかを決めてください。それが他のすべてを決定します。

種類標準的な長さ構成映像
製品説明1~3分問題 → 転換 → 仕組み → 証明 → 閉め少し、証明として
機能ローンチ30~90秒変更点 → 重要性 → 見る → 入手方法中程度
デモ/ウォークスルー2~5分1つの実際のタスクを最初から最後まで支配的
チュートリアル3~10分ステップバイステップ、章立て、追従のための間支配的
リリースノート30~90秒1ビートに1項目、密集スクリーンショットまたは短いクリップ
オンボーディング1~3分初回実行パス、ユーザーが遭遇するままに支配的
タイトルスティング/ループ5~20秒1つのアイデア、しばしば無音なし
ソーシャルカット60秒未満最初にフック、長尺版から派生短く、インパクト大

種類に基づく経験則:

  • デモとチュートリアルは映像優先。 デッキは製品の周りの枠組み(タイトルカード、コールアウト、チャプター区切り)。画面にすでに表示されていることをナレーションで説明しない。
  • 説明とローンチはナレーション優先。 映像は、あなたが行った主張の証拠として表示される。その近接性が効果を生む。
  • チュートリアルには間が必要。 各ステップの後に一呼吸置く。--tailを積極的に使う。視聴者は見ているだけでなく、一緒に作業している。
  • リリースノートは密集。 画面上のテキストが伝え、ナレーションは要約する。1ビートに1項目、長居しない。
  • ソーシャルカットは派生版であり、二度と書かない。 長尺版のシーンのサブセットとして構築し、ずれを防ぐ(PIPELINE.md参照)。

クイックスタート

初期設定(1回のみ):pip install -r requirements.txt && playwright install chromium。ffmpegとffprobeもPATHに含まれている必要があります。

まずは無音で、デッキがレンダリングされることを確認:

cp templates/deck.html .
python3 scripts/render.py --preview 2 8 18   # 静止画
python3 scripts/render.py                    # -> out/silent.mp4

次に、ナレーションができたら完全なパイプラインを実行:

cp templates/script.example.json script.json
# audio/vo_01.mp3 ... をシーンごとに生成。その後:
python3 scripts/assemble.py                    # timings.json + out/voice.wav
python3 scripts/render.py                      # out/silent.mp4
python3 scripts/mux.py --final out/final.mp4   # 音声追加(audio/bed.mp3が存在する場合は音楽も)

assemble.pyが音声を必要とする唯一のステージです。それがない場合、render.pyはデッキで宣言された長さを使用します。

これを機能させ続けるルール

タイムラインを壁時計の時間で駆動しない。 レンダラーは明示的なtにシークしてスクリーンショットを撮ります。render.pyは各フレームでwindow.__seek(t)を呼び出すため、遅いマシンでも速いマシンと同じファイルが生成されます。requestAnimationFrameやCSSアニメーションの再生を使用するものは、スクリーンショットループの下でテアリングやフレーム落ちを起こします。

すべてのアニメーションをナレーションのビートに固定する。 音声が4.2秒で「3つのこと」と言ったら、3枚目のカードは4.2秒に表示されます。書き直しの後は必ずビートを再確認してください。3秒短くなった台詞は、映像を宙に浮かせます。これは、結果が演出されたものに見えるか、それとも無難に見えるかを分ける最大の要因です。

再開可能なチャンクでレンダリングする。 render.pyはout/parts/part_NNN.mp4を書き込み、再実行時には完了したパートをスキップします。停止したスクリーンショットは、全体のパスではなく1チャンクの損失で済みます。同じパーツディレクトリに対して2つのレンダラーを実行しないでください。

推測せず、測定する。 感覚ではなく数値で検証:

  • 空白フレーム検出:標準偏差ではなく暗いピクセル数((pixels < 200).mean())を数える。正当に白が多いUIページでも標準偏差は低くなります。
  • 発音:生成された音声を音声認識でテキストに戻して読み上げる。
  • レベル:毎回、最終ファイルに対してffmpeg -af volumedetectを実行する。
  • ジオメトリ:ハードコードするのではなく、DOMからgetBoundingClientRect()を読み取る。

1つのソース、多数のカット。 単一のデッキからクエリパラメータ(deck.html?cut=short)でシーンのサブセットを選択することで、長尺のデモと40秒のソーシャルカットがずれることを防ぎます。references/PIPELINE.mdを参照。

製品のコードからブランドを一致させる

製品にコードベースがある場合、16進数コードを尋ねる代わりにそこからブランドを読み取ります:

python3 scripts/detect_brand.py ../their-product --css

デザイントークンファイル、tailwind設定、CSSカスタムプロパティ、SCSSおよびLess変数、JS/TSテーマオブジェクト、Webマニフェストを読み取り、見つけたフォント、アイコンライブラリ、ロゴファイルを報告します。出力された:rootブロックをdeck.htmlに貼り付けてください。

ビルド出力はスキップされます。dist/フォルダはブランドではないベンダーのコンポーネントライブラリCSSで満たされているためです。また、パレットは名前の一致だけではなく、一貫性もチェックされます。ライトテーマで--surface、ダークテーマで--bgを定義しているリポジトリは、そうでなければ黒いフレームに白いカードを表示してしまいます。拒否された項目は印刷され、静かに適用されることはありません。

レンダリング前に、検出されたものと拒否されたものをユーザーに表示します。

デザインガイダンス

デッキはHTML/CSSなので、デザインは完全にあなた次第です。知っておくべきことが2つあります:

ソーシャルおよび自動再生コンテキストではミュートされます。画面上の見出しだけで各ビートを伝えなければならず、フックは最初の1~2秒で決まります。ナレーションはあくまで拡張手段であり、伝達手段ではありません。

視覚的に特徴的なものを求められた場合は、暗い背景と1つの明るいアクセントカラー(汎用的な出力が集まる場所)に頼るのではなく、対象の世界(その成果物、道具、専門用語)に根ざしたものにしてください。Anthropicのfrontend-designスキルはこれをうまくカバーしており、このスキルとクリーンに組み合わせることができます。

関連スキル