PTENES
MÓDULO 4.1

📺 YouTube y Shorts

Publica un video explicativo en YouTube (16:9) y un Short/Reel (9:16) a partir del mismo proyecto HyperFrames — sin grabar con cámara, sin edición no lineal.

6
Temas
25
Minutos
Práctico
Nivel
Aplicación
Tipo
build-index.mjs node . 16:9 1920×1080 YouTube 9:16 1080× 1920 Shorts --vertical 📄 SCRIPT.md Un guion. Dos renders. node build-index.mjs node build-index.mjs --vertical
1

🖥️ Video 16:9 para YouTube

El formato estándar de YouTube es 1920 × 1080 px. Con HyperFrames, escribes escenas en HTML + GSAP y renderizas el MP4 en alta calidad, sin abrir un editor de video.

Concepto principal

El generador build-index.mjs escribe un index.html con el viewport fijo en 1920 × 1080. HyperFrames usa Chrome headless para capturar cada fotograma y FFmpeg crea el MP4. Sin la flag, el output siempre es 16:9.

✓ HACER en videos de YouTube
  • ✓ Usar --quality high en el render final
  • ✓ Mantén la narración en ≈ 100s de voz (≈ 1:50 de video)
  • ✓ Incluir una miniatura de alto contraste en la escena 1
  • ✓ Generar MP4 con códec H.264, 60fps fluidos
✗ NO HACER en videos de YouTube
  • ✗ Publicar render --quality draft (baja resolución)
  • ✗ Superar los 15 min sin capítulos (caída de la retención)
  • ✗ Usar una fuente menor que 32px (ilegible en móvil)
  • ✗ Omitir la escena de CTA (pérdida de conversiones)
Render 16:9 — comando exacto
# Genera index.html 1920×1080 y luego renderiza
node build-index.mjs &&
npx hyperframes render --quality high \
--output renders/meu-tutorial-16x9.mp4
Conceptos clave
Viewport fijo
El index.html tiene width/height hard-coded en 1920×1080: Chrome captura exactamente eso.
H.264 + FFmpeg
HyperFrames llama a FFmpeg internamente. El MP4 generado es aceptado por la carga de YouTube sin volver a codificar.
Escenas GSAP
Cada sceneN() devuelve HTML estático; anim() recibe el timeline de GSAP y anima los elementos.
2

📱 Shorts/Reels/TikTok en 9:16

El mismo proyecto HTML se convierte en un video 1080 × 1920 px con el flag --vertical. HyperFrames recompone el diseño y renderiza el fotograma vertical, sin duplicar código.

📊 Dimensiones y destinos
16:9 — Horizontal
Resolución: 1920 × 1080 px
Destino: YouTube, Vimeo, LinkedIn
Flag: node build-index.mjs (sin flag)
9:16 — Vertical
Resolución: 1080 × 1920 px
Destino: YouTube Shorts, Instagram Reels, TikTok
Flag: node build-index.mjs --vertical
💡
Diseño adaptable con CSS

En el modo --vertical, HyperFrames inyecta la clase .vertical no <body>. Usa selectores .vertical .sua-classe en el CSS de las escenas para reposicionar elementos — columna en lugar de fila, texto más grande, márgenes más pequeños.

✓ HACER en Shorts/Reels
  • ✓ Usar fuentes ≥ 48px en modo vertical (zona segura más pequeña)
  • ✓ Mantén el CTA y los subtítulos en la mitad inferior de la pantalla
  • ✓ Validar el diseño con npx hyperframes inspect --samples 16
  • ✓ Limitar a ≤ 60 s para Shorts/Reels (≤ 180 s para TikTok)
✗ NO HACER en Shorts/Reels
  • ✗ Reutilizar el diseño 16:9 sin ajustes .vertical
  • ✗ Colocar el texto importante en la franja superior (la UI de la aplicación la cubre)
  • ✗ Ignorar el lint antes del render — los errores de diseño aparecen ampliados
  • ✗ Publicar sin subtítulos (la mayoría mira sin sonido)
Conceptos clave
Flag --vertical
Inyecta la clase y reescribe el viewport a 1080×1920 sin alterar las funciones de escena.
Zona segura
Reserva ~15% de la parte superior e inferior para la UI de las apps: deja el contenido solo en la franja central.
Reels vs Shorts
El mismo MP4 9:16 sirve para Instagram Reels y YouTube Shorts: súbelo a ambos.
60 s de límite
Shorts debe durar ≤ 60 s para aparecer en la pestaña dedicada. Si dura más, se convierte en un video común.
3

⏱️ Por qué ~110s mantiene la retención

