Skill para Claude Code y Codex

Vídeos de tu producto, hechos con código

Respondes tres preguntas y el agente escribe cada fotograma en HTML, renderiza el MP4 en 16:9 y 9:16 y, si quieres narración, sincroniza cada imagen con la palabra que tu voz está diciendo.

Banner: vídeo creado con código, tu producto en vídeo sin cámara ni editor
En resumen

video-codigo es una skill (un paquete de instrucciones y scripts) para Claude Code y Codex, los agentes de código de Anthropic y OpenAI, que crea vídeos sin cámara ni editor: cada fotograma se escribe en código (HTML, Canvas o SVG) y se convierte en MP4. Sirve para quien quiere mostrar un producto, un proyecto o una idea en vídeo: lanzamiento, anuncio, explicativo o clase. Si el vídeo lleva narración, la voz se genera en tu computadora, sin pagar por voz, y cada imagen aparece en el instante en que se pronuncia la palabra. Para usarlo necesitas Node, Python y FFmpeg; para la voz, inemavox con GPU NVIDIA (sin ella, el vídeo sale solo con música).

Qué es

Un director de vídeo dentro de tu agente

La skill pregunta lo importante, propone la dirección, prueba un fragmento y solo después renderiza el vídeo entero.

Los seis tipos de vídeo: lanzamiento, anuncio con ganchos, explicativo, serie de productos, voz local, 16:9 y 9:16

🎬 Varios tipos de vídeo

La skill sabe dirigir lanzamientos, anuncios con varios ganchos, vídeos explicativos de productos, series con el mismo aspecto, ventas narradas y clases largas. Ya incluye dos ejemplos listos para copiar: uno explicativo narrado y otro de lanzamiento solo con música.

🎙️ Voz sincronizada con cada palabra

scripts/voz.py genera la narración con tu voz clonada y mide el tiempo de cada palabra. En el HTML, pal('frase', 'palabra') indica cuándo aparece cada elemento.

📐 16:9 y 9:16 juntos

El mismo proyecto se recompone para cada formato. Un render para YouTube y otro para Reels, Shorts y TikTok.

Cómo funciona

De la solicitud al MP4

Con voz, el reloj del vídeo es la narración. Sin voz, es la música.

3 preguntas→ roteiro.json→ voz.wav + tiempos→ escenas en HTML→ prueba de 5 s→ MP4 16:9 y 9:16→ revisión

1 · Las preguntas

¿De qué se trata y para quién? (puede ser una carpeta, un repositorio o un sitio web para leer) · ¿Con voz o solo música? · ¿Qué estilo? — el estándar INEMA o un vídeo de referencia.

2 · La voz

Chatterbox pronuncia cada frase con la voz clonada; Whisper escucha, verifica y marca el tiempo de cada palabra. Las frases que salen mal se generan de nuevo.

3 · El render

Un navegador sin ventana abre la página, pide el fotograma de cada instante (window.seek(t)) y FFmpeg lo une todo con el audio. Sin conexión: las fuentes y las imágenes quedan en el proyecto.

Requisitos previos

Lo que debe estar instalado en el equipo

El instalador (instalar.sh) instala Playwright y Chromium automáticamente, sin sudo. El resto solo lo comprueba y muestra el comando para instalarlo.

Node, Python y FFmpeg

Node 18 o posterior, Python 3 con numpy, scipy y Pillow, FFmpeg en el PATH.

# comprobar
node -v && python3 -V && ffmpeg -version | head -1
# bibliotecas de Python (Ubuntu/Debian)
sudo apt install python3-numpy python3-scipy python3-pil
# otros sistemas
python3 -m pip install --user numpy scipy pillow

Playwright + Chromium

Un navegador sin ventana, controlado por un script, que toma una imagen de cada fotograma del vídeo. Se instala en ~/.cache.

# instalar.sh (paso 1) ya ejecuta esto
bash ~/projetos/video-codigo/scripts/preparar-entorno.sh

Voz (opcional, necesita GPU NVIDIA)

