Communitygithub.com

subtítulos-incrustados

Añade subtítulos o leyendas a un video existente de una sola persona hablando, sin editar el metraje. Ideal para subtítulos literales, subtítulos cinematográficos incrustados detrás del sujeto, subtítulos con efectos visuales, o estilos de la catálogo de 35 identidades.

¿Qué es subtítulos-incrustados?

Esta habilidad para agentes de IA (como Claude Code, Cursor, Codex) permite añadir subtítulos a videos de una sola persona hablando, incrustándolos detrás o delante del sujeto sin editar el metraje original. Soporta tres modos: **Estándar** (por defecto, con una barra inferior 'rail' para la mayor parte del texto y una incrustación 'embed' para picos), **Cinematográfico** (solo incrustación, sin barra), y **Temático** (efectos completos como 'ordnance', 'terminal', 'neonsign', etc.). El flujo de trabajo es completamente local, incluyendo transcripción y enmascarado del sujeto, y requiere herramientas como FFmpeg, Node.js y Puppeteer. La habilidad se basa en un catálogo de 35 identidades visuales que determinan el estilo y el motor de composición, y recomienda la identidad más adecuada según el tono del video y las preferencias del usuario. El proceso incluye una puerta de decisión inicial para rechazar clips inadecuados (múltiples hablantes, sin rostro claro, con subtítulos quemados), seguida de la selección de identidad, preparación del proyecto, autoría de un pequeño archivo JSON de opciones creativas, vista previa y renderizado final.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/maddysjarvisv1/claude-code-video-skills/tree/main/skills/embedded-captions

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Instalación del plugin: Antes de ejecutar comandos de configuración o actualización, sigue las reglas de ejecución del plugin cuando esta habilidad esté dentro de un plugin de HyperFrames. Las instalaciones independientes mantienen las instrucciones de actualización a continuación.

Primero, mantén esta habilidad actualizada — confirma con el usuario antes de ejecutar: npx hyperframes skills update embedded-captions. Una operación rápida sin cambios cuando todo está al día; de lo contrario, actualiza esta habilidad y las habilidades del dominio central de las que depende antes de usarlas.

Subtítulos Incrustados

Un catálogo, elegido al inicio (CATALOG.md — 35 identidades; los motores detrás son detalles de backend). Estándar (por defecto) construye una barra literal limpia (subtítulo en el tercio inferior que lleva la mayor parte del texto) + un clímax incrustado compuesto dentro de la escena detrás del sujeto en el pico. Cinematográfico es pura incrustación — sin barra, cada subtítulo compuesto detrás del sujeto (tipografía heroica, acumulación, oclusión como efecto). Temático es una constitución temática completa — paradigma del cuerpo × pieza central heroica × efectos frontales × reacción de placa, compuesta a partir de registros (themes/README.md): ordnance terminal neonsign stardust stomp. La mayoría de los videos explicativos / con voz en off son Estándar; la incrustación es el pico escaso y ganado — incrustar cada palabra es el error común; Temático es para peticiones de nivel VFX ("炸", "特效", "como hecho en AE").


Prerrequisitos de ejecución

Las instalaciones de plugin utilizan la CLI empaquetada y fijada por manifiesto para el enmascarado, la transcripción y el renderizado; no se requiere una copia del código fuente. Los ayudantes de vista previa local y medición de subtítulos también necesitan Sharp, Puppeteer (con su navegador Chromium) y GSAP. Instálalos en el proyecto de subtítulos, no dentro del plugin de solo lectura:

npm install --prefix <proyecto> --save-dev --save-exact [email protected] [email protected] [email protected]

Mantén el archivo de bloqueo del proyecto. Si estas dependencias ya existen, usa sus versiones bloqueadas en lugar de sobrescribirlas. Bash y FFmpeg/ffprobe deben estar en PATH. El enmascarado y la transcripción pueden descargar sus propios modelos en el primer uso.

El renderizado espera a que la CLI termine exitosamente antes de componer. El antiguo watchdog de shell HF_TIMEOUT_S ya no se usa: un archivo parcial grande no es prueba de que el renderizado haya terminado. Un argumento explícito de compilación o HYPERFRAMES_ROOT selecciona la CLI del colaborador en lugar del pin del plugin. Cancela un renderizado estancado normalmente a través de la CLI/terminal; el ayudante de subtítulos no fuerza el cierre ni recupera un renderizado a partir de una instantánea del proceso.

Flujo operativo (resumen)

