PTENES
MÓDULO 2.5

✅ Validar y renderizar

La etapa final del pipeline: lint sin errores, inspect sin overflow, render draft para revisar cuadro por cuadro, validación de la locución, render high-quality y generación de los dos formatos, todo en el orden correcto.

6
Temas
~35
Minutos
Práctico
Nivel
Entrega
Tipo
Pipeline de validación y renderizado LINT → INSPECT → DRAFT → HIGH → MP4 × 2 lint 0 errores overlapping inspect 0 overflow --samples 16 draft 1 fotograma/escena ffmpeg -nostdin 👁 high --fps 30 ~3–4 min 16:9 MP4 1920 × 1080 YouTube 9:16 MP4 1080×1920 Shorts ① LINT ② INSPECT ③ DRAFT ④ HIGH
1

🧹 npx hyperframes lint

La primera barrera de calidad: el linter analiza tu index.html generado e informa problemas estructurales antes de que gastes tiempo en el renderizado. Meta: 0 errores.

Concepto principal

El linter lee el index.html generado (no el build-index.mjs) y valida la estructura de la composición. Los errores detienen el render; las advertencias son informativas.

Ejecuta siempre después node build-index.mjs e antes de cualquier render. El lint es rápido (<2 s) y no inicia Chrome.

Comando
# genera el index.html antes de ejecutar lint
node build-index.mjs
npx hyperframes lint

# salida esperada (0 errores)
✔ 0 errors, 0 warnings
Los 3 errores más comunes
✗
overlapping_clips

Dos clips de escena tienen intervalos de tiempo que se superponen. Corrígelo ajustando el array AUDIO[] no build-index.mjs — la suma de las duraciones debe ser estrictamente secuencial.

✗
multiple_root_compositions

Más de un elemento con data-composition en la raíz del documento. HyperFrames solo acepta una composición por archivo index.html.

✗
google_fonts_import

El lint detecta un @import url('fonts.googleapis.com/...') en el CSS. Las fuentes externas están prohibidas porque Chrome headless no tiene acceso a Internet durante el render. Usa node fetch-fonts.mjs para descargar los .woff2 y servir localmente mediante assets/fonts/fonts.css.

💡
Lint en el ciclo de desarrollo

Durante la composición, ejecuta node build-index.mjs && npx hyperframes lint cada modificación relevante en build-index.mjs. Costo: menos de 2 segundos. Evita sorpresas al renderizar.

Conceptos clave
🧹
0 errores
Meta obligatoria
⏱️
<2 s
Sin Chrome
🔤
Fuentes locales
fetch-fonts.mjs
📋
AUDIO[]
Secuencial
2

🔍 npx hyperframes inspect --samples 16

El inspector abre Chrome en modo headless, captura 16 fotogramas distribuidos a lo largo del video y audita cada uno: diseño, desbordamiento de texto, elementos fuera del lienzo. Meta: 0 problemas.

Comando
# 16 muestras cubren bien videos de hasta ~110s
npx hyperframes inspect --samples 16

# salida esperada
✔ Inspected 16 frames — 0 layout issues found
✓ Buenas prácticas para 0 problemas
  • ✓ Agrega data-layout-ignore en elementos decorativos fuera del lienzo (palabras gigantes de fondo, glows, .bg-layer)
  • ✓ Prefiere left/right en lugar de width para marcadores de resaltado
  • ✓ Prueba código largo en overflow-x: auto con un contenedor de ancho explícito
  • ✓ Usa z-index:-1 en los glows para que no se salgan del bounding box
✗ Causas comunes de overflow
  • ✗ Texto en línea de código que sobrepasa el contenedor — acórtalo o divídelo en líneas
  • ✗ SVG sin viewBox definido — el auditor no puede calcular los límites
  • ✗ position: absolute sin overflow: hidden en el padre
  • ✗ Elementos decorativos sin data-layout-ignore — marcados como falso positivo de overflow
⚠️
Inspect no sustituye la revisión visual

El inspector detecta desbordamientos de bounding box, no problemas de legibilidad o contraste. Después de 0 problemas en inspect, todavía es necesario revisar visualmente los frames del render draft — especialmente en escenas con texto sobre gradiente.

Conceptos clave
🔍
16 muestras
Buena cobertura
🏷️
data-layout-ignore
Decorativos
📐
Cuadro delimitador
Desbordamiento real
🧪
Chrome headless
Render real
3

🎬 Render draft: iterar rápido

El modo --quality draft genera un MP4 de baja resolución en segundos. Extrae un frame por escena con ffmpeg -nostdin y comprueba visualmente antes de dedicar tiempo al render final.

Workflow de revisión cuadro a cuadro
1
Genera el borrador MP4
node build-index.mjs # genera index.html
npx hyperframes render --quality draft --output renders/draft.mp4
2
Extrae 1 frame por escena con ffmpeg

Usa el tiempo de inicio de la escena como <t>. Para una escena que empieza a los 12,5 s, usa -ss 12.5. La flag -nostdin es obligatorio en Windows/git-bash para evitar que ffmpeg consuma stdin y termine sin generar el archivo.

