Communitygithub.com

liangruibupt/explainer-video-pipeline

ナレーション付き解説動画(Opus ストーリーボード、コード描画フレーム、Polly 音声、字幕、音楽、効果音)を生成し、レンダラーを切り替え可能にするスキル。

explainer-video-pipeline とは?

このスキルは、ユーザーが指定したトピックについて、1〜3分のナレーション付き解説動画(MP4)を自動生成するパイプラインです。Opus 5.5 などの大規模言語モデルが脚本・ストーリーボード・各シーンの描画コードを作成し、Remotion、HTML/Canvas、Manim などのレンダラーで映像化します。音声は Amazon Polly や gTTS、字幕は Whisper の単語単位タイミングで焼き込み、BGM や効果音も自動合成。Seedance による動画クリップの組み込みも可能で、科学的・技術的な解説動画を高品質かつ再現性高く制作できます。各工程はスクリプトで自動化されており、手動編集を大幅に削減します。

対応✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/liangruibupt/explainer_video_platform/tree/HEAD/skills/explainer-video-pipeline

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

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

ドキュメント

explainer-video-pipeline (自動生成)

いつ使うか

ユーザーが科学、製品、技術などについて1〜3分のナレーション付き解説動画(MP4)を希望する場合。動画には音声、字幕、BGM、効果音が含まれます。

パラメータとデフォルト値

トピックだけを尋ね、それ以外はユーザーが明示的に指定しない限りデフォルト値を使用します。どの値を使用したかを1行で伝えてください。

パラメータデフォルトその他の値
topic必須—
storyboard_modelclaude-opus-5.5 が脚本・ナレーション・ストーリーボードを執筆kiro-cli chat --list-models で表示される任意のモデルID
video_engineopus-5.5: claude-opus-5.5 が各シーンの描画コードを執筆別のコードモデル(例: claude-sonnet-5.5); seedance(BytePlus ModelArk API、ARK_API_KEY が必要); hybrid(コード描画シーン内に Seedance クリップを埋め込み)
rendererremotion(React/SVG、Remotion がヘッドレス Chromium を駆動)html(Canvas 2D / SVG / GSAP / p5.js ページ、Playwright でキャプチャ); manim(Manim Community シーン、幾何学・グラフ・ベクトル・段階的導出に最適)
seedance_modelseedance-1-5-pro-251215ユーザーのModelArkアカウントで有効な任意のSeedanceモデル
ttspolly、ニューラル音声 Zhiyu、cmn-CN、us-east-1gtts(無料、キー不要、平坦な音声); その他の Polly 音声・言語
captionsオン: Whisper 単語タイミング、単語単位ハイライト付きで焼き込みオフ
whisper_modelsmall(CPU、int8、音声10秒に対し約5秒)base(より高速)、medium(より正確なタイミング)
musicsynth(ffmpeg で生成するロイヤリティフリーの発振器BGM)none; ユーザー所有の音楽ファイルのパス
sfxオン: scenes.json にリストされたイベントを合成し該当フレームに配置オフ: すべてのシーンから sfx を省略
language中国語(マンダリン)ナレーションPolly と Whisper が両方サポートする任意の言語
size, fps1920×1080、30 fps縦向きの場合は 1080×1920

「Opus 5.5 で制作」とは、Opus 5.5 が作者であることを意味します。すなわち、脚本と描画コードを執筆し、レンダラーがそのコードをピクセルに変換します。テキストモデルが直接動画を出力することはありません。Seedance のみが動画を直接生成します。最初の返信でこのことを一度述べてください。 セッションがすでに claude-opus-5.5 上で動作している場合は、自分の力で執筆を行ってください。そうでない場合は、ストーリーボード(ステップ2)のために model="claude-opus-5.5" かつ keep=true のタスクを1つ起動し、シーンコード(ステップ5)のために同じ実行を spawn_continue で続け、その後自分でその出力を確認してください。

セットアップ(マシンごとに1回)

