PTENES
Skill · Claude Code · HTML→MP4

Del tema al video narrado, sin clave de API.

Tú das un tema. La skill escribe el guion, graba la locución, anima las escenas y renderiza los MP4 en 16:9 y 9:16 — todo en tu máquina.

Portada del proyecto video-explicativo
Qué es

Una skill que empaqueta todo el pipeline de video explicativo

No es un generador de video con IA. Es un pipeline determinista: HTML animado + Chrome headless + FFmpeg, orquestado por el HyperFrames, con narración TTS local. El resultado siempre es PT-BR, dark premium ámbar, y termina con la CTA de INEMA.CLUB.

🔒 100% local, sin clave de API

Chrome headless + FFmpeg renderizan el video; la narración se genera en inemavox local (engine chatterbox, voz nei) con Kokoro pf_dora como alternativa. Nada sale de la máquina.

📐 Basado en datos, nº de escenas dinámico

El generador lee el array SCENES[]: una entrada por beat del guion. Un rango saludable es de 4–12 escenas de contenido: el tema decide, no una plantilla rígida.

📱 16:9 y 9:16 con la misma base

El mismo generador escribe los dos formatos (--vertical: versión vertical del explicativo — un reel de verdad se hace en makeshorts + explicavideos 9:16), con zonas seguras para la UI de las apps y un título persistente de 2 líneas en vertical.

Cómo funciona

Ocho etapas, siempre en este orden

El timing es la única fuente: cada escena declara la duración REAL de su WAV (medida con ffprobe), y el generador deriva de ahí tanto los data-start/duration al igual que los tiempos de los tweens — el audio y la animación nunca se desincronizan.

Guion→ Revisión de texto→ Proyecto→ Fuentes→ Narración→ Composición→ Validar→ Render

✍️ Texto (1–2)

Guion con gancho en la escena 1 y revisión en dos formas por frase: pantalla (PT-BR con acentos, inglés con la ortografía original) y habla (siglas expandidas, inglés fonético — deploy → «despliega»).

🎙️ Audio (3–5)

Proyecto creado en ~/projetos/output/<nome>/, fuentes descargadas como .woff2 local, y un WAV por escena generado por el narration.sh.

🎞️ Video (6–8)

Composición a partir del vocabulario de movimiento M.*, lint + inspect de diseño, render en draft para revisar y high para entregar.

Requisitos previos

Lo que debe haber en la máquina

Todo se ejecuta localmente. Si algo falla, npx hyperframes doctor señala lo que falta.

Node 22+ y FFmpeg

FFmpeg en C:\ffmpeg\bin. En git-bash usa siempre -nostdin, de lo contrario el comando termina con exit 0 sin generar el archivo.

# verifica la versión
node -v
ffmpeg -nostdin -version

Chrome headless (HyperFrames)

HyperFrames renderiza el HTML en un Chrome headless propio — descárgalo una vez.

# descarga el navegador de HyperFrames
npx hyperframes browser ensure

# diagnóstico general
npx hyperframes doctor

TTS: inemavox local (voz nei)

Predeterminado de la casa — requiere GPU. python3 del sistema se ejecuta el tts_direct.py; el env conda chatterbox se llama internamente para la transferencia de timbre.

# fallback opcional (Kokoro pf_dora)
pip install kokoro-onnx soundfile

¿No tienes GPU? Puedes ejecutar todo de todos modos

El render (Chrome headless + FFmpeg) nunca necesitó GPU. Solo dos componentes del flujo predeterminado requieren hardware adicional — y ambos tienen un sustituto directo.

🎙️ Narración → edge-tts

Sintetiza en la nube de Microsoft, sin clave ni modelo local. Enumera y escucha las voces primero de generar el video completo — cambiar de voz a mitad del proceso implica rehacer el trabajo.

# instala y revisa las voces PT-BR
pip install edge-tts
edge-tts --list-voices | grep pt-BR

# muestra de 1 frase para escuchar
edge-tts --voice pt-BR-FranciscaNeural \
  --text "Teste de voz." --write-media amostra.mp3

🔌 Narración sin conexión → Kokoro

Modelo ONNX pequeño, se ejecuta en CPU, sin internet. Voces PT: pf_dora (F), pm_alex e pm_santa (M). La misma regla: genera una frase con cada candidata y elige escuchándolas.

pip install kokoro-onnx soundfile