La voz usa inemavox instalado en ~/projetos/inemavox: Chatterbox (modelo que habla con una voz copiada de una grabación, la «voz clonada») y Whisper (modelo que escucha el audio y marca el tiempo de cada palabra). También necesita Miniconda (gestor de entornos Python; el instalador oficial se instala en ~/miniconda3) y una grabación limpia de tu voz de 10–20 s en .wav. La primera vez, los modelos descargan varios GB. Si conda o inemavox están en otro lugar, indícalo con CHATTERBOX_PYTHON=/caminho/python3 y INEMAVOX_DIR=/caminho/inemavox. Sin GPU o sin inemavox, crea vídeos solo con música.

# los tres deben existir
ls ~/miniconda3/envs/chatterbox/bin/python3 \
   ~/projetos/inemavox/chatterbox_tts_worker.py \
   ~/projetos/inemavox/venv/bin/python
# instalar (probado: Python 3.11, chatterbox-tts 0.1.6)
git clone https://github.com/inematds/inemavox ~/projetos/inemavox
conda create -n chatterbox python=3.11 -y
~/miniconda3/envs/chatterbox/bin/pip install chatterbox-tts==0.1.6
cd ~/projetos/inemavox && python3 -m venv venv && venv/bin/pip install faster-whisper soundfile numpy
Guía de uso · paso a paso

Tu primer vídeo con código

Lo habitual es pedirle al agente (paso 2): escribe el guion y las escenas, y lo ejecuta todo. Los comandos de los pasos siguientes son los que ejecuta y te sirven para repetir una etapa a mano. Para eso, ejecútalos primero en la terminal ($K es la carpeta del kit y $P, la de tu vídeo):

K=~/projetos/video-codigo                      # donde se clonó el kit
P=~/videos/trabalho/2026-11-06-meuapp         # una carpeta por vídeo
mkdir -p "$P"
1

Instala la skill

Clona el repositorio, conecta la skill a Claude Code y Codex e instala el navegador del render.

git clone https://github.com/inematds/video-codigo ~/projetos/video-codigo
bash ~/projetos/video-codigo/instalar.sh  # ✓ skill en ~/.claude/skills/video-codigo

Prueba la instalación renderizando el ejemplo listo (no necesita voz ni GPU; tarda alrededor de 1 minuto):

cd ~/projetos/video-codigo/exemplos/lancamento && node ../../scripts/render-video.mjs --project . --output teste.mp4 --audio audio/lancamento/mezcla.wav --overwrite
2

Pide el vídeo

Di el tema y, si tienes material, dónde está. El agente te hará las tres preguntas que falten. Para narrarlo con tu voz, dile dónde está la grabación .wav.

/video-codigo haz un vídeo de 40 s de mi app, lee la carpeta ~/projetos/meu-app, narrado con la voz de ~/minha-voz.wav, estilo INEMA
↷

¿Sin voz? El reloj es la música

Sin narración no necesitas guion ni GPU. Lo más sencillo es pedirle al agente («solo con música, 20 s»): escribirá las escenas. Para partir manualmente del ejemplo de lanzamiento, aprende qué debes cambiar en el <script> de index.html:

• window.videoSpec = {… duration: 21} — la duración del vídeo en segundos; usa la misma que la música.
• SEG — la lista de etapas: a y b son los segundos en que cada etapa entra y sale; rot y sub son el título y la línea inferior.
• S — dónde está y qué tamaño tiene la forma amarilla en cada segundo (t), que es lo que conecta una etapa con otra.
• function conteudo — el dibujo dentro de la forma en cada etapa (módulos, página, play, terminal, conversación). Sustitúyelos por los de tu producto.

cp -r $K/exemplos/lancamento/{index.html,motion.mjs,inema} $P/
python3 $K/scripts/mezcla.py --projeto $P --id meuapp --duracao 21 --musica energica --lufs -14  # misma duración que videoSpec

Después ve al paso 7 (prueba) y al 8 (render, con --audio $P/audio/meuapp/mezcla.wav).

3

