Communitygithub.com

ホワイトボード解説ビデオ生成ツール

論文・記事・概念を手描きホワイトボードスタイルで、5~20分のナレーション付き解説ビデオを作成します。すべてのラベル、下線、円、図が、その言葉が発せられる瞬間に描かれ、スライドごとに積み上げられていきます。

ホワイトボード解説ビデオ生成ツール とは?

このスキルは、ユーザーが論文やarXivリンク、ブログ記事、概念、あるいは「以前と同じようなビデオ」をリクエストした際に、手描きホワイトボードスタイルの長尺解説ビデオ(5~20分)を生成します。fframes(Rustベース、バージョン1.3以上ではthree.js風の3Dショットもサポート)とlocal-ttsスキルを音声に使用し、すべてのラベル、下線、円、図がナレーションの言葉に同期して描画され、スライドごとに段階的に構築されます。論文の図表はその場で注釈付きで表示され、章チップ、難易度の高い多肢選択クイズ、小さなアニメーションキャラクター(ホスト)も含まれます。開発者はテンプレートからコピーして作業を開始し、Pythonスクリプトでナレーションを生成、Rustでレンダリングします。このスキルは、Claude Code、Cursor、CodexなどのAIエージェント向けに設計されており、視覚と音声が完全に同期した説明体験を提供します。

対応✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/Ayushmaniar/claude-explainer-skills/tree/HEAD/plugins/explainer-skills/skills/whiteboard-explainer

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

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

ドキュメント

ホワイトボード解説ビデオ

このスタイルの核心は、声と映像が一緒に動くことです。すべての文字、線、下線、円、矢印が発声と同時に描かれ、各スライドは段階的に構築されます。ストーリーボードを書く前に、references/style-guide.mdを読んでください。そこには色、画面に表示する文字のルール、段階的開示、同期タイミング表、ビデオ全体の構成が記されています。

