SKILL: Subtitles Studio — Biblioteca Modular de Leyendas Dinámicas (subtitles_studio)
1. Visión General para la IA
Repositorio oficial: https://github.com/NicolasCoder/subtitles_studio.git
Esta carpeta es una caja de herramientas 100% independiente y compartible para generar leyendas dinámicas estilo Lockup (una palabra principal gigante en el centro con palabras menores encajadas en los espacios reales de las ascendentes/descendentes de la fuente) para HyperFrames (1080x1920 @ 30fps).
Arquitectura de la Carpeta
subtitles_studio/
├── SKILL.md # Esta guía completa para agentes de IA
├── README.md # Guía rápida para humanos
├── requirements.txt # fonttools, brotli, Pillow, numpy
├── cli.py # Interfaz de línea de comandos lista para usar
├── fonts/ # Fuentes .woff2 locales preempaquetadas (+ descarga automática de Google Fonts)
├── caption_kit/ # Paquete Python importable
│ ├── __init__.py # API pública
│ ├── nesting.py # Motor de geometría real de glifos + descarga automática de Google Fonts
│ ├── grouper.py # Agrupador inteligente palabra por palabra (hold >= 0.38s, antíparpadeo)
│ ├── renderer.py # Compilador HTML/CSS/GSAP y cargador dinámico de la carpeta styles/
│ └── transcribe.py # Transcripción palabra por palabra (CrisperWhisper / faster-whisper / whisper)
├── styles/ # MÓDULOS DE ESTILO (1 archivo .py o .json = 1 estilo compartible)
│ ├── _TEMPLATE_NOVO_ESTILO.py # Plantilla comentada para crear nuevos estilos
│ ├── bold_ciano.py # Bold Social — Ciano (#3de0c8)
│ ├── bold_vermelho.py # Bold Social — Rojo (#ff3355)
│ ├── bold_roxo.py # Bold Social — Púrpura (#b855ff)
│ ├── bold_dourado.py # Bold Social — Dorado (#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/ # Ejemplos listos para probar (en portugués)
├── demo_words_pt.json # Palabras con marcas de tiempo (portugués)
└── demo_groups_pt.json # Grupos lockup/plain (portugués)
2. Cómo Usar a Través de la Línea de Comandos (cli.py)
# 1. Listar todos los estilos instalados en styles/
python cli.py --list-styles
# 2. Generar una demo rápida de cualquier estilo
python cli.py --demo --style bold_roxo
# 3. Generar a partir de un JSON de palabras con marcas de tiempo (word, start, end)
python cli.py --words examples/demo_words_pt.json --style bold_vermelho --out output/mi_prueba
# 4. Cambiar el color de acento sobre la marcha sin necesidad de editar el estilo
python cli.py --words examples/demo_words_pt.json --style bold_ciano --accent "#00ff88"
# 5. Transcribir un video/audio (.mp4/.wav/.mp3) y generar las leyendas sincronizadas
python cli.py --media mi_video.mp4 --lang pt --style bold_dourado --video mi_video.mp4
3. Cómo Usar a Través de Python (Insertando en un Proyecto HyperFrames)
Cuando estés montando una composición completa en HyperFrames (con A-roll, B-roll, motions, efectos de sonido y música), importa caption_kit y usa render_embeddable():
import sys
sys.path.insert(0, "ruta/hacia/leyendas_dinamicas_kit")
from caption_kit import build_groups_from_words, render_embeddable
# 1. `words` es una lista [{"word": "Crear", "start": 0.15, "end": 0.42}, ...]
groups = build_groups_from_words(words, min_hold=0.38)
# 2. Genera CSS, DOM (con <span> internos para cero advertencias de lint) y JS GSAP:
caps_css, caps_dom, caps_js, report = render_embeddable(
groups,
prefix="v1", # Prefijo único de los IDs (#v1-g0, #v1-g1...)
style_name="bold_vermelho", # Cualquier archivo en styles/<nombre>.py
accent_override=None, # O pasa ej: "#ff3355" para cambiar solo el color
y_lockup=0.74, # Rango seguro Reels (1300-1560px en 1080x1920)
y_plain=0.75,
track_index=3,
z_index=95,
)
Después solo hay que inyectar:
{caps_css}dentro de la etiqueta<style>de la composición;{caps_dom}dentro de<div id="root" ...>;{caps_js}dentro de<script>justo después deconst tl = gsap.timeline({ paused: true });.
4. Cómo Crear un Nuevo Estilo Compartible (Sistema de Plugins en styles/)
El sistema de estilos está diseñado para ser 100% plug-and-play:
- Todo archivo
.py(o.json) colocado en la carpetastyles/(cuyo nombre no comience con_) es descubierto automáticamente porload_styles(). - Para crear un nuevo estilo a petición del usuario:
- Copia
styles/_TEMPLATE_NOVO_ESTILO.pyastyles/<nombre_del_estilo>.py. - Edita el diccionario
STYLE = { ... }. - Si usas una fuente nueva de Google Fonts (ej:
"Bebas Neue","Poppins","Syne"), no necesitas descargarla manualmente: el motorcaption_kit/nesting.pydescarga los archivos.woff2de Google Fonts automáticamente en la primera ejecución y los guarda enfonts/<familia>/. - Para que el usuario comparta este estilo con otra persona, ¡basta con enviar ese único archivo
styles/<nombre_del_estilo>.py!
- Copia
Anatomía del Diccionario STYLE
STYLE = {
"id": "neon_cyber",
"label": "Neon Cyber (Montserrat 900 + Brillo Verde)",
# Palabra principal (centro del lockup)
"main_font": "Montserrat",
"main_weight": 900,
"main_style": "normal",
"main_track": -0.05,
"main_case": "none", # IMPORTANTE: usa "none" para preservar ascendentes/descendentes y permitir encaje. Usa "upper" solo 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,
# Palabras pequeñas de apoyo (arriba y abajo)
"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 del tamaño de la principal
# Leyenda corrida simple
"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);",
# Color de acento y brillo
"accent": "#00ff88",
"accent_extra_css": "text-shadow:0 0 24px rgba(0,255,136,0.55);",
"shine": ("#ffffff", "rgba(0,255,136,.9)"),
# Geometría y animaciones
"tilt": (-2, 2), # Inclinación (grados) de la línea superior e inferior
"clear": 0.03, # Margen mínimo entre tintas
"variants": ("slam", "letters", "rise", "blur"),
}
5. Reglas de Oro de Calidad (Aprendidas en Producción)
- Tiempo de lectura (Hold Mínimo): El agrupador (
caption_kit/grouper.py) garantiza al menos0.38scon la frase completa en pantalla antes de cambiar de bloque. Cuando el habla es rápida, comprime el stagger de entrada de las palabras para nunca cortar el final de la frase. - Orden Cronológico: Las líneas entran siempre en el orden real en que se hablan (
above→main→below). - Zona Segura de Instagram Reels / TikTok (
1080x1920):- Por defecto
y_lockup=0.74(~1420px), quedando en el rango seguro1300–1560px(debajo del rostro y de las tarjetas de motion, y encima de los botones inferiores de Reels).
- Por defecto
- Sincronía de Audio en HyperFrames:
- Si el video usa un audio cortado en varios segmentos, nunca uses múltiples etiquetas
<audio>apuntando al mismo archivo condata-media-start(esto desplaza el audio en HyperFrames). Siempre precorta el audio en un único archivo.wavcontinuo y usa una sola etiqueta<audio data-start="0.000">.
- Si el video usa un audio cortado en varios segmentos, nunca uses múltiples etiquetas