Guion con una frase por instante

Archivo $P/roteiro.json. Cada frase tiene un id: es ahí donde se sincroniza la imagen. En voz, la ruta a tu grabación. dicionario cambia lo que aparece en pantalla por lo que debe leer la voz.

{"id": "meuapp", "pausa": 0.28, "voz": "/home/voce/minha-voz.wav",
 "dicionario": [["16:9", "dezesseis por nove"]],
 "blocos": [{"id": "abertura", "frases": [
   {"id": "hook", "texto": "Este vídeo no tiene cámara."},
   {"id": "codigo", "texto": "Cada fotograma se escribió en código."}]}]}
4

Genera la voz con el tiempo de cada palabra

Se ejecuta en tu computadora. Genera $P/voz/meuapp/voz.wav y $P/voz/meuapp/tiempos.js (el tiempo de cada palabra); las frases con menos de un 80 % de similitud se rehacen automáticamente. Cada frase se escucha con Whisper: si no coincide con el texto (o cambia algún número), se genera de nuevo, hasta --tentativas veces. El informe queda en $P/voz/meuapp/checagem.md, con lo que oyó Whisper — lee las frases marcadas con ⚠.

python3 $K/scripts/voz.py --projeto $P $P/roteiro.json  # ej.: meuapp: 41.9 s · 12 frases · 107 palabras
5

Música de fondo

Música original sintetizada (energica, 120 pulsos por minuto; tranquila, 84; o --pista con tu música), 24 dB por debajo de la voz mientras se habla. --lufs -14 deja el volumen final al nivel que usan YouTube e Instagram (así la plataforma no baja ni satura el sonido). Sin voz, pasa --duracao en segundos. La música se ajusta a los cortes de las escenas: cada cambio de escena cae en un tiempo fuerte, en el cambio de acorde, sin saltos de volumen. Al final, el script lo comprueba, verifica que la voz esté al frente y que no haya whoosh, y guarda trilha.json.

python3 $K/scripts/mezcla.py --projeto $P --id meuapp --musica tranquila --lufs -14  # → $P/audio/meuapp/mezcla.wav
6

Escenas sincronizadas con la narración

Parte del ejemplo narrado: ya incluye el tema, el motor de tiempo y el esqueleto que usa el render (videoSpec = tamaño y duración, seek(t) = dibuja el instante t, renderReady = avisa cuando se cargaron las fuentes y las imágenes). Cambia el texto de las escenas y, en cada pal('frase', 'palabra'), ini('frase') y data-in, los id y las palabras por los de tu guion. Si queda alguno del ejemplo, el render se detiene e indica cuál: Não encontrei «câmera» na frase hook do roteiro.

cp -r $K/exemplos/explicativo-narrado/{index.html,engine.mjs,motion.mjs,declarativo.mjs,inema} $P/
cp $P/voz/meuapp/tiempos.js $P/   # los tiempos de tu voz
// en el <script> de index.html: cada elemento aparece con la palabra pronunciada
pop($('.code', c1), t, pal('codigo', 'escrito'));   // aparece cuando la voz dice "escrito"
pop($('.onda', c1), t, ini('voz'));                 // aparece al comienzo de la frase "voz"
7

Prueba antes del render completo

Extrae fotogramas sueltos en los momentos difíciles, en ambos formatos, y revísalos antes de dedicarle tiempo al vídeo completo. --still indica el segundo del vídeo (debe estar dentro de la duración; en un guion de 5 s, usa 2 o 3).

node $K/scripts/render-video.mjs --project $P --output $P/prova.png --still 2
node $K/scripts/render-video.mjs --project $P --output $P/prova-v.png --still 2 --width 1080 --height 1920

Comprueba también que cada texto permanezca el tiempo suficiente para leerlo (1 s + 0,3 s por palabra, mínimo 1,5 s) y guarda los cortes de las escenas; después, vuelve a procesar la música para que se ajuste a ellos.