ツールは安定したキャッシュディレクトリ(例: ~/.cache/explainer-video/)に置き、セッション間で再利用される $KIROCREW_SCRATCH には決して置かないでください。

  • ffmpeg: aevalsrc、anoisesrc、tremolo、sidechaincompress、ass/libass を含む完全な静的ビルド。Remotion にバンドルされた ffmpeg にはこれらがありません。FFMPEG / FFPROBE 環境変数でそれを指すように設定します。
  • Python venv(boto3 gTTS playwright faster-whisper pillow numpy)、その後その venv から python -m playwright install chromium-headless-shell を実行します。 faster-whisper 1.2.x は PyAV 19 で壊れます(unexpected keyword argument 'metadata_errors')。av==16.1.0 を固定してください。Whisper モデルが一度だけダウンロードされるように HF_HOME をキャッシュディレクトリに設定します。
  • Manim(renderer=manim の場合のみ): pip では aarch64 でビルドできません(pycairo、manimpango、moderngl の wheel がありません)。root 権限がない場合は micromamba を使用します: micromamba create -p <cache>/manim-env -c conda-forge python=3.12 manim Text() はCJKフォントで動作します。MathTex/Tex には LaTeX ディストリビューションと dvisvgm が必要です。conda-forge の texlive-core は aarch64 で latex.fmt がないため、数式はそこで失敗します。数式は Text() で書くか(Unicode: F = m·a, x², √, →)、システムの TeX Live をユーザーがインストールできる場所にインストールしてください。

手順

