Communitygithub.com

Subtitles Studio — Studio de Légendes Dynamiques

Bibliothèque modulaire et autonome pour générer des légendes dynamiques de type « Lockup » (mot géant au centre + petits mots insérés géométriquement dans les interstices + effet de lumière/éclat + anti-sclignotement) pour vidéos verticales (Reels/TikTok/Shorts) dans HyperFrames.

Qu'est-ce que Subtitles Studio — Studio de Légendes Dynamiques ?

Cette compétence, nommée « Subtitles Studio », est une bibliothèque Python 100% autonome et prête à l’emploi pour le studio HyperFrames. Elle génère des légendes dynamiques de style *lockup* où un mot principal gigantesque occupe le centre de l’écran, tandis que des mots secondaires s’insèrent automatiquement dans les espaces réels des ascendantes et descendantes de la police. Le système inclut un moteur de géométrie de glyphes, un groupement intelligent mot par mot (avec un temps de maintien minimal évitant le scintillement), un rendu HTML/CSS/GSAP et une transcription audio (via CrisperWhisper). Les styles sont des plugins partagés : il suffit de placer un fichier `.py` dans le dossier `styles/` pour créer un nouveau look. La bibliothèque gère automatiquement le téléchargement des polices Google Fonts, les corrections de synchronisation audio et le respect des zones de sécurité des réseaux sociaux (Reels, TikTok, Shorts).

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add NicolasCoder/subtitles_studio

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

SKILL : Subtitles Studio — Bibliothèque modulaire de légendes dynamiques (subtitles_studio)

1. Vue d'ensemble pour l'IA

Dépôt officiel : https://github.com/NicolasCoder/subtitles_studio.git

Ce dossier est une boîte à outils 100% autonome et partageable pour générer des légendes dynamiques de type Lockup (un mot principal géant au centre avec des mots plus petits insérés dans les creux réels des ascendantes/descendantes de la police) pour HyperFrames (1080x1920 @ 30fps).

Architecture du dossier

subtitles_studio/
├── SKILL.md                        # Ce guide complet pour les agents IA
├── README.md                       # Guide rapide pour les humains
├── requirements.txt                # fonttools, brotli, Pillow, numpy
├── cli.py                          # Interface en ligne de commande prête à l'emploi
├── fonts/                          # Polices .woff2 locales pré-packagées (+ téléchargement automatique via Google Fonts)
├── caption_kit/                    # Paquet Python importable
│   ├── __init__.py                 # API publique
│   ├── nesting.py                  # Moteur de géométrie de glyphes réelle + auto-téléchargement Google Fonts
│   ├── grouper.py                  # Groupeur intelligent mot par mot (maintien >= 0.38s, anti-sclignotement)
│   ├── renderer.py                 # Compilateur HTML/CSS/GSAP et chargeur dynamique du dossier styles/
│   └── transcribe.py               # Transcription mot par mot (CrisperWhisper / faster-whisper / whisper)
├── styles/                         # MODULES DE STYLE (1 fichier .py ou .json = 1 style partageable !)
│   ├── _TEMPLATE_NOVO_ESTILO.py    # Modèle commenté pour créer de nouveaux styles
│   ├── bold_ciano.py               # Bold Social — Cyan (#3de0c8)
│   ├── bold_vermelho.py            # Bold Social — Rouge (#ff3355)
│   ├── bold_roxo.py                # Bold Social — Violet (#b855ff)
│   ├── bold_dourado.py             # Bold Social — Doré (#ffd24a)
│   ├── editorial.py                # Editorial Mix (Inter 900 + Playfair Display Italic)
│   ├── gold_script.py              # Gold Script (Pinyon Script + Oswald)
│   └── poster_impact.py            # Poster Impact (League Gothic + Montserrat 900)
└── examples/                       # Exemples prêts à tester (en portugais)
    ├── demo_words_pt.json          # Mots avec horodatages (portugais)
    └── demo_groups_pt.json         # Groupes lockup/plain (portugais)

2. Utilisation en ligne de commande (cli.py)

# 1. Lister tous les styles installés dans styles/
python cli.py --list-styles

# 2. Générer une démo rapide pour n'importe quel style
python cli.py --demo --style bold_roxo

# 3. Générer à partir d'un JSON de mots avec horodatages (word, start, end)
python cli.py --words examples/demo_words_pt.json --style bold_vermelho --out output/mon_test

# 4. Changer la couleur d'accent à la volée sans modifier le style
python cli.py --words examples/demo_words_pt.json --style bold_ciano --accent "#00ff88"

# 5. Transcrire une vidéo/audio (.mp4/.wav/.mp3) et générer les légendes synchronisées
python cli.py --media ma_video.mp4 --lang pt --style bold_dourado --video ma_video.mp4

3. Utilisation en Python (Intégration dans un projet HyperFrames)