すべてのビデオはtemplate/から開始してください(コピーして使用し、ゼロから始めないでください)。このスキルのtemplate/を<project>/video/にコピーし、source env.sh && cargo build --releaseを実行します。バイナリはtarget/release/explainer(Windowsではexplainer.exe、env.sh内のR ...で実行されます)です。テンプレートは約95秒のデモ(「1分でわかる二分探索」)で、コピー元となる4つのシーンが含まれています。template/README.mdにすべてのコマンドが記載されています。Pythonスクリプトはプロジェクトフォルダからpython -I narration/<x>.pyのように実行し、numpy、soundfile、librosa、faster-whisper、pillowがインストールされている必要があります。含まれているもの:

  • src/kit.rs:描画キット(手描きストローク、hand/noteテキスト、underline、circle、arrow、stamp、counter、論文図用のCardとmark/ring/spot/zoom、camera、shrink_aside、アイコン)。全体を使用します。
  • src/lib.rs:シーンディスパッチ、0.1秒のディップを伴う章チップ、画像テーブル、SceneCues(c.w(beat, "word") = 単語が発声されるタイミング)。デモシーン:s_intro.rs(コールドオープン、タイトル、アウトロの要約)、s_idea.rs(発声された単語に基づいて構築されるスライド)、s_figure.rs(リング/マーク/ノート/スポットとズームを備えた図カード)、s_quiz.rs(トラップスタンプ付きのmcqクイズ)。
  • src/objs.rs:再利用可能なオブジェクト(mcq、grid、token、vecbar、hbar、code_panel、chat_card、quote_card、axes/trace、vec_arrow、photoなど)に加え、「このビデオ」セクション。各ビデオの繰り返し使用するオブジェクトをここに配置し、すべてのシーンで同一に描画できるようにします。
  • src/duck.rs:ホストスプライト(足の位置、音声エンベロープからのトーキングボブ、シーンごとのスポット:コールドオープン/クイズ/アウトロでは大きく、それ以外では右下に小さく表示)。スプライトがない場合はホストなし。
  • src/t3d.rs(オプション):イミディエイトモードのキューブと、テンソル/配列3Dインセット用のView3。
  • narration/:script.py(シーン→ビート、クイズ用のPAUSE)、tts.py(音声設定、local-ttsのsay.pyを見つける)、build_vo.py(音声 + 行ごとのキャッシュ + ポーズ整形 + テンポ + faster-whisperによるワードアラインメント → audio/narration.wav、src/cues.rs、src/envelope.rs)、words.py(すべてのc.w(...)キー、欠落したディスパッチアーム、残ったプレースホルダをチェックし、WORDS.mdを書き出す)、est_cues.py(音声がない場合の仮のキューと無音トラック)、audit_vo.py / tts_try.py(発音監査)、make_srt.py(DISPLAYマップ、OVERRIDE、--reviewを使用した字幕)、envelope.py、glitch.py(最終ファイルのチェック)。
  • tools/:prep_figs.py(figs/*.pngからsrc/figs.rsを書き出す)、get_pet.py(ホストスプライトをダウンロードする)、font_metrics.py、make_demo_fig.py、lowprio.py(アイドル優先度でジョブを実行する)。
  • media/:フォント。メディアファイルのみがそのトップレベルに配置できます(include_media_dir!はそれ以外でパニックを起こします)。そのため、ライセンステキストはmedia/licenses/にあります。
  • HELPERS.md:各シーンヘルパーに与える指示書(ルール、ファイルマップ、ビルド&チェックループ)。
  • STORYBOARD.md:デモのストーリーボード。ヘルパーが必要とする詳細レベルを示しています。
  • THIRD_PARTY.md:フォント、スプライト、fframes、FFmpegのライセンス。

要件

  • Rust(安定版)とcrates.ioのfframes 1.3.0(template/Cargo.tomlに固定。ライセンス条項を確認してください)。
  • FFmpeg共有ライブラリ(FFmpeg 7+ "shared"ビルド)とfframesビルド用のLLVM/libclang。template/env.shはFFMPEG_DIRとLIBCLANG_PATHを読み取ります。WindowsではFFmpegのbinをPATHに追加し、cargoとビルド済みバイナリの両方がDLLを見つけられるようにしてください(DLLがないと、パイプ時にサイレント終了コード127になります)。
  • Python 3.10+(faster-whisper(ワードアラインメント、監査)とnumpyが必要)。
  • 音声用のlocal-ttsスキル(同じプラグイン)。GPUがあれば非常に高速です。すべてCPUでも実行可能です。
  • ホストスプライト(オプション):github.com/gennadi-kuzmin/awesome-codex-pets のCodexペット(192x208セル)。python -I tools/get_pet.py --list、次にpython -I tools/get_pet.py <pet-id>でダウンロードし、sprites/にスライスします。そのリポジトリのMITライセンスはコードをカバーしています。ビデオを公開する前に、各ペットのアートワークの権利を確認してください。明るい色のペットを選んでください(暗いペットは黒板に映えません)。スプライトがない場合、ビデオはホストなしでレンダリングされます。

fframesのバージョンと公式スキル

新しいビデオにはfframes 1.3.0を使用します。作成者の公式スキルfframes-videoは、一般的なAPIとリリースごとの変更をカバーしています。このスキルでカバーされていない点については、そちらを参照してください。npx skills add https://fframes.studio -g -a claude-code -yでインストールできます(権限でブロックされる場合はユーザーに実行を依頼してください)。同じファイルがgithub.com/dmtrKovalenko/fframesのskills/fframes-video/にあります。このスキルは、このスタイルに固有のもの(ルック、パイプライン、以下のレッスン)のみを保持します。レンダリングについて両者で矛盾がある場合は、以下の落とし穴が優先されます。

1.3で新しく、使用価値のあるもの:

  • 3Dショット(fframes::three_d):次のセクションを参照。
  • よりシャープなチェック:frame 3s --crop x,y,w,h(ビデオピクセル単位のズームクロップ。ストロークや小さなラベルの確認に)、frame --ids(idを持つすべての要素の輪郭と名前を表示)、strip 2s,5s,9s(選択した時間を並べて表示)、inspect --pops(1フレームでポップイン/アウトするものを見つける。ホストのまばたきをグループ化)。--popsはフレームをチェックし、エンコードされたmp4ではないため、最終ファイルに対してglitch.pyを実行してください。
  • Lottie:機能lottie、frame.play_lottie(ctx, "x.json", LottieOptions { .. })で既製のアニメーションアイコンを使用。手描きキットのストロークはデフォルトのまま。Lottieはホワイトボードのルックに合う場合のみ使用してください。
  • include_media_dir!(pub struct M, "media", stereo)でステレオファイルをステレオのまま保持します。

ホワイトボードビデオでの3Dショット

3Dは、奥行きや動くカメラが説明そのものである場合にのみ使用してください:そこから引き出されるレイヤーのスタック、テンソル形状、メモリ階層、物理デバイス、損失曲面、傾く論文図カードなど。テキスト、ラベル、チャート、矢印は手描きSVGのままにしてください。1チャプターあたり1~2つの3Dモーメントに抑えてください:ビデオはまだホワイトボードです。references/three_d_example.rsは4秒のテストです(回転するレイヤースタック、持ち上げられるレイヤー、それにピン留めされた手書きラベル、3D平面上にsvgrで描かれたペーパーカード)。

  • fframes = { version = "=1.3.0", features = ["compile-time-svgtree", "cli", "3d", "wgpu"] }。3DはCPUフレームレンダラーでも動作します:wgpuを使用すると3DはGPUでレンダリングされ、読み戻されます(1080pで120フレーム:RTX 4070 Laptopで1.4秒、Renderer::cpu()で4.2秒)。GPUがビジーな場合はレンダラーを.cpu()に切り替えてください(例ではFF_3D=cpuを読み取ります)。他の部分は変わりません。wgpu型ではmain.rsに#![recursion_limit = "256"]が必要になる場合があります。
  • ボードのルック:Background::TransparentをキットのBG矩形の上に、Material::shadow_catcherフロア、ToneMapping::Neutral(キットパレットを忠実に保つため)、そしてMaterial::standard(c).roughness(0.45).clearcoat(0.4)をストリップサイズで読み取れる塊状のオブジェクトに使用します。
  • 3Dオブジェクトへの手書きラベル:camera.project(scene.local_to_world(id, local), w, h)でインセット内のピクセル座標を取得し、インセットのx/yを加算します。キットを使用して、トリガーワードでラベルを描画します。
  • 3D内の論文図:ctx.render_svgr(svgr!(..), w, h) → Texture::from_image(&img)をGeometry::planeに、Material::unlit(0xffffff)とともに使用します。同じパスで図PNGをカードに配置します。
  • 移動するオブジェクトは、そのインセットレンダラーのボックス内に留まらなければなりません。そうしないと、端で切り取られます。
  • シーンをnew()で一度構築し、フレームごとにクローンしてポーズを設定します(公式の3d.mdを参照)。
  • テンソル/配列ビジュアル:イミディエイトモードが適しています。シーン関数は各フレームのtからVec<Cube>を構築し(位置は単純な算術計算なので、ブロックの折りたたみ、分割、展開、ゴーストフィルが可能)、1つの共有rounded_boxジオメトリでインセットをレンダリングし、手描き矢印用の点を投影します。キューブ番号は前面レイヤーのみに書き、フェードしたキューブ(アルファ < 0.6)のラベルはスキップしてください。そうしないと透けて見えます。3Dを含む完全なinspectは遅いです(5,400フレームで約10分):バックグラウンドで実行してください。
  • ピン留めされたラベルは、カメラ移動全体を通してすべてのオブジェクトからクリアに保ち(ショットの開始時と終了時に静止画で確認)、shrink_asideの完了後に3Dショットを開始し、その最中には開始しないでください。

ワークフロー

  1. リサーチ:ソースをresearch/paper_notes.mdにリサーチします。すべての数値とその表/ページ、および表現上の注意点(パーセントとポイントなど)を含めます。論文の図を画像として抽出します(figs/、ビデオ内では白いカード)。論文自身の図や図表を画面に表示します。
  2. スクリプト(narration/script.py):約150語/分、1ビートあたり1文、音声のためにスペルアウトします(「スイーベンチ」、「ティーゼロ」、数字は言葉で)。最も驚くべき数字でコールドオープン → タイトル + ペーパーカード → ロードマップ → チャプター → 3~4のクイズ(質問、選択肢A-D、PAUSE、答え) → 以前に描かれた同じオブジェクトを再利用する評決ポスター → 細字 → アウトロ。音声ビルド後に長さを確認します。急ぐよりも、行をトリミングするかTEMPOを上げてください(1.06で機能します)。
    • クイズは難しく、正確な多肢選択(スタイルガイドセクション6):推論問題、4つの選択肢(誤ったものは実際の誤解)、正確に1つの防御可能な答え。research/quiz_keys.mdを書き(すべての選択肢をページ/表参照で正当化し、派生した数値はPythonで計算)、音声ビルド前にチェックします。
    • 要約するのではなく、教えること。 各アイデアをゼロから構築し、実際の数値で実例を示します。すべての用語をそれが導入される行で定義し、専門用語を日常的なものに縮小します(「ノードは単なる1つのジョブです」)。ほとんどのビートを接続詞(「つまり」「さて」「しかし」)で始め、ターンが聞き取れるようにします。150語/分近くを維持します:描画には時間が必要です。
    • 使用前にすべての記号を適切に導入します。使用する行で短いリマインダーを繰り返します。
    • AIではなく、人間らしく聞こえるようにします。 スクリプトを書く前にreferences/natural-narration.mdを読み、その後python -I scripts/aispeak_scan.py <project>/narration/script.pyを実行します。段取りの説明(「ここが核心です」)、「XではなくY」のリフレーム、引用可能なクローザー、自己回答の質問を、音声ビルド前に修正します。
    • コロン断片の行(「最初に:...」「3つのベンチマーク。」)は避けてください。音声がそこで停止し、次の行が唐突に聞こえます。シーンの最初の単語だけ(「プローブ。」)は飲み込まれる可能性があります。「次に、プローブ。」と書きましょう。「ご視聴ありがとうございました!」には独自のビートを与えます。
  3. ストーリーボード(STORYBOARD.md):シーンごとに、どの要素がどのトリガーワードで現れるか、そのおおよその位置(x, y)、サイズ、色、どの図/クロップか、繰り返し使用するオブジェクトと色の意味。実装可能で、デザインではない具体性。チップ領域(左上)とホスト領域(右下)を確保します。
  4. 音声:narration/build_vo.pyは、local-ttsスキルのsay.pyを通じて音声を生成します。say.pyはLOCAL_TTS_SAY、次に~/.claude/skills/local-tts/、次に~/.claude/plugins/**から検索されます。GPUがビジーな場合:GGML_BACKEND=CPUとWHISPER_DEVICE=cpu。行ごとにキャッシュされます。行を言い換えると、新しいテイクが強制されます。shape()は、各クリップ内の無音をその前の句読点(なし:0.14秒、,:0.24秒、:;:0.3秒、.?!:0.42秒)でキャップし、行間は0.5秒(疑問文の後は0.7秒)です。シーンを描画する前に音声を監査します:audit_vo.pyは、スクリプトをプロンプトとして使用せずにすべてのクリップを書き起こし(build_voのプロンプト付きWhisperは誤った発音を隠します)、それをスクリプトと比較します。米国スペルと同音異義語は無視します。実際の誤読を修正し、修正をtts_try.pyでテストします(文全体の中で行います。名前は単独では問題なくても、文中で歪むことがあります)。既知の誤読はlocal-ttsスキルの落とし穴にあります。再音声のたびに監査を再実行します(Qwenは時々単語を重複させることがあります、「the the」)。音声の準備がまだできていない場合:est_cues.pyが仮のキューと無音トラックを書き込み、build_vo.pyが両方を上書きするときにシーンが自分自身を再タイミングします。
  5. キット + 1~2の模範シーン:あなた自身が描画し、フルサイズでチェックします。これにより、ヘルパーが品質基準を持てるようにします。
  6. シーングループを並列サブエージェントにファンアウトします(小規模で高速なモデルと高い推論努力が、指示が厳格な場合にこれをうまく行います。より強力なモデルは模範シーンにのみ必要です)。最初にobjs.rsに繰り返し使用するオブジェクトを配置し、HELPERS.mdに絶対パスでresearch/へのパスを記入します。プロジェクトをwork/<group>/にエージェントごとにコピーし(レンダリングとナレーションキャッシュはスキップ)、ターゲットディレクトリをハードリンクします(cp -al target work/g/target、またはヘルパーごとにCARGO_TARGET_DIRを設定し、そのコピー自身のexplainerクレートアーティファクトを削除します)。これによりディスクとビルド時間を節約します。各ヘルパーは自身のsrc/s_<group>.rsのみを編集し、ビルド、words.pyとinspectの実行、ストリップとフルフレームのチェックを行います。マージはs_*.rsをコピーして戻すことで行います。他のファイルは最初に差分を確認します。
    • ヘルパーを高速に保ちます。 ビルドがボトルネックです:[profile.release] incremental = true + codegen-units = 256を維持し(再ビルド約50秒→約25秒)、同時に実行するヘルパーは最大約4つにします。後のグループは、最初に終了したヘルパーに割り当てます。1グループ = 同じ重みの2シーン。クイズや密度の高いシーンは分割します。予算:シーンあたり最大3回のビルド&ルックラウンド、12フレームストリップと@end、その後は残りの疑問をリストアップして洗練は行いません。ヘルパーあたり1回の的を絞った修正ラウンドは安価です。
    • 事実を検証します:すべての画面上の数値をpaper_notesと照合し、すべての実例を計算します(ヘルパーは数値を発明したり、繰り上がりを間違えたり、後のクイズの答えを漏らすデモを作成することがあります)。写真がナレーションと一致することを確認します。
    • 各ヘルパーのストリップとフレームを自分自身でレビューします(ヘルパー自身のチェック画像は古くなっている可能性があります)。その後、具体的な修正を送信します。彼らの一般的な欠点は、各フェーズを上半分に小さなタイプで詰め込むことです:y範囲とpxを指定します。

... [翻訳のために省略]

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

関連スキル