Communitygithub.com

rizomaai/video-narrado

Convierte un Markdown (informe, minuta, fichas, análisis) en productos audiovisuales: primero un video detallado 16:9 narrado con la voz seleccionada, con subtítulos y música de fondo; después versiones cortas 9:16 para Reels, YouTube Shorts y TikTok, con sus textos de publicación.

¿Qué es video-narrado?

Esta skill transforma documentos Markdown en videos narrados profesionales, ideales para comunicación institucional, divulgación de informes o creación de contenido para redes sociales. Convierte un `.md` en un video detallado 16:9 de 2 a 4 minutos que recorre todo el contenido, y luego genera dos o tres versiones cortas 9:16 (menos de 60 segundos) para plataformas como Reels, YouTube Shorts y TikTok. Cada pieza incluye voz seleccionada (por defecto una voz clonada de HeyGen en español chileno neutro), subtítulos automáticos, música de fondo sintetizada sin derechos, y un archivo `publicacion.md` con título, descripción, hashtags y texto alternativo. El flujo de trabajo es colaborativo: primero se proponen los storyboards, se espera aprobación, luego se genera la voz, se renderiza el video con Playwright y ffmpeg, y finalmente se entregan los MP4 listos para publicar. Es útil cuando alguien pasa un `.md` y pide "hazme un video", "video narrado", "ponle mi voz" o "shorts/reels de esto".

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add rizomaai/video-narrado

Preguntar en tu IA favorita

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

Documentación

¿Qué hace video-narrado?

Entrada: un .md. Salida, en este orden:

  1. Video detallado 16:9 (2 a 4 min) que recorre el MD completo.
  2. Versiones cortas 9:16 (2 o 3, menos de 60 s): cada una toma un hallazgo del video detallado.
  3. Un publicacion.md por pieza (título, descripción, hashtags y texto alternativo).

Todo con la voz seleccionada, subtítulos y música de fondo propia.

  • Motor: motor/, dentro de esta skill (Playwright 1.63.0 + ffmpeg; Python 3 sin dependencias). MOTOR = ruta absoluta de esa carpeta.
  • Proyecto: una carpeta por video, p. ej. videos/AAAA-MM-DD_tema/, con una subcarpeta por pieza: largo/, short-1-…/, short-2-…/. Cada pieza lleva su storyboard.json.
  • Instalación (una sola vez): ver README.md.

Voz seleccionada

Por defecto, la voz clonada «audio_pmm» de HeyGen:

campo de create_speechvalor
voiceIdb088805628184836963fa5d2881bb23b
engineelevenlabs
settings{"model_id": "eleven_v4"}
languagees

Si quien pide el video quiere otra voz, buscarla con mcp__heygen__list_voices y confirmarla antes de generar.

Flujo

1. Leer el MD y proponer las piezas

Leer el MD completo. Definir el recorrido del video detallado (todos los hallazgos, en orden) y un hallazgo por versión corta (el más fuerte primero). Mostrar la lista de piezas antes de escribir los storyboards.

2. Storyboards → aprobación

Una escena por idea. El video detallado, de 8 a 16 escenas; una versión corta, de 4 a 7 escenas, con un gancho (destacado) en la primera. Ejemplo completo: motor/ejemplos/storyboard-desalacion-16x9.json.

{"id": "03-sesiones", "tipo": "barras", "kicker": "Sesiones por caso", "titulo": "Dónde se habló más",
 "items": [{"etiqueta": "Caleta Chañaral", "valor": 6}], "destacar": 0, "nota": "Fuente…",
 "subtitulo": "Chañaral de Aceituno fue el caso con más sesiones.",
 "voz": "Chañaral de Aceituno fue el caso con más sesiones."}

Encabezado del storyboard: titulo, serie (lo que va junto a «Rizoma ·» arriba), formato ("16:9" para el detallado, "9:16" para las versiones cortas), fuente_md y, si se quiere, musica (ver paso 5).

Tipos de escena (todos aceptan kicker, tono: "oscuro" y lluvia: true):

tipocampospara qué
portadatitulo, bajadaabrir el video detallado
cifrastitulo, items[{valor, prefijo?, sufijo?, texto, detalle?}] (1 a 3), destacarnúmeros que cuentan hacia arriba
barrastitulo, items[{etiqueta, valor, rotulo?}] (hasta 8), destacar, notacomparar cantidades
hitofecha, etiqueta, titulo, texto, progreso{i, n}un hecho de una cronología
listatitulo, items[{marca?, texto, alerta?}] (hasta 6)argumentos o pasos
citafecha, texto, quien, notalo que alguien dijo
destacadotexto, bajadala frase que hay que recordar; el gancho de una versión corta
cierrebajada, url, fuentemarca y fuente