Lorsque vous assemblez une composition complète dans HyperFrames (avec A-roll, B-roll, motions, SFX et musique), importez caption_kit et utilisez render_embeddable() :

import sys
sys.path.insert(0, "chemin/vers/legendas_dinamicas_kit")

from caption_kit import build_groups_from_words, render_embeddable

# 1. `words` est une liste [{"word": "Criar", "start": 0.15, "end": 0.42}, ...]
groups = build_groups_from_words(words, min_hold=0.38)

# 2. Génère le CSS, le DOM (avec <span> internes pour zéro avertissement lint) et le JS GSAP :
caps_css, caps_dom, caps_js, report = render_embeddable(
    groups,
    prefix="v1",                 # Préfixe unique des IDs (#v1-g0, #v1-g1...)
    style_name="bold_vermelho",  # N'importe quel fichier dans styles/<nom>.py
    accent_override=None,        # Ou passez e.g. "#ff3355" pour changer uniquement la couleur
    y_lockup=0.74,               # Zone de sécurité Reels (1300-1560px en 1080x1920)
    y_plain=0.75,
    track_index=3,
    z_index=95,
)

Il suffit ensuite d'injecter :

  • {caps_css} dans la balise <style> de la composition ;
  • {caps_dom} dans la <div id="root" ...> ;
  • {caps_js} dans la balise <script> juste après const tl = gsap.timeline({ paused: true });.

4. Créer un nouveau style partageable (Système de plugins dans styles/)

Le système de styles a été conçu pour être 100% plug-and-play :

  • Tout fichier .py (ou .json) placé dans le dossier styles/ (dont le nom ne commence pas par _) est découvert automatiquement par load_styles().
  • Pour créer un nouveau style à la demande de l'utilisateur :
    1. Copiez styles/_TEMPLATE_NOVO_ESTILO.py vers styles/<nom_du_style>.py.
    2. Modifiez le dictionnaire STYLE = { ... }.
    3. Si vous utilisez une nouvelle police de Google Fonts (ex : "Bebas Neue", "Poppins", "Syne"), pas besoin de téléchargement manuel : le moteur caption_kit/nesting.py télécharge automatiquement les fichiers .woff2 depuis Google Fonts lors de la première exécution et les sauvegarde dans fonts/<famille>/ !
    4. Pour que l'utilisateur partage ce style avec quelqu'un d'autre, il suffit d'envoyer ce seul fichier styles/<nom_du_style>.py !

Anatomie du dictionnaire STYLE

STYLE = {
    "id": "neon_cyber",
    "label": "Neon Cyber (Montserrat 900 + Glow Vert)",
    # Mot principal (centre du lockup)
    "main_font": "Montserrat",
    "main_weight": 900,
    "main_style": "normal",
    "main_track": -0.05,
    "main_case": "none",           # IMPORTANT : utilisez "none" pour préserver les ascendantes/descendantes et permettre l'encastrement ! Utilisez "upper" uniquement si "nest_mode": "overlap".
    "main_lh": 0.80,
    "main_css": "color:#ffffff;text-shadow:0 10px 34px rgba(0,0,0,.6);",
    "max_px": 280,
    # Petits mots de soutien (au-dessus et en dessous)
    "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 de la taille du mot principal
    # Légende simple continue
    "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);",
    # Couleur d'accent et éclat
    "accent": "#00ff88",
    "accent_extra_css": "text-shadow:0 0 24px rgba(0,255,136,0.55);",
    "shine": ("#ffffff", "rgba(0,255,136,.9)"),
    # Géométrie et animations
    "tilt": (-2, 2),               # Inclinaison (degrés) de la ligne du haut et de la ligne du bas
    "clear": 0.03,                 # Jeu minimal entre les cadres
    "variants": ("slam", "letters", "rise", "blur"),
}

5. Règles d'or de qualité (apprises en production)

  1. Temps de lecture (Maintien minimal) : Le groupeur (caption_kit/grouper.py) garantit au moins 0.38s avec la phrase complète à l'écran avant de changer de bloc. Quand le débit de parole est rapide, il compresse l'échelonnement d'entrée des mots pour ne jamais couper la fin de la phrase.
  2. Ordre chronologique : Les lignes entrent toujours dans l'ordre réel où elles sont prononcées (above → main → below).
  3. Zone de sécurité Instagram Reels / TikTok (1080x1920) :
    • Par défaut y_lockup=0.74 (~1420px), ce qui se situe dans la zone de sécurité 1300–1560px (en dessous du visage et des cartes de motion, et au-dessus des boutons inférieurs du Reels).
  4. Synchronisation audio dans HyperFrames :
    • Si la vidéo utilise un audio coupé en plusieurs segments, n'utilisez jamais plusieurs balises <audio> pointant vers le même fichier avec data-media-start (cela décale l'audio dans HyperFrames). Découpez toujours l'audio en un seul fichier .wav continu et utilisez une seule balise <audio data-start="0.000">.

Skills associés