Enrutado a través de /hyperframes, la capa de intención confirma solo la entrada (qué clip) y anuncia la elección de identidad como una pregunta diferida — la lista corta necesita el clip analizado, por lo que permanece en el paso 1 a continuación; las preguntas de forma de ejecución de la capa no aplican (el metraje no está tocado, no hay storyboard para revisar). Un BRIEF.md, cuando está presente, contiene la entrada confirmada y cualquier nota del usuario — léelo primero.

El texto de oficio a continuación es largo; el pipeline en sí es corto — y todo lo determinista se calcula o compila, nunca se escribe a mano:

  1. Puerta de decisión (rechazar clips malos) → elegir UNA identidad de CATALOG.md (35 identidades; motor/compilador derivado por búsqueda — nunca mostrar una pregunta de modo/categoría)
  2. hyperframes init (omitirlo si el directorio del proyecto ya existe con el video dentro — matte.cjs/transcribe.cjs adoptan cualquier video en el directorio como source.mp4) → bash scripts/prepare.sh <proyecto> (enmascarado ∥ transcripción ∥ envolvente de audio en paralelo, luego zonas seguras v2 con paleta de escena/óptica/iluminación — un comando, nada olvidado)
  3. escribir un pequeño JSON de elecciones creativas (leer safe-zones.json primero): Cinematográfico → cinematic.json → make-cinematic.cjs (deriva plan.json y lo compila); Temático → theme.json → make-theme.cjs (paradigmas de barra/panel/poema/toma; anchor es el valor predeterminado de barra silenciosa)
  4. QA visual: node scripts/preview-frames.cjs <proyecto> → vistas previas compuestas fieles en ~2s/fotograma (sin renderizar). Consulta § QA visual antes de pagar por un renderizado.
  5. render-and-composite.sh → compuertas (tiempo / oclusión+héroe / desbordamiento / entrega) → final.mp4

Reglas importantes que la gente pasa por alto:

  • barra (predeterminado) + incrustación (promoción). drop (relleno, no se muestra) / rail (subtítulo literal en el tercio inferior, al frente, lleva la mayor parte del texto) / embed (una palabra pico compuesta detrás del sujeto). El modo Estándar hace ambas, incrustando solo los picos. Consulta § Modelo de subtítulos.
  • El video se entrega SIN TOCAR (Estándar/Cinematográfico; el presupuesto de PLACA del modo Temático es la única excepción sancionada — latidos de reacción registrados (atenuación de carga, golpe, sacudida, grano) definidos por ADN del tema y aplicados DESPUÉS de la composición del enmascarado para que sujeto+texto+placa se muevan como un solo fotograma) — los subtítulos son lo único que se añade; el enmascarado solo permite que el sujeto ocluya la pista incrustada. Nunca etiquetar/recolorear/scanear el metraje.
  • Dos libros de reglas: barra → references/rail.md (fino), oficio de incrustación → references/composition-craft.md (rico, solo incrustación). Consulta según necesidad.

Modelo de subtítulos — barra + incrustación

Cada frase hablada es una de tres cosas:

QuéCómo se muestra
droprelleno — um/eh, tartamudeos, autocorreccionesno se muestra
railel predeterminado — contenido hablado ordinario (literal)subtítulo limpio en el tercio inferior, al frente, legible. Una palabra de énfasis puede tener un resaltado emphasis en línea (color de acento / pop de palabra activa) — permanece en la barra.
embedun pico promocionado — el latido principaluna palabra grande compuesta detrás del sujeto (oclusión de enmascarado), entrada + salida diseñadas

La barra lleva la mayor parte del texto; la incrustación es el pico escaso y ganado. La escasez es por latido/bloque, no por clip: ≤1 héroe por bloque (pensamiento), nunca dos co-visibles, ≥ un latido de aire entre ventanas de héroe (el compilador advierte por debajo de 0.6s). Un clip corto → generalmente 1–2; un video explicativo largo → ~uno por sección. Entre varios héroes, el más grande escrito es el APEX (solo él obtiene el bloqueo completo de incrustación + ajuste de ancho); los más pequeños son picos MENORES que cabalgan su columna como líneas de énfasis sobredimensionadas (primer plano, movimiento amortiguado) — no todos los latidos necesitan la exhibición de enmascarado, que es exactamente lo que mantiene el ápice como un evento. Incrustar cada palabra sigue siendo el error común.