node $K/scripts/checar-leitura.mjs --project $P --salvar-cortes $P/audio/meuapp/cortes.json  # sale 0 = todo legible; 1 = algún texto desaparece demasiado pronto
python3 $K/scripts/mezcla.py --projeto $P --id meuapp --musica tranquila --lufs -14  # la música ahora cae en los cortes
8

Render y revisión

Un MP4 por formato y una hoja de fotogramas para revisar todo el vídeo de una vez.

node $K/scripts/render-video.mjs --project $P --output $P/renders/meuapp-16x9.mp4 --audio $P/audio/meuapp/mezcla.wav
node $K/scripts/render-video.mjs --project $P --output $P/renders/meuapp-9x16.mp4 --width 1080 --height 1920 --audio $P/audio/meuapp/mezcla.wav
python3 $K/scripts/inspect-video.py $P/renders/meuapp-9x16.mp4 --output-dir $P/reviews
9

Modo b-roll: vídeo de una persona hablando

Para una clase, un testimonio o un avatar: la grabación no se corta. A partir de la transcripción con el tiempo de cada palabra, el kit decide frase por frase qué muestra la pantalla: a la persona completa, a la persona en un círculo con el concepto dibujado con trazos, o un gráfico a pantalla completa; y prepara el proyecto listo para renderizar. Revisa $P/plano.md y edita $P/plano.json antes del render.

# transcripción local con el tiempo de cada palabra
cd ~/projetos/inemavox && venv/bin/python transcrever_v1.py --in aula.mp4 --outdir $P/transcricao --src pt --words
# plan + plantilla + cuadros + audio; --rosto = dónde está el rostro
python3 $K/scripts/broll-plano.py --fala aula.mp4 --transcricao $P/transcricao/transcript.json --projeto $P --rosto 0.58,0.45,0.38
# después de editar el plano.json
python3 $K/scripts/broll-plano.py --projeto $P --replanejar
node $K/scripts/checar-leitura.mjs --project $P
node $K/scripts/render-video.mjs --project $P --output $P/renders/aula-broll.mp4 --audio $P/audio/fala.wav
Ejemplos

Tres videos hechos con el propio kit

El código, el guion y el audio de cada uno están en exemplos/. No se filmó ningún fotograma. El primer éxito más rápido, sin voz ni GPU: renderiza el ejemplo de lanzamiento.

cd $K/exemplos/lancamento && node ../../scripts/render-video.mjs --project . --output teste.mp4 --audio audio/lancamento/mezcla.wav --overwrite
Película de producto de atende-leads (61 s) — recrea las pantallas reales: prospectos esperando en WhatsApp, el agente que califica, el llamado en Telegram que pasa de Ana a Bruno en 2 min, el panel del equipo, la sugerencia de respuesta y la venta. Cursor que hace clic, voz de Nei atada a cada palabra. Caso de ejemplo. versión 9:16
Explicativo narrado (44 s) — voz local de Nei; código que se escribe, marcas de tiempo de cada palabra y el formato 16:9 que pasa a 9:16 en la palabra exacta. versión 9:16 · YouTube
Lanzamiento solo con música (21 s) — un único plano: la misma forma se convierte en curso, guía, vídeo, kit, comunidad y el punto de INEMA.CLUB. versión 9:16 · YouTube
Próximos pasos

Lo que ya existe y lo que viene

Hecho = está en el repositorio y se usó en los ejemplos.

Hecho
Skill, voz local y tema INEMASKILL.md y referencias en portugués, voz.py con Chatterbox + Whisper, tema con fuentes locales, dos ejemplos en 16:9 y 9:16.
Hecho
Calidad comprobada automáticamente (1.2)Verificador del tiempo de lectura, voz comprobada con Whisper (incluidos los números), música ajustada a los cortes y modo b-roll para vídeos de personas hablando.
Siguiente
Ejemplo listo de anuncio con varios ganchosLa skill ya sabe hacerlo; falta un ejemplo renderizado con el mismo cuerpo y cinco aperturas distintas.
Después
Ejemplo listo de serie de productosUn vídeo por producto con el mismo aspecto, a partir de una lista.