E1 · Crear el proyecto
5 minEjecuta el bloque "criar o projeto e ver o que veio".
Listo cuando: La salida muestra saída: 0, la lista con index.html y package.json, la línea hyperframes@0.8.176 render y Status: disabled.
Clase 2 · 15 min
HyperFrames es un motor abierto de HeyGen que renderiza HTML en video. Tres atributos dicen el tamaño y la duración, una timeline GSAP en pausa dice el movimiento, y el check lo revisa todo antes del render. En esta clase creas el proyecto, escribes la primera composición y sales con un MP4 verificado.
Empezar la clase
Objetivo: crear un proyecto HyperFrames, escribir la composición con data-* y renderizar un MP4 que pase el verificador.
Haz clic en cada etapa.
Cuando la raíz tiene data-duration, es ella la que manda: una timeline más corta sostiene el último fotograma.
El init sin preguntas (--non-interactive) y la telemetría desactivada antes de todo.
export HYPERFRAMES_NO_TELEMETRY=1 NO_COLOR=1
E=${TMPDIR:-/tmp}/ensaio-motion/a2; rm -rf "$E"; mkdir -p "$E"; cd "$E"
npx -y hyperframes@0.8.176 init minha-abertura --non-interactive > init.log 2>&1; echo "saída: $?"
ls minha-abertura
grep '"render"' minha-abertura/package.json
npx -y hyperframes@0.8.176 telemetry status | head -2saída: 0
AGENTS.md
CLAUDE.md
hyperframes.json
index.html
meta.json
package.json
"render": "npx --yes hyperframes@0.8.176 render",
Status: disabledEl script render del package.json ya llama a la versión exacta. La telemetría aparece desactivada porque el bloque exportó HYPERFRAMES_NO_TELEMETRY=1.
Por defecto el CLI envía datos anónimos de uso. El telemetry status del 0.8.176 muestra cómo desactivarla: hyperframes telemetry disable (queda guardado) o las variables HYPERFRAMES_NO_TELEMETRY=1 o DO_NOT_TRACK=1 (solo en la sesión). Los bloques del curso usan la variable.
Título, filete y subtítulo entrando en orden. Cópialo sobre el index.html del init.
<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=1920, height=1080" />
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { width: 1920px; height: 1080px; overflow: hidden; background: #0c0c10; }
#root { width: 100%; height: 100%; position: relative; font-family: ui-sans-serif, system-ui, sans-serif; }
#cena { position: absolute; inset: 0; display: flex; flex-direction: column; justify-content: center; padding-left: 200px; }
#titulo { color: #f4f4f5; font-size: 120px; font-weight: 700; line-height: 1.1; letter-spacing: -0.02em; }
#linha { width: 640px; height: 6px; margin: 36px 0; background: #e9b949; transform-origin: left center; }
#sub { color: #a1a1aa; font-size: 48px; line-height: 1.2; }
</style>
</head>
<body>
<div id="root" data-composition-id="main" data-start="0" data-duration="5" data-width="1920" data-height="1080">
<section id="cena">
<h1 id="titulo">El video es código</h1>
<div id="linha"></div>
<p id="sub">Una página HTML, un reloj, un MP4.</p>
</section>
</div>
<script>
const tl = gsap.timeline({ paused: true });
tl.fromTo("#titulo", { y: 60, opacity: 0 }, { y: 0, opacity: 1, duration: 0.8, ease: "power3.out" }, 0.3);
tl.fromTo("#linha", { scaleX: 0 }, { scaleX: 1, duration: 0.7, ease: "power2.inOut" }, 0.9);
tl.fromTo("#sub", { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.6, ease: "power2.out" }, 1.4);
window.__timelines["main"] = tl;
</script>
</body>
</html>K=~/projetos/formacao-cinema-ia-motion-v72/kit
export HYPERFRAMES_NO_TELEMETRY=1 NO_COLOR=1
cd ${TMPDIR:-/tmp}/ensaio-motion/a2/minha-abertura
cp "$K/exemplos/a2-ola/index.html" index.html
npx -y hyperframes@0.8.176 check 2>&1 | grep -E "◇|✗|⚠"
npx -y hyperframes@0.8.176 render --quality draft --workers 2 --quiet --output renders/abertura.mp4 > render.log 2>&1
echo "render: $?"
python3 "$K/conferir.py" renders/abertura.mp4 5 1920x1080; echo "saída: $?"◇ 0 errors, 0 warnings ◇ 0 errors, 0 warnings ◇ 0 issues across 9 sample(s) ◇ 0 errors, 0 warnings ◇ 7/7 text checks pass WCAG AA ◇ disabled ◇ Check passed render: 0 OK: 5,0 s · 1920×1080 · 30 fps · sem áudio saída: 0
Las cinco primeras líneas ◇ son las partes del check (lint, ejecución, layout, movimiento, contraste); la sexta, disabled, es la captura de fotogramas, que viene desactivada (--snapshots la activa). El verificador lee el MP4 con ffprobe y lo compara con lo que pediste: 5 s, 1920×1080.
Poner data-start en una sección que tiene título y texto dentro hizo que el lint del 0.8.176 avisara nested_structure_needs_subcomposition. En el ejemplo, la sección es solo un contenedor (sin data-start) y la timeline anima a los hijos; una escena con varios elementos propios se vuelve subcomposición.
HyperFrames publica skills para agentes (investigación, §5). El init ya deja un AGENTS.md y un CLAUDE.md en la carpeta del proyecto.
npx skills add heygen-com/hyperframes
Del init al MP4 verificado, y un cambio tuyo.
Ejecuta el bloque "criar o projeto e ver o que veio".
Listo cuando: La salida muestra saída: 0, la lista con index.html y package.json, la línea hyperframes@0.8.176 render y Status: disabled.
Ejecuta el bloque "check, render e conferir".
Listo cuando: ◇ Check passed, render: 0 y OK: 5,0 s · 1920×1080 · 30 fps · sem áudio con saída: 0.
En el index.html de tu proyecto, cambia data-duration de la raíz a 8, cambia el título por uno tuyo, ejecuta check y render de nuevo.
Listo cuando: python3 ~/projetos/formacao-cinema-ia-motion-v72/kit/conferir.py renders/abertura.mp4 8 1920x1080; echo "saída: $?" → OK: 8,0 s · 1920×1080 · 30 fps · sem áudio y saída: 0.
La explicación aparece después de tu respuesta.
Pregunta 1 de 4
¿Qué define la duración del MP4 en HyperFrames?
Pregunta 2 de 4
El check pasó, pero el render salió mal. ¿Cuál de estos el check NO garantiza?
Pregunta 3 de 4
¿Por qué el curso fija hyperframes@0.8.176 en cada comando?
Pregunta 4 de 4
¿Cómo desactivar la telemetría solo en la sesión de la terminal?
Elige una alternativa. La explicación aparece después de tu intento.