# la sincronización del video viene del audio real
ffprobe -v error -show_entries format=duration \
  -of csv=p=0 assets/audio/s1.wav

🖼️ Imágenes → Agnes AI

En lugar de flux2-klein (difusión local, GPU): el CLI imagens-agnes llama a la API de Agnes — US$ 0, sin créditos, nada se ejecuta en tu máquina. Prompt en inglés (PT tiene problemas con el filtro), como máximo 2 referencias, y descárgalas en el momento (la URL vence).

cd ~/projetos/imagens-agnes
python3 gerar.py "dark premium abstract \
  data landscape, amber accent" \
  --ratio 16:9 --size 2K -o s3.png

Sin Agnes y sin GPU, el alternativa SVG sigue vigente: el house-style ya es vectorial/CSS; la imagen es un refuerzo, no un requisito. Los detalles completos están en references/sem-gpu.md.

Guía de uso · paso a paso

Del tema al MP4

Los comandos de abajo son los reales de la skill. Todo el contenido — proyecto, assets, audios, index.html y los MP4 finales — todo vive en una sola carpeta: ~/projetos/output/<nome>/.

1

Escribe el guion (SCRIPT.md)

Un beat por escena, 1–3 frases cortas (~8–15s de voz cada una). La escena 1 abre directamente en el gancho — pregunta incisiva, cifra impactante, promesa concreta o error común. Sin logo, sin «hola a todos»: los ~3s iniciales determinan la retención. Duración predeterminada cuando nadie pide nada: ~1:40–2:00.

# arco de referencia (profundiza o desarrolla los beats según el tema)
# gancho → primer principio → mecánica → concepto clave →
# aplicación → avanzado → ejemplo real → cierre → CTA INEMA.CLUB
2

Revisa el texto antes de generar el audio y las diapositivas

Cada frase tiene dos formas. Pantalla (caption + literales en html(p)): PT-BR con acentuación revisada palabra por palabra, términos en inglés con la ortografía original. Voz (txt/sN.txt): siglas y URL expandidas, inglés reescrito fonéticamente: el TTS fonemiza según la ortografía escrita.

# pantalla  → Toda skill começa com o SKILL.md
# habla  → Toda skiu começa com o SKILL ponto M D

# léxico: deploy→"deplói" · design→"dizáin" · framework→"frêimuork"
3

Crea el proyecto en una única carpeta

Init de HyperFrames con el ejemplo blank (la skill tiene su propio estilo). Copia el design.md de la referencia de house style a la raíz del proyecto.

cd ~/projetos/output
npx hyperframes init <nome> --example blank --non-interactive
4

Descarga las fuentes localmente

Sora, Inter y JetBrains Mono como .woff2 (subset latin) + fonts.css. Nunca uses Google Fonts por CDN: desaparecen del render.

# copia scripts/fetch-fonts.mjs al proyecto y ejecútalo
node fetch-fonts.mjs   # → assets/fonts/*.woff2 + fonts.css
5

Genera la narración (voz nei, local)

Copia scripts/narration-template.sh como assets/narration.sh, escribe los txt/sN.txt en forma-fala y ejecútalo. Itera sobre todos los sN.txt que existan, prueba la voz nei en el inemavox local y, si falla, usa Kokoro para cada escena.

bash assets/narration.sh   # → assets/audio/sN.wav

# mide la duración REAL de cada WAV (va en el campo `audio` de la escena)
ffprobe -v error -show_entries format=duration \
  -of default=noprint_wrappers=1:nokey=1 assets/audio/s1.wav
6

Compón las escenas

Copia scripts/composition-template.mjs como build-index.mjs y edita el array SCENES[] — una entrada por escena, cada una { audio, caption, html(p), anim(at,p) }. La CTA de INEMA.CLUB ya se añade como última escena. En 9:16, define TITLE con persona + gancho.

const TITLE = { l1: "PROFISSIONAL <b>LIBERAL</b>",
                l2: "por que ainda faz tudo <b>sozinho?</b>" };

// la CTA siempre es la última: no quitar
const ALL = [...SCENES, CTA];
7

Valida antes de renderizar

El lint debe dar 0 errores y el inspect, 0 problemas de diseño. No dejes dos index*.html en la raíz — el lint detecta multiple_root_compositions.

npx hyperframes lint                  # 0 errores
npx hyperframes inspect --samples 16  # 0 problemas de diseño
8

Renderiza los dos formatos