ヘルパーはこのスキルの scripts/ フォルダにあります。

  1. プロジェクト. ユーザーのワークスペース下にgitリポジトリとしてプロジェクトフォルダを作成します。renderer=remotion の場合、package.json、tsconfig.json(resolveJsonModule: true)、src/index.ts、src/Root.tsx を手動で雛形作成し、npm i remotion @remotion/cli react react-dom を実行します。
  2. 脚本とストーリーボード(storyboard_model が担当)。scenes.json を作成します。各シーンは id、narration(話す台詞)、visual(画面に表示される内容)、オプションの manim(Scene クラス名)、オプションの sfx: [{"at": FRAME_IN_SCENE, "kind": "whoosh|hiss|pop|rise|thud|PATH"}] を含むオブジェクトです。タイトルシーンとエンドカードを含め、1つのアイデアにつき6〜10シーンを使用します。ウェブ検索で事実を確認し、README に出典を引用します。
  3. 参考画像. 動画に実在の物体が登場する場合、明確な写真を探すかユーザーに依頼し、ref/ に保存します。記憶だけで実在物体の形状を描かないでください。写真にエッジ検出を適用し、キーポイントを測定し、それらの点から形状を生成する小さなスクリプトをリポジトリに保存して使用します。
  4. ナレーションがタイミングを決定. narrate.py scenes.json . --tts polly を実行します。これにより durations.json(実際の音声長さ+パディングから計算されたシーンごとのフレーム数)、narration.wav、audio/sNN.mp3 が作成されます。シーンコードは durations.json を読み込むため、各シーンは台詞の長さだけ継続します。
  5. シーンコード(video_engine が担当)。
    • remotion: シーンごとに1つのReactコンポーネントを作成し、useCurrentFrame と interpolate/spring を使用してシーンの開始を基準にアニメーションさせます。
    • html: 1つの index.html に window.seek = async (frame) => {...} 関数を実装し、フレーム番号と durations.json 配列から正確にそのフレームを描画します。requestAnimationFrame、壁時計、シード指定のない Math.random は使用禁止。durations.json 配列を定数としてページ内に貼り付けます。file:// で開かれたページは fetch() でローカルファイルを取得できず、失敗は黙って行われます。GSAP: 一時停止タイムライン + tl.seek(frame / fps)。p5.js: noLoop() + seek 内で redraw()。
    • manim: 1つの scenes.py にシーンごとのSceneクラスを作成します。ターゲット長を os.environ["SCENE_SECONDS"] から読み取り、self.wait(max(0.04, secs - self.renderer.time)) で終了します。長いアニメーションのサイズも secs から決定します。フレームの下部15%を字幕用に空けておきます。
    • seedance: ARK_API_KEY を設定して seedance_clips.py scenes.json . を実行します。clips/<id>.mp4 をダウンロードします(URLは24時間で期限切れ)。
  6. フルレンダリング前に静止画を確認. キーシーンから4〜6フレームをレンダリングし、1枚の縮小コンタクトシートにまとめて、その1枚の画像を確認します。独立した確認のために、新しいレビューアーを起動してシートと scenes.json だけを渡すこともできます。
  7. 音声. いずれかのシーンに sfx がある場合、sfx.py scenes.json . を実行します。その後 mix_bgm.py . --music <music> を実行します。これは音楽を音声の下にダッキングし、sfx.wav を追加し、narration_bgm.wav を書き出し、RMSレベルを表示します。音楽のみのリードインは約−20〜−30 dB にします。−55 dB 以下ではほぼ聞こえません。
  8. 字幕. captions.py scenes.json . --size <WxH> は faster-whisper の単語タイムスタンプを使用して各行を書き起こし、それをスクリプトの文字にマッピングします(Whisper が同音異義語を誤認識するため、例えば「気体」を「漆体」と聞くことがあります)。captions.ass(各文字が話されたときにハイライト)と words.json(文字ごとのタイミング、ステップ5で画面上の強調に使用可能)を書き出します。
  9. レンダリング(映像のみの無音動画)。
    • remotion: npx remotion render src/index.ts <Comp> out/silent.mp4
    • html: capture_html.py index.html out/silent.mp4 --frames <durations.json の合計>
    • manim: manim_scenes.py scenes.py . --manim <manim-env>/bin/manim --quality h。各クラスをレンダリングし、正確なフレーム数になるようにパディングまたはトリミングします。
  10. FFmpegで合成. 字幕あり: ffmpeg -i silent.mp4 -i narration_bgm.wav -vf "ass=captions.ass" -c:v libx264 -crf 18 -pix_fmt yuv420p -c:a aac -b:a 192k -shortest final.mp4(字幕なしの場合は -c:v copy を使用し -vf を削除)。動画と音声の長さが約0.1秒以内で一致していることを確認し、最終的な MP4 から4〜5フレームを取得して確認します。特に文の途中で字幕のハイライトが正しいか確認します。
  11. 納品. フィーチャーブランチにコミットし、PRを作成します。マージ後、gh api repos/<o>/<r>/git/trees/<base>?recursive=1 でファイルが正しく配置されたことを確認します。

注意点

  • SVGパスの d= 文字列内に /* */ 形式のコメントを入れないでください。Chromium は / で解析を停止します。6桁のHEXカラーを使用してください。
  • ハードコードされた絶対フレーム番号を持つコードは、シーンのクライマックスがシーン終了後に発生する可能性があります。
  • Manimでは、オブジェクトが移動した後にラベルや矢印を配置するか(あるいは always_redraw / add_updater でアタッチする)、そうしないと古い位置に留まります。DashedVMobject は独自のポイントを持たないため、通常の図形から位置を取得してください。
  • pip でインストールされた Playwright は、キャッシュされたものよりも新しい Chromium ビルドを必要とする場合があります。
  • 複数の並列 strReplace 呼び出しで1つのファイルを編集しないでください。編集が失われます。シェルのヒアドキュメントでコードを記述しないでください。ガードレールがブロックする可能性があります。
  • Seedance 2.x モデルはアカウントのアクティベーションが必要で、実在の人間の顔を含む参照画像を拒否します。Seedance 1.5 pro のクリップは4〜12秒です。
  • Remotion ライセンス: 個人および3人以下の企業は無料です。より大規模な企業は有料の Company License が必要です。html と manim はそれを回避します。

関連スキル