レッスンビデオプロデューサー
1つのレッスンのスライドデッキを完成した教育ビデオに変換します。合成音声がナレーションを読み、各カード、ステップ、または行が音声のタイミングに合わせて表示され、トランジションは変化に富み、各表示をソフトな効果音がマークし、ピアノBGMがボイスの下でダッキングされ、学習者が一時停止する場所にはカウントダウンが表示され、重要な項目には手描きのサークルが追加され、字幕は別ファイルとして出力され、ハウツーレッスンには実際の画面録画が挿入されます。1レッスンずつ実行し、確認してから納品します。
入力(lesson-slide-designerスキルから): slides/<course>/<lesson>/slides.json、<file_name>.pptx、_preview/slide-NN.png。不足している場合は、最初にデッキを構築します。ベトナム語版(kieu、loi_doc、_kiem/)のデッキも読み取ります。
出力は videos/<course>/<lesson>/(スライドパスをミラーリングし、それ以外の場合は <slides folder>/video/):
| ファイル | 説明 |
|---|---|
<file_name>.mp4 | ビデオ:1920x1080、30 fps、H.264、AAC 48 kHz、-16 LUFS |
<file_name>.<lang>.vtt / .srt | 個別ファイルとしての字幕。決して埋め込まれません(スライドテキストを覆うため)。.vttをキャプションとしてアップロードしてください |
<file_name>.narration.txt | クリーンなナレーション、1行に1つの話されたビート。` |
<file_name>.storyboard.json / .md | いつ何が起こるか:pptxから測定された領域、各領域が表示される行、エフェクト、トランジション、サークル、ズーム、カウントダウン。.mdは目視確認用 |
<file_name>.voice.mp3 + .timeline.json | ナレーションと各行の正確な開始と終了(行は .voice.mp3.cache/ にキャッシュされます) |
<file_name>.events.json、.audio.mp3 | サウンドイベントと3レイヤーミックス |
video.json(オプション、ユーザーが記述) | スライドごとのオーバーライド:表示行、トランジション、ホールド、サークル、ズーム、画面録画 |
_check/ | contact-NN.png(完成ビデオのフレーム)、<file_name>.report.md(測定値)、voice-review.txt(Whisper)、voice-exceptions.txt |
_segments/ | スライドごとにレンダリングされた1つのセグメント。そのスライドが変更されていない場合に再利用されます |
ツール:Python 3.10+(python-pptx、numpy、Pillow、opencv-python(録画のスムージング用)、faster-whisper(音声レビュー用))、Node 18+(puppeteer-core(assets/engine で npm install)およびChrome、Chromium、またはEdge)、ffmpeg/ffprobe。音声:Kokoro(pip install kokoro soundfile)またはVieNeu-TTS、どちらもApache 2.0でローカル動作。エンジンが独自の仮想環境にある場合は、KOKORO_PYTHON または VIENEU_PYTHON をそのPythonに設定します。GPUは役立ちますが必須ではありません。
ワークフロー
ステップ0. デッキを読み、概要を確定する
slides.json(ナレーション、制作ノート、スライドタイプ)を読み、_preview/contact-sheet.pngをざっと確認します。レッスンソースが存在する場合は、学習者が練習する場所や質問される場所を把握するために読みます。references/video-standards.md(標準:1トピック、台本、起承転結、トランジション、対話促進)とreferences/motion-and-sound.md(各スライドタイプが何を得るか、ビデオが動き続ける理由、ただし忙しくなりすぎない理由)を読みます。- 確定:言語と音声(
slides.jsonのlanguage。英語はデフォルトでKokoroam_michael、女性音声はaf_heart、他のKokoro言語は音声プレフィックスで、ベトナム語はVieNeu)。レッスンに実際の画面録画が必要かどうか(クリック、タイピング、ソフトウェアを教えるレッスン:はい、ステップ2を参照)。どの質問スライドで一時停止するか、その時間。何をサークルまたはズームするか。ナレーションはスライドステップでテキスト読み上げ用に書かれています。ここで教材コンテンツを書き換えないでください。音声が間違えた単語の発音の仕方のみ修正します。
ステップ1. ストーリーボードを構築してレビューする
python scripts/storyboard.py slides/<course>/<lesson>/slides.json
<file_name>.storyboard.md を読みます:スライドごとの領域、各領域が表示される行、トランジション、ホールド、サークル。motion-and-sound.md のセクション4と照らし合わせて確認します:3番目のカードは音声が3番目のアイデアに達したときに表示されます。隣接するものは決して同じトランジションを共有しません。質問スライドはホールドします。「答えBをサークル」のようなメモはサークルを生成します。video.json(templates/video.example.json を参照)で修正し、再度実行します。「領域が見つかりません」はスライド全体が表示されることを意味します。image タイプでは問題ありませんが、他のタイプについてはpptxを確認してください。
ステップ2. 実際の画面録画(ハウツー、実践、ソフトウェアレッスン)
レッスンがアクションを教える場合、実際のアクションを見せてください。スクリーンショットやモックアップページに置き換えないでください。references/screen-recording.md のルール。簡単に:
- ウィンドウを準備します:プライベートブラウザウィンドウまたはクリーンなアカウント、通知なし、サイドバーに実名なし。Windowsでは、
python scripts/record_screen.py --listでウィンドウタイトルを取得します。 - 録画:
python scripts/record_screen.py videos/<course>/<lesson>/clips/S07-name.mp4 --window "<title>" --seconds 40 --size 1280x720 [--crop-top 90] [--scroll "6:200:4"](Windows。それ以外の環境ではOBSまたはffmpegを使用)。クリックとタイピングはブラウザツールを通じて自分で行うか、ユーザーに任せます。スクロールは--scrollまたはスムーズなページ内スクロールのみ(window.scrollBy({top: 200, behavior: 'smooth'})を0.6~0.8秒ごと)、段階的には行いません。各結果の後、3~5秒静止します。長い結果はゆっくり(150~250 px/s)スクロールし、学習者が読めるようにします。 - 各録画後に
check_motion.pyを実行します。ジャンプが残っている場合:python scripts/smooth_scroll.py <in> <out>を実行し、ゼロになるまで再度測定します。クリップの上部バンドを確認して、アカウント名や余分なタブがないか確認します。 video.jsonで宣言します:"S07": {"clip": {"file": "clips/S07-name.mp4", "mode": "frame", "speed": "auto"}}。スライドは大きなフレームを持つimageまたはtwo-columnスライドである必要があります。クリップの最初のフレームをそのスライドに配置し(composite_clips.py --first-frame clips/S07-name.mp4 slides/<course>/<lesson>/S07-first-frame.png)、デッキを再構築して、クリップがジャンプなしでフェードインするようにします。make_video.py ... --extendを実行します。録画がナレーションより長く実行される場合に無音を追加します。録画を1.25倍以上にスピードアップしないでください。
ステップ3. 1つのコマンドでレンダリングする
python scripts/make_video.py slides/<course>/<lesson>/slides.json [--extend]
9つのステップ:ストーリーボード、ナレーション(gpu_lock.py 経由)、Whisperレビュー、レンダリング計画、3レイヤーミックス、画像(ヘッドレスChrome、スライドごと)、画面録画、字幕、最終チェック。3分を超えるレッスンの場合はバックグラウンドで実行します(レンダリングには初回、ビデオ1分あたり約1~2分かかり、スライドレベルの修正では数秒です)。停止したら:
- 音声レビュー(
_check/voice-review.txt):Whisperがファイル全体を一度聞き、その後、疑わしい行のみが再生成されて再チェックされ、最大3ラウンド行われます。短い単語、音楽の上でWhisperがでっち上げたフレーズ、2回目の、事前にヒントを与えたリスニングで正しく聞こえるものをフィルタリングします。長い単語、用語、名前、または連続するいくつかの単語でのみ停止します。該当箇所を聞きます(ffmpeg -ss 1:23 -t 4 -i <voice.mp3> clip.wav)。音声が間違っている場合、make_voice.pyのPRONUNCIATIONにスペル修正を追加するか(キャプションは実際のスペルを保持)、slides.jsonの単語を変更します。Whisperが聞き間違えた場合、その単語を_check/voice-exceptions.txtに追加します。その後--from-step 2を実行します(キャッシュされた行は再生成されません)。 - 最終チェックFAIL(
_check/<file_name>.report.md):原因を修正し(ラウドネスは--music-dbで、ジャンプは録画のスムージングで、長さは再レンダリングで)、そのステップから再実行します。
ステップ4. 報告前に確認する
_check/contact-NN.png(スライドごとに3フレーム:到着時、安定時、退出直前)を、references/quality-checks.mdのチェックリストとともに確認します:テキスト上に残ったカバーパッチ、ズームでクリップされたテキスト、トランジション中に同時に見える2つのスライド、テキスト上のカウントダウン、フレームからはみ出た録画、空の最初のフレーム。瞬間を詳しく検査するには:node assets/engine/render.mjs sheet <storyboard.json> <timeline.json> _check/zoom --from 40 --to 46 --every 0.25。- 2箇所を聞きます:最初の20秒と1つのトランジション(
ffmpeg -ss 0 -t 20 -i <mp4> -vn test.mp3)。エフェクトは聞こえるが、明らかに音声の下にあること、音楽が低いこと。 video.jsonまたはスクリプトで修正し、再度レンダリングし(変更されたスライドのみ再レンダリング)、完全なパスで問題が見つからなくなるまで再度確認します。最新のレンダリングのコンタクトシートを見る前に、ビデオが完了したと報告しないでください。
ステップ5. 報告する
ユーザーに提供:mp4およびvttのパス、実際の長さ、音声とペース(1秒あたりの単語数)、スライド、エフェクト、ポーズ、チェックレポート(判定、LUFS、ジャンプ)、合成された録画、発音テーブルまたはWhisper例外に追加された単語、残された警告とその理由。コンタクトシートを表示します。
複数のレッスンを連続して行う
コース全体で音声、音楽レベル、効果音を一定に保ちます。レッスン間の差は1.5 LU以下にします(各レポートのLUFSラインを比較)。発音テーブルとWhisper例外は時間の経過とともに拡大します。リセットしないでください。録画は videos/<course>/<lesson>/clips/ に、テイクごとに新しいファイル名で保存します。トピックビデオ(V<k>-<name>/slides.json)に分割されたデッキは、サブデッキごとに1つずつレンダリングされます。
原則
- 標準は固定されています(
video-standards.md):1つのビデオに1つのトピック、台本、起承転結、パート間の音声トランジション、対話促進。リズム、映像、音声はあなたが創造するところです。 - 映像と音声は互いに補完し合います。音声は決してスライドを読み上げません。 領域は音声がそれに達したときに表示されます。読み上げられているテキストは動きません。
- 画面と一致するポーズ:「ビデオを一時停止してください」と言うナレーションは3秒のホールドがあり、カウントダウンはありません(学習者は一時停止を押します。「60秒」のラベルの横にタイマーが動いていると矛盾します)。そのフレーズがない質問は、指定された時間(最大60秒)ホールドされ、カウントダウンが表示されます。
- 注目サークル:「Bをサークル」のような回答やメモは意図的なサークルを取得します。強調語で読まれるアイデアはフェードする自動サークルを取得します。カードには楕円、行には角丸ボックス。スライドあたり最大3つ。
- カーソルはデフォルトでオフ。 描かれたポインターはほとんどの視聴者に迷子のマウスとして認識されます。デモスタイルのビデオの場合は、
video.jsonで{"_all": {"cursor": true}}を設定してオンにします。カーソルはカーブ上を移動し、テキストの外で静止し、タイトル、セクション、キーメッセージ、クロージングスライドでは決して表示されません。 - 活気がありつつも、うるさくない:5~10秒ごとに何かが変化し、25秒以上静止するものはありません。ただし、フレームごとに1つの焦点、回転や反転なし、1分あたり最大16の効果音、トランジション音はスライド変更時のみ、音楽は音声より17~23 dB低くします。
- 音声が人々が最初に聞く品質です。 伸ばすと悪く聞こえるモデル(VieNeu)をタイムストレッチしないでください。代わりに長いポーズで遅くします。Whisperレビューはオプションではありません。用語の発音ミスは教育上のエラーです。
- 字幕は個別ファイルであり、決して埋め込まれません。
- ビデオステップではコンテンツは変更されません:新しいアイデアやでっち上げた数字はありません。ナレーションの問題はレッスンまたはスライドステップに戻されます。
- 実行し、測定し、確認してから納品します:ラウドネス、ジャンプ、長さ、コンタクトシート。
- 録画は録画です:アクションの代わりにスクリーンショットを使用しないでください。スクロールはスムーズに測定する必要があります。
- トランジション、エフェクト、またはサウンドを追加するには:
assets/engine/video.js、scripts/storyboard.pyのテーブル、references/motion-and-sound.mdを拡張し、テストをレンダリングし、確認してから使用します。
リファレンス
references/video-standards.md:オーディオおよびビデオ学習教材の教育標準、スライドタイプへのマッピング、およびプラットフォーム仕様(Udemyなど)。references/motion-and-sound.md:領域とアクションの推論方法、スライドタイプテーブル、モーション数値、サウンドトラック、video.json構文、学習者を眠らせない方法。references/narration-voice.md:KokoroとVieNeu、ペース、発音修正、Whisperレビュー。references/screen-recording.md:ウィンドウの録画、スムーズスクロール、ジャンプの測定とスムージング、合成、プライバシー。references/quality-checks.md:最終チェックのしきい値とコンタクトシートのチェックリスト。templates/video.example.json:スライドごとのオーバーライド。