Communitygithub.com

Subtitles Studio

Biblioteca modular e autossuficiente para geração de Legendas Dinâmicas estilo "Lockup" para vídeos verticais (Reels/TikTok/Shorts) no HyperFrames.

O que é Subtitles Studio?

O Subtitles Studio é uma caixa de ferramentas 100% independente e compartilhável para gerar legendas dinâmicas no estilo Lockup no HyperFrames (1080×1920 @ 30fps). Ele combina um motor de geometria real de glifos (que encaixa palavras menores nos vãos das ascendentes/descendentes da fonte principal), um agrupador inteligente palavra-por-palavra com hold mínimo de 0,38s (anti-pisca), e um compilador HTML/CSS/GSAP que gera código pronto para embed. Suporta transcrição via CrisperWhisper/faster-whisper, download automático de fontes do Google Fonts, e um sistema de plugins onde cada arquivo .py em styles/ define um estilo compartilhável. Pode ser usado tanto por CLI (listar estilos, gerar demos, transcrever vídeos) quanto como biblioteca Python importável em projetos HyperFrames. Ideal para criadores de conteúdo que precisam de legendas dinâmicas profissionais com efeito de luz/shine, anti-pisca e cores de destaque customizáveis.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add NicolasCoder/subtitles_studio

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

SKILL: Subtitles Studio — Biblioteca Modular de Legendas Dinâmicas (subtitles_studio)

1. Visão Geral para a IA

Repositório oficial: https://github.com/NicolasCoder/subtitles_studio.git

Esta pasta é uma caixa de ferramentas 100% independente e compartilhável para gerar legendas dinâmicas estilo Lockup (uma palavra principal gigante no centro com palavras menores encaixadas nos vãos reais das ascendentes/descendentes da fonte) para o HyperFrames (1080x1920 @ 30fps).

Arquitetura da Pasta

subtitles_studio/
├── SKILL.md                        # Este guia completo para agentes de IA
├── README.md                       # Guia rápido para humanos
├── requirements.txt                # fonttools, brotli, Pillow, numpy
├── cli.py                          # Interface de linha de comando pronta para uso
├── fonts/                          # Fontes .woff2 locais pré-empacotadas (+ download automático do Google Fonts)
├── caption_kit/                    # Pacote Python importável
│   ├── __init__.py                 # API pública
│   ├── nesting.py                  # Motor de geometria real de glifos + auto-download de Google Fonts
│   ├── grouper.py                  # Agrupador inteligente palavra-por-palavra (hold >= 0.38s, anti-pisca)
│   ├── renderer.py                 # Compilador HTML/CSS/GSAP e carregador dinâmico da pasta styles/
│   └── transcribe.py               # Transcrição palavra-por-palavra (CrisperWhisper / faster-whisper / whisper)
├── styles/                         # MÓDULOS DE ESTILO (1 arquivo .py ou .json = 1 estilo compartilhável!)
│   ├── _TEMPLATE_NOVO_ESTILO.py    # Template comentado para criar novos estilos
│   ├── bold_ciano.py               # Bold Social — Ciano (#3de0c8)
│   ├── bold_vermelho.py            # Bold Social — Vermelho (#ff3355)
│   ├── bold_roxo.py                # Bold Social — Roxo (#b855ff)
│   ├── bold_dourado.py             # Bold Social — Dourado (#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/                       # Exemplos prontos para testar (em português)
    ├── demo_words_pt.json          # Palavras com timestamps (português)
    └── demo_groups_pt.json         # Grupos lockup/plain (português)

2. Como Usar via Linha de Comando (cli.py)

# 1. Listar todos os estilos instalados em styles/
python cli.py --list-styles

# 2. Gerar um demo rápido de qualquer estilo
python cli.py --demo --style bold_roxo

# 3. Gerar a partir de um JSON de palavras com timestamps (word, start, end)
python cli.py --words examples/demo_words_pt.json --style bold_vermelho --out output/meu_teste

# 4. Trocar a cor de destaque na hora sem precisar editar o estilo
python cli.py --words examples/demo_words_pt.json --style bold_ciano --accent "#00ff88"

# 5. Transcrever um vídeo/áudio (.mp4/.wav/.mp3) e já gerar as legendas sincronizadas
python cli.py --media meu_video.mp4 --lang pt --style bold_dourado --video meu_video.mp4

3. Como Usar via Python (Embutindo em um Projeto HyperFrames)

