Communitygithub.com

NicolasCoder/subtitles_studio

HyperFrames用の縦型動画(Reels/TikTok/Shorts)向け「Lockup」スタイル動的キャプション生成モジュラライブラリ。大きな中央単語と幾何学的に配置された補助単語、ライト/シャイン効果、ちらつき防止機能を備えています。

subtitles_studio とは?

Subtitles Studioは、HyperFramesプラットフォーム向けに設計された、自己完結型のモジュラライブラリで、縦型動画(1080x1920 @ 30fps)にダイナミックなLockupスタイルのキャプションを生成します。「Lockup」とは、巨大な中央単語の周りに、フォントのアセンダー/ディセンダーの実際の隙間を幾何学的に計算して補助単語を配置するレイアウト手法です。このライブラリは、フォントのグリフ形状を解析する独自のネスティングエンジン、0.38秒以上のホールド時間で単語をグループ化してちらつきを防ぐスマートグルーパー、HTML/CSS/GSAPアニメーションを出力するレンダラー、そしてCrisperWhisper/faster-whisperによる文字起こし機能を備えています。CLIツールとして直接使用できるほか、HyperFramesプロジェクト内のPythonコードとして組み込むことも可能で、スタイルシステムはプラグイン方式で拡張でき、ユーザーはstyles/フォルダに単一のPythonファイルを追加するだけで新しいキャプションスタイルを作成・共有できます。Google Fontsからのフォントダウンロードや、実行時のアクセントカラー変更、メディアファイルからの直接文字起こしとキャプション生成にも対応しています。

対応✓Claude Code~Codex CLI~Cursor
npx skills add NicolasCoder/subtitles_studio

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

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

ドキュメント

SKILL: Subtitles Studio — 動的サブタイトルのモジュラーライブラリ (subtitles_studio)

1. AIのための概要

公式リポジトリ:https://github.com/NicolasCoder/subtitles_studio.git

このフォルダは、HyperFrames (1080x1920 @ 30fps) 向けにLockupスタイル(フォントのアセンダー/ディセンダーの実際の隙間を利用して、中央に巨大なメインワードを配置し、その隙間に小さな単語を収める)の動的サブタイトルを生成するための100%独立した共有可能なツールボックスです。

フォルダ構造

subtitles_studio/
├── SKILL.md                        # AIエージェント向け完全ガイド
├── README.md                       # 人間向けクイックガイド
├── requirements.txt                # fonttools, brotli, Pillow, numpy
├── cli.py                          # 即時利用可能なコマンドラインインターフェース
├── fonts/                          # 事前パッケージ化されたローカル .woff2 フォント(+ Google Fonts 自動ダウンロード)
├── caption_kit/                    # インポート可能なPythonパッケージ
│   ├── __init__.py                 # 公開API
│   ├── nesting.py                  # 実際のグリフジオメトリエンジン + Google Fonts 自動ダウンロード
│   ├── grouper.py                  # 賢い単語単位のグルーピング(ホールド0.38秒以上、ちらつき防止)
│   ├── renderer.py                 # HTML/CSS/GSAP コンパイラ、styles/ からの動的読み込み
│   └── transcribe.py               # 単語単位の文字起こし (CrisperWhisper / faster-whisper / whisper)
├── styles/                         # スタイルモジュール(1 .py または .json ファイル = 1つの共有可能スタイル!)
│   ├── _TEMPLATE_NOVO_ESTILO.py    # 新しいスタイル作成用コメント付きテンプレート
│   ├── bold_ciano.py               # ボールドソーシャル — シアン (#3de0c8)
│   ├── bold_vermelho.py            # ボールドソーシャル — レッド (#ff3355)
│   ├── bold_roxo.py                # ボールドソーシャル — パープル (#b855ff)
│   ├── bold_dourado.py             # ボールドソーシャル — ゴールド (#ffd24a)
│   ├── editorial.py                # エディトリアルミックス (Inter 900 + Playfair Display Italic)
│   ├── gold_script.py              # ゴールドスクリプト (Pinyon Script + Oswald)
│   └── poster_impact.py            # ポスターインパクト (League Gothic + Montserrat 900)
└── examples/                       # テスト用の既製サンプル(ポルトガル語)
    ├── demo_words_pt.json          # タイムスタンプ付き単語(ポルトガル語)
    └── demo_groups_pt.json         # lockup/plain グループ(ポルトガル語)

2. コマンドラインでの使用法 (cli.py)

# 1. styles/ にインストールされている全スタイルを一覧表示
python cli.py --list-styles

# 2. 任意のスタイルで簡単デモを生成
python cli.py --demo --style bold_roxo

# 3. タイムスタンプ付き単語JSON (word, start, end) から生成
python cli.py --words examples/demo_words_pt.json --style bold_vermelho --out output/meu_teste

# 4. スタイルを編集せずにアクセントカラーをその場で変更
python cli.py --words examples/demo_words_pt.json --style bold_ciano --accent "#00ff88"

# 5. 動画/音声 (.mp4/.wav/.mp3) を文字起こしし、同期サブタイトルを生成
python cli.py --media meu_video.mp4 --lang pt --style bold_dourado --video meu_video.mp4

