hyperframes-captions について
hyperframes-captionsは、Hyperframesで動画字幕を作る制作者向けのスキルです。単語単位のタイミング、トランスクリプトに応じたスタイル、字幕のはみ出しや表示残りを防ぐアニメーション処理を扱います。
主な機能
- 01音声言語に応じたWhisperモデル選択
- 02トランスクリプトに基づくスタイル選択
- 03単語ごとの視覚的な強調
- 04トーンや間に応じた字幕グループ化
- 05テキスト計測によるはみ出し防止
- 06字幕グループの時間どおりの非表示
活用シーン
- 01音声に同期した動画字幕の作成
- 02マーケティングやチュートリアルの字幕演出
- 03ブランド名、数字、行動喚起の強調
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ heygen-com/ hyperframes --skill hyperframes-captionsインストール後、Claude Code で/hyperframes-captionsを入力して読み込まれたか確認します。
同梱ファイルdynamic-techniques.mdtranscript-guide.md
詳細
キャプション
言語ルール(必須)
ユーザーが音声は英語だと明示しない限り、.en モデルは絶対に使用しないでください。 .en モデル(small.en、medium.en)は、英語以外の音声を英語に翻訳してしまい、文字起こしを行いません。その結果、元の言語が気付かれないまま失われます。
文字起こしを行う場合:
- ユーザーが言語を指定した場合 →
--model small --language <code>を使用します(.enサフィックスなし) - ユーザーが英語だと指定した場合 →
--model small.enを使用します - 言語が不明な場合 →
--model smallを使用します(.enなし、--languageなし)。whisper が自動検出します
デフォルトのモデルは small(small.en ではありません)です。 音声が英語だと明示された場合に限り、.en を追加してください。
話されている内容を分析して、キャプションのスタイルを判断してください。ユーザーがスタイルを指定した場合は、それを使用します。指定がない場合は、文字起こしからトーンを検出してください。
文字起こしのソース
プロジェクトの transcript.json には、単語ごとのタイムスタンプを含む正規化済み単語配列が格納されています。
[
{ "text": "Hello", "start": 0.0, "end": 0.5 },
{ "text": "world.", "start": 0.6, "end": 1.2 }
]
キャプションの構成で使用する形式はこれだけです。このまま使用してください。
const words = JSON.parse(transcriptJson); // [{ text, start, end }]
文字起こしコマンド、whisper のモデル選択、外部 API(OpenAI、Groq)、サポートされている入力形式については、transcript-guide.md を参照してください。
スタイルの検出(デフォルト — スタイルが指定されていない場合)
スタイルを選ぶ前に、文字起こし全体を読んでください。スタイルはテンプレートではなく、内容から決まります。
4 つの要素
1. 見た目の印象 — 全体的な美的個性:
- 企業向け/プロフェッショナルな台本 → すっきりとした、ミニマルで控えめなスタイル
- エネルギッシュな/マーケティング用の台本 → 大胆で、歯切れがよく、インパクトの強いスタイル
- ストーリーテリング/物語調の台本 → 洗練され、温かみのある、映画的なスタイル
- 技術/教育向けの台本 → 正確で、コントラストが強く、構成の整ったスタイル
- ソーシャルメディア/カジュアルな台本 → 遊び心があり、動きがあって、親しみやすいスタイル
2. カラーパレット — 内容のムードを反映します:
- エネルギッシュな内容には、明るいアクセントカラーを使った暗い背景
- プロフェッショナルな内容や落ち着いた内容には、落ち着いた/ニュートラルな色調
- 明瞭さを重視する場合は、高いコントラスト(黒地に白、白地に黒)
- 強調にはアクセントカラーを 1 色使用し、複数は使わない
3. フォントの雰囲気 — 特定のフォント名ではなく、タイポグラフィの個性:
- インパクトやエネルギーを出すには、太字/コンデンス体
- モダンでプロフェッショナルな印象には、すっきりしたサンセリフ体
- 親しみやすく近づきやすい印象には、丸みのある書体
- 優雅さやストーリーテリングには、セリフ体
4. アニメーションの特徴 — 単語がどのように表示され、消えるか:
- 歯切れのよいエネルギーには、スケールポップ/スラム
- 落ち着いた内容やプロフェッショナルな内容には、穏やかなフェード/スライド
- 強調には、単語ごとの表示
- 技術的または物語調のペースには、タイプライター
単語ごとのスタイル設定
台本を確認し、独自の視覚表現に値する単語を探してください。すべての単語が同じではありません。メッセージを伝える重要な単語があります。
検出する対象
- ブランド名/製品名 — サイズを大きくし、独自の色を使い、異なる表示アニメーションを適用
- すべて大文字の単語 — 作者が意図的に強調しています。拡大、フラッシュ、またはアクセントカラーを適用
- 数値/統計情報 — 太字にし、アクセントカラーを使用。データ主導の内容では、数値が重要な情報です
- 感情を表すキーワード — 「incredible」、「insane」、「amazing」、「revolutionary」など → 誇張したアニメーション(オーバーシュート、バウンス)
- 固有名詞 — 人名、場所、イベント名 → 異なるアクセントカラーまたはイタリック
- 行動を促すフレーズ — 「sign up」、「get started」、「try it now」など → ハイライト、下線、または色のポップ効果
適用方法
検出した単語ごとに、次の内容を指定します:
- フォントサイズの倍率(例:強調には 1.3x、主役となる場面には 1.5x)
- 色の上書き(具体的な hex 値)
- ウェイト/スタイルの変更(太字、イタリック)
- アニメーションのバリエーション(オーバーシュートする表示、グローパルス、スケールポップ)
- マーカーハイライトモード — 色やサイズ以外の視覚的な強調には、マーカー風の効果を追加します。単語の背後にハイライトを引く、手描きの円で囲む、周囲に放射状のバースト線を加える、または下に走り書き風の下線を引く方法があります。パターンとエネルギーに応じたモードの対応表については、
/marker-highlightスキルを参照してください。
スクリプトからスタイルへのマッピング
| スクリプトのトーン | フォントの雰囲気 | アニメーション | 色 | サイズ |
|---|---|---|---|---|
| ハイプ/ローンチ | 太字のコンデンス体、ウェイト800~900 | スケールポップ、back.out(1.7)、高速0.1~0.2秒 | 暗い背景に明るいアクセント(シアン、黄色、ライム) | 大きめ72~96px |
| 企業向け/ピッチ | すっきりしたサンセリフ、ウェイト600~700 | フェード+スライドアップ、power3.out、0.3秒 | 暗い背景に白/ニュートラルカラー、控えめなアクセント1色 | 中程度56~72px |
| チュートリアル/教育 | モノスペースまたはすっきりしたサンセリフ、ウェイト500~600 | タイプライターまたは穏やかなフェード、0.4~0.5秒 | 高コントラスト、色は最小限 | 中程度48~64px |
| ストーリーテリング/ブランド | セリフ体またはエレガントなサンセリフ、ウェイト400~500 | ゆっくりしたフェード、power2.out、0.5~0.6秒 | 温かみのある落ち着いた色調、低い不透明度(0.85~0.9) | 小さめ44~56px |
| ソーシャル/カジュアル | 丸みのあるサンセリフ、ウェイト700~800 | バウンス、elastic.out、単語ごと | 遊び心のある色、ピル型の背景に色を付ける | 中~大56~80px |
トーンに応じた単語のグループ分け
グループのサイズはテンポに影響します。テンポの速いコンテンツでは、キャプションも素早く切り替える必要があります。
- エネルギッシュ: 1グループあたり2~3語。素早い切り替えが、速い話し方に合います。
- 会話調: 1グループあたり3~5語。自然なフレーズの長さです。
- 落ち着いた調子: 1グループあたり4~6語。長めのグループが、ゆっくりしたテンポに合います。
文の区切り(ピリオド、疑問符、感嘆符)、間(150ms以上の空白)、または単語数の上限のうち、最初に到達した箇所でグループを区切ります。
配置
- 横向き(1920x1080): 下から80~120px、中央揃え
- 縦向き(1080x1920): 下から約600~700pxの下部中央、中央揃え
- 被写体の顔を覆わないでください
position: absoluteを使用し、relativeは使用しないでください(オーバーフローの原因になります)- 一度に表示するキャプショングループは1つだけです
キャプションレイヤーの構造: left: 50%; transform: translateX(-50%) の代わりに、マージン付きの全幅コンテナーを使用します。transformで中央揃えする方法ではコンテンツの幅に縮小されるため、テキストの幅が広い場合や単語を拡大した場合に、コンポジションの端でクリッピングが発生します。
/* ✓ Full-width with margins — safe for scaled words */
#caption-layer {
position: absolute;
bottom: 80px;
left: 80px;
right: 80px;
text-align: center;
overflow: visible;
}
/* ✗ Collapsed width — clips at edges */
#caption-layer {
left: 50%;
transform: translateX(-50%);
}
テキストのはみ出し防止
window.__hyperframes.fitTextFontSize() を使って実際に描画されたテキストの幅を測定し、適切なフォントサイズを算出します。これにより、文字数に基づく経験則を、pretext によるピクセル単位で正確な測定に置き換えます。
GROUPS.forEach(function (group, gi) {
var result = window.__hyperframes.fitTextFontSize(group.text.toUpperCase(), {
fontFamily: "Outfit",
fontWeight: 900,
maxWidth: 1600,
});
wordEls.forEach(function (el) {
el.style.fontSize = result.fontSize + "px";
});
});
| オプション | デフォルト | 説明 |
|---|---|---|
maxWidth | 1600 | コンテナの幅(px)(横向きは1600、縦向きは900) |
baseFontSize | 78 | テキストが収まる場合に使う開始フォントサイズ |
minFontSize | 42 | 下限 — これより小さくしません |
fontWeight | 900 | CSS の font-weight と一致させる必要があります |
fontFamily | "Outfit" | CSS の font-family と一致させる必要があります |
step | 2 | 反復ごとの減少幅(px) |
fontWeight と fontFamily は、テキスト要素に適用される CSS と正確に一致させる必要があります。一致しないと、測定が不正確になります。
強調する単語の拡大分を考慮する: 単語ごとのスタイルで1.0倍を超えて拡大する場合(例:「GOLDEN」に scale: 1.3 を指定)、拡大された単語は fitTextFontSize で測定した幅よりも広くなります。これを補うために maxWidth を小さくします:maxWidth = safeWidth / maxScale。たとえば、1920px のコンポジションで余白が80px、最大スケールが1.3倍の場合:maxWidth = 1760 / 1.3 ≈ 1350。
安全策(CSS で引き続き必要):
- キャプションコンテナに
max-widthを指定する(強調表示の拡大分を考慮し、コンポジション幅より小さくする) overflow: visibleを指定する —overflow: hiddenは使わないでください。hiddenは拡大された強調単語とそのグロー効果を切り取ります。代わりに、縮小したmaxWidthを指定したfitTextFontSizeを使います。- すべてのキャプション要素に
position: absoluteを指定する - キャプションコンテナに明示的な
heightを指定する(例:200px)
キャプションの終了保証
画面に残り続けるキャプションは、最もよくあるキャプションの不具合です。すべてのキャプショングループには、終了アニメーションの後に必ず強制終了処理を設定してください。
// Animate exit (soft — can fail if tweens conflict)
tl.to(groupEl, { opacity: 0, scale: 0.95, duration: 0.12, ease: "power2.in" }, group.end - 0.12);
// Hard kill at group.end (deterministic — guarantees invisible)
tl.set(groupEl, { opacity: 0, visibility: "hidden" }, group.end);
両方必要な理由: カラオケ風の単語単位のトゥイーンが親の終了トゥイーンと競合する場合、fromTo の開始アニメーションが後続のトゥイーンを上書きする値を固定する場合、またはタイムラインのスクラブ位置が終了の開始から終了までの間にある場合、tl.to による終了処理ではグループを完全に非表示にできないことがあります。group.end の tl.set は確実な強制終了処理です。正確な時刻に実行され、アニメーションせず、上書きもされません。
セルフリントルール: タイムラインを構築した後、すべてのキャプショングループに強制終了処理があることを確認してください:
GROUPS.forEach(function (group, gi) {
var el = document.getElementById("cg-" + gi);
if (!el) return;
tl.seek(group.end + 0.01);
var computed = window.getComputedStyle(el);
if (computed.opacity !== "0" && computed.visibility !== "hidden") {
console.warn(
"[caption-lint] group " + gi + " still visible at t=" + (group.end + 0.01).toFixed(2) + "s",
);
}
});
tl.seek(0);
コンポジションの初期化時に実行されるよう、window.__timelines[id] = tl の前に配置してください。
参考資料
動的なアニメーション技法(カラオケ、クリップパスによる表示、単語のスラム、散乱する終了アニメーション、弾力のある登場、3D 回転、音声に反応するキャプション、pretext に基づく位置指定とグループ化)については、dynamic-techniques.md を参照してください。
単語ごとのスタイルと組み合わせる、アニメーション付きテキスト強調(ハイライトのスイープ、手描きの円、バースト線、手描きの下線、スケッチアウト効果)については、/marker-highlight スキルを参照してください。
文字起こしコマンド、whisper モデル、外部 API、トラブルシューティングについては、transcript-guide.md を参照してください。
制約
- 決定論的であること。
Math.random()とDate.now()は使いません。 - 文字起こしのタイムスタンプに同期すること。 単語は発話時に表示します。
- 同時に表示するグループは1つだけにすること。 キャプショングループを重ねて表示しません。
- すべてのキャプショングループに、
group.endでハードなtl.setによる強制終了処理を設定すること。 終了アニメーションだけでは不十分です。 - Google Fonts をデフォルトとして使う前に、プロジェクトのルートにフォントファイルがないか確認してください。