Reglas editoriales:

  • Solo hechos del MD. Lo que el MD marca como dudoso queda fuera o se dice como tal.
  • voz es lo que se lee: números, años, porcentajes y siglas van en palabras (texto_voz.py rechaza dígitos). subtitulo es lo que se ve, con cifras. texto es el texto en pantalla de hito, cita y destacado.
  • Frases cortas, español de Chile neutro, ~2,9 palabras por segundo. Una versión corta no pasa de ~140 palabras de voz.
  • Lo tomado de una transcripción automática se marca como paráfrasis (nota).
  • Lo que se publica no nombra clientes ni plataformas internas. El cierre lleva la fuente.

Mostrar cada storyboard como tabla (escena · tipo · lo que se ve · lo que se narra) y esperar el visto bueno: cada narración gasta cuota de voz.

3. Voz (una llamada por pieza)

python3 $MOTOR/texto_voz.py <pieza>

Pasar el texto que imprime (la voz de cada escena unida con <break time="1.2s"/>) a mcp__heygen__create_speech con la voz seleccionada. Con el audio_url que devuelve:

python3 $MOTOR/bajar_voz.py <pieza> "<audio_url>"

Descarga el audio y lo corta por escena buscando las pausas. Si avisa que faltan pausas, re-correr sobre el audio ya bajado con un umbral menor: python3 $MOTOR/bajar_voz.py <pieza> <pieza>/voz/narracion.wav --pausa 0.7 (en la práctica ElevenLabs acorta un poco alguna pausa). Si aun así falla, la voz no respetó un <break>: preguntar antes de regenerar. Nunca reintentar la generación sola tras un error.

4. Construir y renderizar

bash $MOTOR/producir.sh <pieza>                                   # video completo
bash $MOTOR/producir.sh <pieza> --hasta 15 --salida prueba.mp4    # prueba corta

Cada escena dura lo que dura su voz. El MP4 queda en <pieza>/salida/video.mp4; tarda más o menos lo que dura el video.

5. Música de fondo

Automática: colchón ambiental sintetizado con ffmpeg (sin derechos de terceros), 14 dB bajo la voz, con ducking suave y mezcla final a -16 LUFS. En el storyboard: "musica": {"bajo_voz_db": 18} la baja; {"archivo": "pista.mp3"} usa una pista propia (solo de uso libre, con la licencia anotada); false la apaga.

6. Versiones cortas

Después de aprobar el video detallado, armar cada versión corta como pieza aparte (formato: "9:16"), reutilizando escenas del detallado: gancho → 2 a 4 escenas de dato → cierre. Mismo paso 3 (una llamada de voz por pieza) y paso 4.

7. Revisión y entrega

  • Sacar 4 a 8 cuadros con ffmpeg y mirarlos: que el subtítulo no tape un dato, que ningún texto se salga del cuadro y que ninguna escena quede en blanco.
  • Escribir publicacion.md por pieza: título (≤ 60 caracteres), descripción con la fuente, 3 a 5 hashtags, texto alternativo y lo que falta verificar antes de publicar.
  • Copiar los MP4 a ~/Downloads con nombres claros (Video_<tema>.mp4, Short_<n>_<tema>.mp4). El audio y los MP4 no van a git (**/voz/*.wav, **/salida/).

Desde un HTML animado propio

Si ya existe un HTML con window.seek(t) y escenas con tiempos fijos, se escribe guion.json a mano (html: [a, b] por segmento) y se corre preparar.py + render.mjs. Para versiones cortas hechas a mano: motor/plantillas/motor-vertical.js.

Formato y zonas seguras

  • 16:9: 1920×1080, subtítulo de 34 px abajo, frases de hasta 58 caracteres.
  • 9:16: 1080×1920, subtítulo de 54 px a 400 px del borde inferior, frases de hasta 34 caracteres; contenido entre y=400 e y=1380 (arriba y abajo van los botones de cada red).
  • Ningún subtítulo termina en «que», «las», «por» y similares.

Errores conocidos

  • Sin red: las fuentes de Google no cargan y el render cae a Arial.
  • ffmpeg sin libass (Homebrew): por eso los subtítulos se dibujan dentro de la página.
  • Tipo de escena desconocido: el video sale en blanco; revisar tipo.

Skills relacionados