3. Pythonでの使用法(HyperFramesプロジェクトへの組み込み)

HyperFramesでAロール、Bロール、モーション、SFX、音楽を含む完全なコンポジションを組んでいる場合、caption_kitをインポートし、render_embeddable()を使用します。

import sys
sys.path.insert(0, "caminho/para/legendas_dinamicas_kit")

from caption_kit import build_groups_from_words, render_embeddable

# 1. `words` はリスト [{"word": "Criar", "start": 0.15, "end": 0.42}, ...]
groups = build_groups_from_words(words, min_hold=0.38)

# 2. CSS、DOM(lint警告ゼロの内部 <span> 付き)、GSAP JSを生成:
caps_css, caps_dom, caps_js, report = render_embeddable(
    groups,
    prefix="v1",                 # IDの一意なプレフィックス(#v1-g0, #v1-g1...)
    style_name="bold_vermelho",  # styles/<名前>.py の任意のファイル
    accent_override=None,        # または例: "#ff3355" で色だけ変更
    y_lockup=0.74,               # Reels安全圏(1080x1920で1300-1560px)
    y_plain=0.75,
    track_index=3,
    z_index=95,
)

あとは以下を注入するだけです:

  • {caps_css} をコンポジションの <style> タグ内に
  • {caps_dom} を <div id="root" ...> 内に
  • {caps_js} を const tl = gsap.timeline({ paused: true }); 直後の <script> 内に

4. 新しい共有可能スタイルの作成方法 (styles/ プラグインシステム)

スタイルシステムは100%プラグアンドプレイとして設計されています:

  • styles/ フォルダ内の、名前が _ で始まらないすべての .py(または .json)ファイルは、load_styles() によって自動的に検出されます。
  • ユーザーから新しいスタイルのリクエストがあった場合:
    1. styles/_TEMPLATE_NOVO_ESTILO.py を styles/<スタイル名>.py にコピーします。
    2. 辞書 STYLE = { ... } を編集します。
    3. Google Fonts の新しいフォント(例:“Bebas Neue”、“Poppins”、“Syne”)を使用する場合、手動でダウンロードする必要はありません:エンジン caption_kit/nesting.py が初回実行時に自動的に .woff2 ファイルをダウンロードし、fonts/<ファミリー>/ に保存します!
    4. ユーザーがこのスタイルを他の人と共有するには、この単一のファイル styles/<スタイル名>.py を送信するだけです!

STYLE 辞書の構造

STYLE = {
    "id": "neon_cyber",
    "label": "Neon Cyber (Montserrat 900 + グリーングロー)",
    # メインワード(lockupの中央)
    "main_font": "Montserrat",
    "main_weight": 900,
    "main_style": "normal",
    "main_track": -0.05,
    "main_case": "none",           # 重要:アセンダー/ディセンダーを保持し、収まりを可能にするには "none" を使用! "nest_mode": "overlap" の場合のみ "upper" を使用。
    "main_lh": 0.80,
    "main_css": "color:#ffffff;text-shadow:0 10px 34px rgba(0,0,0,.6);",
    "max_px": 280,
    # 補助の小さな単語(上と下)
    "small_font": "Inter",
    "small_weight": 800,
    "small_style": "normal",
    "small_track": -0.03,
    "small_case": "none",
    "small_css": "color:#ffffff;text-shadow:0 5px 20px rgba(0,0,0,.6);",
    "small_scale": 0.44,           # メインサイズの0.25〜0.50
    # シンプルな連続字幕
    "plain_font": "Inter",
    "plain_weight": 800,
    "plain_style": "normal",
    "plain_case": "none",
    "plain_css": "color:#ffffff;text-shadow:0 5px 20px rgba(0,0,0,.6);",
    # アクセントカラーと光彩
    "accent": "#00ff88",
    "accent_extra_css": "text-shadow:0 0 24px rgba(0,255,136,0.55);",
    "shine": ("#ffffff", "rgba(0,255,136,.9)"),
    # ジオメトリとアニメーション
    "tilt": (-2, 2),               # 上段・下段の行の傾き(度)
    "clear": 0.03,                 # インク間の最小クリアランス
    "variants": ("slam", "letters", "rise", "blur"),
}

5. 品質の黄金律(本番で学んだこと)

  1. 読み取り時間(最小ホールド): グルーパー(caption_kit/grouper.py)は、ブロックを切り替える前に文全体が画面に表示されている時間を最低 0.38秒 保証します。話す速度が速い場合、単語のステガーエントリーを圧縮し、文の終わりが途切れないようにします。
  2. 時系列順: 行は常に実際に話された順序で入力されます(above → main → below)。
  3. Instagram Reels / TikTok のセーフゾーン (1080x1920):
    • デフォルト y_lockup=0.74(~1420px)で、安全圏 1300–1560px(顔やモーションカードの下、Reelsの下部ボタンの上)に収まります。
  4. HyperFramesでの音声同期:
    • 動画が複数のセグメントに分割された音声を使用する場合、決して複数の <audio> タグを同じファイルに対して data-media-start で使用しないでください(HyperFramesで音声がずれます)。常に音声を連続した単一の .wav ファイルに事前にカットし、単一の <audio data-start="0.000"> タグを使用してください。

関連スキル