Communitygithub.com

JaviMaligno/agilabs-video-studio

Narra el locución de un video explicativo de un artículo - Cartesia TTS con marcas de tiempo por palabra (búsqueda de clave, IDs de voz, modelo), el fallback local Kokoro, consejos de pronunciación para números y símbolos, selección de voz en español y umbrales de QA de audio (recorte, líneas distorsionadas, -16 LUFS). Úsalo al ejecutar o depurar npm run tts / npm run audio-qa, o cuando la narración suene mal.

¿Qué es agilabs-video-studio?

Este skill define el proceso completo de locución para videos explicativos generados desde un artículo. Utiliza el servicio Cartesia TTS para convertir el texto del guion en audio, incluyendo marcas de tiempo por palabra que permiten sincronizar subtítulos de forma precisa. Si Cartesia no está disponible, el sistema recurre automáticamente a Kokoro, un motor TTS local gratuito, aunque sin marcas de tiempo, por lo que los subtítulos se temporizan de manera proporcional. La configuración del motor, voces, velocidad y modelo se realiza en el archivo `video.config.mjs`, con soporte para voces en inglés y español (seleccionando el ID de voz desde la biblioteca de Cartesia). Además, incluye un sistema de QA de audio que normaliza el volumen, detecta recortes (clipping) y líneas excesivamente largas (posible distorsión o repetición), y verifica que la mezcla final cumpla con el estándar de -16 LUFS. También ofrece consejos para corregir la pronunciación de números y símbolos añadiendo una forma hablada como cuarto argumento en la función `say`, sin alterar el texto escrito que se muestra como subtítulo. Está diseñado para ser usado junto a los comandos `npm run tts` y `npm run audio-qa`, así como durante la depuración de la narración.

Compatible con~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/JaviMaligno/agilabs-video-studio/tree/HEAD/skills/narration

Preguntar en tu IA favorita

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

Documentación

Narración

npm run tts vocaliza cada línea de src/timeline.ts en public/audio/<lang>/<key>.wav, con las marcas de tiempo por palabra de Cartesia en <key>.words.json, y reescribe src/audio.generated.ts con las duraciones reales de las líneas. Las líneas se almacenan en caché según motor, voz, modelo, velocidad y texto: solo las líneas nuevas o editadas se vuelven a vocalizar. npm run tts -- en o -- es limita la ejecución a un solo idioma.

Configuración de Cartesia

  • Los ajustes se encuentran en video.config.mjs (tts): modelo sonic-3.6-2026-08-27, velocidad 1.
  • Voz EN: 5568a7df-e5ab-4442-9fae-2e9ba1b15ad8 (en-GB).
  • CARTESIA_API_KEY se busca en este orden:
    1. las variables de entorno;
    2. .env en la carpeta del video (ignorado por git; copia .env.example);
    3. ~/Documents/repos/.env.
  • Nunca imprimas la clave, la hagas eco o la subas al repositorio. Verifica que exista sin mostrarla, por ejemplo test -n "$CARTESIA_API_KEY" && echo set.

Motores y el fallback Kokoro

tts.engine en video.config.mjs:

  • auto (por defecto): Cartesia cuando se encuentra una clave y el servicio responde; en caso contrario, todo el idioma se vocaliza con Kokoro (local, gratuito) y se muestra una advertencia. Un idioma nunca es una mezcla de dos voces: si Cartesia falla a mitad de camino, todo el idioma se vuelve a hacer con Kokoro, y la siguiente ejecución con Cartesia de nuevo lo repite.
  • cartesia: falla en lugar de recurrir al fallback.
  • kokoro: permanece offline. Voces: af_bella (EN), ef_dora (ES). Kokoro no proporciona marcas de tiempo por palabra, por lo que los subtítulos se temporizan de forma proporcional.

Una advertencia sobre Kokoro en la salida significa que el video no tiene la voz de Cartesia: indícalo al entregar el video.

Voz en español

voices.es es null hasta que se cree una versión en español. Elige una voz en español de la biblioteca de voces de Cartesia, escucha una línea de muestra del guion, registra su ID en video.config.mjs (es: { id: '<voice-id>', language: 'es' }), y añade 'es' a SETTINGS.voices (y a SETTINGS.subtitles si se desean subtítulos en español).

Pronunciación

El TTS lee el texto de la narración; los subtítulos muestran el texto escrito. Cuando el TTS lee mal un número o símbolo, asigna a la línea una forma hablada como cuarto argumento de say, y mantén la forma escrita del artículo como subtítulo:

say(0.3, 'It solved 14/20 tasks.', 'Resolvió 14/20 tareas.', {
  en: 'It solved fourteen out of twenty tasks.',
  es: 'Resolvió catorce de veinte tareas.',
})
  • El TTS vocaliza la forma hablada (y la caché vuelve a vocalizar la línea cuando esta cambia); la duración de la línea se obtiene de ella.
  • El subtítulo muestra el texto escrito, temporizado proporcionalmente durante la línea (las marcas de tiempo por palabra pertenecen a las palabras habladas, por lo que no se usan para esa línea).
  • Escribe la línea de forma simple ("14/20", "83 %", "p = 0.0018") y añade una forma hablada solo cuando al escuchar notes que el TTS se equivoca.
  • Las barras inclinadas, cadenas de versión ("gpt-5.6"), nombres de archivo y acrónimos son los problemas habituales. Escucha cada línea que contenga alguno de estos.

QA de audio

npm run audio-qa (escribe out/audio-qa.md):

  • normaliza cada línea al mismo volumen (una vez por versión de archivo);
  • marca una línea como recortada cuando su pico de origen alcanza -0.1 dBFS;
  • marca una línea como demasiado larga cuando dura más de 1.6x su estimación basada en la longitud del texto: señal de habla distorsionada o repetida. Escucha cada línea marcada y vuelve a vocalizarla (edita ligeramente el texto, o elimina su archivo wav) si está mal;
  • después de npm run render, mide cada mezcla en out/ con respecto a -16 LUFS integrados, ±1 LU (pico verdadero -1.5 dBTP) y sale con código 1 si alguna no cumple el objetivo.

Después de narrar, ejecuta npm run lint nuevamente: las duraciones reales reemplazan las estimaciones y pueden hacer que el video se desvíe de su duración objetivo o que un subtítulo supere los 17 caracteres/s.

Música de fondo

Se genera una música suave localmente (npm run music, creada automáticamente por npm run render cuando falta; necesita python3 con numpy, o uv). Su volumen se reduce al 30 % mientras se reproduce una línea. Establece SETTINGS.music en null para no tener música.

Individual skills in this repo

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

Skills relacionados