100 segundos de voz equivalen a ~1:50 de video. Este intervalo es lo bastante largo para enseñar un concepto completo y lo bastante corto para mantener la atención: el punto ideal para Shorts y tutoriales de YouTube.

Timeline de retención típica
0 – 5 s
Hook — no cierres
5 – 30 s
Contexto rápido
30 – 90 s
Contenido central
90 – 110 s
CTA — conversión
> 180 s
Caída pronunciada
⚡
La narración es el metrónomo

Cada escena de SCRIPT.md tiene ≈ 15–18 s de narración (medido con ffprobe). Con 6–7 escenas llegas exactamente a ~100 s de voz. Voz: pf_dora --speed 0.98 en Kokoro. Guarda las duraciones en el array AUDIO[] del build-index.mjs.

📊 Ecuación duración × retención
~100s
de habla (TTS pf_dora)
≈ 1:50
de video renderizado
> 65%
retención media esperada
Conceptos clave
Hook en los 5s
La escena 1 determina si el viewer se queda. Empieza con la promesa o el problema: nunca con una intro de marca.
AUDIO[] real
Completa con las duraciones exactas de ffprobe assets/audio/sN.wav — HyperFrames sincroniza la animación y el audio.
speed 0.98
Una velocidad ligeramente inferior a 1.0 hace que el habla suene más natural en PT-BR con la voz pf_dora.
4

💬 Subtítulos/captions siempre activados

El 85 % de los videos en los feeds se ve sin sonido. Los subtítulos integrados en el fotograma (burned-in) garantizan accesibilidad y legibilidad incluso sin sonido, y además refuerzan la identidad visual dark premium.

Cómo funciona en HyperFrames

El array CAPTIONS[] en build-index.mjs define textos sincronizados con el audio. La plantilla inyecta un <div class="caption"> fijo en el pie de cada escena. El CSS predeterminado usa Inter 600, 36px, fondo rgba(0,0,0,0.55), padding de 12px: legible sobre cualquier fondo.

Estilo de captions (estilo de la casa)
/* caption integrada en el frame */
.caption {
position: absolute;
bottom: 72px; /* sobre la zona segura */
left: 50%; transform: translateX(-50%);
font-family: 'Inter', sans-serif;
font-weight: 600;
font-size: 36px;
color: #F0EBD8;
background: rgba(0,0,0,0.55);
border-radius: 8px;
padding: 10px 20px;
max-width: 80%; text-align: center;
}
⚠️
Caption no es una leyenda de archivo

La caption de HyperFrames es burned-in — forma parte del frame del video. Es intencional: garantiza que aparezca en cualquier plataforma, incluso cuando el reproductor está en silencio y no admite SRT/VTT. Para SEO, añade también subtítulos por separado al subir el video a YouTube.

💡
Vertical: ajusta el font-size

En el modo --vertical, usa .vertical .caption { font-size: 52px; bottom: 160px; } — la resolución 1080×1920 es mucho mayor y el caption debe escalarse.

Conceptos clave
CAPTIONS[]
Array de strings en build-index.mjs: cada elemento corresponde a una escena y se inyecta en el frame.
Accesibilidad
Los subtítulos incrustados sirven a las personas sordas y a quienes están en un entorno sin audio (autobús, trabajo).
rgba translúcido
El fondo semitransparente conserva el aspecto del fotograma y garantiza el contraste mínimo de WCAG 2.1 AA.
5

🏁 CTA al final

La última escena es el CTA — Call to Action. En el estándar de INEMA.CLUB, muestra "CONTINUA EN" + dominio destacado + URL legible. Ya viene lista en la plantilla de HyperFrames como scene9().

Escena CTA estándar de INEMA.CLUB

La escena final muestra "CONTINÚA EN" + INEMA.CLUB con glow ámbar, URL 🌐 inema.club y una narración breve: "Esto es contenido de INEMA punto CLUB. Accede: inema punto club.". Es la scene9() en el template — no lo elimines.

Prompt de ejemplo — activar la skill video-explicativo
# Pega en Claude Code (skill video-explicativo instalada)
Crea un video explicativo sobre "cómo funciona Kokoro TTS".
Genera en 16:9 y 9:16. CTA para INEMA.CLUB.
Voz pf_dora, speed 0.98, PT-BR.
Paleta dark premium, acento ámbar #FFC300.
El skill sigue el flujo: SCRIPT.md → init → fetch-fonts → narración WAV → build-index.mjs → lint → render ×2.
Dónde aparece el CTA en la estructura del video
Escenas 1–7: contenido
Guion, ejemplos, animaciones: el valor real del video.
Escena 8: resumen
Resumen rápido (3–5 s) de los puntos principales: ancla la memoria.
Escena 9: CTA INEMA.CLUB ← obligatorio
INEMA.CLUB con glow + URL + narración breve. Ya está incluida en la plantilla.
✓ HACER en el CTA
  • ✓ Mantén la escena de CTA en TODOS los videos
  • ✓ URL legible y URL mencionada en la narración
  • ✓ Adaptar a tu marca (cambia INEMA.CLUB por tu dominio)
  • ✓ Mantén el brillo ámbar: identidad visual coherente
