リールビルダー
エンジン: $(reelsmith root)/engine/ (build.py、template.html、music.py、pull_vo.py、capcut.py、fonts/)。リール1つにつき1フォルダ: <reel-dir>/reel.json → <reel-dir>/out/reel.mp4。reelsmithがセットアップされていないと表示されたら、reelsmith setupを1度実行します。
reelsmith new reels/my-reel # src/、vo/、テンプレートreel.jsonを含むフォルダを作成
reelsmith sheet reels/my-reel/src/* # コンタクトシート → 各セグメントのssを選択
reelsmith build reels/my-reel --stills # 約1分: フレーム、単語タイミング、字幕、out/qa_sheet.jpgを生成
reelsmith stills reels/my-reel 0.5,7.8,21.3 # 追加チェック用フレーム
reelsmith build reels/my-reel # フルレンダリング(60秒で約4~5分)
必ず最初に --stills を実行してください。表示された字幕リストを読み、out/qa_sheet.jpg(赤色 = Reels/TikTok UIゾーン。重要な要素が赤色領域にかかってはいけません)を確認します。reel.jsonを修正してからビルドします。最後に表示されるラウドネス値(−14 LUFS ±1、ピーク ≤ −1 dB)を確認します。その後、最終MP4の各エフェクトとトランジション周辺のフレームを確認してから納品してください。
ワークフロー(クリエイターの作業時間: リール1本あたり約10分)
- スクリプト:
reel-scriptスキル → クリエイターが承認。アクセント単語は<em>…</em>でマーク。数字は表示用にそのまま数字で保持。 - 音声: クリエイター自身の録音(
vo/vo.mp3)かElevenLabs(docs/voice.md参照)。TTSテキスト = タグを除いたスクリプト、数字は単語にスペルアウト、ブランド名は発音通りに表記。無料プランの場合はElevenLabsのWeb UI(ChromeのClaudeで操作可能)で生成し、reelsmith voice <reel-dir>で最新2テイクをvo/に取り込み、長さを表示。両方を書き起こし、クリーンな方をvo/vo.mp3として保持。声が遅い場合:vo内の"speed": 1.07を設定。 - フッテージ:
footage-scoutスキル — 新しいクリップのみ(used_footage.mdを確認)、コンタクトシート、プライバシーチェック。セグメントの合計時間は音声終了時間 + 約2秒に合わせる。 - 編集計画:
reel-directorスキルがこのストーリーに合った3~5個のエフェクトとトランジションの配置を選択。 - reel.jsonを記述 →
--stills→ 修正 → ビルド →out/reel.mp4+out/cover.jpg+out/caption.txtを納品。 - オプションのCapCutでのサウンド調整:
reel-capcutスキル(ライブラリのサウンドエフェクト + 耳で選んだ音楽)。
reel.json
{
"vo": {"file": "vo/vo.mp3", "offset": 0.25, "speed": 1.07, "gaps": [[5.73, 0.8]]},
"script": "I've been rewriting my guide for three months and yesterday I changed the cover font <em>for the fourth time</em>. …",
"hook": {"tag": "the eternal-draft scenario", "lines": ["the guide is almost ready.", "<em>for three months now</em>"], "out": 5.55},
"end": {"from": 55.6, "lines": ["how long has", "<em>yours been waiting?</em>"], "lines_at": [55.75, 56.6],
"sub": "tell me in the comments", "sub_at": "@comments", "handle": "@yourhandle", "handle_at": 58.6},
"cover": {"from": 0, "to": 4.35, "title": "DRAFT", "left": "No.4 · October", "right": "@yourhandle", "top": 330},
"cover_t": 2.0,
"stamps": [{"seg": ["I", "J"], "text": "tanya · 2 years in drafts"}],
"punch": [[3.02, 4.4], ["@thousand", 9.0]],
"segments": [
{"id": "A", "clip": "src/night_desk.mp4", "ss": 9.5, "dur": 2.5, "crop": [0, 0.196, 0.75], "cut": true},
{"id": "B", "clip": "src/keys.mp4", "ss": 1.3, "dur": 1.9, "move": "none"},
{"id": "E", "clip": "src/phone_walk.mov", "ss": 0.8, "dur": 4.5, "cut": true, "in": "zoom"},
{"id": "I", "clip": "src/cafe.mp4", "ss": 0.3, "dur": 3.2, "look": "bw"},
{"id": "K", "clip": "src/walk.mov", "ss": 14.0, "dur": 4.95, "look": "burst"},
{"id": "N", "clip": "src/breakfast.mov", "ss": 0.0, "dur": 3.45, "rate": 0.4},
{"id": "Q", "clip": "src/meadow.mov", "ss": 13.2, "dur": 9.1, "move": "pull-out", "in": "zoom"}
],
"caption": "…",
"music": "synth"
}
実際の完全な例(ウクライナ語、61秒、17セグメント、以下のすべてのエフェクト使用)は $(reelsmith root)/examples/chernetka/reel.json に、最小限の例は examples/template/reel.json にあります。
音声と字幕
- lang: ナレーションのWhisper言語(
"uk"、"en"など)。省略時は自動検出(またはREELSMITH_LANG環境変数を使用)。 - vo.gaps
[vo_time, extra_s]: 音声(スピード調整済み)のその時間に最も静かなポイントに挿入される呼吸用ポーズ — フォトモンタージュ用のスペース。vo.speed: atempo倍率。 - "@word" アンカー: hook / end / doodles / glass / checklist / cover / orbit / wall / punch / subs_skip 内の任意の時間に
"@thousand"(スクリプト内のその単語の開始位置; 完全一致が優先、なければ前方一致)、"@again#2"(2回目の出現)、"@twice+0.3"のように使用可能。Whisperが聞き間違えた単語は秒単位で補間時間を使用。out/words.jsonに--stills実行後の実際のタイミングが保存されます。 - subs / punch: 省略時は
scriptと単語タイミングから自動生成(5~7単語、1~2行、アクセント単語はイタリックのアクセントカラー、末尾にピリオドなし、行末が「and/in/of…」で終わらない。アクセントフレーズが3秒以上間隔で最大4か所までパンチイン)。"subs": [[a, b, "html"]]、"punch": [[a, b]]で上書き可能。フックカード表示中、ガラスタイトルとチェックリスト下、エンドカード開始後は字幕を非表示(subs_from/subs_until/subs_skip [[a, b]]で調整可能)。
カードとテキスト
- hook: フレーム0から表示されるペーパーカード(
at: [t…]で行を1つずつ表示、size、top)。end:fromから始まるカード、lines_atで行表示、sub、handle。 - stamps: 指定されたセグメント上に左上に表示されるモノクロピル(場所、日付、キャラクター名)。
- cover(カバーストーリー + フレームブレイク): 幅にフィットする雑誌のマストヘッド、文字がドロップイン。
"cut": trueのセグメントでは人物がタイトルの前に立つ。頭の上部がマストヘッド上部から40~80ピクセル下に収まるショットを選択/クロップ — 決して目の上にかからないように。colorでマストヘッドの色、topで位置調整。cover_tは約2にして、out/cover.jpgで完成したカバーが表示されるようにします。 - glass(ガラスタイプ):
{"from", "to", "lines", "at", "top"}すりガラス風タイトル。 - checklist:
{"from", "to", "title", "items": [{"text", "sub", "at", "sub_at"}]}アイテムごとに増えていくカード。atでチェックマークが描画。 - wall(ヘッドラインウォール):
{"from", "to", "items": [...], "every": 0.06}ファイル名/ヘッドラインのタイルが積み重なる。上部にガラスタイトルを配置。 - orbit:
{"from", "to", "seg", "text": "1000 FOLLOWERS · ", "speed", "scale", "tilt", "lift"}cutセグメント上で人物の頭の周りにテキストリング。後半部分は人物の背後を通過。自撮りクローズアップに最適。 - doodles(ドゥードゥルボイル):
{"kind": "text"|"circle"|"underline"|"strike"|"arrow", "at", "to", "x", "y", …}— text:text, size, rot, write; circle/strike:w, h(strikenジグザグ; 3で単語が読める状態に); underline:w; arrow:x2, y2, bend;color,width。クリーム色のハローを伴うアクセントインク。左から右に書かれ、3フレームごとに揺れます。フックカード表示中は y ≈ 1000 より上、かつ顔の上に配置しないこと。
セグメント
- パス: リールフォルダからの相対パス、次にカレントディレクトリ、次にリポジトリ。HEIC/JPG写真は
imgで指定可能。 ssクリップ内の開始秒数、dur秒数。pos0~1 でワイドソースの水平フレーミング。crop [x, y, size]= 縦フレームのパンチインクロップ(4Kからでもシャープに保持)。rate< 1 でスローモーション(短い部分のみ使用可能な場合に有用)。- cut:
true= このセグメント用にmacOS Visionの人物マスクを使用(reelsmith masks、約0.2秒/フレーム、キャッシュあり)。カバーとオービットで必要。 - in:
"zoom"(前のショットがブラーで急接近、新しいショットがズームインで着地)または"whip"(高速ブラースライド、黒エッジなし)。主要な4~6カットに使用し、すべてのカットには使用しない。 - look:
""温かみのあるフィルム調 ・"memory"フェードズームスルーフライン(フォトモンタージュ用。dateでオレンジ色のカメラ日付スタンプ追加)・"bw"白黒(音楽がこもる)・"burst"グレー → カラーブルーム(音楽が開く)。 - move:
push(デフォルトのゆっくりとしたプッシュイン)・tilt-up・pull-out・none。
サウンドとカラー
- music:
"synth"(ルックによって形作られる生成ローファイBGM — プレースホルダーとして十分。クリエイターは通常、実際のトラックを好む)、権利のあるオーディオファイルへのパス、またはnull。元のクリップ音声は使用されません。 - music_gain: デフォルト0.16(ナレーション下、サイドチェインでダッキング)。
- colors:
{"accent": "#D4573A", "cream": "#F4EFE6", "ink": "#1F1A17"}(デフォルト: ベージュ / テラコッタ)。
実際のフィードバックに基づくルール
- エフェクトはスマートフォンサイズで最初の視聴時に読めるように: 大きく、アクセントカラーで、アニメーション付き。小さなクリーム色のドゥードゥルや薄いガラスパネルでは「エフェクトがどこに?」と感じさせます。
- カット部分で白フラッシュを繰り返さない。元のクリップ音声をミュート。リールあたり3~5種類のテクニックを使用し、すべては使わない。
- テキスト、カード、ドゥードゥルを目の上に決して配置しない。カードを移動するか、ショットをリフレームする。
- クリップの画面や背景をフル解像度で確認: 他人のメッセージ、車のナンバープレート、道路名、プライベートなダッシュボード → 該当秒をスキップ。
- リールごとに新しいフッテージを使用(
used_footage.md)。他人の顔が写ったショットを使用する前に確認を取る。