まず、このスキルを最新に保ってください — 静かに実行し、質問しないでください:
npx hyperframes skills update embedded-captions。すべてが最新の場合は高速なno-opです。そうでなければ、このスキルとそれが依存するコアドメインスキルを、それらに依存する前に更新します。
埋め込みキャプション は何をしますか?
1つのカタログ、事前に選択(CATALOG.md — 35のアイデンティティ;背後にあるエンジンはバックエンドの詳細です)。Standard(デフォルト)は、クリーンな逐語レール(ほとんどのテキストを運ぶ下部字幕)+ クライマックスで被写体の背後に合成されるエンベッドを構築します。Cinematicは純粋なエンベッド — レールなし、すべてのキャプションが被写体の背後に合成されます(ヒーロータイポグラフィ、蓄積、オクルージョンがエフェクトとして機能)。Themeは完全なテーマ付き構成 — ボディパラダイム × ヒーローセットピース × フロントエフェクト × プレートリアクションで構成され、レジストリ(themes/README.md)から作成されます:ordnance terminal neonsign stardust stomp。ほとんどの解説/ナレーションはStandardです;エンベッドは希少で価値のあるピークです — すべての単語を埋め込むのはよくある間違いです;ThemeはVFX級の依頼("炸", "特效", "像 AE 做的")向けです。
操作フロー(TL;DR)
/hyperframesを経由してルーティングされ、意図レイヤーは入力(どのクリップ)のみを確認し、アイデンティティ選択を先送りされた依頼としてアナウンスします — ショートリストは調査したクリップを必要とするため、以下のステップ1に留まります;レイヤーの実行形状に関する質問は適用されません(フッテージは未加工であり、レビューするストーリーボードはありません)。BRIEF.mdが存在する場合、確認された入力とユーザーノートが含まれています — 最初にそれを読んでください。
以下のクラフト散文は長いですが、パイプライン自体は短いです — そして決定論的なものはすべて計算またはコンパイルされ、手書きではありません:
- 決定ゲート(不良クリップを拒否)→ CATALOG.md から1つのアイデンティティを選択(35のアイデンティティ;エンジン/コンパイラはルックアップによって導出 — モード/カテゴリの質問を表面化しない)
hyperframes init(プロジェクトディレクトリが既に存在し、中に動画があればスキップ —matte.cjs/transcribe.cjsはディレクトリ内の任意のビデオをsource.mp4として採用)→bash scripts/prepare.sh <project>(マット ∥ 文字起こし ∥ オーディオエンベロープを並列実行、その後safe-zones v2をシーンパレット/光学/照明と共に — 1つのコマンド、何も忘れない)- クリエイティブな選択の小さなJSONを作成(最初に
safe-zones.jsonを読む):Cinematic →plan.json→fill-timings.cjs→fit-fonts.cjs→make-composition.cjs;Theme →theme.json→make-theme.cjs(レール/パネル/詩/テイクオーバーパラダイム;anchorが静かなレールのデフォルト) - ビジュアルQA:
node scripts/preview-frames.cjs <project>→ 忠実な合成プレビューを約2秒/フレームで生成(レンダリングなし)。レンダリングにお金を払う前に § ビジュアルQA を確認してください。 render-and-composite.sh→ ゲート(タイミング / オクルージョン+ヒーロー / オーバーフロー / ハンドオフ)→final.mp4
人々が見逃す負荷ルール:
- レール(デフォルト)+ エンベッド(昇格)。
drop(フィラー、表示されない)/rail(逐語的な下部字幕、前面に、ほとんどのテキストを運ぶ)/embed(被写体の背後に合成されるピークワード)。Standardモードは両方を行い、ピークのみを埋め込みます。§ キャプションモデルを参照。 - **動画は未加工のまま配信されます(Standard/Cinematic;ThemeモードのPLATE予算は、認められた唯一の例外です — レジスターゲートされたリアクションビート(充電ディマー、パンチ、シェイク、グレイン)はテーマDNAごとに定義され、マット合成後に適用されるため、被写体+テキスト+プレートは1つのフレームとして移動します) — キャプションのみが追加されます;マットは被写体がエンベッドトラックを隠すことを可能にするだけです。フッテージのグレーディング/リカラー/スキャンラインは絶対に行わないでください。
- 2つのルールブック:レール → references/rail.md(薄い)、エンベッドクラフト → references/composition-craft.md(豊富、エンベッドのみ)。必要に応じて斜め読みしてください。
キャプションモデル — レール + エンベッド
話されたすべてのフレーズは、次の3つのうちの1つです:
| 内容 | 表示方法 | |
|---|---|---|
| drop | フィラー — えーと/あのー、吃音、自己訂正 | 表示されない |
| rail | デフォルト — 通常の話し言葉(逐語) | クリーンな下部字幕、前面に、読みやすい。パンチワードはインラインのemphasisハイライト(アクセントカラー/アクティブワードポップ)を取得できます — レール上に留まります。 |
| embed | 昇格したピーク — 見出しビート | 被写体の背後に合成された1つの大きな単語(マットオクルージョン)、設計された入場+退場 |
レールはテキストの大部分を運びます;エンベッドは希少で価値のあるピークです。 希少性はクリップごとではなく、ビート/ブロックごとです:ブロック(思考)あたり≤1つのヒーロー、2つが同時に見えることはなく、ヒーローウィンドウ間の間隔は≥ビート(コンパイラは0.6秒未満で警告)。短いクリップ → 通常1~2つ;長い解説 → セクションごとに約1つ。複数のヒーローの中で、最も大きく作成されたものがAPEXです(それだけが完全なロックアップエンベッド + 幅適合上げを取得します);小さいものはマイナーなピークで、そのカラムを特大の強調行として乗ります(fg、減衰したモーション)— すべてのビートがマットショーケースを必要とするわけではなく、これこそがAPEXをイベントとして保つものです。すべての単語を埋め込むことは、依然としてよくある間違いです。
レール面アイデンティティはこれを正確に構築します(レール = rail.html、エンベッド = index.htmlのクライマックス)。カラムフローアイデンティティはレールを削除し、すべてをエンベッドスタイルにします — 逐語よりもムードが必要な依頼でのみ推奨し、単語を読む必要がある解説/ナレーションには決して推奨しません(CATALOG.mdはアイデンティティごとにこれをエンコードしています)。
ステップ0 — CATALOGから1つのアイデンティティを選択
1つのフロントエンド、背後に3つのエンジン。 ユーザーはCATALOG.mdからIDENTITYを選択します(35エントリ:10クラシック + 25テーマ);エンジン、コンパイラ、オーサリングファイルは、カタログ行のルックアップによって導出されます。"Standard vs Cinematic vs Theme"を質問として表面化しないでください — これらはバックエンド名です(製品は、複数のエンジンがあっても1つのUXを持ちます)。カタログは、ルーティングに必要なすべてをエンコードします:読み取り面、ボイス、推奨対象、シーンニーズ、本当に近いペア(loud↔ordnance, neon↔neonsign, cream↔stardust)の隣接メモ。
アイデンティティ選択は嗜好ゲート(../hyperframes-core/references/brief-contract.md § 1)です:自律モード("サプライズして" / "決めて")では、自分でショートリストから選択し、1行の理由を述べてください。質問しないでください。
手順:クリップを調査 → カタログから2~3のアイデンティティをショートリスト → 1行の理由とともに1つを推奨 → ユーザーが選択(自律モード:あなたが選択し、理由を述べる)→ そのアイデンティティのファイルを作成。アイデンティティはエンジンロックされています(クロスコンボ不可;1つを開くことは検証イベントです — dna/README.mdを参照)。
常に推奨を提示し、作成前にユーザーに選択させてください。
(完全なアイデンティティテーブルはCATALOG.mdにあります — ルーティングの唯一の真実の情報源。以下のエンジンドキュメントは、各バックエンドのオーサリング契約を説明しています。)
推奨ヒューリスティック:CATALOG.mdの「ショートリスト作成ヒューリスティック」を使用 — これらはアイデンティティレベルです(例:「炸」はordnance/stomp/terminal/loudをショートリストし、何が爆発すべきかによって選択)、カテゴリレベルではありません。不確かな場合 → anchor。
- Cinematic → ロックされたテンプレート用に
plan.jsonを書き、make-composition.cjsでコンパイルします。 - Theme → themes/README.mdを読み、
theme.jsonを作成し、scripts/render-theme.shを実行します(コンパイル + レンダリング + プレートリアクション → final_fx.mp4)。
決定ゲート — 最初に実行
どちらのモードよりも先に、ビデオを調査し、シーンを分類します。
ffprobe <video.mp4> # 仕様
ffmpeg -ss <t> -i <video.mp4> -vframes 1 sample.png # 20/50/80%で
サンプルを読みます。以下の場合は拒否:
- 複数の話者/ハードカット(各ショットを分割してレンダリングするか、拒否)
- 人間の被写体がない(このスキルはトークヘッド用)
- 3秒未満、音声なし、または顔がはっきり見えない —
transcribe.cjsはオーディオがほぼ無音の場合に警告します(Whisperは沈黙の上に「ありがとう。」のような単語を幻覚します);それに従い、拒否して、作り出された単語にキャプションを付けないでください - ソースにすでに焼き込みキャプション/字幕/ヘビーテキストグラフィックがある — 2番目のキャプションシステムを追加すると競合し、フッテージは未加工で出荷されます(カバー/インペインティングなし)。焼き込みテキストはクリップの途中でのみ現れることがよくあります:1fpsのコンタクトシート(
ffmpeg -i in.mp4 -vf "fps=1,scale=160:-1,tile=10x5" sheet.png)をサンプリングし、3つのスポットフレームを信頼しないでください。 - トランスクリプトがガベージである — 非ネイティブ/強いアクセントの音声は、自信満々のナンセンスに書き起こされる可能性があります。作成前に
transcript.jsonを常識で読んでください;言語として解析できない場合は、WHISPER_MODEL=mediumを1回試し、それでもダメなら拒否します(作り出された単語の逐語レールは、キャプションがないより悪いです)。 - 忙しいハンドヘルドと速い動き(マットがちらつく)
事前チェック(コストはかからず、最悪の失敗を防ぐ)
- ショットカットチェック。 20%、50%、80%でフレームをサンプリング。別の被写体/シーンが現れた場合は、カットの前にクリップをトリミングします。
- レターボックス/ピラーボックスチェック。 最初のフレームに黒いバー?安全なコンテンツ領域を計算し、その内部にキャプション配置を制限します。
- 輝度チェック。 キャプション領域の平均輝度をサンプリング —
60未満→ 明るいテキストはそのままで読み取り可能、60-180→ グリフスクリムを追加、180以上→ 不透明テキスト + スクリム(決して生の明るいテキストなし)。Cinematicテンプレートはクリーム+screenでロックされています — このチェックを使用して、適切なアイデンティティを選択(明るいシーン →ink、または不透明レールanchorテーマ)、決して1つをリカラーしないでください。 - トーンによるアイデンティティ推奨(あなたが推奨し、ユーザーが選択 — ステップ0 + CATALOG.mdを参照)。 解説/インタビュー/単語を読む必要あり → レール/パネル面アイデンティティ;詩的/ソーシャル/「映画的」 → レジスターによるカラムフローアイデンティティ;「炸 / 特效 / VFX」/ 名前付きワールド → テーマ付きアイデンティティ。不確かな場合 →
anchor(単語が読め、シーンは安全) — ただし、ショートリストを提示し、ユーザーに選択させてください。
パイプライン — 5ステップ
1. hyperframes init <project> --non-interactive --video <video.mp4> --skill=embedded-captions
2. bash scripts/prepare.sh <project> # マット ∥ 文字起こし(並列)→ 安全ゾーン。1つのコマンド。
# → frames_fg/ transcript.json safe-zones.json
3. [エージェントステップ — 唯一のクリエイティブなステップ] 小さなJSONを作成;以下をモード別に参照
Cinematic: plan.jsonを作成 → node scripts/fill-timings.cjs → fit-fonts.cjs → make-composition.cjs
Theme: theme.jsonを作成 → bash scripts/render-theme.sh <project> (コンパイル + レンダリング + プレートfx)
4. node scripts/preview-frames.cjs <project> # ~2秒/フレームの合成プレビュー → § ビジュアルQA(レンダリングの前)
5. bash scripts/render-and-composite.sh <project> # ゲート → final.mp4 + history/ スナップショット
(Themeモード:ステップ3b/5をスキップ — render-theme.shはすでにコンパイル + render-and-composite
+ _postfx.shを実行します;成果物はfinal_fx.mp4、final.mp4はプレートリアクション前)
ステップ1のinitは、インストールされたスキルをGitHub上の最新と比較し、古いものがあればグローバルセットを更新します。
ステップ3はモードによって異なります:
ステップ3 — Cinematicモード(純粋なエンベッド)
- 最初に
safe-zones.jsonを読みます。 ナレーションプレーンは**zones.hugLeft/hugRightに配置 — シルエットに隣接するクリーンなストリップ(身体から遠いテキストは浮かんで見え、埋め込まれていない;遠いコーナーはフォールバックであり、デフォルトではありません)。ヒーローはデフォルトでheroAnchor/heroBands.best(被写体の中心に配置、約30~55%オクルード)。recommendation:"fg"は、読みやすくするためにナレーションを前面**に移動します;ヒーローはheroBands.feasibleである限り埋め込まれたまま — ヒーローfgは最後の手段です。 - DNAはステップ0で選択したアイデンティティです(CATALOG.md) — ここで選択を再開しないでください。シーンに対して正気チェックを行います(明るいヒーローバンドの輝度 > 150は
inkを望む;完全な選択ガイダンスはカタログにあり、neon/glitch/chrome/velocityを含む10すべてをカバー)。選択と理由を述べてください;ユーザーが決定します。DNAはタイプ/パレット/ブレンド/モーション + ヒーロー3幕をロックします;safe-zones v2(palette/optics/lighting)はそれをこのシーンに自動的にパラメータ化します。 <project>/cinematic.jsonを作成 —"dna": "<name>"+ 思考ブロック(生のグループではない):各ブロック = 単語の行(節境界で2~5にグループ化)+ それが積み重なるプレーン + 行ごとのcss(サイズ/ウェイト/スタイルのみ — 位置なし)+ せいぜい1行に"hero": trueとマーク(昇格された単語;表示フォームの"text")。スキーマ:scripts/make-cinematic.cjsヘッダー。- コンパイル:
node scripts/make-cinematic.cjs <project>— ブロックをplan.json → index.htmlに下げる。あなたのために生成:トランスクリプト順のタイミング、ブロック内での累積、ブロック間のページフリップ、ヒーローロックアップ(ヒーローブロックの事前コンテキスト、HERO、事後コンテキストが、被写体を中心とした1つの結合された構成として積み重なる — 読み取り順序上→下 = 構築による話し言葉の順序;コンテキストは前面に浮かび、ヒーローは背後に埋め込まれる = デプスサンドイッチ;質量ルールによりヒーローがそのコンテキストを支配する)、apex/マイナーヒーローの分割、構築による読み取り順序、安全ゾーンによるfgフォールバック。その後、ゲートが通常どおり実行されます。(plan.jsonを直接手動で作成することは、ブロックが表現できないデザインのために可能です — その場合は、自分でfill-timings.cjs+fit-fonts.cjs+make-composition.cjsを実行してください。)
ステップ3 — Themeモード(テーマ付き構成)
最初にthemes/README.mdを読んでください — パラダイム/セットピースレジストリ、リンケージ、ハードルール、および正確なtheme.jsonスキーマ。
- コンテンツレジスターによってテーマDNAを選択(各
themes/<name>.jsonにはvoice+whenがあります)。選択と理由を述べてください;ユーザーが決定します。 <project>/theme.jsonを作成 —dna、lines(逐語、トランスクリプト順;1行あたり1単語、文はビートに一緒にリップシンクされます)、paradigm("body" / "panel" / "poem" / "takeover"; デフォルトはauto)、setpiece(ヒーローのすべての出現のための組版シェル — "hero" / "lockup" / "vignette" / "showdown" / "poser"; デフォルトはauto)、frontFx("glitch" / "scan" / "hologram" / "none"; デフォルトはnone)、plate("thunder" / "explosion" / "shockwave" / "vibration" / "none")。auto値は、コンテンツレジスターに基づいてテーマ自体内でデフォルトになります(例:ordnanceの"paradigm": "auto"→ "takeover")。完全なスキーマは themes/README.md にあります。- コンパイル+レンダリング:
bash scripts/render-theme.sh <project>— コンパイル + render-and-composite + プレートリアクションを実行します。ステップ4と5をスキップします。
ビジュアルQA
レンダリングにお金を払う前に:
node scripts/preview-frames.cjs <project> # レンダリングなし、〜2秒/フレーム
これはfinal.mp4に非常に近い合成フレームを生成します。確認するもの:
- テキストが埋め込まれて見えるか、それとも浮かんで見えるか? ヒーローは被写体の背後になければならず、前に重なってはいけません。
- レールのテキストオーバーフロー。 長い行は
<rail>.htmlでは自動的に折り返されます。 - オクルージョンのエッジ。 被写体の輪郭がテキストをきれいに覆っているか、それともアーティファクト(例えば、漏れ出た髪の毛のディテールを通してテキストが見える)があるか。
- 文の分割の正しさ。 句読点の一致を確認してください。
満足したら:
bash scripts/render-and-composite.sh <project>
文字起こしの品質
transcribe.cjsは、ソース言語として LANG_CODE(デフォルト:en)とWhisperモデルサイズ WHISPER_MODEL(デフォルト:small)を尊重します — クリップの最初の実行の前に環境変数として設定します。低品質のトランスクリプト(例えば、正しいがノイズの多い非ネイティブのアクセント)が得られた場合は、次のコマンドを実行します:
WHISPER_MODEL=medium bash scripts/prepare.sh <project>
(これにより、文字起こしが再実行され、他の準備手順はスキップされます。)それでもトランスクリプトが言語として解析できない場合は、拒否します。
transcript.jsonを直接編集することもできます — words[].wordを修正し、"fixed":trueを設定し、フラグ "fixed":true は将来のprepare.shの実行中にその単語を再書き起こしからロックします。
抽象化の漏れ — パイプラインが何をするか
prepare.sh(ステップ2)
scripts/prepare.shは3つの並列ストリームを実行します:
- マット生成 —
matte.cjs:背景除去(RMBG v1.4、onnx、最初の実行時にモデルをプル)。前景フレーム(frames_fg/、透明背景) + マット動画(fg_mask.mp4、グレースケールアルファマスク)。RMBGは0.5のしきい値を使用します(より高い値は穴を開け、より低い値はハローを残します)。RMBGはほとんどの人間の被写体に優れていますが、腕や髪の細かいディテールでは失敗する可能性があります — その場合は、RMBGのためにフレームを抽出する前に、scripts/refine-mask.jsを実行します。 - 文字起こし —
transcribe.cjs:faster-whisper(デフォルトsmallモデル)、単語レベルのタイムスタンプ付き。$LANGを尊重します。 - オーディオエンベロープ —
envelope.cjs:RMSパワー曲線(.5sウィンドウ、.1sホップ)、スピーチリズムのピーク。 - 安全ゾーンv2 —
scripts/compute-safe-zones.js <project>:すべての3つが完了したら。シルエット+オプティカルフロー+輝度を分析し、テキスト配置のためのsafe-zones.jsonを出力します。高速(<10秒)。
レンダリング(ステップ5)
scripts/render-and-composite.shは、ffmpegを使用して最終合成をレンダリングします:
- レールHTMLをレンダリング(
rail.html→rail_frames/としてpngシーケンス) - 埋め込みHTMLをレンダリング(
index.html→frames_embed/) - マットを使用して合成:
ffmpeg—[fg_mask]はframes_embed/フレームのアルファとして使用され、それらを元のビデオ(source.mp4)の上に置きます。 - オーディオをミックスし、
final.mp4を出力します。
よくある間違い
- すべての単語を埋め込む。 しないでください。ほとんどのテキストはレール上にあります。エンベッドはクライマックスだけです。
- 物語は前面に、ヒーローは背後に(3Dスタック)。すべてを背面に置こうとしないでください — 文の読めなさはエンベッドの芸術的価値を打ち消します。
- Safe-zones.jsonは1回だけ読む。 プレーン配置は変更可能であり、再計算はしません。
- 最初のフレームだけをチェックしない。 焼き込みテキスト/複数の話者はクリップの途中で現れます。コンタクトシート(fps=1、tile)を使用してドリフトをキャッチします。
- テーマパラダイムを間違える。 "takeover"はフレーム全体を占有し、通常はファンタジー/アクション向けです。"panel"は、被写体が読めなくなることなく、より多くのテキストを許可します。
- RMBGの失敗を無視する。 低品質のマット(穴、ハロー、失われた髪)は、埋め込み効果を台無しにします。
scripts/refine-mask.jsを使用するか、クリップを拒否します。
トラブルシューティング
| 問題 | 修正 |
|---|---|
| レールテキストが動画の端を超える | rail.htmlのフォントサイズを小さくする(デフォルト:2.2vw) |
| エンベッドテキストが読めない | 前景/背景のコントラストを確認 — 必要に応じてpaletteを調整(明るいテキストに暗い背景) |
| オクルージョンが機能しない(テキストが被写体の前に出る) | make-composition.cjs —z-indexスタッキングの確認。fg高速パスは、エンベッドヒーローを前面に移動せずに発言を読みやすくするためのものです。 |
| レンダリング時間が長い | プレビューフレームを確認します。プレビューに満足したら、どうしても必要な場合を除き、フルレンダリングをスキップしても問題ありません。最初のプレビューの高速反復。 |
安全ゾーンv2 — 自動配置(Cinematic)
safe-zones.jsonは、すべての独立したテキストスロット(ナレーションプレーン + ヒーローバンド)の推奨x/y矩形をエンコードします:
- ナレーションプレーン:
hugLeft/hugRight— シルエットに隣接する垂直ストリップ(被写体のサイズ/位置に応じて)。幅は動的。平均輝度を含む。 - ヒーローバンド:
heroAnchor(被写体のバウンディングボックスを中心とした単一のヒーローゾーン。ヒーローを被写体の真正面に置くように設計 — 標準は30~55%のオクルージョン)、heroBands.feasible(利用可能な場合は真)。 - フォールバック:
fallback— すべてのプレーンが被写体と重なる場合(例:極端なクローズアップ)、ナレーションは**zones.fallback**に配置され、読みやすくするためにヒーローopacityを下げます。
safe-zones.jsonは、作成中にキャプション配置決定のための読み取り専用の提案として機能します。ヒーローを強制するのではなく、アドバイスします。
ヒーローロックアップ(Cinematic)
ヒーローブロック("hero": trueの行を含むブロック)は、被写体を中心とした単一の結合された構成としてレンダリングされます:
- 事前コンテキスト:ヒーローの前の行(同じブロック内の行2~5)は、前面にスタックされます。
- ヒーロー:
"text"フィールドを持つ行(昇格された単語で、多くの場合読みやすくするために調整されます) — 背後に埋め込まれます。 - 事後コンテキスト:ヒーローの後の行は前面にスタックされます。
- 読書順序:上から下へ = 構築による話し言葉の順序:事前コンテキスト(前面)、ヒーロー(背面)、事後コンテキスト(前面) — 「デプスサンドイッチ」。一括ルールにより、ヒーローがそのコンテキストを支配します。
単一のヒーローを含まないブロックは、heroAnchor/hugLeft/hugRightの安全ゾーンを使用して、平面にスタックされます。