OpenCaptions拡張機能
CWI(Caption With Intent)キャプションをContent Engineのポストプロダクションパイプラインにフックします。フラットで静的な字幕とは異なり、CWIは音声の体感をエンコードします。ピッチはフォントウェイト、音量はフォントサイズ、強調はグローアニメーション、スピーカー識別情報はWCAG AAに準拠した色にマッピングされます。結果として、何が言われたかだけでなく、どのように言われたかを伝えるキャプションが生成されます。
CWIは、2025年にFCBシカゴとシカゴ聴覚協会によってアカデミー賞を受賞したキャプション標準です。OpenCaptionsは、そのための最初のオープンソースプログラムツールチェーンです。
パイプラインフックポイント
ステージ: ポストプロダクション(ステージ3) 位置: アップスケールとカラーグレードの後、最終エクスポートの前。
ポストプロダクションチェーン:
1. アップスケール(Real-ESRGAN / Topaz) --> 高解像度化
2. カラーグレード(ブランドLUT / ffmpeg) --> ブランドカラー適用
3. OpenCaptions(CWI) --> インテント駆動型キャプション
4. 最終エクスポート(ffmpeg) --> プロダクション対応ファイル
この拡張機能は、グレーディング済みの動画ファイルを受け取り、以下を生成します:
- 単語レベルのインテントアノテーションが付いたCWIドキュメント(
.cwi.json) - 標準的な字幕が必要なプラットフォーム向けのWebVTTフォールバック(
.vtt) - ピラースコアを含むバリデーションレポート(JSON)
- Remotionまたはffmpegでレンダリングされたキャプション付き動画(
.mp4)
動作の仕組み
グレーディング済み動画 + シーン概要
|
├── [1] 文字起こし(faster-whisper) --> 単語レベルのタイムスタンプ
├── [2] 話者ダイアライゼーション(pyannote-audio) --> 話者属性
├── [3] インテント抽出 --> 発話ごとのピッチ、音量、感情、強調
| V1: parselmouth + FER(音声+映像)
| V2: V-JEPA2ワールドモデル
| V3: TRIBE v2ニューラル予測
├── [4] インテント → CWIへマッピング --> 単語ごとのウェイト、サイズ、強調、アニメーション
| V1: RulesMapper(ピッチ→ウェイト、音量→サイズ)
| V2: LearnedMapper(修正データで学習)
| V3: NeuralMapper(脳領域の活性化がスタイルを決定)
├── [5] バリデーション(12ルール) --> 属性 + 同期 + 抑揚スコア
└── [6] レンダリング --> Remotionオーバーレイ OR ffmpeg焼き込み
ステップ1-2:文字起こし + 話者ダイアライゼーション
パイプラインはOpenCaptions CLIまたはMCPサーバーを呼び出し、faster-whisperで単語レベルのタイムスタンプを、pyannote-audioで話者検出を実行します。これらのステージは、各単語が話者にタグ付けされたDiarizedTranscriptを生成します。
ステップ3:インテント抽出
インテント抽出器は音声と動画を分析し、各発話の体感されるレジスターを決定します:
- 音声シグナル: ピッチ(Hz)、音量(dB)、発話速度(WPM)、ポーズのタイミング
- 感情シグナル: 価数(-1~1)、覚醒度(0~1)、支配的な感情
- 意味シグナル: 皮肉の確率、強調語、修辞的デバイス
これらのシグナルは、各発話に対してIntentFrameを形成します。発話のベースラインから逸脱する個々の単語には、WordIntentオーバーライドが適用されます。
ステップ4:インテントマッピング
マッパーはインテントシグナルをCWIのビジュアルパラメータに変換します:
| インテントシグナル | CWIプロパティ | マッピング(V1 RulesMapper) |
|---|---|---|
| ピッチ(正規化 0-1) | weight(100-900) | 線形補間:100 + pitch_norm * 800 |
| 音量(正規化 0-1) | size(0.7-1.5) | 線形補間:0.8 + volume_norm * 0.55 |
| 意味的強調 + 高音量 | emphasis(ブール値) | emphasis_wordsに含まれる単語 OR 音量 > p90 |
| 話者識別情報 | 話者 color | 12色のWCAG AAパレットから割り当て |
| ささやき(低音量) | weight < 300 | オーバーライド:ウェイトを100-250に制限 |
| 叫び(高音量) | size > 1.3 + emphasis | オーバーライド:サイズ1.35-1.5、強調 true |
ステップ5:バリデーション
@opencaptions/specバリデーターは、CWIドキュメントを3つのピラーにわたる12のルールに対してチェックします:
属性(3ルール):
- ATT_001:すべてのキャプションにキャスト内の話者がいる
- ATT_002:話者には一意の色が割り当てられている
- ATT_003:色がWCAG AAコントラスト(#1a1a1aに対して4.5:1)を満たしている
同期(5ルール):
- SYN_001:すべての単語にタイムスタンプがある
- SYN_002:タイムスタンプが単調増加している
- SYN_003:キャプションイベントが重複しない
- SYN_004:アニメーション期間は仕様通り600ms
- FCC_001:発話中に3秒以上のギャップがない
- FCC_002:1行あたり最大42文字(FCC準拠)
抑揚(3ルール):
- INT_001:ウェイトが有効範囲(100-900)内にある
- INT_002:サイズが有効範囲(0.7-1.5)内にある
- INT_003:20%以上の単語がデフォルト以外のウェイトを持つ(キャプションが実際に変化している)
各ピラーは0-100でスコアリングされます。CWIドキュメントは、3つのピラーすべてが80以上の場合に合格となります。
ステップ6:レンダリング
2つのレンダリングパス:
Remotionパス(Content Engine推奨):CWIの単語が<CaptionOverlay>コンポジション内のReactコンポーネントになります。各単語は、タイムスタンプに合わせてspring()エントランスアニメーション、話者色、可変フォントウェイト、強調グローとともに表示されます。完全なマッピングについてはreferences/cwi-remotion-bridge.mdを参照してください。
ffmpeg焼き込み(フォールバック):CWIドキュメントからASS字幕ファイルを生成し、ffmpeg -vf ass=captions.assで動画に焼き込みます。単語ごとのアニメーションは失われますが、話者色とフォントウェイトの変化は保持されます。
CLIの使用方法
# 動画からCWIキャプションを生成
npx opencaptions generate video.mp4 --output captions.cwi.json
# TRIBE v2ニューラルバックエンドで生成
npx opencaptions generate video.mp4 --backend tribe --output captions.cwi.json
# CWIドキュメントをバリデーション
npx opencaptions validate captions.cwi.json
# ターミナルでキャプションをプレビュー(ANSIカラー)
npx opencaptions preview captions.cwi.json
# WebVTTにエクスポート
npx opencaptions export captions.cwi.json --format webvtt
# After Effects ExtendScriptにエクスポート
npx opencaptions export captions.cwi.json --format ae-json
# Premiere Pro XMLにエクスポート
npx opencaptions export captions.cwi.json --format premiere-xml
# システム依存関係をチェック
npx opencaptions doctor
# Python依存関係をインストール
npx opencaptions setup
MCPサーバーの使用方法
OpenCaptions MCPサーバーは、エージェント統合用に4つのツールを公開しています:
| ツール | 説明 |
|---|---|
generate_captions | 動画ファイルに対してフルパイプラインを実行 |
validate_captions | CWIドキュメントを12ルールで検証 |
preview_captions | 指定時刻のターミナルフォーマットプレビュー |
export_captions | WebVTT形式にエクスポート |
Claude Codeで使用するには、設定にMCPサーバーを追加します:
{
"mcpServers": {
"opencaptions": {
"command": "npx",
"args": ["@opencaptions/mcp"]
}
}
}
その後、会話内で「Generate CWI captions for video.mp4」と入力すると、generate_captionsがトリガーされます。
compose-video.pyの統合
Content Engineのcompose-video.pyは、--captionsフラグを受け付けます:
python3 scripts/compose-video.py storyboard.md --brand arcan-studio --captions
--captionsが渡されると、すべてのクリップが生成され結合された後、パイプラインは次の処理を行います:
npx opencaptions generate {final-video}.mp4 --output {output-dir}/captions.cwi.jsonを実行- CWIドキュメントを検証(スコアが80未満の場合は警告を出すがブロックはしない)
--remotionも渡された場合、CWI JSONをRemotionコンポジションに<CaptionOverlay>プロップとして注入- それ以外の場合、最終動画と一緒にWebVTTをサイドカーファイルとして生成
OpenCaptionsがインストールされていない場合(npx opencaptions doctorが失敗する場合)、パイプラインはグレースフルにフォールバックします:
- シーン概要のテキストオーバーレイ(ストーリーボードの
## Shot説明からの静的テキスト)にフォールバック - 警告をログに記録:「OpenCaptions not available, using scene brief text overlay」
- クリップ境界から導出されたタイミングを持つ
.vttファイルを引き続き生成
キャプションスタイル
3つの組み込みキャプションスタイルプリセットがあり、設定で選択できます:
1. 単語ごと(脳を掴む)
高いリテンションスタイル:各単語が個別に中央に表示され、サイズ変化が最大。ソーシャル/TikTok/Reels向けのドーパミンフック最適化コンテンツに使用。
- 一度に表示される単語は1つ
- ベースサイズ大(1080pで64px)
- 極端なウェイト変化(100-900の全範囲)
- 強調語は1.5倍に拡大しグローを伴う
- 背景:なし(単語が動画の上に浮かぶ)
- フォント:Roboto Flex可変
2. ナラティブ(編集用)
全文表示で単語ごとにスタイリング。長尺コンテンツ、ドキュメンタリー、ブログの動画埋め込みに使用。
- キャプションイベント全体が表示され、単語がインラインでスタイリング
- ベースサイズ中(1080pで48px)
- 適度なウェイト変化(300-700)
- 強調語は控えめなサイズアップ(1.15倍)
- 背景:半透明のピル(rgba(0,0,0,0.6))
- フォント:Roboto Flex可変
3. ミニマル(ローワーサード)
クリーンなローワーサード表示。話者名 + テキスト。視覚的な気散じを最小限に。インタビュー、トーキングヘッド、会議録画に使用。
- 話者名ラベルを話者色で表示、キャプションテキストは白
- ベースサイズ小(1080pで36px)
- 強調のみウェイト変化(デフォルト400、強調700)
- サイズ変化なし
- 背景:グラデーションバー(フレーム下部15%)
- フォント:システムサンセリフ
データ契約
読み取り(不変)
- 先行するポストプロダクションステップからのグレーディング済み動画アセット
knowledge/compiled/brands/{brand_slug}.md-- キャプションのカラーパレットとタイポグラフィ設定用- シーン概要(実行時パラメータ) -- 意図された感情のトーンに関するコンテキスト用
書き込み(自身の名前空間のみ)
extensions/opencaptions/output/{asset_id}.cwi.json-- CWIドキュメントextensions/opencaptions/output/{asset_id}.vtt-- WebVTTフォールバックextensions/opencaptions/output/{asset_id}-report.json-- バリデーションレポートextensions/opencaptions/output/{asset_id}-captioned.mp4-- レンダリング動画(Remotionパスのみ)
設定
opencaptions:
# キャプションスタイルプリセット
style: "narrative" # word-by-word | narrative | minimal
# ビジュアルパラメータ
font_family: "Roboto Flex" # ウェイト軸の可変フォント
base_font_size: 48 # 1080pでのピクセル数
position: "bottom" # top | center | bottom
max_chars_per_line: 42 # FCC準拠
background: "pill" # pill | shadow | gradient | none
background_opacity: 0.6 # 0.0 - 1.0
# パイプラインバックエンド
backend: "av" # av (V1) | jepa (V2) | tribe (V3)
language: "en" # 文字起こし用のISO 639-1ヒント
# 話者オーバーライド(オプション、デフォルトでは自動検出)
speakers:
- name: "Narrator"
color: "#6B8AFF"
- name: "Guest"
color: "#FF6B6B"
# レンダリング
render_mode: "remotion" # remotion | ffmpeg | sidecar-only
output_format: "mp4" # mp4 | webm
fps: 30 # ソース動画に合わせる
# バリデーション
min_score: 80 # 続行するための最低スコア
fail_on_low_score: false # trueの場合、低スコアでパイプラインをブロック
# TRIBE v2ニューラルマッピング(V3バックエンドのみ)
neural_mapping: false # 予測ニューラル応答スタイリングを有効化
グレースフルデグラデーション
この拡張機能は、Content Engineパイプラインをブロックしません。デグラデーションの段階:
| 条件 | 動作 |
|---|---|
| OpenCaptions CLIがインストール済み + 全Python依存関係 | 完全なCWIパイプライン(文字起こし、話者ダイアライゼーション、インテント抽出、マッピング) |
| OpenCaptions CLIがインストール済み、Python依存関係なし | モックバックエンドでプレースホルダーキャプション + バリデーション |
| OpenCaptions CLIがインストールされていない | シーン概要のテキストオーバーレイを静的キャプションとしてクリップ境界に表示 |
| 動画に音声トラックがない | キャプション生成をスキップし、情報メッセージをログに記録 |
| バリデーションスコア < 80 | 警告を出すが続行(fail_on_low_score: trueの場合を除く) |
| Remotionが利用不可 | ffmpeg ASS焼き込みにフォールバック |
| ffmpegが利用不可 | CWI JSON + WebVTTをサイドカーのみ出力(レンダリング動画なし) |
関連情報
- OpenCaptionsプロジェクト:
~/broomva/apps/opencaptions/ - CWI-Remotionブリッジ:
references/cwi-remotion-bridge.md - 統合ガイド:
references/integration-guide.md - Content Engine SKILL.md:
../../SKILL.md - 拡張機能フレームワーク:
../README.md