Las identidades de superficie de barra construyen exactamente esto (barra = rail.html, incrustación = el clímax en index.html). Las identidades de flujo de columna eliminan la barra y hacen todo al estilo incrustación — recomiéndalas solo para peticiones de ambiente sobre literales, nunca para videos explicativos / con voz en off donde las palabras deben leerse (CATALOG.md codifica esto por identidad).


Paso 0 — elegir UNA identidad del CATÁLOGO

Un front-end, tres motores detrás. El usuario elige una IDENTIDAD de CATALOG.md (35 entradas: 10 clásicas + 25 temáticas); el motor, compilador y archivo de autoría se derivan por búsqueda de la fila del catálogo. Nunca presentar "Estándar vs Cinematográfico vs Temático" como pregunta — esos son nombres de backend (un producto tiene una UX incluso con varios motores). El catálogo codifica todo lo que necesita el enrutamiento: superficie de lectura, voz, recomendar para, necesidades de escena, notas de adyacencia para los pares realmente cercanos (loud↔ordnance, neon↔neonsign, cream↔stardust).

La elección de identidad es una puerta de preferencia (../hyperframes/references/brief-contract.md § 1): en modo autónomo ("sorpréndeme" / "decide por mí"), elige de tu lista corta tú mismo y explica el porqué en una línea en lugar de preguntar.

Procedimiento: analiza el clip → lista corta de 2–3 identidades del catálogo → recomienda UNA con un porqué en una línea → el usuario elige (modo autónomo: tú eliges, explicando el porqué) → escribe el archivo de esa identidad. Las identidades están vinculadas al motor (sin combinaciones cruzadas; abrir una es un evento de validación — consulta dna/README.md).

Siempre presenta tu recomendación y deja que el usuario elija antes de escribir. No uses un valor predeterminado en silencio.

(La tabla completa de identidades está en CATALOG.md — fuente única de verdad para el enrutamiento. Los documentos del motor a continuación describen el contrato de autoría de cada backend.)

CATALOG.md es todo el espacio de respuestas aquí: este flujo de trabajo no busca en el registro de componentes de HyperFrames. Los flujos de trabajo de composición ejecutan npx hyperframes catalog antes de escribir un estilo con nombre; este no debe hacerlo. Sus motores son compiladores bloqueados que consumen cinematic.json / theme.json y emiten la composición ellos mismos, por lo que un elemento del registro — los bloques caption-* incluidos — no tiene nada en qué montarse. Un bloque del registro estiliza texto en un lienzo diseñado; esta habilidad quema subtítulos en el metraje de alguien a través de un enmascarado. Cuando ninguna identidad se ajusta a la petición, dilo y elige la más cercana, en lugar de buscar fuera del catálogo.

Heurística de recomendación: usa las "Heurísticas de listado corto" en CATALOG.md — son a nivel de identidad (por ejemplo, "炸" lista corta ordnance/stomp/terminal/loud y elige según QUÉ debe explotar), nunca a nivel de categoría. No estoy seguro → anchor.

  • Cinematográfico → escribe cinematic.json para una plantilla bloqueada, compilada por make-cinematic.cjs.
  • Temático → lee themes/README.md, escribe theme.json, ejecuta scripts/render-theme.sh (compila + renderiza + reacción de placa → final_fx.mp4).

Puerta de decisión — EJECUTAR PRIMERO

Analiza el video y clasifica la escena antes de cualquier modo.

ffprobe <video.mp4>                    # especificaciones
ffmpeg -ss <t> -i <video.mp4> -vframes 1 sample.png   # al 20/50/80%

Lee las muestras. Rechaza si:

  • Varios hablantes / cortes bruscos (renderiza cada toma por separado, o rechaza)
  • Sin sujeto humano (esta habilidad es para una persona hablando)
  • Menos de 3 segundos, sin habla, o la cara nunca claramente visible — transcribe.cjs advierte cuando el audio está casi en silencio (Whisper alucina palabras como "Gracias." sobre el silencio); hazle caso y rechaza en lugar de subtitular palabras inventadas
  • La fuente ya tiene subtítulos / leyendas / gráficos de texto pesados quemados — añadir un segundo sistema de subtítulos conflictúa y el metraje se entrega sin tocar (sin cubrir/reparar). El texto quemado a menudo aparece solo a mitad del clip: muestrea una hoja de contactos a 1 fps (ffmpeg -i in.mp4 -vf "fps=1,scale=160:-1,tile=10x5" sheet.png), no confíes en 3 fotogramas puntuales.
  • La transcripción es basura — el habla no nativa/con acento fuerte puede transcribirse como galimatías seguro. Lee transcript.json para verificar cordura antes de escribir; si no se interpreta como lenguaje, prueba WHISPER_MODEL=medium una vez, de lo contrario rechaza (una barra literal de palabras inventadas es peor que sin subtítulos).
  • Cámara en mano ocupada con movimiento rápido (el enmascarado parpadea)