# fotograma de la escena que empieza en t=12.5s
ffmpeg -nostdin -y -ss 12.5 -i renders/draft.mp4 \
-vframes 1 -update 1 frame-cena3.png
3
Abre el PNG con la herramienta Read

Claude puede visualizar imágenes PNG directamente. Extrae un frame por escena y verifica: alineación del texto, desbordamiento, animaciones en la posición correcta, legibilidad sobre el fondo. Repítelo para todas las escenas.

4
Corrige y repite

Edita el build-index.mjs, ejecuta node build-index.mjs && npx hyperframes render --quality draft nuevamente. El loop draft es barato: itera sin culpa antes del render final.

📊 Draft vs High: cuándo usar cada uno
Aspecto Borrador High
Objetivo Revisión visual Entrega final
Velocidad Rápido (<30 s) 3–4 min / 110s de video
Calidad Reducida Máxima (30 fps)
Uso Ciclo de iteración Una vez, al final
💡
Cobertura mínima recomendada

1 fotograma por escena basta. Para un video de 8 escenas, son 8 llamadas a ffmpeg. Enfócate en los momentos de transición y en los títulos: son las partes más propensas a desbordarse.

Conceptos clave
🎬
--quality draft
Iteración rápida
📸
-vframes 1
Frame único
🛡️
-nostdin
Win/git-bash
🔁
-update 1
Sobrescribe PNG
4

👂 Validar la locución con el usuario

Claude no escucha audio. La validación de la narración es responsabilidad del usuario, y debe realizarse antes del render high para no desperdiciar 3–4 minutos de procesamiento.

⚠️
Claude no puede escuchar los archivos WAV

La herramienta de análisis de imágenes (Read) funciona con PNG y frames, pero no admite audio WAV. Toda validación de locución debe hacerla el usuario escuchando los archivos assets/audio/sN.wav directamente.

Qué validar en la locución

Antes de render high, confirma con el usuario: la pronunciación correcta de los términos técnicos, la velocidad (pf_dora --speed 0.98 es el valor predeterminado), las pausas naturales entre escenas y una duración coherente con el aspecto visual de cada escena.

✓ Lista de verificación para validar el audio
  • ✓ Escucha cada assets/audio/sN.wav antes del render final
  • ✓ Confirma que las siglas se hayan expandido correctamente (por ejemplo, ¿"GSAP" → "yi-sap" suena natural?)
  • ✓ Verifica que la duración del WAV sea coherente con la escena visual
  • ✓ Verifica mediante ffprobe si la duración medida coincide con el AUDIO[]
✗ No omitas la validación del audio
  • ✗ No hagas un render high sin escuchar los WAVs: retrabajo costoso
  • ✗ No confíes solo en la duración medida: la voz puede estar truncada
  • ✗ No uses una velocidad superior a 1.05: la voz suena metálica y artificial
  • ✗ No ignores las pronunciaciones incorrectas de términos en inglés en el texto PT-BR
Confirma la duración con ffprobe
# medir la duración exacta de cada WAV
ffprobe -v error -show_entries format=duration \
-of default=noprint_wrappers=1:nokey=1 \
assets/audio/s1.wav

# resultado: p. ej. 14.2327
14.2327

# usa este valor en AUDIO[0] en build-index.mjs
const AUDIO = [14.23, /* s2 */ 11.80, ...]
💡
Voces PT-BR disponibles en Kokoro

Además de pf_dora (femenina, recomendada por defecto con --speed 0.98), hay pm_alex e pm_santa para variaciones masculinas. Si la pronunciación de un término es incorrecta, reescríbelo fonéticamente en el assets/txt/sN.txt y vuelve a generar el WAV.

Conceptos clave
👂
Revisión humana
Claude no escucha
🎙️
pf_dora
speed 0.98
⏱️
ffprobe
Mide la duración
📝
AUDIO[]
Sincroniza la escena
5

🚀 Render high — calidad de entrega

Tras obtener un lint limpio, un inspect sin overflow, revisar el draft y aprobar la locución, llega el momento del render final: --quality high --fps 30. Un video de ~110s equivale a ~3.500 frames y tarda 3–4 minutos en una máquina típica con 22 cores.

Qué ocurre en el render high

HyperFrames abre Chrome headless en resolución completa (1920×1080 o 1080×1920), captura cada frame en PNG, pasa todos a FFmpeg y codifica H.264 con el audio WAV integrado. A 30 fps, 110 segundos = 3.300 frames.

El tiempo de render varía según el número de colores disponibles. Con 22 colores, espera ~3–4 minutos para un video de 110s.

Comando (render 16:9 high-quality)
# render final 16:9 (1920×1080)
node build-index.mjs &&
npx hyperframes render \
--quality high \
--fps 30 \
--output renders/meu-video-16x9.mp4

