🧹 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.
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.
overlapping_clipsDos 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_compositionsMá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_importEl 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.
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.
🔍 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.
- ✓ Agrega
data-layout-ignoreen elementos decorativos fuera del lienzo (palabras gigantes de fondo, glows,.bg-layer) - ✓ Prefiere
left/righten lugar dewidthpara marcadores de resaltado - ✓ Prueba código largo en
overflow-x: autocon un contenedor de ancho explícito - ✓ Usa
z-index:-1en los glows para que no se salgan del bounding box
- ✗ Texto en línea de código que sobrepasa el contenedor — acórtalo o divídelo en líneas
- ✗ SVG sin
viewBoxdefinido — el auditor no puede calcular los límites - ✗
position: absolutesinoverflow: hiddenen el padre - ✗ Elementos decorativos sin
data-layout-ignore— marcados como falso positivo de overflow
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.
🎬 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.
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.
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.
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.
| 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 |
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.
👂 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.
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.
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.
- ✓ Escucha cada
assets/audio/sN.wavantes 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
ffprobesi la duración medida coincide con elAUDIO[]
- ✗ 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
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.
🚀 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.
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.
- ✓
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
- ✗ 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.htmlno se regeneró después de la última edición
📐 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.
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.
node build-index.mjs (sin flag)renders/nome-16x9.mp4node build-index.mjs --verticalrenders/nome-9x16.mp4Para automatizar ambos formatos a la vez, encadena con &&:
O && garantiza que el renderizado de 9:16 solo comience después de que el de 16:9 termine correctamente.
- ✓
node build-index.mjs→ render 16:9 →node build-index.mjs --vertical→ render 9:16 - ✓ Confirma siempre cuál
index.htmlestá activo antes del render - ✓ Nombra los outputs con el sufijo
-16x9e-9x16desde el inicio
- ✗ Ejecutar
build-index.mjsebuild-index.mjs --verticalsin renderizar entre ambos - ✗ Renderizar sin
--outputexplícito — puede sobrescribir un render anterior - ✗ Usar el mismo nombre de output para los dos formatos
📋 Resumen del Módulo 2.5
- ✓
npx hyperframes lint: los 3 errores fatales y cómo corregir cada uno - ✓
npx hyperframes inspect --samples 16: overflow,data-layout-ignorey 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