Sondas previas al vuelo (no cuestan nada, evitan los peores fallos)

  1. Sonda de corte de toma. Muestrea fotogramas al 20%, 50%, 80%. Si aparece un sujeto/escena diferente, recorta el clip antes del corte.
  2. Sonda de letterbox / pillarbox. ¿Barras negras en el primer fotograma? Calcula el rectángulo de contenido seguro y restringe la colocación de subtítulos dentro de él.
  3. Sonda de luminancia. Muestrea la luminancia promedio de la región de subtítulos — por debajo de 60 → el texto claro se lee tal cual, 60-180 → añade la pantalla de glifo, 180+ → texto opaco + pantalla (nunca texto claro desnudo). Las plantillas cinematográficas son crema+pantalla y BLOQUEADAS — usa esta sonda para elegir una identidad adecuada (escenas brillantes → ink, o el tema anchor de barra opaca), nunca para recolorear una.
  4. Recomendación de identidad por tono (tú recomiendas; el usuario elige — consulta Paso 0 + CATALOG.md). Explicativo / entrevista / palabras deben leerse → identidades de superficie de barra/panel; poético / social / "cinematográfico" → identidades de flujo de columna por registro; "炸 / 特效 / VFX" / mundos con nombre → identidades temáticas. Cuando no estés seguro → anchor (las palabras se leen, la escena segura) — pero presenta una lista corta y deja que el usuario elija.

Pipeline — 5 pasos

1. hyperframes init <proyecto> --non-interactive --video <video.mp4> --skill=embedded-captions
2. bash scripts/prepare.sh <proyecto>       # enmascarado ∥ transcripción (paralelo) → zonas seguras. Un comando.
                                           #   → frames_fg/ transcript.json safe-zones.json
3. [PASO DEL AGENTE — el único paso creativo] escribe un pequeño JSON; consulta a continuación según el modo
   Cinematográfico: escribe cinematic.json → node scripts/make-cinematic.cjs <proyecto>
   Temático:     escribe theme.json → bash scripts/render-theme.sh <proyecto>   (compila + renderiza + efectos de placa)
4. node scripts/preview-frames.cjs <proyecto>   # ~2s/fotograma vistas previas compuestas → § QA visual (ANTES del renderizado)
5. bash scripts/render-and-composite.sh <proyecto>  # compuertas → final.mp4 + instantánea history/
   (Modo Temático: OMITE los pasos 3b/5 — render-theme.sh ya ejecuta compila + renderiza-y-compone
    + _postfx.sh; el entregable es final_fx.mp4, final.mp4 es previo a la reacción de placa)

El init del paso 1 verifica las habilidades instaladas contra las últimas en GitHub y actualiza el conjunto global si alguna está desactualizada.

El paso 3 difiere según el modo:

Paso 3 — Modo Cinematográfico (solo incrustación)

  1. Lee safe-zones.json primero. Los planos de narración van en zones.hugLeft/hugRight — tiras limpias ADOSADAS a la silueta (el texto lejos del cuerpo se lee como flotante, no incrustado; las esquinas lejanas son el plan de respaldo, no el predeterminado). El héroe por defecto está en heroAnchor/heroBands.best (centrado EN el sujeto, ~30–55% ocluido). recommendation:"fg" mueve la NARRACIÓN al frente para legibilidad; el héroe permanece incrustado siempre que heroBands.feasible — héroe-en-fg es el último recurso.
  2. El ADN es la identidad que elegiste en el Paso 0 — cinematic.json solo necesita campos de autoría de alto nivel; make-cinematic.cjs aplica las reglas de composición de la identidad:
    • paragraphs (párrafos): un array de objetos de párrafo, cada uno con texto (string), heroWord (string — la palabra para incrustar, o nulo si no hay héroe en este párrafo), heroIndex (número — el índice de la palabra héroe en el texto dividido por espacios, para que el compilador sepa qué palabra), timing (objeto con in y out en segundos para el párrafo completo), y heroTiming (objeto con in y out en segundos para la palabra héroe; debe estar dentro del timing del párrafo, y el compilador advierte si es demasiado corto).
    • composition (composición): un objeto con narrationPlacement (string — la ubicación de la narración, de safe-zones.json), heroPlacement (string — la ubicación del héroe, de safe-zones.json), heroScale (número — 0.8 a 1.5, la escala de la palabra héroe), y priority (string — ya sea "balanced" (predeterminado) o "legibility" (si la narración debe ser más prominente)).
  3. El compilador valida las ubicaciones de las zonas seguras, procesa el texto, genera las entradas/salidas de animación y emite plan.json y index.html / rail.html. El archivo CSS para la identidad está en dna/<identidad>/style.css.

