reel-subs — リール用字幕&アニメーション
あなたは、完成したトーキングヘッドのカット(CapCut/Premiere/スマートフォンから出力)を、フレーズごとのキャプションとクリーンなモーショングラフィックスが付いたリールに仕上げます。すべてユーザーのマシン上でローカルに実行されます。
仕組み: 音声 → タイミング付き単語(sherpa-onnx、オフライン)→ あなたが edit.json(キャプション+グラフィックアイテム)を書く → Remotionが透明なグラフィックスレイヤーのみをレンダリング → ffmpegが元の動画ソース(その色タグを保持したまま)の上に重ねる。動画全体をRemotionでレンダリングしてはいけません。それを行うと異なるカラーマトリックスで再エンコードされ、肌色が変化します。
SKILL_DIR はこのファイルが置かれているフォルダを指します。ENGINE は ~/.reel-subs/engine(Windows では %USERPROFILE%\.reel-subs\engine、または環境変数 $REELS_HOME/engine が設定されている場合はそのパス)です。すべてのスクリプトはプレーンなNode.jsです — node で実行します。macOS、Windows、Linuxで同じように動作します。
ユーザーの言語で話してください。 ユーザーがあなたに書いてきた言語(通常はロシア語)で応答してください。このファイルは英語で書かれていますが、進捗状況、質問、エラー、最終サマリーはその言語で行います。コマンド、パス、JSONキーはそのままにします。
最初にユーザーの設定を読んでください。 ~/.reel-subs/preferences.md(または $REELS_HOME/preferences.md)が存在する場合は、ステップ1の前にそれを読み、従ってください。そこには、以前のセッションでこのユーザーがリクエストした内容が保存されており、このファイルのデフォルト設定よりも優先されます。「ユーザーの好みを学習する」の節を参照してください。
0. セットアップ(初回、または doctor が NOT READY と表示したとき)
node SKILL_DIR/scripts/setup.mjs # ロシア語音声モデル(デフォルト)
node SKILL_DIR/scripts/setup.mjs --lang multi # 英語+24のヨーロッパ言語
必要なのは Node.js 18+ のみです。node がない場合は、nodejs.org から LTS をインストールするようユーザーに伝え(macOS: brew install node でも可、Windows: winget install OpenJS.NodeJS.LTS)、停止します。セットアップはエンジンを ENGINE にコピーし、npm install(Remotion、ffmpeg/ffprobeバイナリ、sherpa-onnx)を実行し、音声モデル(ru:約170 MB、multi:約490 MB)とヘッドレスChromeをダウンロードします。冪等性があります。初回は2~5分かかります — その旨を1行で伝えてください。READY で終了します。
✗ headless browser と表示された場合:RemotionのChromeダウンロードがこのネットワークでブロックされており、インストール済みのChrome/Edgeも見つかりません → ユーザーにGoogle Chromeをインストールしてからsetupを再実行するよう依頼します。
1. 準備
node ENGINE/scripts/prepare.mjs "<video>" [--lang ru|multi] [--audio clean_voice.wav]
--lang:ru(GigaAM、ロシア語に最適)またはmulti(英語、ドイツ語、スペイン語、フランス語、ウクライナ語…)。動画内で話されている言語に基づいて選択します。不明な場合のみユーザーに確認してください。不足しているモデルは自動的にダウンロードされます。--audio: ユーザーがクリーンな音声トラック(Auphonic、Adobe Podcast…など)を持っている場合に使用します。認識精度が向上し、レンダリングでは最終動画にその音声が使用されます。- 動画と同じ場所に
<video name>.reels/フォルダを作成します:transcript.txt、words.json、edit.json(ドラフト)。 - HDR動画の場合は、説明とともに処理を停止します(HDRにオーバーレイすると色が変わります) — その説明をユーザーに伝えます。
2. 動画を理解する
transcript.txt(タイムコード付きフレーズ)を読み、words.jsonで正確な単語のタイミングを確認します。- フレームを確認します:
node ENGINE/scripts/look.mjs "<video>" --every 1→ シート画像を開きます。顔の位置(上/中央)、手のジェスチャーの位置、画面/製品が表示されている位置、カットのタイミングをメモします。長い動画の場合は、部分ごとにシート化します(--from 0 --to 30)。
3. キャプションを修正する(edit.json → captions)
ドラフトのページはすでにフレーズごとに分割されています(約2秒、32文字以内)。あなたの仕事:
- 認識ミスを修正します:製品名、英語の用語、数字(
четыре бакса→$4)、ブランドのスペル。認識には句読点がありません — 読解に役立つ場合のみ追加し、基本的には追加しません。 - 話者自身の言葉と言語を保持します。依頼がない限り翻訳しないでください。
- 各ページが1つの自然なフレーズになるように、ページの結合/分割を行います。
startMs/endMsがwords.jsonと一致するようにします。 - キャプションテキスト内のマークアップ:
*word*→ アクセントカラー(まれに、キーワードに対して)、~word~→ 赤色(話者が冗談として言い間違えた部分)。 - 確信が持てなかった単語は、最終メッセージにリストアップし、黙って推測しないでください。
4. グラフィックスを計画する(edit.json → items)
フィールドの完全なリファレンスと例は SKILL_DIR/reference/edit-schema.md にあります — アイテムを書く前に読んでください。
- hook — 最初の2~4秒、最初のカットまたはジョークが来るまで:動画の本質を話者の言語で1行の短いフレーズで表現します。表示中はキャプションが自動的に非表示になります。
- card — 重要なポイント:
label(スモールキャップス)+titleおよび/または説明する単語に合わせて表示されるchips(at)、結果のチップにはon: true、何かを取り消し線で消すにはstrikeAt。 - big — 話者が強調する数字または1つの単語("$1"、"5000")。
- terminal — コード、エージェント、コマンドについて話している場合のみ。
- punch — ジョーク/自己皮肉:
aが取り消され、bが大きく表示されます。キャプションは自動的に非表示になります。 - pop — 話者が手でジェスチャーをしたときに手の横にスナップインする小さなHUDウィジェット(「そしてこれらのアニメーションが…」)。認識タイミングには遅延があるため、単語の 約0.3秒前 に配置します。
- badge — 左上に固定表示されるタグ(エピソード番号など)。ユーザーが希望する場合のみ。
ルール:
- 顔を決して覆わないでください。 カードはデフォルトで上部3分の1(
top: 260)に配置されます。顔がフレームの上半分にある場合は、top: 1110(低い位置)を使用します。また、話者が指さしているものも覆わないでください。 - すべてセーフゾーン内に収めてください(カードは幅840 px、中央揃え) — 端に配置しないでください。
- 密度:平均5~10秒に1つのグラフィック、単語に合わせてタイミングを設定します。言っていることを繰り返すだけのキャプション枠、自明なことの説明、跳ねるような/子供じみた動きは避けてください。
- 製品/プロジェクトの初出:カードにはそれが何であるかを数語で記載します — 視聴者は初見です。
- 時間はソース動画の秒数です。アイテムはキャプションと重なる場合があります。hook/punchはキャプションを非表示にします。
- 事実を創作しないでください:chipsやcardは話者が言ったことを正確に表示します。
5. プレビュー — フルレンダリングの前に必ず確認する
node ENGINE/scripts/preview.mjs "<work>/edit.json" # 各アイテム内の1フレーム
node ENGINE/scripts/preview.mjs "<work>/edit.json" --at 1.2,7,15
previews/sheet.jpg(および必要に応じて単体の at_<t>.jpg)を開きます。以下を確認:顔がはっきり見える、テキストが収まっている、端に当たっていない、キャプションが読める。edit.json を修正して再度プレビューします。実行あたり約10~30秒。
6. レンダリング
node ENGINE/scripts/render.mjs "<work>/edit.json" [--out file.mp4]
動画1分あたり約1~4分。出力はデフォルトでソースと同じ場所に <video name>_final.mp4 として保存されます。出力フレーム数とソースのフレーム数が出力されます — MISMATCH と表示された場合はユーザーに伝えます。その後、ユーザーに次の情報を提供します:出力パス、追加した内容の2~3行のサマリー、疑問のある単語。
修正
edit.json を編集 → 変更した瞬間をプレビュー → 再度レンダリングします。ユーザーがキャプションを承認した後は、決して prepare.mjs --force を再実行しないでください(リセットされます)。大きな変更の前に edit.json をコピーしておきます。
ユーザーの好みを学習する
このスキルは、ユーザーが使用するたびに改善されるべきです。ユーザーのメモは ~/.reel-subs/preferences.md($REELS_HOME/preferences.md が設定されている場合はそちら)に保存されます。スキルフォルダと ENGINE の外にあるため、スキルの更新やセットアップの再実行で消えることはありません。
保存を提案するタイミング:
- ユーザーが同じ種類のことを2回修正した場合(フォント、色、キャプションサイズや位置、グラフィックの量、フックの文言、アクセントをつける単語…)。
- ユーザーが「запомни(覚えて)」「в следующий раз делай так(次はこうして)」「мне так больше нравится(こっちのほうが好き)」などと言った場合。
- 修正を伴うセッションの終了時:修正点を2~4行でリストアップし、次回のために保存するかどうかを1回だけ尋ねます。
方法:
- 常に事前に尋ね、実際に書く内容を正確に表示し、「はい」の返事があった場合のみ書き込みます。決して自分で保存しないでください。
- 履歴ではなくルールを書きます:「キャプションのフォントサイズを大きく:captionSize 60」「フックに絵文字を使わない」「10秒あたり1つ以上のプラークを配置しない」。短い見出し(Style、Captions、Graphics、Wording)でグループ化します。矛盾する古いルールは更新または削除します。
edit.json→styleでサポートされているスタイル値は、正確な値として記述し、新しいedit.jsonにコピーできるようにします。- 要望がコードの変更を必要とする場合(新しいフォント、新しいアニメーション、異なるカードの見た目)、
ENGINE/src/で変更を行い、preferences.mdの Engine changes セクションにも記録します:どのファイル、何を変更したか、なぜか。セットアップはエンジンを再度コピーし、編集済みファイルを上書きします(新規ファイルは残ります)。そのため、セットアップ実行後はこのリストを確認し、不足している変更を再適用します。 - ユーザーは
preferences.mdを手動で編集したり、変更内容をあなたに指示することもできます。
カスタマイズ
- 色/サイズ:
edit.json→style(accent、captionSize、captionTop、font)。 - 新しい種類のグラフィック:
ENGINE/src/components/にコンポーネントを追加し、src/types.tsにタイプを追加し、src/Overlay.tsxにケースを追加します。バンドルは次のプレビュー時に自動的に再構築されます。レイヤーは透明に保ちます(Remotion内に背景や動画を含めない)。 ENGINE内でnpm run studioを実行すると、Remotion Studioが開き、ライブで調整できます。
トラブルシューティング
doctor:node ENGINE/scripts/doctor.mjs— すべての依存関係について ✓/✗ を表示します。- 可変フレームレートの警告 → ユーザーに一定の30または60 fpsで出力するよう依頼します。
- 9:16 ではない → グラフィックスは縦長動画用にレイアウトされていますが、スケーリングして収まるようにします。その旨を伝えます。
- Windows:同じコマンドを使用します。スペースを含むパスは引用符で囲みます。PowerShellとcmdの両方で動作します。
- どこにもアップロードされません:モデルとChromeは一度ダウンロードされ、その後はすべてオフラインで動作します。