Communitygithub.com

vidmoat/caption-styling

スマートフォンで音を消して視聴するためのキャプション・字幕のスタイル、タイミング、配置を設定します。一行あたりの文字数、読解速度、キュー間隔、サイズ、コントラスト、プラットフォームのセーフゾーンを定義し、SRT/VTTファイルをそれらに照らしてチェックします。ユーザーがキャプションの追加、スタイル変更、修正、アクセシビリティ対応、または「画面に喋りを載せて」と依頼したとき、TikTok、Reels、Shorts、YouTube動画を準備しているときに使用します。

caption-styling とは?

このスキルは、モバイル動画向けのキャプションと字幕をプロフェッショナルな基準でスタイリング・検証するためのリファレンスを提供します。音声オフ、アプリのボタンの下、動く映像の上という過酷な視聴環境においても、キャプションが確実に読めるようにするための具体的なデフォルト値(1行あたり最大42文字、読解速度17文字/秒、最小表示時間1秒など)を定義します。対応フォーマットはSRTとVTTで、ffmpegを使用した焼き込みやASSファイルによる高度なスタイリングもサポートします。スクリプトによる自動チェック機能(`scripts/check_captions.py`)により、行数、文字数、読解速度、重複/ギャップを検出し、品質を担保します。横画面(16:9)と縦画面(9:16)の両方に対応し、TikTok、Reels、Shorts、YouTubeに最適化されたセーフゾーンとピクセル値を提供します。さらに、フォント幅の推定誤差やASSのプレートレンダリングの問題など、実践的なトラブルシューティング情報も網羅しています。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/vidmoat/skills/tree/HEAD/skills/core/caption-styling

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

キャプションスタイリング

キャプションは、スマートフォンで、音声オフ、動く映像の上、アプリのボタンの下で、約2秒で読まれます。以下のデフォルトはすべてその読者のために設定されています。ユーザーがエディタを持っている場合はそのエディタで作業してください。数値はどこでも同じです。エディタがない場合は、references/ffmpeg-burn-in.md のffmpegレシピを使用してください。

デフォルト

ユーザーまたはスタイルガイドで別途指示がない限り、これらを使用してください。

設定デフォルト理由
1キューあたりの行数最大2行3行目は被写体を隠し、時間内に読まれないため。
1行あたりの文字数横画面16:9: 42文字; 縦画面9:16: セーフ幅に収まる文字数(64pxで約32文字、72pxで約28文字(大文字小文字混在))長い行は視線の移動を強制し、縦画面ではフレームからはみ出します。
読解速度最大17文字/秒(約160~180語/分)放送慣行による。WCAGは速度を定めていないため、これが実用的な標準です。
キュー持続時間最小1秒、最大6秒1秒未満はフリッカー、6秒超は読み直しが発生します。
キュー間のギャップ0または最低2フレーム1フレームのギャップはフラッシュのように見えます。
位置画面下部中央、セーフゾーン内。1080x1920の場合、テキストは下部420px(高さの22%)より上に配置TikTokとReelsの両方でクリアになるため。下半分に顔、焼き込みテキスト、アプリUIがある場合は上部に移動。
サイズ(文章字幕)横画面: フレーム高の4.5~5%(1080pで49~54px)。縦画面: 1080x1920で64~72px腕を伸ばした距離で読め、上記の行長も900pxのセーフ幅に収まります。
サイズ(短くインパクトのあるキャプション、1~3語)1080x1920で約140~150px、大文字小文字混在で1行最大約14文字、大文字のみで11文字これらはグラフィック要素であり、字幕ではありません。

| 色 | オフホワイト #F2F2F2、背景に70~80%不透明の暗いプレート、または3~5pxの暗い輪郭+ソフトシャドウ | 動く映像に対するコントラストはフレームごとに測定できません。プレートを使用することでWCAG 4.5:1を保証します。 | | フォント | 太めのサンセリフ(ボールドまたはセミボールド)。1動画内で2ファミリー以上は使用しない。 | 細いウェイトは圧縮後に消えます。 | | ワードハイライト(カラオケ) | アクティブな単語のみに1つのアクセントカラーを使用し、それも4.5:1のコントラストを満たす必要がある。 | 「強調」のための2色目があると、視聴者は意味を探そうとします。 |

レンダリング前にフィットチェックを行う。 太字Arialクラスのサンセリフを大文字小文字混在で使用した場合、1文字あたりの平均幅はフォントサイズの0.44倍(スペース込み、実測値)、大文字のみで0.55倍、コンデンス書体で約0.35倍です。したがって、行の幅はおおよそ 文字数 x 係数 x フォントサイズpx であり、これはセーフ幅(1080x1920では900px、横画面では幅の90%)に収まる必要があり、フレーム幅ではありません。96pxで27文字の大文字小文字混在行の場合、約27 x 0.44 x 96 = 1,140pxとなり、1080pxのフレーム全体よりも広くなります。これらの係数は実測元の書体における平均値です(「注意点」参照)。そのため、レンダリングフレームで確認してください。

プラットフォームのピクセルセーフゾーンと、任意のキャンバスからセーフボックスを導出する方法については、references/platform-safe-zones.md を参照してください。縦画面動画にキャプションを配置する前に読んでください。