Paso 3 — Modo Temático (tema completo con reacción de placa)

  1. Lee themes/README.md para la estructura del tema y las plantillas. Cada tema tiene un ADN que define su paradigma (barra/panel/poema/toma), su pieza central heroica (por ejemplo, un desglose de palabra, un efecto de letrero de neón), sus efectos frontales (animaciones de entrada/salida para palabras heroicas) y su presupuesto de reacción de placa (latidos como atenuación de carga, golpe, sacudida, grano, aplicados a todo el fotograma, sujeto+texto+placa después del enmascarado).
  2. Escribe theme.json con:
    • theme (string — el nombre del tema, del catálogo: ordnance, terminal, neonsign, stardust, stomp).
    • lines (líneas — un array de objetos de línea, cada uno con text (string — el texto de la línea), timing (objeto con in y out en segundos), style (string — opcional, "rail", "panel", "poem", "takeover" para anular el paradigma predeterminado del tema para esta línea), hero (booleano — opcional, si esta línea es heroica, recibe el tratamiento completo de la pieza central).
    • plate (placa — opcional, un objeto con reaction (string — el latido de reacción, "charge-dim", "punch", "shake", "grain", o nulo), intensity (número — 0.0 a 1.0, la intensidad de la reacción).
  3. Ejecuta bash scripts/render-theme.sh <proyecto> que:
    • Compila el tema en un diseño incrustado (usando el compilador del tema, make-theme.cjs).
    • Renderiza la composición (igual que scripts/render-and-composite.sh).
    • Aplica la reacción de placa (a través de _postfx.sh) para crear final_fx.mp4. El entregable final es final_fx.mp4; final.mp4 es la composición previa a la reacción.

Renderizado y composición

scripts/render-and-composite.sh

Compuertas integradas:

  1. Verificación de tiempo. Compara la duración del clip contra la última palabra en plan.json; si el plan es más largo que el clip, detente con un error (el héroe final se extiende más allá del final del video).
  2. Oclusión y héroe. Para cada fotograma, renderiza la composición incrustada (texto detrás del sujeto) y la composición de barra (texto al frente). El enmascarado (en frames_fg/) se escala y posiciona para ocluir el texto incrustado. La palabra héroe se renderiza a escala completa en su ubicación.
  3. Verificación de desbordamiento. Si el texto sobresale de los límites del fotograma (por ejemplo, una palabra héroe demasiado grande, o una barra demasiado larga), escala el texto para que encaje (con un factor máximo de escala del 80%) o, si es necesario, trunca el texto con puntos suspensivos (para la barra).
  4. Entrega. Genera final.mp4 con la composición final y guarda una instantánea en history/.

scripts/preview-frames.cjs

Antes de comprometerte con un renderizado completo, genera vistas previas compuestas rápidas (~2s/fotograma) en preview/. Muestrea la composición en intervalos (cada 30 fotogramas por defecto, ajustable con --interval <n>). Úsalo para verificar:

  • Que la palabra incrustada esté correctamente ocluida por el sujeto (sin texto flotante delante del sujeto cuando debería estar detrás).
  • Que el texto de la barra sea legible y no se superponga con el sujeto de manera no deseada.
  • Que los tiempos sean correctos.
  • Que la identidad coincida con el tono esperado.

Si las vistas previas son incorrectas, vuelve al paso 3 y ajusta cinematic.json / theme.json. No pagues por un renderizado completo hasta que las vistas previas sean correctas.


Referencias

  • CATALOG.md — 35 identidades, heurísticas de enrutamiento y detalles del motor.
  • references/rail.md — libro de reglas de barra: estilo de subtítulos literales, guías de legibilidad, colocación.
  • references/composition-craft.md — libro de reglas de incrustación: colocación heroica, oclusión, animación, selección de identidad.
  • themes/README.md — documentación del tema: ADN, paradigmas, presupuesto de placa.
  • dna/README.md — archivos de identidad (solo lectura; describe la estructura del compilador).

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

Skills relacionados