Renderiza justo después de generar cada modo — el generador siempre escribe index.html. Un archivo por formato y nada más: el render ya es la entrega, sin una copia comprimida al lado. Revisa los frames en draft antes de high.

node build-index.mjs           && npx hyperframes render --quality high --output <nome>-16x9.mp4
node build-index.mjs --vertical && npx hyperframes render --quality high --output <nome>-9x16.mp4

# extrae un frame para verificarlo
ffmpeg -nostdin -y -ss 12 -i <nome>-16x9.mp4 -vframes 1 -update 1 frame.png
Ejemplos

Lo que la skill ya produjo

Casos reales que validaron cada recurso del pipeline, y el curso publicado sobre la propia skill.

🎓 Curso: Skills en Claude Code

El ejemplo que acompaña al narration-template.sh: 8 escenas + CTA explicando qué son las Skills, del SKILL.md a la divulgación progresiva. El curso completo sobre esta skill está publicado en skill-video-explicativo.

💼 Piloto «Liberal v1»

Caso que validó el título persistente de 2 líneas en 9:16 (v1.10.3): l1 = "PROFESIONAL LIBERAL" (persona), l2 = "¿por qué todavía haces todo solo?" (gancho). Se mantiene fijo en la parte superior durante todo el video y desaparece en la CTA.

📊 hormozi-12-dicas

Origen de las safe zones de 9:16 (v1.5.0/1.5.1): mensaje en el medio, medios como una franja superior que entra desde la derecha, caption oculta en vertical — espacio libre para la UI de la app.

🎞️ Variantes (2–3 versiones)

Una variación es otro ángulo del mismo tema — didáctico vs. caso real vs. contrarian vs. lista — con guion, gancho y narración propios. Cada una genera los dos formatos: <nome>-v1-16x9.mp4, <nome>-v2-16x9.mp4…

Roadmap

Cómo llegó la skill a la 1.12.3

Versionado v1.yy.xxx — yy = recurso, xxx = corrección. Historial completo en CHANGELOG.md.

1.0.0
Versión inicialPipeline HTML→MP4 (HyperFrames + Kokoro TTS local), estilo de marca dark premium ámbar, 16:9 y 9:16.
1.2.0
Escenas basadas en datos + actividad a mitad de escenaEl número de escenas ahora se obtiene del guion (SCENES[]), CTA añadida automáticamente y cámara Ken Burns en cada escena: fin del slideshow.
1.3.0
Lenguaje de movimientoVocabulario M.* (reveal/sweep/type/float/pulse/glow/countUp) en lugar de tweens improvisados, con desplazamientos menores en 9:16.
1.4.0
Transiciones entre escenasMapa TRANS en GSAP: fade (predeterminado), push, slideUp, zoom, wipe, fadeBlack — efectos especiales solo en 2–3 momentos clave.
1.5.x
Safe zones, alternativa con SVG y salida únicaDiseño vertical validado, la imagen rasterizada pasa a ser opcional (SVG lo cubre), cambia el final de la cola y hay un único MP4 por formato — sin copia -FINAL.
1.6.3
Revisión de texto + pronunciación del inglésNueva etapa antes de los WAV: dos formas por frase (pantalla vs. voz) y léxico de inglés fonético.
1.7.3
Gancho, audio bajo la voz y legibilidadCuatro comportamientos se convierten en contrato: gancho de apertura, música baja (MUSIC_VOL ~0.14), scrim/blur/panel bajo el texto, y qué es una variación.
1.8.3
Voz bella como predeterminadaLa narración pasa a usar la voz de la casa mediante inemavox (chatterbox-vc); Kokoro pf_dora se convierte en fallback automático por escena.
1.10.3
Título del 9:16 en 2 líneasTITLE = { l1, l2 } — personalidad + curiosidad, fija en la parte superior del formato vertical y desaparece en la CTA, cerrando el ciclo de retención.
1.12.3
Explicativo, no reelVersión actual. Reel y short pasan a makeshorts con explicavideos 9:16; narración 100% local con la voz de Nei (sin Edge TTS); verificación de la narración mediante transcripción local; un prototipo aprobado antes de cualquier lote.
1.11.3
Ejecutar sin GPUDocumenta las alternativas para quienes no tienen GPU: narración por edge-tts o Kokoro (con validación obligatoria de voz) e imágenes mediante Agnes AI (US$ 0) en lugar de flux2-klein.