ワークフロー

  1. 実際のタイミングから始める。 キャプションにはセグメントまたは単語のタイムスタンプを持つトランスクリプトが必要です。トランスクリプトがない場合は、作成できるキャプションはありません。その旨を伝えるか、最初に文字起こしを行ってください。文言をでっち上げないでください。

  2. タイミングを編集後のタイムラインに合わせる。 トランスクリプトはソースファイルに対してタイミングが取られています。トリミング、カット、速度変更後は、各キューの時間をタイムラインに合わせてシフトおよびスケーリングしてください(「注意点」参照)。

  3. キューに分割する。 句の境界(句読点の後、接続詞・前置詞の前)で分割します。冠詞と名詞、名前と名字、数字と単位を分割しないでください。2つの分割候補がある場合は、2行の長さが最も近くなる方を採用します。

  4. 読解速度を守る。 17文字/秒を超えるキューは、その後の無音部分に分割するか延長します。タイプサイズを小さくして収めようとしないでください。

  5. 話者と音をマークする。 話者が変わったら行頭を - にします(または最初の出現時に括弧で名前を示します)。意味のある非言語音は角括弧で囲みます:[ドアがバタンと閉まる]、[緊迫した音楽]。音声からカットされたフィラーワードはキャプションに含めないでください。

  6. デフォルトとこのキャンバスのセーフボックスを使用してスタイルと配置を設定する。

  7. ファイルをチェックし、報告されたすべてのエラーを修正する。

    python scripts/check_captions.py captions.srt --fps 30 --max-chars 32
    

    このスクリプトは行数、行長、1秒あたりの文字数、持続時間、ギャップ、重複をチェックし、エラーがある場合はゼロ以外の終了コードを返します。マシンリーダブルなレポートを得るには --json を追加してください。デフォルトの行制限は32文字(縦画面およびアクセシビリティの数値)です。横画面字幕の場合は --max-chars 42 を渡してください。

  8. 設定ではなく、レンダリングフレームを確認する: 最初のキュー、最も長いキュー、最も込み入った背景上のキュー。テキストがクリップされていないこと、アプリUIの下に隠れていないこと、スマートフォンサイズで読めることを確認します。

  9. ソーシャル向けの焼き込み版と、アクセシビリティ・プラットフォームアップロード用のサイドカー .srt または .vtt の両方を納品する。 ただしユーザーがどちらか一方のみを要求した場合は除きます。

注意点

  • コンデンス書体では幅の見積もりが誤る。 平均グリフ幅の見積もりは3倍以上ずれることがあります。あるオーバーフローチェックでは、実際に1080pxフレーム内で270px幅でレンダリングされた行が、左右それぞれ127pxはみ出していると報告されました。その見積もりを満たすためにタイプを縮小した結果、1080x1920で約150pxを想定したインパクトスタイルが76pxのキャプションになり、スマートフォンで読むには小さすぎました。フレームをレンダリングして測定してください。
  • トランスクリプトのタイムはソース基準。 クリップがソースの12.4秒後から始まる場合、すべてのキューから12.4秒を引き、クリップのタイムライン開始時間を加算します。2倍速の場合、持続時間は半分になるため、キューが1秒未満になることがあります。古いキュー境界を維持せず、再分割してください。
  • ffmpegはSRTをピクセルではなく288行グリッドで焼き付ける。 subtitles=file.srt:force_style=... では、FontSize と MarginV は384x288のスクリプトに対する値として測定されます。したがって FontSize=24 は1080ラインの動画で90pxフォント、1920ラインの動画で160pxフォントとしてレンダリングされます。変換には FontSize = px * 288 / frame_height を使用するか、PlayResX と PlayResY が動画サイズと等しいASSファイル(単位がピクセルになる)を書き込んでください(レシピが示す方法です)。
  • ASSのプレートはOutlineColourを使用する。 BorderStyle=3 の場合、ボックス色は BackColour ではなく OutlineColour から取得されます。また、ASSの色は &HAABBGGRR で、アルファ 00 は不透明です。&H40000000 は黒で75%不透明です。
  • インラインの色変更はASSプレートを壊す。 BorderStyle=3 の行内に {\c...} ハイライトがあると、色のランごとに個別のボックスが描画され、半透明のボックスが重なって暗い継ぎ目が生じます。プレートを非表示テキストの独自レイヤーとして描画し、表示テキストを上のレイヤーに配置してください(レシピが方法を示しています)。
  • 不足フォントはエラーなしで置き換わる。 libassはエラーを出さずに別のフォントにフォールバックします。ffmpegログの fontselect: 行を確認するか、fontsdir= を渡してください。
  • Windowsのパスはsubtitlesフィルタを壊す。 ドライブのコロンをエスケープしてください:subtitles='C\:/clips/subs.srt'。
  • 歌詞はフレーズ単位でタイミングが取られる。 音楽下の音声認識は単語を失い(あるテストでは17語中4語を喪失)、単語タイムではなくフレーズタイムを返します。オーディオと照合せずに単語ごとのカラオケを構築しないでください。
  • プリセットがアクティブワードを複数箇所で着色することがある。 あるエディタのネオンプリセットは、ハイライト色とグローの両方からハイライトを描画していました。そのため、存在しないフィールドのみを上書きしても何も変わらず、エラーも発生しませんでした。色を保持するすべてのフィールドを実際の名前で上書きし、レンダリングフレームで確認してください。

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

関連スキル