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 ni editar de forma 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 frame y FFmpeg ensambla el MP4. Sin una flag, el output siempre es 16:9.

✓ HACER en videos de YouTube
  • ✓ Usar --quality high en el render final
  • ✓ Mantener la narración ≈ 100s de habla (≈ 1:50 de video)
  • ✓ Incluir una miniatura de alto contraste en la escena 1
  • ✓ Generar MP4 con códec H.264, 60fps fluido
✗ NO HACER en videos de YouTube
  • ✗ Publicar render --quality draft (resolución baja)
  • ✗ 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 conversión)
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 codificarlo.
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 frame en formato 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 el 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
  • ✓ Limita a ≤ 60 s para Shorts/Reels (≤ 180 s para TikTok)
✗ NO HACER en Shorts/Reels
  • ✗ Reutilizar el diseño 16:9 sin ajustes .vertical
  • ✗ Poner el texto importante en la franja superior (cubierta por la UI de la app)
  • ✗ Ignorar el lint antes del render — los errores de diseño se ven ampliados
  • ✗ Publicar sin subtítulos (la mayoría mira sin sonido)
Conceptos clave
Flag --vertical
Inyecta una 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 interfaz de las apps: deja solo contenido 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 límite
Shorts requiere ≤ 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. Ese intervalo es lo suficientemente largo para enseñar un concepto completo y lo suficientemente 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 habla. 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 voz (TTS pf_dora)
≈ 1:50
de video renderizado
> 65%
retención promedio 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 feeds se ve sin sonido. Los subtítulos incrustados (burned-in) en el frame 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 12px: legible sobre cualquier fondo.

Estilo de subtítulos (estilo propio)
/* subtítulo integrado en el fotograma */
.caption {
position: absolute;
bottom: 72px; /* por encima de la safe zone */
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 un archivo de subtítulos

La caption de HyperFrames es burned-in — forma parte del frame del video. Esto es intencional: garantiza que aparezca en cualquier plataforma, incluso cuando el reproductor está silenciado y no admite SRT/VTT. Para SEO, agrega también subtítulos por separado al subirlo 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 frame y garantiza un contraste mínimo 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 "CONTINÚA EN" + dominio destacado + URL legible. Ya viene lista en la plantilla de HyperFrames como scene9().

Escena de CTA estándar 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 16:9 y 9:16. CTA para INEMA.CLUB.
Voz pf_dora, speed 0.98, PT-BR.
Paleta premium oscura, acento ámbar #FFC300.
La 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
Repaso 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 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
  • ✓ Adapta a tu marca (reemplaza INEMA.CLUB por tu dominio)
  • ✓ Mantener el glow ámbar — identidad visual coherente
✗ NO HACER en la CTA
  • ✗ Eliminar la escena final (se pierden conversión e identidad)
  • ✗ Poner un CTA largo (> 8 s) — el viewer abandona
  • ✗ URL ilegible o fondo que compite con el texto
  • ✗ Olvidar decir la URL en la narración
Conceptos clave
scene9()
Función preconstruida en el template — no la reescribas desde cero, solo ajusta el dominio y el glow.
Glow ámbar
una sombra paralela ámbar #FFC300 pulsa en la marca — señala «haz clic aquí» sin necesidad de un botón.
Canal doble
URL visual + URL narrada = refuerzo bimodal. Quien vio el video con sonido y quien lo vio en silencio captan 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 — ningún 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 16:9 — YouTube (1920×1080)
node build-index.mjs && \
npx hyperframes render --quality high \
--output renders/kokoro-tts-16x9.mp4

# 2. Renderizar 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 el borrador primero

Usa --quality draft para verificar los tiempos y el diseño antes de dedicar tiempo al 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, ~100s de locución
→
🔧
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 del 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 errores de diseño aparecen en el reproductor
  • ✗ Sobrescribir renders/ sin control de versiones
  • ✗ Ignorar la safe zone en el modo vertical
Conceptos clave
DRY
Don't Repeat Yourself: un código fuente, dos resultados. Sin mantenimiento duplicado.
renders/
Carpeta de salida predeterminada. Usa siempre los sufijos -16x9 y -9x16 para no confundirlos.
lint + inspeccionar
Dos pases de calidad: lint verifica el HTML/JS; inspect extrae frames 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 fala (≈ 1:50) maximiza la retención. Voz pf_dora speed 0.98.
✓ Captions incrustados: Inter 600, 36px, rgba(0,0,0,0.55). Siempre activas.
✓ CTA final (scene9) obligatoria — INEMA.CLUB o tu marca.
✓ Un SCRIPT.md → dos MP4. Lint + inspect antes de publicar.
Próximo módulo:
4.2 🚀 Incorporación, clases y lanzamientos
Aplica HyperFrames a videos de bienvenida de cursos, clases grabadas y lanzamientos de productos, con variaciones de CTA según el contexto.