✗ NO HACER en la CTA
  • ✗ Eliminar la escena final (se pierde conversión e identidad)
  • ✗ Agregar un CTA largo (> 8 s): el espectador abandona
  • ✗ URL ilegible o con un fondo que compite con el texto
  • ✗ Olvidar decir la URL en la narración
Conceptos clave
scene9()
Función preconstruida en la plantilla: no la reescribas desde cero, solo ajusta el dominio y el resplandor.
Glow ámbar
la sombra drop-shadow ámbar #FFC300 pulsa en la marca — indica "haz clic aquí" sin necesidad de un botón.
Doble canal
URL visual + URL narrada = refuerzo bimodal. Quien lo vio con sonido y quien lo vio en silencio capta el destino.
6

♻️ Un guion, dos formatos

Un único SCRIPT.md + uno solo build-index.mjs producen los dos MP4. Es el flujo completo de publicación de HyperFrames: no hay código duplicado.

Principio DRY aplicado al video

Escribe el guion una vez. Adapta el CSS de las escenas con selectores .vertical. Ejecuta el generador dos veces. El resultado son dos MP4 listos para publicar en YouTube (16:9) y en YouTube Shorts / Instagram Reels / TikTok (9:16).

Secuencia completa de renderizado (ambos formatos)
# 1. Renderizar en 16:9 — YouTube (1920×1080)
node build-index.mjs && \
npx hyperframes render --quality high \
--output renders/kokoro-tts-16x9.mp4

# 2. Renderizar en 9:16 — Shorts/Reels (1080×1920)
node build-index.mjs --vertical && \
npx hyperframes render --quality high \
--output renders/kokoro-tts-9x16.mp4

# 3. Validar antes de publicar
npx hyperframes lint # 0 errores
npx hyperframes inspect --samples 16 # 0 problemas de diseño
💡
Renderiza siempre primero el borrador

Usa --quality draft para revisar el timing y el diseño antes de invertir tiempo en el render final. Extrae frames con npx hyperframes inspect --samples 16 y revisa las 16 capturas antes de ejecutar --quality high.

Pipeline resumido
📄
SCRIPT.md
6–9 escenas, ~100 s de voz
→
🔧
build-index.mjs
sceneN() + anim()
→
🎬
16x9.mp4
9x16.mp4
listos para subir
✓ HACER en el flujo dual
  • ✓ Renderizar primero en 16:9, validar y después en 9:16
  • ✓ Guardar los dos MP4 en renders/ con nombres distintos
  • ✓ Probar --quality draft en ambos modos antes de high
  • ✓ Agregar selectores .vertical en el CSS de escenas con texto largo
✗ NO HACER en el flujo dual
  • ✗ Mantener dos archivos build-index separados (viola DRY)
  • ✗ Publicar sin hacer lint — los bugs de diseño aparecen en el reproductor
  • ✗ Sobrescribir renders/ sin control de versiones
  • ✗ Ignorar la zona segura en el modo vertical
Conceptos clave
DRY
Don't Repeat Yourself: un código fuente, dos resultados. Cero mantenimiento duplicado.
renders/
Carpeta de salida predeterminada. Usa siempre los sufijos -16x9 y -9x16 para no confundirlos.
lint + inspect
Dos pasadas de calidad: lint verifica HTML/JS; inspect extrae fotogramas y muestra el desbordamiento visual.
draft → high
El render draft es rápido (~20s). High puede tardar minutos. Valida siempre primero en draft.

📋 Resumen del Módulo 4.1

✓ 16:9 (1920×1080) = YouTube. Sin flag en build-index.mjs.
✓ 9:16 (1080×1920) = Shorts/Reels/TikTok. Flag --vertical.
✓ ~100s de habla (≈ 1:50) maximiza la retención. Voz pf_dora speed 0.98.
✓ Captions integradas en el video: Inter 600, 36px, rgba(0,0,0,0.55). Siempre activadas.
✓ CTA final (scene9) obligatorio — INEMA.CLUB o tu marca.
✓ Un SCRIPT.md → dos MP4s. Ejecuta lint + inspect antes de publicar.
Próximo módulo:
4.2 🚀 Incorporación, clases y lanzamientos
Aplica HyperFrames en videos de bienvenida a cursos, clases grabadas y lanzamientos de productos, con variaciones de CTA según el contexto.