Reel — ストーリー編集(フルフレームモーション)
スピーカーはフルフレームで表示され続けます。ストーリーは、クリエイター自身のクリップへのカットアウェイ、発言に合わせてポップするステッカー/カード/ウィジェット、リアクションするマスコット、そしてスピーカーの背後(人型マット)に大きな文字やブランド背景が配置されるデプスモーメントによって進行します。動作例: examples/story/story_stoodi_inviteraw.py
引数: $ARGUMENTS
デフォルト(ユーザーが明示した場合のみ変更)
最初に reel.config.json を読み込みます(フォールバックとして reel.config.example.json を使用)。
| 項目 | デフォルト |
|---|---|
| 字幕 | なし。 キーワードグラフィックは可。常時表示のトランスクリプトは禁止 |
| 音声 | テイクのミックスそのまま、変更不可 — finish.py でリマックスする。効果音、BGMなし |
| テイク | カット、グレーディング、音楽追加済みと仮定 → カットやグレーディングは行わない。未編集/生テイク → まずユーザーに確認 |
| Bロール | 設定ファイルの broll_dir。work/_catalog/<folder>/NOTES.md に説明あり |
| ブランド | 設定ファイルの brand + palette。マスコットファイルがない場合 → マスコットシーンなし |
| CTA | コメントキーワードを画面に大きく表示。フォローカード = @<creator.handle> のテキストのみ、顔のトリミングはしない |
| 言語 | 設定ファイルの language(Whisper と使用するテキストクラスを決定) |
入力
テイク名とトピックは引数から取得します。不足している情報(テイクのカット/グレーディング/音楽の有無、コメントキーワード、Whisper が聞き間違えそうな名前や専門用語、含めたい/除外したいクリップ)は1回のメッセージでまとめて質問します。
パイプライン
PY = .venv/Scripts/python.exe -X utf8(Windows)または .venv/bin/python -X utf8(macOS/Linux)。長時間かかるステップはバックグラウンドで実行します。
| # | ステップ | コマンド / アクション | 確認事項 |
|---|---|---|---|
| 1 | 確認 | ffprobe でテイクを確認。コンタクトシート ffmpeg -i raw/<take> -vf fps=1/5,scale=216:384,tile=9x2 -frames:v 1 work/<take>/sheet.jpg を作成して確認 | 頭上に余白があるか、フレーム内のテキストが反転していないか、すでにグレーディング済みか |
| 2 | 文字起こし | $PY tools/transcribe.py <take> --prompt "<名前, 専門用語>" | 名前を校正。単語間の間隔が 3 秒以上 → その区間を再文字起こし |
| 3 | 顔追跡 | $PY tools/face_track.py <take> | FACE = (x, y) と頭頂部の位置を出力 |
| 4 | Bロール | $PY tools/story_assets.py <take> catalog。NOTES.md を読む。まだ説明されていないクリップのストリップを確認し、その行を NOTES.md に追加 | HDR / 反転 / VFR フラグ |
| 5 | ビートシート | work/<take>/beats.md を作成: `時間 | 単語 |
| 6 | マット | デプスモーメントがある場合: $PY tools/story_assets.py <take> matte(80秒でCPU約8分、バックグラウンド、ffmpeg 並列処理なし) | work/<take>/matte/fg.webm |
| 7 | テイクモジュール | examples/story/story_stoodi_inviteraw.py を tools/story_<slug>.py にコピー(slug: テイク名、非英数字は _ に変換)。NAME、FACE、BROLL、TILES、MIRRORED、シーン、SCENES(DUR はオプション — プローブで取得)を設定。マスコット名 = assets/mascot 内のファイル名(小文字、スペースは -) | |
| 8 | アセット | $PY tools/story_assets.py <take> all(マスコット、ロゴ、Bロールトリム、タイル) | |
| 9 | ビルド | $PY tools/story_build.py <take>。work/<take>/sc で: npx hyperframes lint public → エラー0(nested_structure 警告は許容)。npx hyperframes snapshot public -o ../snaps --no-end --describe false --at <すべてのビート>。コンタクトシートを確認し、修正、再ビルド | |
| 10 | クイックレンダー | $PY tools/finish.py <take> --seconds 12。work/<take>/sc/quick_sheet.jpg を確認 | オーバーレイが出現し、かつ画面から退出していること。色がくすんでいないこと |
| 11 | フルレンダー | $PY tools/finish.py <take>(80秒で約12分、バックグラウンド)→ final/<take>/、確認、qa/sheet.jpg | シートをフレームごとに確認 |
| 12 | レポート | パス、長さ、ビート、使用したクリップ、反転/トーンマップしたもの、結果の確認。新たに学んだことがあれば、このスキルに追加 |
ビートルール
- 2~4秒ごとに何かが変化する。何もないスピーカーのみの状態が5秒以上続くことは禁止。
- モードを混在させる: スピーカー+ステッカー · Bロールカットアウェイ(ランタイムの約25~30%) · デプスモーメント(リールあたり4~6回) · スピーカーをフェイスカムバブルとして表示する全画面グラフィック(最大1~2回)。
- キュー =
transcript.json内の発言の開始時間。各要素は次のビートの前に画面から退出する。 - デプスワードは頭の上(ステップ3の頭頂部位置)に配置する: 一度に1つの大きな単語を表示し、前の単語は飛び去る。複数行重ねると頭に隠れる。
- セーフゾーン: y 150(Instagram ヘッダー)より上、および y 1560(キャプション)より下にはテキストを配置しない。x < 960、y 1100~1650(いいね/コメントボタン)の範囲も避ける。
- 数字で示す事実はテイクから取得すること。説明用のラベルは問題ない。
- ペルシア語/アラビア語テキスト:
.faクラス(RTL は要素にスコープ —<html>にdir="rtl"を設定しないと黒くレンダリングされる)、letter-spacing: 0、数字はfa()を使用、大きなゼロはラテン文字の0(ペルシア語のゼロはドット)。ラテン語テキスト:.en。大きな表示用単語:.blk。
エンジン契約 — 既知のバグは対処済み
- シーン =
def scene(c: Comp):c.clip(layer, id, start, end, html, track)、c.broll(name, a, b, mstart)、c.matte(n, a, b)、c.j(js...)。レイヤー:under(バブルの背後)、tiles、behind(テイクとマットの間)、fw、broll、over、fx。 - クリップ div には id
k-<id>を付与。#<id>-iまたは内部ID をアニメーション —.clip自体には決してアニメーションを適用しない。 - 画面外からスライドインするものは、from ステートに
autoAlpha:0が必要。さもないと早期に表示される。 - 要素の最初のトゥイーンで初期状態を設定する(
fromToは即座にレンダリングされる)。後続のトゥイーンは.toまたはimmediateRender:falseを使用。 from:"random"のスタガーやMath.randomは絶対に使用しない — Python でrandom.Random(seed)を使用して DOM の順序をシャッフルする。- 同じプロパティ、同じ要素に対して、あるトゥイーンが終了してから次のトゥイーンを開始する(lint
overlapping_gsap_tweens)。 #camの scale/x/y/clipPath/borderRadius でパンチイン、バブル、モザイクを制御する。マットは#camの内部にあるため、デプスモーメントはカメラのスケールに関わらず常に正しく配置される。- フロントカメラのBロールでフレーム内に読み取り可能なテキストがある場合 →
MIRROREDに追加する。メインテイクを反転してはいけない。 - HLG/HDR ソースは
story_assets.pyでトーンマッピングされる。finish.pyが「HDR auto-promotion」で停止した場合、そのソースがパスから外れたことを意味する。 hyperframes snapshotはレンダリングの証拠ではない。ステップ10 がそのための確認ステップである。