Extensión OpenCaptions
Integra subtítulos CWI (Caption With Intent) en el pipeline de postproducción de Content Engine. En lugar de subtítulos planos y estáticos, CWI codifica la experiencia sentida del habla: el tono impulsa el peso de la fuente, el volumen impulsa el tamaño de la fuente, el énfasis activa animaciones de brillo y la identidad del hablante se asigna a colores WCAG AA. El resultado son subtítulos que comunican cómo se dijo algo, no solo qué se dijo.
CWI es el estándar de subtitulado ganador del Oscar (2025) de FCB Chicago y Chicago Hearing Society. OpenCaptions es la primera cadena de herramientas programática de código abierto para ello.
Punto de Inserción en el Pipeline
Etapa: Postproducción (Etapa 3) Posición: Después del upscale y la gradación de color, antes de la exportación final.
Cadena de Postproducción:
1. Upscale (Real-ESRGAN / Topaz) --> Resolución más alta
2. Gradación de Color (LUT de marca / ffmpeg) --> Color de marca
3. OpenCaptions (CWI) --> Subtítulos basados en intención
4. Exportación Final (ffmpeg) --> Archivo listo para producción
La extensión recibe un archivo de vídeo gradado y produce:
- Un documento CWI (
.cwi.json) con anotaciones de intención a nivel de palabra - Un WebVTT de respaldo (
.vtt) para plataformas que necesitan subtítulos estándar - Un informe de validación (JSON) con puntuaciones de los pilares
- Un vídeo subtitulado (
.mp4) renderizado mediante Remotion o grabado con ffmpeg
Cómo Funciona
Vídeo Gradado + Resumen de Escena
|
├── [1] Transcripción (faster-whisper) --> marcas de tiempo a nivel de palabra
├── [2] Diarización (pyannote-audio) --> atribución del hablante
├── [3] Extracción de Intención --> tono, volumen, emoción, énfasis por enunciado
| V1: parselmouth + FER (audio+vision)
| V2: modelo mundial V-JEPA2
| V3: predicción neuronal TRIBE v2
├── [4] Mapa de Intención --> CWI --> peso, tamaño, énfasis, animación por palabra
| V1: RulesMapper (tono-->peso, volumen-->tamaño)
| V2: LearnedMapper (entrenado con datos de corrección)
| V3: NeuralMapper (las activaciones de regiones cerebrales impulsan el estilo)
├── [5] Validación (12 reglas) --> Puntuaciones de Atribución, Sincronización y Entonación
└── [6] Renderizado --> Superposición Remotion O grabación ffmpeg
Paso 1-2: Transcripción + Diarización
El pipeline llama a la CLI de OpenCaptions o al servidor MCP, que ejecuta faster-whisper para marcas de tiempo a nivel de palabra y pyannote-audio para la detección de hablantes. Estas etapas producen un DiarizedTranscript con cada palabra etiquetada con un hablante.
Paso 3: Extracción de Intención
El extractor de intención analiza el audio y el vídeo para determinar el registro sentido de cada enunciado:
- Señales vocales: Tono (Hz), volumen (dB), velocidad del habla (PPM), tiempo de pausa
- Señales afectivas: Valencia (-1 a 1), activación (0 a 1), emoción dominante
- Señales semánticas: Probabilidad de sarcasmo, palabras de énfasis, recursos retóricos
Estas señales forman un IntentFrame para cada enunciado. Las palabras individuales que se desvían de la línea base del enunciado reciben anulaciones de WordIntent.
Paso 4: Mapeo de Intenciones
El mapeador convierte las señales de intención en parámetros visuales CWI:
| Señal de Intención | Propiedad CWI | Mapeo (V1 RulesMapper) |
|---|---|---|
| Tono (normalizado 0-1) | weight (100-900) | Interpolación lineal: 100 + pitch_norm * 800 |
| Volumen (normalizado 0-1) | size (0.7-1.5) | Interpolación lineal: 0.8 + volume_norm * 0.55 |
| Énfasis semántico + volumen alto | emphasis (booleano) | Palabra en emphasis_words O volumen > p90 |
| Identidad del hablante | color del hablante | Asignado desde paleta de 12 colores WCAG AA |
| Susurro (volumen bajo) | weight < 300 | Anulación: peso limitado a 100-250 |
| Grito (volumen alto) | size > 1.3 + emphasis | Anulación: tamaño 1.35-1.5, énfasis verdadero |
Paso 5: Validación
El validador @opencaptions/spec comprueba el documento CWI contra 12 reglas en tres pilares:
Atribución (3 reglas):
- ATT_001: Cada subtítulo tiene un hablante en el reparto
- ATT_002: Los hablantes tienen colores únicos
- ATT_003: Los colores cumplen con el contraste WCAG AA (4.5:1 contra #1a1a1a)
Sincronización (5 reglas):
- SYN_001: Todas las palabras tienen marcas de tiempo
- SYN_002: Las marcas de tiempo aumentan monótonamente
- SYN_003: Los eventos de subtítulos no se superponen
- SYN_004: Duración de la animación 600 ms según especificación
- FCC_001: Sin espacios > 3s durante el habla
- FCC_002: Máximo 42 caracteres por línea (cumplimiento FCC)
Entonación (3 reglas):
- INT_001: Peso en rango válido (100-900)
- INT_002: Tamaño en rango válido (0.7-1.5)
- INT_003: > 20% de las palabras tienen peso no predeterminado (los subtítulos varían realmente)
Cada pilar puntúa 0-100. Un documento CWI pasa si los tres pilares obtienen una puntuación >= 80.
Paso 6: Renderizado
Dos rutas de renderizado:
Ruta Remotion (preferida para Content Engine): Las palabras CWI se convierten en componentes React dentro de una composición <CaptionOverlay>. Cada palabra aparece en su marca de tiempo con animación de entrada spring(), color del hablante, peso de fuente variable y brillo de énfasis. Consulte references/cwi-remotion-bridge.md para conocer el mapeo completo.
Grabación ffmpeg (respaldo): Genere un archivo de subtítulos ASS a partir del documento CWI y grábelo en el vídeo mediante ffmpeg -vf ass=captions.ass. Pierde la animación por palabra pero conserva los colores del hablante y la variación del peso de la fuente.
Uso de la CLI
# Generar subtítulos CWI a partir de un vídeo
npx opencaptions generate video.mp4 --output captions.cwi.json
# Generar con el backend neuronal TRIBE v2
npx opencaptions generate video.mp4 --backend tribe --output captions.cwi.json
# Validar un documento CWI
npx opencaptions validate captions.cwi.json
# Vista previa de subtítulos en la terminal (colores ANSI)
npx opencaptions preview captions.cwi.json
# Exportar a WebVTT
npx opencaptions export captions.cwi.json --format webvtt
# Exportar a After Effects ExtendScript
npx opencaptions export captions.cwi.json --format ae-json
# Exportar a XML de Premiere Pro
npx opencaptions export captions.cwi.json --format premiere-xml
# Verificar dependencias del sistema
npx opencaptions doctor
# Instalar dependencias de Python
npx opencaptions setup
Uso del Servidor MCP
El servidor MCP de OpenCaptions expone cuatro herramientas para la integración con agentes:
| Herramienta | Descripción |
|---|---|
generate_captions | Ejecutar el pipeline completo en un archivo de vídeo |
validate_captions | Validar un documento CWI contra 12 reglas |
preview_captions | Vista previa formateada en terminal en un momento dado |
export_captions | Exportar a formato WebVTT |
Para usar a través de Claude Code, agregue el servidor MCP a su configuración:
{
"mcpServers": {
"opencaptions": {
"command": "npx",
"args": ["@opencaptions/mcp"]
}
}
}
Luego invoque en la conversación: "Generar subtítulos CWI para video.mp4" activa generate_captions.
Integración con compose-video.py
El compose-video.py de Content Engine acepta un indicador --captions:
python3 scripts/compose-video.py storyboard.md --brand arcan-studio --captions
Cuando se pasa --captions, después de que se generan y unen todos los clips, el pipeline:
- Ejecuta
npx opencaptions generate {final-video}.mp4 --output {output-dir}/captions.cwi.json - Valida el documento CWI (advierte si la puntuación < 80 pero no bloquea)
- Si también se pasa
--remotion, inyecta el JSON de CWI en la composición de Remotion como propiedades de<CaptionOverlay> - De lo contrario, genera WebVTT como un archivo complementario junto al vídeo final
Si OpenCaptions no está instalado (npx opencaptions doctor falla), el pipeline se degrada correctamente:
- Vuelve a la superposición de texto del resumen de escena (texto estático de las descripciones del storyboard
## Shot) - Registra una advertencia: "OpenCaptions no disponible, usando superposición de texto de resumen de escena"
- Aún produce un archivo
.vttcon tiempos derivados de los límites del clip
Estilos de Subtítulos
Tres estilos de subtítulos predefinidos, seleccionables mediante configuración:
1. Palabra por Palabra (brainrot)
Estilo de alta retención: cada palabra aparece individualmente, centrada, con variación máxima de tamaño. Utilizado para contenido social/TikTok/Reels optimizado para ganchos de dopamina.
- Una palabra visible a la vez
- Tamaño base grande (64px a 1080p)
- Variación de peso extrema (rango completo 100-900)
- Las palabras de énfasis se escalan a 1.5x con brillo
- Fondo: ninguno (las palabras flotan sobre el vídeo)
- Fuente: Roboto Flex variable
2. Narrativo (editorial)
Visualización de oración completa con estilo por palabra. Utilizado para contenido de formato largo, documentales, inserciones de vídeo de blog.
- Evento de subtítulo completo visible, palabras con estilo en línea
- Tamaño base medio (48px a 1080p)
- Variación de peso moderada (300-700)
- Las palabras de énfasis obtienen un aumento de tamaño sutil (1.15x)
- Fondo: píldora semitransparente (rgba(0,0,0,0.6))
- Fuente: Roboto Flex variable
3. Mínimo (tercio inferior)
Presentación limpia en el tercio inferior. Nombre del hablante + texto. Distracción visual mínima. Utilizado para entrevistas, cabezas parlantes, grabaciones de conferencias.
- Etiqueta del nombre del hablante en el color del hablante, texto del subtítulo en blanco
- Tamaño base pequeño (36px a 1080p)
- Variación de peso solo para énfasis (400 por defecto, 700 énfasis)
- Sin variación de tamaño
- Fondo: barra degradada (15% inferior del fotograma)
- Fuente: sans-serif del sistema
Contrato de Datos
Lecturas (inmutables)
- Activo de vídeo gradado del paso de postproducción anterior
knowledge/compiled/brands/{brand_slug}.md-- para la paleta de colores de los subtítulos y las preferencias tipográficas- Resumen de escena (parámetro de tiempo de ejecución) -- para contexto sobre el tono emocional previsto
Escrituras (solo espacio de nombres propio)
extensions/opencaptions/output/{asset_id}.cwi.json-- Documento CWIextensions/opencaptions/output/{asset_id}.vtt-- WebVTT de respaldoextensions/opencaptions/output/{asset_id}-report.json-- Informe de validaciónextensions/opencaptions/output/{asset_id}-captioned.mp4-- Vídeo renderizado (solo ruta Remotion)
Configuración
opencaptions:
# Estilo de subtítulos predefinido
style: "narrative" # word-by-word | narrative | minimal
# Parámetros visuales
font_family: "Roboto Flex" # Fuente variable para el eje de peso
base_font_size: 48 # Píxeles a 1080p
position: "bottom" # top | center | bottom
max_chars_per_line: 42 # Cumplimiento FCC
background: "pill" # pill | shadow | gradient | none
background_opacity: 0.6 # 0.0 - 1.0
# Backend del pipeline
backend: "av" # av (V1) | jepa (V2) | tribe (V3)
language: "en" # Indicación ISO 639-1 para la transcripción
# Anulaciones de hablante (opcional, detectado automáticamente por defecto)
speakers:
- name: "Narrador"
color: "#6B8AFF"
- name: "Invitado"
color: "#FF6B6B"
# Renderizado
render_mode: "remotion" # remotion | ffmpeg | sidecar-only
output_format: "mp4" # mp4 | webm
fps: 30 # Coincidir con el vídeo de origen
# Validación
min_score: 80 # Puntuación mínima general para continuar
fail_on_low_score: false # Si es verdadero, bloquea el pipeline en caso de puntuación baja
# Mapeo neuronal TRIBE v2 (solo backend V3)
neural_mapping: false # Habilitar estilo de respuesta neuronal predicho
Degradación Correcta
La extensión nunca bloquea el pipeline de Content Engine. Escalera de degradación:
| Condición | Comportamiento |
|---|---|
| CLI de OpenCaptions instalada + todas las dependencias de Python | Pipeline CWI completo (transcripción, diarización, intención, mapeo) |
| CLI de OpenCaptions instalada, sin dependencias de Python | Backends simulados con subtítulos de marcador de posición + validación |
| CLI de OpenCaptions no instalada | Superposición de texto de resumen de escena como subtítulos estáticos en los límites del clip |
| El vídeo no tiene pista de audio | Omitir generación de subtítulos, registrar mensaje informativo |
| Puntuación de validación < 80 | Advertir pero continuar (a menos que fail_on_low_score: true) |
| Remotion no disponible | Recurrir a grabación ASS de ffmpeg |
| ffmpeg no disponible | Generar solo JSON CWI + WebVTT como archivos complementarios (sin vídeo renderizado) |
Relacionados
- Proyecto OpenCaptions:
~/broomva/apps/opencaptions/ - Puente CWI-Remotion:
references/cwi-remotion-bridge.md - Guía de integración:
references/integration-guide.md - SKILL.md de Content Engine:
../../SKILL.md - Marco de extensiones:
../README.md