漫画で語るストーリー
テーマを 110~135 秒の縦型ショート動画に:線画を一本ずつ描き、吹き出しを順に表示、ナレーション+大字幕。
成果物:<プロジェクト>/out/final.mp4(1080×1920)。
音声が主軸。 音声トラックだけを聞いても、理解できるストーリーになっていること。映像は演出を加えるものであり、理解の前提ではない。
5ステップ
① ストーリーを決める → <プロジェクト>/story.json
ディレクトリを作成し、テンプレートをコピー:
mkdir -p <プロジェクト>/raw && cp templates/comic/story.example.json <プロジェクト>/story.json
まずファイルの先頭3行を記入する。これが書けないならコマを書くな:
"story_line": "誰が / 何をしたい / 何に詰まっている / 結果、一言で",
"question": "冒頭で投げかける問題",
"answer": "最後のコマで出てくる、その問題への答え"
question は「説明がつかない点」を選ぶこと。「これは何?」ではない。答えは時系列の羅列であってはならない。
次に各コマの narration(ナレーション)と bubbles[].text(台詞)を書く。ナレーションは 440~540 字(句読点含む)、4.0 字/秒で逆算。
python scripts/pipeline.py <プロジェクト> --stage script # ただし次に進んではいけない
① の判定基準:3行が揃っている → 文字数が範囲内 → 各コマにナレーションがある → 吹き出しが画面内 → charts.py の関数が存在する。
② 画像生成 → <プロジェクト>/raw/<id>.png
すべてのプロンプトを先に書き終えてから、一括で画像生成する。 1枚ずつ見ながら生成すると1~2時間かかり、途中でプロンプトを変えると画風がぶれる。
python scripts/comic_gen.py <プロジェクト> --list # 未生成のプロンプトを表示、生成済みはスキップ
表示されたプロンプトを1枚ずつ生成し、raw/ に保存する。必ず画像To画像で行い、参照画像には assets/reference/01-style-anchor.png を使い、類似度は低めに設定する。
python scripts/contact_sheet.py <プロジェクト> # 一覧画像にまとめる
python scripts/pipeline.py <プロジェクト> --stage image
② の判定基準:一覧画像で次の2点だけ確認する——登場人物が揃っているか、全面塗りつぶしや空白がないか。 それ以外(画像内の散発的な文字、身長差が数センチ、線が汚い、しっぽの位置が数十ピクセルずれている)はすべて無視し、次のステップに進む。
③ 制作 → final.mp4
python scripts/comic_run.py <プロジェクト>
順に実行:ナレーション生成 → 吹き出しレイヤー/インフォグラフィック → クリーンエンドカード → 逐筆レンダリング → 縦型合成 → 字幕焼き付け。
個別のステップを再実行する場合は、対応する comic_*.py を使う。
④ 検収
python scripts/verify_media.py --file <プロジェクト>/out/final.mp4 --expect <秒数>
ffmpeg -y -ss 3 -i <プロジェクト>/out/final.mp4 -vframes 1 <プロジェクト>/check/03.png
2フレームを抽出(3秒目、および該当コマの長さ×0.75)して比較:画面が動いているか、背景色は正しいか、字幕が画面外にはみ出していないか。 さらに音声トラックを抽出して目を閉じて聞き、「誰が何を望み、どんな出来事が起き、どう結末を迎えたか」を言えるか確認する。これがOKなら合格。
⑤ 納品
<プロジェクト>/out/final.mp4。横長バージョンが必要な場合は out/story_flat.mp4 を使う。
10のハードルール
最初の3つはストーリーに関するルール。違反すると「何を言っているかわからない」状態になる。残りの7つは制作に関するルール。違反すると映像や音声に問題が出る。
1. まず story_line / question / answer を記入せよ。これが書けないならコマを書くな。
これら3行が欠けたまま8コマを書き終えてから「まとまりがない」と気づくのが、最もコストのかかる手戻りである。
2. 骨格は「主人公と障害の関係」に基づいて選べ。すべてのテーマに同じコマ割り表を当てはめるな。
| 主人公 vs 障害 | 骨格 |
|---|---|
| 具体的な敵がいて、一進一退 | 攻撃 → 回避 → 強化 → 回避 → 最強の一撃 → 回避 |
| 自分の道が行き詰まった | 古い仕事が死にかける → いくつか試すが失敗 → 思いがけないことが起きる → それに賭ける → 成功 → 初めて売っているものに気づく |
| 説明のつかない現象を逆から調べる | 異常な出来事 → その人物を見つける → 当時の苦境 → その人がどう解決したか |
| 頂点に達したが、些細なことで転落 | 絶頂 → 一つのひび割れ → 誰も真剣に受け止めない → 賭けを誤る → 崩壊 |
コマ数はストーリーに合わせて5~9コマでよい。
3. 並列的な出来事に「ラウンド」と番号を振るな。 「第一ラウンド」を「一度目」に置き換えてもストーリーが損なわれないなら、それはラウンドではなく貼り付けたラベルだ——削除せよ。 同様に、「強化」「頂点」「決着」「秘密」といった解説者用の専門用語を使ってはならない。視聴者は暗号のように聞こえる。
4. ナレーションは単独で理解できる完全なストーリーでなければならない。台詞は実際に発声せよ。 「彼は一言返した」「二文字だけ許可した」「その一言で彼は目覚めた」——聞き手は誰かが話したことだけを知り、何を言ったかはわからない。 吹き出しがナレーションを繰り返すのは問題ない。字幕はもともと音声の反復である。
5. 生成モデルは線画のみを描け。文字はコードで重ねる。 プロンプトには「文字を一切描くな」と記述する。これは予防措置であり、画像の検収基準ではない。
6. 吹き出しはエンジンに入れるな。 エンジンはカラーを白黒の塊に二値化する。吹き出しは合成時に時間に応じて表示するほうがリズムを制御しやすい。
7. element_plan を渡すな。
渡すと各オブジェクトが1.6秒の上限で描画完了し、コマ全体が2秒で塗りつぶされる。渡さない場合は√面積に応じて予算が配分され、総時間は一定に保たれる。
8. 必ず画像To画像で行い、参照画像の類似度は低く(0.3~0.5)設定せよ。 類似度が高いと、モデルがあなたの書いた動作指示を無視して参照画像のポーズをコピーする。
9. キャラクターは characters に記述し、プロンプト内では {名前} で参照せよ。任意の2人のキャラクターは少なくとも3つの異なる特徴を持て。
頭飾り、ひげ、服装、体型をそれぞれ明確に記述せよ。主人公には異質な頭飾り(柔らかい布・冠なし)を使い、四角い冠や兜は敵や兵士に残せ。
10. 背景色は colorkey + overlay を使え。字幕はASS形式で焼き付け、PlayResX/Y を宣言せよ。
blend=all_mode=multiply を使うと背景色が蛍光緑になる。SRTをlibassに渡すと384×288の座標系に配置され、文字が画面外に飛び出す。
問題が発生したらどこを読むか
| 状況 | 読むべきもの |
|---|---|
| テーマをどうやってストーリーに落とし込むか、各コマに何を入れるか、どう締めるか | references/story.md |
| プロンプトの書き方、キャラクター設定、吹き出しレイアウト、TTS、レンダリングと合成パラメータ | references/production.md |
| 映像/音声/長さに問題がある | references/troubleshooting.md |
| プロンプトの具体的なテンプレートと逆制約ワード | references/prompt-recipes.md |
| ナレーションの音節/声色 | references/voice-design.md |
| edge-ttsが403エラーを返す場合 | references/apiz-tts-fallback.md |
ディレクトリ構成
<プロジェクト>/
├── story.json 唯一の設定ファイル:タイトル、ストーリー3行、各コマのナレーション/吹き出し/プロンプト
├── charts.py インフォグラフィックコマの描画関数(チャートコマがある場合のみ必要)
├── raw/ 生成モデルの出力元画像 ← あなたが配置する
├── boards/ bubbles/ charts/ audio/ out/ ← スクリプトの出力
└── subs.ass
初回利用時
bash scripts/setup.sh # macOS / Linux / Git Bash
powershell -ExecutionPolicy Bypass -File scripts/setup.ps1 # Windows
python scripts/self_test.py # 6項目の自己診断、1回実行すれば十分