# salida durante el render
⠸ Rendering frame 1547/3300 (46.9%)...
✔ Render completo → renders/meu-video-16x9.mp4
📊 Estimaciones de tiempo de renderizado (22 colores)
Video corto (~60s)
~1.800 frames
≈ 1,5–2 min de renderizado
Video estándar (~110s)
~3.300 frames
≈ 3–4 min de renderizado
Video largo (~180s)
~5.400 frames
≈ 5–7 min de renderizado
✓ Antes de iniciar el render high
  • ✓ npx hyperframes lint — 0 errores confirmados
  • ✓ npx hyperframes inspect --samples 16 — 0 problemas de diseño
  • ✓ Borrador revisado visualmente (1 frame/escena)
  • ✓ Locución aprobada por el usuario
✗ No hagas un render high si...
  • ✗ El lint aún reporta errores: fallará a mitad del render
  • ✗ No vio ningún frame del draft: riesgo de retrabajo
  • ✗ El usuario no escuchó los archivos WAV; puede que sea necesario volver a renderizar
  • ✗ O index.html no se regeneró después de la última edición
Conceptos clave
🚀
--quality high
Resolución completa
🎞️
30 fps
Entrega estándar
⏳
~3.500 frames
110s de video
🏁
H.264 MP4
Listo para subir
6

📐 Generar los dos formatos — 16:9 y 9:16

A partir del mismo proyecto, genera el formato 16:9 (YouTube) y el 9:16 (Shorts/Reels) en secuencia. La regla crítica: renderiza justo después de generar cada formato — nunca dejes dos index.html simultáneos en la raíz.

Regla del index.html único

O build-index.mjs siempre sobrescribe el mismo index.html. Si ejecutas los dos modos antes de renderizar, el segundo sobrescribe el primero y pierdes la composición. La secuencia correcta es: generar → renderizar → generar otra versión → renderizar.

Secuencia completa (orden correcto)
# ── PASO 1: formato 16:9 ──────────────────────────
node build-index.mjs # sin flag → 1920×1080
npx hyperframes render \
--quality high --fps 30 \
--output renders/meu-video-16x9.mp4

# ── PASO 2: formato 9:16 ──────────────────────────
node build-index.mjs --vertical # → 1080×1920
npx hyperframes render \
--quality high --fps 30 \
--output renders/meu-video-9x16.mp4

# resultado: 2 archivos en renders/
renders/meu-video-16x9.mp4 # YouTube
renders/meu-video-9x16.mp4 # Shorts / Reels
📊 Formatos y destinos
16:9 — Horizontal
Resolución: 1920 × 1080 px
Destino: YouTube, Vimeo, LinkedIn
Flag: node build-index.mjs (sin flag)
Output: renders/nome-16x9.mp4
9:16 — Vertical
Resolución: 1080 × 1920 px
Destino: YouTube Shorts, Instagram Reels, TikTok
Flag: node build-index.mjs --vertical
Output: renders/nome-9x16.mp4
💡
Pipeline completo en un script

Para automatizar ambos formatos a la vez, encadena con &&:

node build-index.mjs && npx hyperframes render --quality high --output renders/v-16x9.mp4 &&
node build-index.mjs --vertical && npx hyperframes render --quality high --output renders/v-9x16.mp4

O && garantiza que el renderizado de 9:16 solo comience después de que el de 16:9 termine correctamente.

✓ Secuencia correcta
  • ✓ node build-index.mjs → render 16:9 → node build-index.mjs --vertical → render 9:16
  • ✓ Confirma siempre cuál index.html está activo antes del render
  • ✓ Nombra los outputs con el sufijo -16x9 e -9x16 desde el inicio
✗ Errores que cuestan tiempo de renderizado
  • ✗ Ejecutar build-index.mjs e build-index.mjs --vertical sin renderizar entre ambos
  • ✗ Renderizar sin --output explícito — puede sobrescribir un render anterior
  • ✗ Usar el mismo nombre de output para los dos formatos
Conceptos clave
📺
1920×1080
YouTube
📱
1080×1920
Shorts/Reels
🚩
--vertical
Flag único
⚡
Generación → renderizado
Orden obligatorio

📋 Resumen del Módulo 2.5

Qué aprendiste
  • ✓ npx hyperframes lint: los 3 errores fatales y cómo corregir cada uno
  • ✓ npx hyperframes inspect --samples 16: overflow, data-layout-ignore y falsos positivos
  • ✓ Render draft + extracción de fotogramas con ffmpeg -nostdin -y -ss <t> -vframes 1 -update 1
  • ✓ Claude no escucha audio; la validación de la locución es responsabilidad del usuario
  • ✓ Render high: --quality high --fps 30 · ~110s ≈ 3.500 frames ≈ 3–4 min
  • ✓ Secuencia 16:9 → 9:16: genera y renderiza cada modo antes de generar el siguiente
Siguiente ruta
T3
🔧 Por dentro de HyperFrames
Terminaste la Ruta 2 — Pipeline. La siguiente ruta profundiza en el funcionamiento interno del framework: cómo Chrome headless controla el tiempo, cómo FFmpeg codifica y cómo GSAP se integra en el renderizado cuadro por cuadro.
Iniciar Ruta 3: Por dentro →