コード解説動画
開発者向けの、ナレーション付きアニメーションによるコードウォークスルー。視聴者はエンジニアです。実際のコードを表示し、実際のファイル名や関数名を明記し、なぜ と どのように を説明し、非開発者向けのたとえ話に単純化してはいけません。
技術スタック: RemotionのCode Hikeテンプレート(シンタックスハイライトされたコードがステップ間でモーフィング)、アーキテクチャ図用のMermaid、ナレーション用のElevenLabs(ElevenLabsコネクタまたはAPIキー)、そして埋め込みキャプション。template/内のRemotionコードを変更するときは、remotion-best-practicesスキルを読み込んでください。
このSKILL.md(「スキルディレクトリ」)の隣にあるファイル:
template/: すべての動画プロジェクトにコピーされるRemotionソースファイル。references/voice.md: ステップ8で、ナレーション生成の前に読むファイル。references/long-form.md: 動画が15〜30分の場合に最初に読むファイル。作業をチャプターに分割し、各チャプターがステップ2〜9を実行します。
1. インプット: 3つの質問。作業前にこの順番で
質問は一度に1つずつ行います(AskUserQuestionが利用可能な場合はそれを使用)。スキップしたり、まとめたりしないでください。
- 何を理解する必要がありますか? 対象(行、ブロック、関数、ファイル、フロー、またはアーキテクチャ全体)と理由(バグ修正、機能追加、PRレビュー、オンボーディング)を取得します。回答が曖昧な場合(「認証関連」など)、まずコードを読み、2〜4の具体的な選択肢を提供します。例:「リクエストがエンドツーエンドで認証される方法」と「セッションの保存と期限切れの方法」。
- どのくらいの時間がかかるべきですか? 以下を提案します: 約30秒(1行またはブロック)、1〜2分(関数またはモジュール)、約5分(サブシステムまたはフロー)、15〜30分(コードベースオンボーディング。並列エージェントによるチャプターとして構築)。もしユーザーがわからない場合は、ステップ1で見つけた内容に基づいて推奨します。
- 私の理解は正しいですか? コードを読んだ後、以下を送り返します:
- 動画が答える1つの質問を1文で。
- 長さとビート数。
- アウトライン: ビートごとに1行(画面上の内容 + そのビートが伝えるポイント)。
- 意図的に省略しているもの。 「はい」の返答があった場合のみ構築を開始します。否定の場合は修正して再確認します。このステップは、ナレーションにElevenLabsのクレジットがかかり、レンダリングに数分かかるため存在します。
無人実行時(返答する人がいない場合)、最も妥当な解釈を選び、それを返信の先頭に明記し、先に進みます。
2. コードを調査する(執筆前に)
- 実際のコードを読む。呼び出し元から定義までトレースする。名前から動作を推測しない。大規模なコードベースの場合は、エージェントがサブエージェントをサポートしていれば、領域ごとに1つの読み取り専用サブエージェントを使用して調査し、それらの結論のみを保持します。
- ナレーション内のすべての主張は、読んだファイルと行に対応している必要があります。調査中に
notes.mdにclaim → path:lineを記録します。これはステップ7で見つかった問題を修正するときに使用します。 - 開発者がつまずきそうな点をメモします: 隠れた副作用、順序の仮定、エラーパス、動作を変更する設定、誤解を招く名前。
3. 時間予算に合わせてビートを計画する
ビート は1つのビジュアルと1〜3文のナレーションです。ナレーションは約150語/分(2.5語/秒)で進み、各ビートの後に0.6秒のポーズがあります。
| 予算 | ビート数 | 語数 |
|---|---|---|
| 30秒 | 3〜4 | 〜70 |
| 1〜2分 | 6〜12 | 150〜280 |
| 5分 | 20〜30 | 〜700 |
| 15〜30分 | 各3〜5分のチャプター(references/long-form.mdを参照) |
ビートのルール:
- 冒頭で回答する質問を示し、末尾で1行の要約で締めくくります。「この動画では」などの導入の無駄は不要。
- アーキテクチャを先に示し、その後ズームイン: 図、エントリーポイントコード、その次に関心のある行。
- 行を説明するのではなく、目的を説明する。各コードビートでは、コードが 何のために あり、前のビートとどのように関連するかを説明し、次に重要ないくつかの行を指摘します。決してブロック全体を行ごとに説明しないでください。
- コードビート: 最大16行(フレーム下部はキャプション用に予約)かつ1行80文字以内。無関係な行は削除し
// ...コメントで置き換えます。連続するビートで同じスニペットを異なるハイライトで表示する場合、スムーズにアニメーションするので、スニペットを再利用してハイライトを移動します。 - ナレーションが話している内容を、その上にCode Hikeコメントとしてハイライトします:
// !mark(次の行)または// !mark(1:4)(次の4行)。言語のコメント構文を使用します(Pythonでは# !mark)。 - 図ビート: Mermaid
flowchartで最大8ノード。4ノードより長いチェーンにはTDを使用します。連続する図ビートでノードを同一に保ち、class X hot行だけを移動してレイアウトがジャンプしないようにします。 - ナレーションは耳で聞いてわかるように書きます: 短い文、識別子は開発者が話すように発音(「handle-request関数」)、記号ごとにコードを読み上げない、行番号を発声しない。
4. プロジェクトのセットアップ(動画ごとに1回)
SKILL_DIR をスキルディレクトリに設定し、次を実行:
npx create-video@latest --yes --code-hike explainer && cd explainer
npx remotion add @remotion/media && npm rm twoslash-cdn && rm public/code*
rm src/calculate-metadata/process-snippet.ts src/annotations/Callout.tsx src/annotations/Error.tsx src/ProgressBar.tsx src/ReloadOnCodeChange.tsx
cp -R "$SKILL_DIR/template/." .
command -v mmdc || npm i -g @mermaid-js/mermaid-cli
Twoslashは意図的に削除されています。コード抜粋内の未解決のインポートすべてを赤いエラーとしてフラグするためです。コピーされたファイルは、テンプレートのコンポジションを beats/ によって駆動されるものに置き換えます:
scripts/build.mjsはbeats/をpublic/beats/(音声、レンダリングされた図、manifest.json)に変換し、各ビートの音声の長さを測定します。src/Main.tsxはビートを順に再生します: タイトル、コードまたは図、音声、キャプション。src/annotations/Mark.tsxは!markハイライトを実装します。src/Captions.tsxは各ビートの音声全体でキャプションのチャンクのタイミングを調整します。
5. ビートを書く
beats/ 内にビートごとに1組のファイルを、ソートされるように番号を付けて(01、02、… 10)配置:
NN.txt: オプションの最初の行# <画面タイトル>(コードビートの場合はpath/to/file.ts:42-60を使用、図の場合は短い見出し)、その後にナレーション。- 1つのビジュアル: コード抜粋の
NN.<ext>(拡張子がハイライト言語を設定:.ts、.py、.go、…)または Mermaid図のNN.mmd。図のノードをclassDef hot fill:#facc15,color:#000,stroke:#facc15とclass NodeId hotでハイライトします。
例:
beats/04.txt
# src/auth/session.ts:31-44
セッションは遅延的に更新されます。有効期限チェックはリクエストが到着したときにのみ実行されるため、アイドル状態のセッションはここでは決してクリーンアップされません。
beats/04.ts
export async function getSession(id: string) {
const s = await store.get(id);
// !mark(1:3)
if (s && s.expiresAt < Date.now()) {
return renew(s);
}
return s;
}
6. ドラフトパス(クレジット消費なし)
node scripts/build.mjsをbeats/*.mp3なしで実行すると、推定の長さでサイレントのプレースホルダー音声が生成され、合計時間が表示されます。予算より15%以上超過または不足している場合は、ビートを削除または追加します。- 最も多くの画面要素がある瞬間と、各ハイライトが表示される瞬間(ビート開始から約1.5秒後)の静止画をレンダリング:
npx remotion still Main out/check.png --frame=<n> --scale=0.5。それらを確認します。はみ出した行、読めない図、間違った行のハイライトを修正します。
7. 独立した事実確認(ナレーション生成前)
スクリプトの作成者はそれをチェックするのに最適な人物ではありません。スクリプトを書いていないレビュアーに、すべての主張をコードと照合させます。無人実行時でもこれを行ってください。
- エージェントがサブエージェントをサポートしている場合、新しいサブエージェントを起動します。リポジトリパス、すべての
beats/NN.txtとそのビジュアル、および以下の指示を与えます。ただしnotes.mdやアウトラインは与えず、コードの独自の解釈を形成させます:この解説スクリプトをコードと照合してください。ナレーションと画面上のタイトルにあるすべての事実主張をリストアップし、それぞれについて、呼び出し元を定義までトレースしてそれを確認または矛盾するコードを見つけてください。主張ごとに1行を返してください:
beat | claim | correct / wrong / unverifiable | path:line | why。また、ソースと異なるコード抜粋(// ...のカットと!markコメント以外)、path:lineの範囲が間違っているタイトル、このコードに関する重要事項でスクリプトが誤解を招くように述べているもの、コードの目的を述べずに行をウォークスルーしているコードビートもフラグしてください。 - そうでない場合、自分で2回目のパスを実行します: 各主張について、引用されたコードを再度開き、
notes.mdではなくそこで確認します。
すべての wrong の主張を修正し、 unverifiable の主張を削除または緩和し、フラグが立てられた行ごとのビートを目的に基づいて書き直します。ドラフトビルドを再実行し、変更されたビートだけを2回目のチェックに送ります。
8. 音声とレンダリング
references/voice.mdを読み、利用可能な最初のオプション(ElevenLabsコネクタ、ElevenLabs APIキー、別のテキスト読み上げプロバイダ、またはなし(キャプション付きの無音動画))を使用して、ビートごとに1つのナレーションファイルを生成します。動画全体で1つの声を使用します。node scripts/build.mjsを再度実行します。beats/NN.mp3が存在する場合それを使用するため、1つのビートを変更するにはそのファイルだけを置き換えれば済みます。- 1回レンダリング:
npx remotion render Main out/explainer.mp4。動画と音声の長さが一致していることを確認し(ffprobe -v error -show_entries stream=codec_type,duration -of csv=p=0 out/explainer.mp4)、動画が無音でない限り音声が存在することを確認します(ffmpeg -i out/explainer.mp4 -af volumedetect -vn -f null - 2>&1 | grep mean_volume; プレースホルダ音声は約-91 dBです)。
9. 引き渡す前に
- 最初と最後のビート、および中間の1つのビートを視聴するか、少なくとも聴取します。識別子の発音が間違っている場合、
NN.txtで音声的に書き直し、そのビートのみを再音声化します。キャプションにはナレーションテキストが表示されるため、音声的な書き直しもそこに表示されます。読みやすさを保ってください。 - ステップ7の後に変更されたナレーションはすべて、再度ステップ7のチェックを受けます。
- 動画が答える質問の1行の要約とともにmp4を提供します。明示的な許可なしに、どこにもアップロードまたは公開しないでください。