srt-whiteboard-animation について
srt-whiteboard-animation は、SRT 字幕からホワイトボードアニメーションを作るクリエイティブスキルです。字幕の語りに沿ってマスク領域を順に描き、プレビュー、編集、レンダリング、シーン結合まで行う手順を備えています。
主な機能
- 01字幕解析とシーン構成案の作成
- 02マスクによる領域の段階表示
- 03連続した筆跡で描画と着色
- 04プレビューで領域と時刻を編集
- 05シーンの MP4 レンダリングと結合
活用シーン
- 01字幕内容をホワイトボードアニメーション化
- 02語りの順に画面要素を表示
- 03領域アノテーションと時刻を確認・調整
- 04複数シーンを一つの動画に結合
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ geeklee/ srt-whiteboard-animation --skill srt-whiteboard-animationインストール後、Claude Code で/srt-whiteboard-animationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSE.gitignoreREADME.mdagents/openai.yamlassets/preview.htmlexamples/scene-01-monkey-mountain-banana.annotation.jsonscripts/merge_scenes.pyparse_srt.pyprepare_env.pyrender_annotation_preview.pyrender_stream_whiteboard.pystream_render.py詳細
SRT ホワイトボードアニメーション(mask オーケストレーション + stream 描画法)
SRT 字幕をホワイトボード手描きアニメーションに変換します:オーケストレーションは分割マスクによるreveal(物語の順序に沿って領域ごとに順次reveal、未開始の領域は完全に非表示、重なりは protectedRegions で保護)を踏襲し;描画法はストリーミング筆跡に置き換えます——各領域は自身の許可マスク内で、筆先がスケルトン/グリッドに沿って連続的に滑りインクを落とします(起筆 ink → 彩色 color)。すべての領域は一枚の永続キャンバスを共有し、描き終わった領域はキャンバス上に保持されます。ユーザー向けの説明、絵コンテ、設定、UI テキストはすべて中国語を使用する必要があります。
コマ送りのジャンプや矩形のワイプとは異なります:本 skill の筆跡は連続的に流れるものです;全体画像の stream とも異なります:本 skill は字幕の物語区分ごとに順に描画し、各要素の登場順序とタイミングを制御できます。
デフォルト実装パラメータ
| 項目 | デフォルト要件 |
|---|---|
| 紙の背景 | 生成画像は暖かい生成り色の古紙色(推奨 #F5EBD7)を使用;レンダリング時は元画像の四隅から内側に縮めた位置でサンプリングして下地を染め、純白は禁止。 |
| 描画法 | 各領域を stream で連続筆跡:起筆 ink(線画を敷く)→ 彩色 color(原色を復元);重みは ink:color = 2:1。 |
| 筆跡パス | --ink-path grid(グリッド、デフォルト、安定)または skeleton(スケルトントラッキング、線画がはっきりしたイラストにさらに適合)。 |
| 彩色スタイル | --color-fill contour-wipe(輪郭スキャン、デフォルト)または brush(軌跡に沿ってブラシ)。 |
| 未描画領域 | 領域の許可マスク = 矩形 region から「後続領域 + protectedRegions」を差し引いたもの;未開始の領域は完全に非表示。 |
| 時間の由来 | 各画像の sceneDurationMs はその幕の字幕の時間幅から取得(推奨 25〜35 秒/幕)。 |
| 編集ボックス | プレビューコンソールはデフォルトで全番号付き編集ボックスを表示;編集ボックスはアニメーション画面の内容には含まれない。 |
統一画像生成ビジュアル仕様(必須)
すべてのシーンの元画像は同一のビジュアル言語に従う必要があります;生成前に以下の要件を完全に画像生成プロンプトへ記述し、生成後に項目ごとに確認してください:
- スタイルと構図: ミニマルな手描きイラスト、純粋なスケッチ草案スタイル、Notion に似た抑制の効いた落書き美学。概念表現を主とし、写実性は追求しない;構図は簡潔、背景は清潔、大量の余白、全体的な情感は穏やかで明快、シリーズ内で線/人物/配色が一致。
- 色と質感: ベージュの紙背景
#F5EBD7、濃いグレーのスケッチ線;赤、オレンジ、青のみを少量の概念的アクセントとして使用可能。その他のアクセントカラー、高彩度の配色、複雑なテクスチャは使用してはならない。 - 人物とオブジェクト: オブジェクトは簡潔な輪郭、少量の線と余白で表現し、実寸比、質感、細部ではなく関係/変化/中核概念を強調する。
- 絶対禁止: シーン元画像内のいかなる文字、語、アルファベット、数字、フォント、ラベル;写実感、写真のディテール、3D 効果、絵画的質感;複雑なシーン、密集した背景、繁雑な装飾、高彩度の画面。
- 描画する手の例外: ユーザーがペン軸上の文字が自身の識別であり保持を明示的に要求した場合、
drawing-hand.pngのペン軸上の識別を保持してよい;これはシーン元画像の文字には該当せず、消去や再描画も不要。ユーザーの明示的な説明がない場合は、依然として文字なし画面として扱う。
確認ゲート(必須)
デフォルトのワークフローの各ステップ完了後は必ず停止し、ユーザーの明確な確認を待ってから次のステップを開始しなければなりません。確認前に次のステップの画像、注釈、プレビュー、動画、結合ファイルを生成してはならない;「未返信」「以前の包括的な承認」「ユーザーが反対しなかった」を確認と見なしてはならない。ユーザーが前のステップの修正を要求した場合、そのステップのみをやり直し、完了後に再び確認を待つ。
唯一の連動アクションは:注釈 JSON の作成完了後、直ちにプレビューコンソールを自動的に開き、その JSON のあるディレクトリを読み込むこと;これはステップ 3 の納品に属し、「プレビューコンソールを開く」ために別途確認を待つ必要はない。ブラウザの File System Access API がユーザー操作を要求する場合、ブラウザ UI でこの確定済みディレクトリを選択する;これを理由にユーザーへ追加の確認を求めたり、ユーザー自身にプレビューコンソールを開かせるよう変更してはならない。
ワークフロー
- 字幕を読み、戦略を出す(画像は生成しない)。
scripts/parse_srt.pyで SRT を字幕行に解析し、25〜35 秒/幕で推奨絵コンテを提示。これに基づき配図戦略を出力:各幕のシーン番号、中核表現、画面主体、対応する字幕区間とsceneDurationMs。各幕は中核的な意味を一つだけ表現する。完了後停止し、ユーザーの戦略確認を待つ。 - 線画を生成。 ユーザーが戦略を確認した後のみ、「統一画像生成ビジュアル仕様」に従い、幕ごとに 16:9 の暖かい生成り色の古紙下地の線画を生成、背景
#F5EBD7、主体間には自動分割しやすいよう十分な余白を確保;文字、複雑な写真、重なり合うオブジェクト、仕様に反する要素を生成してはならない。完了後停止し、線画を提示してユーザーの確認を待つ。 - まず字幕を読み、次に画像を見て、その後注釈してプレビューコンソールを開く。 ユーザーが線画を確認した後のみ、まずその画像に対応する字幕を読み、次に実際に画像を閲覧し、元画像のピクセル幅と高さを取得する;字幕のみから画面を推測してはならず、画面位置のみで機械的に並べてもならない。まず字幕の物語イベントを抽出し、次に画像中の可視主体をイベントに対応付け、「シーンの下敷き → キーとなる人物/物体 → 動作の衝突または変化 → 反応/結果」の意味的順序で描画を手配する。その後
<画像名>.annotation.jsonを作成。作成完了後、直ちにデフォルトブラウザでassets/preview.htmlを開き、プレビューコンソールの「フォルダを開く」からその注釈ファイルのあるディレクトリのすべての<名称>.png+<名称>.annotation.jsonを読み込む;ファイルパスを示すだけにしたり、ユーザー自身に操作させてはならない。プレビューコンソールにディレクトリが読み込まれた後停止し、ユーザーの注釈とプレビュー内容の確認を待つ。 - 領域プレビュー画像を生成。 ユーザーが注釈とプレビュー内容を確認した後のみ、
render_annotation_preview.pyで番号/方向チェック図を出力し、分割が物語順序と一致するか、領域がすべてキャンバス内にあるか、重なる主体がprotectedRegionsで保護されているかを確認する。完了後停止し、ユーザーのプレビュー画像確認を待つ。 - プレビューコンソールで調整して保存。 ユーザーがプレビュー画像を確認した後のみ、すでに開かれ対応ディレクトリが読み込まれたプレビューコンソールで調整:デフォルト(未再生)では完全な画像と領域枠を表示;キャンバスは矩形プロキシ:領域の四辺四角をドラッグして
regionを変更、右側で名称/方向/開始(ms)/終了(ms)(長さ = 終了 − 開始、読み取り専用)と字幕を変更、モジュールリストをドラッグして順序を調整(sequenceを自動再配置)、モジュールを選択すると対応する字幕が自動ハイライト;タイムラインをドラッグまたは再生を押してrevealを確認(未開始領域は非表示);directionはこのプロキシのみに影響。変更後「本シーンを保存/すべて保存」をクリックして元の.annotation.jsonへ書き戻す(各領域のsubtitleを含み、sceneDurationMsを最後の領域終了+0.5s に合わせる)。保存後停止し、ユーザーの最終的な注釈とタイミングの確認を待つ。 - コマンドラインでレンダリングして成片。 ユーザーが最終的な注釈とタイミングを確認した後のみ、
render_stream_whiteboard.pyで幕ごとに全クリア MP4 を出力し、冒頭、任意の重なりモジュールの中間、末尾の三つの時点を抜き取り確認する。完了後停止し、ユーザーの成片確認を待つ。 - 複数幕の結合(複数幕の場合のみ適用)。 ユーザーがすべての単幕成片を確認した後のみ、
merge_scenes.pyで順に結合して一本にする。完了後停止し、ユーザーの最終合成動画の確認を待つ。
ディレクトリの取り決め
ユーザープロジェクト内に作成:
assets/whiteboard/<项目名>/
scene-01-<名称>.png
scene-01-<名称>.annotation.json # 与 png 同名
scene-01-<名称>-whiteboard.mp4 # 成片
scene-01-<名称>-preview.mp4 # 真实片段(预览台生成,低清)
画像と設定は同名でなければならない:foo.png は foo.annotation.json に対応。プレビューコンソールはこれに基づき設定を自動読み込みする。
意味的順序付けとピクセル単位の注釈(必須実行)
- 読解の根拠: 注釈前に字幕と閲覧済みの元画像の両方が必須。いずれか欠ける場合は先に要求し、注釈を生成してはならない。
- 順序の根拠:
sequence、startMs、labelは字幕中のイベントの前後関係を反映しなければならず、左から右、上から下、または視覚的な目立ちやすさのみに基づいてはならない。 - 座標の根拠: 各モジュールは元画像座標系の整数ピクセル
x、y、width、heightを出力;原点は左上隅、パーセント/比率/推定座標やサイズの省略は禁止。canvas.width/canvas.heightは元画像のピクセル寸法と等しくなければならない。 - モジュールのフィールド: 各要素は
sequence、narrativeRole、subtitle、region、reveal、handPathを含む。narrativeRoleは字幕中でのその物語上の役割を中国語で説明;subtitleはその領域に対応する字幕テキスト(SRT 由来、プレビューコンソールの連動および今後の用途のため)を格納;sequenceは 1 から連続。 - 検証: プレビュー生成前に各領域がキャンバス内にあるか、対応する可視主体を覆っているか、字幕イベントと一致するかを確認;重なる主体は
protectedRegionsで保護したうえでモジュールを描画する。
時系列モデル(stream 描画法専用)
- 各幕の総時間
sceneDurationMsはその幕の字幕時間範囲(parse_srt.pyのscenes[].sceneDurationMs)から取得します。 - 領域の直列描画: stream 描画法は 1 本のペンが動く方式であるため、同一幕内の各領域は時間的に順番に進める必要があります(
startMsを重複させない)。次の領域は前の領域のstartMs + durationMs(+ 任意で 100〜300ms の間)から開始します。startMsが重複しても、レンダラーは順序どおりに処理しますが、視覚的にはもはや並行ではありません。 - 領域内の ink→color: 各領域の
durationMsはink:color = 2:1で起筆段階と彩色段階に分割されます。durationMsはプレビュー台の開始/終了時間(終了−開始)で決まり、その領域に対応する字幕の長さに合わせることができます。また、150 ピクセル/秒 × 描画距離を初期見積もりとして使うこともできます。 - 凝視の締め: すべての領域を描き終えたら自動的に
sceneDurationMsまで補い、結尾で少なくとも 0.5 秒間は完全な原図を静止させます。 reveal.directionは stream 描画法では実際の筆跡を決定しません(筆跡は骨格/グリッドから自動生成されます)。プレビュー台の矩形プロキシによるデモ専用であり、プレビュー台で使えるようにするために保持しています。
マスク不変条件(オーケストレーション層、必ず実行)
- 時刻
tにおいて、モジュールはそのreveal.startMs ≤ t以降、かつ現在の作画進捗を超えないピクセルのみを表示できます。未開始のモジュールの線/塗り/画像は一切表示されてはなりません。 - 各領域の許可マスク = 矩形
regionからすべての後続モジュールのregionを差し引き、さらに本モジュールのreveal.protectedRegionsを差し引いたものです。stream の着墨は許可マスク内に制限されるため、後続領域の線が早く露出することはありません。 protectedRegionsはregionと同じ原図の整数ピクセル座標を採用し、矩形が大きすぎる場合、主体が重なる場合、背景の線が漏れる可能性がある場合に使用します。- レンダラーは「許可マスク内への着墨に制限 → 後続領域と保護区が自然に触れられない」という順序を実装済みです。プレビュー台の矩形プロキシは等価な
destination-outによる差し引きで同じオーケストレーションをデモします。
設定例
{
"sceneId": "scene-01",
"canvas": { "width": 1672, "height": 941 },
"storyBasis": "该幕字幕的事件摘要",
"sceneDurationMs": 9000,
"elements": [
{
"id": "rockery",
"label": "假山场景",
"sequence": 1,
"narrativeRole": "故事的场景铺垫",
"subtitle": "猴子山上,一只小猴子坐在假山顶端,手里拿着香蕉。",
"type": "structure",
"region": { "x": 20, "y": 120, "width": 540, "height": 780 },
"reveal": { "direction": "top_to_bottom", "startMs": 300, "durationMs": 2600, "maskPaddingPx": 22, "protectedRegions": [] },
"handPath": { "start": [290, 130], "end": [290, 890], "easing": "easeInOut" }
}
]
}
direction/handPathはプレビュー台の矩形プロキシ専用です。完成映像の筆跡は stream が自動生成するため、細かく調整する必要はありません。
スクリプトの使用
すべてのレンダリングスクリプトは skill 内の .venv のインタープリターで実行します(依存関係の分離)。
- 環境の準備(初回または依存関係が不足している場合):
python scripts/prepare_env.py --check # 探测;成功末行输出 ENV_PY=<路径>,捕获备用 python scripts/prepare_env.py # 缺则建 .venv 并装 opencv-python/numpy/av - 字幕の解析 + 絵コンテの提案:
python scripts/parse_srt.py <字幕.srt> --target-sec 30 --min-sec 25 --max-sec 35 - 領域番号のプレビュー画像:
python scripts/render_annotation_preview.py <图片> <标注> <预览图输出> - プレビュー台(サーバー不要):Chrome / Edge で直接
assets/preview.htmlを開き、「フォルダを開く」をクリックしてディレクトリを選択 → すべての画像 + 同名の注釈を読み込み → ドラッグして編集 → 「保存」で元のファイルに書き戻します。書き戻しには File System Access API(Chrome/Edge)が必要です。その他のブラウザーではダウンロード後に手動で上書きします。レンダリングは引き続きコマンドラインで行います(下記の手順 5)。 - 単一の幕の成片をレンダリング:
<ENV_PY> scripts/render_stream_whiteboard.py <图片> <标注> <输出mp4> assets/drawing-hand.png \ [--ink-path grid|skeleton] [--color-fill contour-wipe|brush] [--total-ms <毫秒>]--total-msを省略した場合は注釈内のsceneDurationMsを使用します。最終行にOUTPUT=<パス>を出力します。 - 複数の幕の結合:
<ENV_PY> scripts/merge_scenes.py --inputs 幕1.mp4 幕2.mp4 幕3.mp4 --output final.mp4
品質チェック
レンダリングの前後に確認:
- 最初のフレームが清潔な暖かいベージュの古紙の下地で、線が早く露出していない。
- 対応する字幕を読み、実際に原図を確認した。
canvasが原図のピクセルサイズと一致し、すべてのregionが整数ピクセル座標でキャンバス内にある。 sequence、startMsが字幕イベントの順序と一致している。プレビュー画像の番号/ラベル/領域が同一の注釈 JSON から取得されている。- 開場時、任意の重複モジュールの中間、すべてのモジュール完了後の 3 つの時点で確認:未描画のモジュールは不可視で、重複する保護区が漏れ出さず、最終フレームが完全な原図を表示している。
- ペン先が進行中の筆跡に近接している。線画が明確なイラストでは
--ink-path skeletonを使うと筆跡がより密着します。 - すべてのモジュール終了後に少なくとも 0.5 秒間は完全な原図を静止させる。
- 複数の幕を結合した後、順序、時間が字幕の絵コンテと一致している。
効果を変更したい場合は、まずプレビュー台(assets/preview.html)で注釈(領域/順序/時系列)を調整して保存し、その後コマンドラインでレンダリングしてください。当て推量で何度も書き出すのはやめましょう。