Quando você estiver montando uma composição completa no HyperFrames (com A-roll, B-roll, Motions, SFX e Música), importe caption_kit e use 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` é uma lista [{"word": "Criar", "start": 0.15, "end": 0.42}, ...]
groups = build_groups_from_words(words, min_hold=0.38)

# 2. Gera CSS, DOM (com <span> internos para zero warnings no lint) e JS GSAP:
caps_css, caps_dom, caps_js, report = render_embeddable(
    groups,
    prefix="v1",                 # Prefixo único dos IDs (#v1-g0, #v1-g1...)
    style_name="bold_vermelho",  # Qualquer arquivo em styles/<nome>.py
    accent_override=None,        # Ou passe ex: "#ff3355" para trocar só a cor
    y_lockup=0.74,               # Faixa segura Reels (1300-1560px em 1080x1920)
    y_plain=0.75,
    track_index=3,
    z_index=95,
)

Depois basta injetar:

  • {caps_css} dentro da tag <style> da composição;
  • {caps_dom} dentro do <div id="root" ...>;
  • {caps_js} dentro do <script> logo após const tl = gsap.timeline({ paused: true });.

4. Como Criar um Novo Estilo Compartilhável (Sistema de Plugins em styles/)

O sistema de estilos foi desenhado para ser 100% plug-and-play:

  • Todo arquivo .py (ou .json) colocado na pasta styles/ (cujo nome não comece com _) é descoberto automaticamente por load_styles().
  • Para criar um novo estilo a pedido do usuário:
    1. Copie styles/_TEMPLATE_NOVO_ESTILO.py para styles/<nome_do_estilo>.py.
    2. Edite o dicionário STYLE = { ... }.
    3. Se usar uma fonte nova do Google Fonts (ex: "Bebas Neue", "Poppins", "Syne"), não precisa baixar manualmente: o motor caption_kit/nesting.py baixa os arquivos .woff2 do Google Fonts automaticamente na primeira execução e salva em fonts/<familia>/!
    4. Para o usuário compartilhar esse estilo com outra pessoa, basta enviar esse único arquivo styles/<nome_do_estilo>.py!

Anatomia do Dicionário STYLE

STYLE = {
    "id": "neon_cyber",
    "label": "Neon Cyber (Montserrat 900 + Glow Verde)",
    # Palavra principal (centro do lockup)
    "main_font": "Montserrat",
    "main_weight": 900,
    "main_style": "normal",
    "main_track": -0.05,
    "main_case": "none",           # IMPORTANTE: use "none" para preservar ascendentes/descendentes e permitir encaixe! Use "upper" apenas se "nest_mode": "overlap".
    "main_lh": 0.80,
    "main_css": "color:#ffffff;text-shadow:0 10px 34px rgba(0,0,0,.6);",
    "max_px": 280,
    # Palavras pequenas de apoio (acima e abaixo)
    "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 a 0.50 do tamanho da principal
    # Legenda corrida simples
    "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);",
    # Cor de destaque e brilho
    "accent": "#00ff88",
    "accent_extra_css": "text-shadow:0 0 24px rgba(0,255,136,0.55);",
    "shine": ("#ffffff", "rgba(0,255,136,.9)"),
    # Geometria e animações
    "tilt": (-2, 2),               # Inclinação (graus) da linha de cima e de baixo
    "clear": 0.03,                 # Folga mínima entre as tintas
    "variants": ("slam", "letters", "rise", "blur"),
}

5. Regras de Ouro de Qualidade (Aprendidas em Produção)

  1. Tempo de leitura (Hold Mínimo): O agrupador (caption_kit/grouper.py) garante no mínimo 0.38s com a frase completa na tela antes de trocar de bloco. Quando a fala é rápida, ele comprime o stagger de entrada das palavras para nunca cortar o final da frase.
  2. Ordem Cronológica: As linhas entram sempre na ordem real em que são faladas (above → main → below).
  3. Zona Segura do Instagram Reels / TikTok (1080x1920):
    • Padrão y_lockup=0.74 (~1420px), ficando na faixa segura 1300–1560px (abaixo do rosto e dos cards de motion, e acima dos botões inferiores do Reels).
  4. Sincronia de Áudio no HyperFrames:
    • Se o vídeo usar um áudio cortado em vários segmentos, nunca use múltiplas tags <audio> apontando para o mesmo arquivo com data-media-start (isso desloca o áudio no HyperFrames). Sempre pré-corte o áudio em um único arquivo .wav contínuo e use uma única tag <audio data-start="0.000">.

Habilidades Relacionadas