make-video は何をしますか?
アイデアを、無料のローカルツールだけでレンダリング・チェック済みのMP4に変換します。このスキルから作られたプロジェクトには独自のルールが AGENTS.md にありますので、それに従ってください(アニメーションの純粋性、useScale、sec()、フォルダ構成など)。
0. 動画プロジェクトのセットアップ(1回のみ)
カレントフォルダに tools/make-story.sh がなければ、まだ動画プロジェクトではありません。
-
マシンの確認を最初に行う:
uname -sm(Darwin arm64 が必要)、node --version(20+)、brew --version、df -h ~(約8GBの空き容量)。他のOSの場合は、何が動作しないか(ChatterboxとテイクチェッカーはApple GPU上で動作します)を先に伝えてから進めてください。NodeまたはHomebrewが不足している場合は、ユーザーにインストールコマンドを1つ提示し、待機します。 -
ダウンロードするものをユーザーに伝え、承諾を得るまで待ちます。 承諾なしにダウンロードを開始しないでください。以下の表を表示します(すべて無料、公式ソースから)。
ダウンロード サイズ 用途 保存先 npmパッケージ(Remotion等) ~500 MB レンダリング node_modules/ffmpeg, uv, FluidSynth(Homebrew、不足している場合のみ) ~150 MB 音声・動画ツール Homebrew Pythonパッケージ(PyTorch、Chatterbox…) ~1.5 GB 音声、品質保証 .venv/GeneralUser GS サウンドフォント ~30 MB 音楽 tools/soundfonts/Chatterbox 重み ~3 GB 音声 Hugging Face キャッシュ( ~/.cache/huggingface)、全プロジェクトで共有Whisper small.en ~590 MB キャプション tools/models/Whisper large-v3-turbo(オプションのテイクチェッカー) ~1.6 GB 不明瞭なラインの再録音 Hugging Face キャッシュ 合計約6 GB、10〜20分かかります。より軽量なオプションも提供:
SKIP_TAKE_CHECK=1でテイクチェッカーをスキップ(合計4.4 GB)。プロジェクトの作成場所を尋ねます(デフォルトは~/videos)。 -
承諾を得たら、このSKILL.mdの隣にある
template/フォルダをプロジェクトにコピーします(ドットファイルも含む:cp -R <skill dir>/template/. <dest>/)。その後git initを実行。 -
tools/setup.shをバックグラウンドで実行し、ユーザーに進捗を伝えます:どのステップにいるかを表示し(▶行を出力)、大きなダウンロード中は進捗状況を示します(du -shL ~/.cache/huggingface/hub/models--ResembleAI--chatterbox、目標 ~3 GB)。再実行は安全です:完了したステップはスキップされ、中断されたダウンロードは再開されます。ダウンロードが停止した場合(5分間サイズが増加しない場合)、停止してセットアップを再実行してください。失敗した場合はエラーを読み、原因(ツール不足、ディスク容量、ネットワーク)を修正して再実行してください。モデルが不足している場合でも回避策を取らないでください。 -
動作確認:
tools/make-story.sh stories/fridge-drama FridgeDramaで33秒のサンプル(冷蔵庫の中で3つの野菜が議論する)を約4分で作成します。ユーザーにout/FridgeDrama.mp4を表示し、次に何を作りたいか尋ねます。
ツールはモデルを自動で見つけます(ChatterboxとテイクチェッカーはHugging Faceキャッシュ、キャプションは tools/models/ から)。そのため、セットアップ後に設定は必要ありません。2つ目のプロジェクトはキャッシュされた重みを再利用するため、セットアップがはるかに高速です。
1. ブリーフの確定(不足している場合のみ質問)
| フィールド | デフォルト |
|---|---|
| プラットフォーム/フォーマット | Reel/Short: 1080×1920、30 fps · YouTube: 1920×1080、30 fps · フィード投稿: 1080×1350 |
| 長さ | Reel/Short: 15〜45秒 · YouTube: 3〜10分 |
| 種類 | ストーリー(キャラクターが話すので§3Bを使用) または モーショングラフィックス(テキスト、データ、図なので§3Aを使用) |
| トピック + 1つの要点 | 視聴者が覚えるべき1つのこと |
| 音声 | ボイス(Chatterbox)、音楽+効果音(tools/music.py)、または音楽のみ |
| 音声 | Chatterboxの組み込み音声、またはユーザー自身の録音のクローン(§3B)。同意なく他人の声をクローンしないでください。 |
2. コードより先にスクリプトを書く
長さの予算: Chatterboxのペースでの英語の話し言葉は、約 2.6 単語/秒 です。目標時間 ≈ 単語数 ÷ 2.6 + Σ ポーズ + アウトロ。生成前に確認してください。(冷蔵庫ドラマ:62単語 + 6.4秒のポーズ + 3秒のアウトロ = 33秒。)
縦型ショートフォームのペース配分ルール:
- フレーム 0 でフックを画面と音声で表示。最初の1.5秒で継続率が決まり、フレーム0はサムネイルになることが多いため、空のフレームやフェードで開始しないでください。
- 各行は12単語以下。キャプションは一度に3単語以下を表示。
- 毎秒 何かが動いている。
- 1080×1920 のセーフゾーン: y=220 より上、y=1540 より下には重要なものを配置しない(プラットフォームUI)。また、y≈1000 より下で x≈940 より右にも配置しない(いいね/コメント/共有ボタンが右端に配置されるため)。
tools/qa.py --layoutで違反を検出します。プレゼンターは左下に配置します。 - ペイオフまたは決めゼリフで終了し、その後2〜3秒のコールトゥアクションカードを表示。
解説テンプレート(「仕組み」や開発者向けヒントのリール向け、45〜60秒、120〜160単語):
- フック(≤ 3秒):驚くべき真実の事実または結果。
- 「実際の仕組みはこうです」:解説を開始する一行。
- 2〜4つのビート、それぞれに1つの数字 + 1つのアナロジー(「動画は1秒間に30枚の写真、まるでパラパラ漫画のようなもの」)。
- 「しかし、ここが落とし穴です」:ひねり、落とし穴、よくある間違い。
- 1行のペイオフ、その後1つの明確なコールトゥアクション(保存、共有、フォロー)。
次に、スクリプトの下にすべての事実主張と出典リンクをリストし、検証できないものはマークして、音声化する前に修正または削除します。数字や主張が表示される際に、出典を画面に(小さく、カードの下部)表示します。
ショート/リール向けクラフトチェックリスト:
- 進捗が見えること。 ステップバイステップの動画には
<StepCard steps={[{at: 0, title: "ダウンロード"}, …]} />(src/components/StepCard.tsx)を使用:「STEP 2/4」のピルとセグメントバーを表示。 - カラオケキャプション(オプションのスタイル)。
<Karaoke words={captions} keywords={["無料"]} style={{left: 60, right: 140, top: 1180}} />(src/components/Karaoke.tsx):2〜5単語のチャンク全体が画面に表示され、発話中の単語は実線、これからの単語は灰色、キーワードと強調単語はアクセントカラーで表示。視聴者はミュートの自動再生でも先読みできます。backgroundで明るいカード風に。qaを渡してレイアウトチェックに認識させる。 - シリーズチップ。 左上にエピソードマーカー(「パート2」)を付け、連続視聴を促進。
- 対比を見せる。 「before/after」や「私たち対彼ら」は、スピーチよりも2カラムカードの方が効果的。
- ストーリービートはリストより効果的。 「試行1失敗→試行2失敗→うまくいった方法」は、機能リストより注目を集めます。
- CTAの前に決めゼリフ。 人間らしい一行の後、コールトゥアクション。
- 「キーワードをコメントしてDMします」という報酬は、実際にガイド、プロンプト、リポジトリなどの実体が背後にある場合のみ約束すること。
TTS(テキスト読み上げ)向けのライティング:
- 行を「…」で始めない:Chatterboxがフィラーの単語を即興で入れてしまいます。
- 行を数字の単語だけで始めない(「二つ。顔」は「to the face」と出力されました)。「第二に、…」と書きましょう。
- 数字や奇妙な名前は、発音通りに書きます(「5.6」、「XZ」)。実際のテキストは行の
captionフィールドに入れます。 - 大きな数字は丸める(「600以上」)。TTSは「646」や「87,000」をうまく発音できません。
- フック内の短い単語は不明瞭になりやすい(「このリポ」は「The three」と聞こえました)。テイクチェッカーが正しく聞き取れるまで言い換えます。
- 複数の声で同じ短い単語を同時に叫ばせないでください。ミックスが不明瞭になります。
- 句読点は話し方を指示します:「?」は語尾を上げ、「。」は下げ、大文字は強調を追加します。
3A. モーショングラフィックス動画
src/compositions/_Templateをsrc/compositions/<名前>にコピーし、ビートタイプごとに1つのコンポーネントを作成(Hook、Point、Stat、List、CTA)。- スクリプトから再生時間を計算(ビートの合計 − トランジション)。
getSampleIntroDurationと同様に行います。 src/Root.tsxにインラインのdefaultPropsを指定して登録。- 音楽のみ:
totalMs、outroStartMs、eventsを含むタイムラインJSONを作成し、tools/music.pyを実行。
3B. 音声付きストーリー(キャラクター + キャプション + 音楽)
stories/<スラッグ>/script.json を作成(stories/fridge-drama/script.json をコピー):
characters:color、exaggeration(0.3 穏やか → 0.9 劇的)、オプションでrefVoice:クローン用のクリーンな10〜30秒のWAVファイルをtools/voices/に配置。これがない場合は、Chatterboxの組み込み音声が使用されます。ユーザーの声をクローンする場合:静かな部屋で60〜90秒自然に話してもらい、音楽やエコーのないクリーンな10〜15秒の部分を切り出す(ffmpeg -ss <開始> -t 12 -i note.m4a -af highpass=f=80,loudnorm=I=-18 -ar 24000 tools/voices/me.wav)。lines:speaker、text、pauseAfter(秒)、オプションのevent+eventAt: "start"でストーリービート(ドアが開く、隠れる…)をマーク。アニメーションと音楽の両方がこれをキーにします。- 各行にオプションの音声指示:
emotion(calm|neutral|warm|excited|dramatic|whisper)、pace(slow|normal|fast)、emphasis(大文字で発話されキャプションで強調表示される単語)、pauseBefore(秒)。"pace": "slow"と0.4秒のポーズで、すべての単語が明確になります。
次に 1つのコマンド を実行:
tools/make-story.sh stories/<スラッグ> <CompositionId> # 音声 → キャプション → 音楽/効果音 → lint → レンダリング → マスター → 品質保証
SKIP_VOICE=1 tools/make-story.sh … # ビジュアルのみを反復
SAMPLE=15 tools/make-story.sh … # 最初の15秒を承認用にレンダリングして停止
| ツール | 出力 |
|---|---|
tools/voice.py | public/<スラッグ>/lines/*.wav(テキスト+音声設定でキャッシュ)、public/<スラッグ>/voice.wav、stories/<スラッグ>/timeline.json(ラインタイミング、イベント、フレームごとの口の形状)。テイクチェッカーがインストールされている場合、Whisperが各文を聞き、不明瞭なものを再録音します(VOICE_TAKES、デフォルト3回)。 |
tools/captions.mjs | public/<スラッグ>/captions.json(Whisperからの単語タイミング、スクリプトからのスペル)、stories/<スラッグ>/captions-report.json(単語誤り率と行ごとの一致単語数、Whisperが見逃した「filled」部分、全体的な matchRate) |
tools/music.py | public/<スラッグ>/music.wav(MIDI → FluidSynth、カットに合わせて調整)、public/<スラッグ>/sfx.wav |
tools/qa.py | stories/<スラッグ>/qa/report.md:PASS / FIX / FAIL |
timeline.json / captions.json からコンポジションを構築(src/compositions/FridgeDrama/data.ts を参照)。mouthOpen() で口の動きを制御、アクティブな話者に視線を向け、イベントは timeline.events.* を介して、再生時間は timeline.durationInFrames から取得。
タイミングの変更(テキストまたはポーズ)はキャプションの再生成が必要です。 キャプション時間は絶対値なので、そうしないとずれます。make-story.sh は常にキャプションを再実行します。
4. 検証(常に、完了と言う前に行う)
tools/make-story.sh は tools/qa.py で終了し、FAILの場合はゼロ以外の終了コードを返します。ファイル、ラウドネス(-14 ±1 LUFS、トゥルーピーク ≤ -1)、キャプション精度、ビートに合ったカット(≤ 120 ms)、フリーズ状態(≤ 3秒)、視覚的な多様性(最長の同じ見た目の連続 ≤ 5秒)、および画面上のテキストを繰り返すキャプションをチェックします。LAYOUT=<CompId> はさらに、キャプションがデッドゾーンや顔にかかっていないかをチェックします(コンポジションは、キャプションを #FF00FF、顔を #00FFFF で囲む qa プロパティが必要です)。stories/<スラッグ>/qa/report.md を読み、すべてのFAILとFIXを修正します。
次に目視確認:
npm run lint。stories/<スラッグ>/captions-report.json内の WER > 0.2 の行は、おそらく不明瞭に発話されています。言い換えて再生成(キャッシュのおかげで安価)。Whisperが見逃した単語は、ギャップの音声部分にのみ配置され、長い単語により多くの時間が割り当てられ、filledの下にリストされます。それらの箇所を聞いて確認します。matchRateが70%未満の場合、スクリプトと音声が異なるため、先に進む前に再音声化します。- キービート(フック、各話者、各イベント、アウトロ)で静止画をレンダリングし、1枚のコンタクトシートにまとめて確認します:
キャラクターのサイズ、セーフゾーン、キャラクターを覆うオーバーレイ、アウトロの背景に残るもの、キャプションの同期、テキストサイズ(チップは28 px以上、本文は54 px以上、1080幅時)を確認。npx remotion still <Id> out/stills/f<N>.png --frame=<N> --scale=0.4 ffmpeg -i a.png -i b.png … -filter_complex hstack=inputs=K out/stills/contact.png - 最終MP4から4〜5フレームを抽出して確認。
- 重要なものについては、新しいサブエージェントにコンテキストなしでコンタクトシートを批評してもらいます。新鮮な目がビルダーが見逃す問題を見つけます。
5. 納品
ユーザーにMP4、タイトル、キャプション、3〜5個のハッシュタグ、サムネイルフレームを提供します。明示的な承認なしに投稿またはアップロードしないでください。 クローンした声やAIの顔を使用する場合は、YouTubeの「改変または合成コンテンツ」ラベルをチェックするようユーザーに注意を促します。
時間を節約するルール
- 一度に1つのレンダリング。 複数のRemotionレンダリングを同時に行うと、マシンが長時間過負荷になります。パイプラインは既に
--timeout=180000 --concurrency=2を渡しています。 - Remotionパッケージの追加は
npx remotion add <pkg>で行い、決してnpm iだけで行わないでください。バージョンの整合性が保たれます。 - ラウドネス:台詞 −16 LUFS、音楽ベッド約 −24、最終マスター −14(ツーパス、既に
make-story.shで実施)。音声は音楽より少なくとも10 dB大きい状態を維持。 - Studioは
defaultPropsがRoot.tsx内のインラインオブジェクトである場合にのみ、プロップの編集を保存できます。 - 行をループする場合は
while read -r a b c; do …; done <<EOFを使用(zsh)。for x in "a b c"は壊れます。
さらなる教訓と独自の追加方法: reference/lessons.md。
測定されたコスト(M1 Max、64 GB)
| ステップ | 時間 |
|---|---|
| Chatterboxモデル読み込み | 実行ごとに約20秒(すべての行がキャッシュされている場合はスキップ) |
| 音声生成 | 最初の行約55秒(ウォームアップ)、その後は約3倍の実時間 |
| テイクチェック | 再テイクが必要な文ごとに約20〜30秒 |
| キャプション(Whisper small.en、WebGPU) | 11行で約10秒 |
| 音楽+効果音 | 2〜5秒 |
| 1080×1920、33秒のレンダリング | 約97秒(動画1秒あたり約3秒) |
| フルパイプライン | 音声キャッシュ時約2分、スクラッチから約4分 |
make-video は TheNoumanDev によるもので、zero-dollar-studio の一部です。これは @0x45.dev YouTubeチャンネルの裏側で動作しているパイプラインです。