E1 · Dos formatos del ejemplo
10 minEjecuta el bloque "marca, check, dos renders y conferir".
Listo cuando: OK: 15,0 s · 1920×1080 · 30 fps · sem áudio y OK: 15,0 s · 1080×1920 · 30 fps · sem áudio, cada uno con saída: 0.
Clase 8 · 20 min
Es hora de juntar todo en una pieza que uses: una apertura de 15 s con tu DESIGN.md, en los dos formatos que piden las redes. El 9:16 no sale del 16:9 con una opción de render: es otra composición que reutiliza el CSS y la coreografía. En esta clase entregas las dos, verificadas por el kit, y armas el plan con fechas.
Empezar la clase
Objetivo: entregar una apertura de 15 s en 16:9 y 9:16, con el DESIGN.md, verificada por el kit en los dos formatos.
Las cuatro entregas que reúne la apertura. Haz clic en un nivel para ver el "listo cuando".
init y render
3 ejercicios
Proyecto HyperFrames que renderiza y pasa el verificador.
Ver la claseDESIGN.md
3 ejercicios
DESIGN.md con las cuatro secciones y colores verificados.
Ver la claseRISE y fotogramas
3 ejercicios
Composición que hizo el agente y que tú verificaste en cinco fotogramas.
Ver la claseEl proyecto de la clase 2, con la versión fija y la telemetría desactivada. Es la carpeta donde vivirá la apertura.
El DESIGN.md de la clase 4 manda en los colores y en el movimiento de los dos formatos.
El pedido RISE de la clase 3, ahora para 15 s y dos formatos. La E incluye el check y los fotogramas de los dos.
Si tu apertura tiene voz o banda sonora, la clase 7 pone el sonido. Si no, sáltala: el verificador dice "sem áudio" y tiene razón.
Las clases 1, 5 y 6 son la base: determinismo, Remotion y bibliotecas entran cuando tu pieza lo pida.
abertura.css y abertura.js son compartidos; index.html (1920×1080) y formatos/vertical.html (1080×1920) solo cambian la raíz y una clase.
/* tokens del DESIGN.md + layout que sirve a los dos formatos (16:9 y 9:16) */
:root { --fundo: #0c0c10; --superficie: #1c1c22; --linha: #3f3f47; --texto: #f4f4f5; --texto2: #a1a1aa; --destaque: #e9b949; }
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body { overflow: hidden; background: var(--fundo); }
#root { width: 100%; height: 100%; position: relative; font-family: ui-sans-serif, system-ui, sans-serif; }
#luz { position: absolute; inset: 0; background: radial-gradient(ellipse at 50% 45%, var(--superficie) 0%, var(--fundo) 70%); }
#bloco { position: absolute; left: 10%; right: 10%; top: 50%; transform: translateY(-50%); }
#rotulo { color: var(--texto2); font-size: 40px; letter-spacing: 0.2em; text-transform: uppercase; line-height: 1.3; }
#titulo { color: var(--texto); font-size: 150px; font-weight: 700; line-height: 1.1; margin-top: 36px; }
#apoio { color: var(--texto2); font-size: 54px; line-height: 1.2; margin-top: 40px; }
#trilho { position: absolute; left: 10%; right: 10%; bottom: 14%; height: 4px; background: var(--linha); transform-origin: left center; }
#cabeca { position: absolute; left: 10%; bottom: calc(14% - 38px); width: 18px; height: 80px; background: var(--destaque); border-radius: 4px; }
/* 9:16: la misma pieza, letra más grande en relación al ancho, todo apilado */
.vertical #titulo { font-size: 132px; }
.vertical #apoio { font-size: 56px; }
.vertical #rotulo { font-size: 36px; }// La misma coreografía en los dos formatos: solo la distancia del cabezal de lectura depende del ancho.
window.criaAbertura = function () {
const root = document.getElementById("root");
const largura = Number(root.dataset.width);
const corrida = largura * 0.8 - 18; // del comienzo al final del riel (80% del ancho)
const tl = gsap.timeline({ paused: true });
tl.fromTo("#trilho", { scaleX: 0 }, { scaleX: 1, duration: 1.2, ease: "power2.inOut" }, 0.4);
tl.fromTo("#cabeca", { opacity: 0 }, { opacity: 1, duration: 0.3 }, 1.4);
tl.fromTo("#rotulo", { y: 24, opacity: 0 }, { y: 0, opacity: 1, duration: 0.6, ease: "power2.out" }, 2.0);
tl.fromTo("#cabeca", { x: 0 }, { x: corrida, duration: 9, ease: "power1.inOut" }, 2.0);
tl.fromTo("#titulo", { y: 50, opacity: 0 }, { y: 0, opacity: 1, duration: 0.8, ease: "power3.out" }, 4.0);
tl.fromTo("#apoio", { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: 0.7, ease: "power2.out" }, 7.5);
// de 11 s a 15 s el fotograma principal se sostiene (regla del DESIGN.md: el final se sostiene al menos 1,5 s)
return tl;
};<!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>
<link rel="stylesheet" href="abertura.css" />
<style>html, body { width: 1920px; height: 1080px; }</style>
</head>
<body>
<div id="root" data-composition-id="main" data-start="0" data-duration="15" data-width="1920" data-height="1080">
<div id="luz"></div>
<div id="bloco">
<p id="rotulo">Formação Cinema com IA</p>
<h1 id="titulo">Motion por código</h1>
<p id="apoio">HyperFrames e Remotion, do terminal ao MP4</p>
</div>
<div id="trilho"></div>
<div id="cabeca"></div>
</div>
<script src="abertura.js"></script>
<script>window.__timelines["main"] = window.criaAbertura();</script>
</body>
</html>K=~/projetos/formacao-cinema-ia-motion-v72/kit
export HYPERFRAMES_NO_TELEMETRY=1 NO_COLOR=1
E=${TMPDIR:-/tmp}/ensaio-motion/a8; rm -rf "$E"; mkdir -p "$E"
cp -r "$K/exemplos/a8-abertura" "$E/abertura"; cd "$E/abertura"
python3 "$K/conferir-design.py" DESIGN.md abertura.css; echo "saída: $?"
npx -y hyperframes@0.8.176 check 2>&1 | grep -E "Check passed|✗"
npx -y hyperframes@0.8.176 render --quality draft --workers 2 --quiet --output renders/abertura-16x9.mp4 > render-16x9.log 2>&1
npx -y hyperframes@0.8.176 render -c formatos/vertical.html --quality draft --workers 2 --quiet --output renders/abertura-9x16.mp4 > render-9x16.log 2>&1
python3 "$K/conferir.py" renders/abertura-16x9.mp4 15 1920x1080; echo "saída: $?"
python3 "$K/conferir.py" renders/abertura-9x16.mp4 15 1080x1920; echo "saída: $?"OK: 4 seções · 6 cores · 5 regras de movimento · a composição usa só cores do DESIGN.md saída: 0 ◇ Check passed OK: 15,0 s · 1920×1080 · 30 fps · sem áudio saída: 0 OK: 15,0 s · 1080×1920 · 30 fps · sem áudio saída: 0
El render del 9:16 usa -c formatos/vertical.html. El vertical.html es el index.html con la raíz en 1080×1920, la clase vertical y las rutas ../abertura.css y ../abertura.js.
✗ Output resolution incompatible outputResolution portrait (1080×1920) does not match the aspect ratio of the composition (1920×1080). The composition is landscape, so use --resolution landscape instead.
La opción --resolution cambia la resolución dentro de la misma proporción (por ejemplo, 4K). Pasar de 16:9 a 9:16 es cambiar el encuadre: otra composición.
En el primer render, el 9:16 partió el título en "Motion por" / "código": falla 2 de la clase 3. La corrección fue unir las dos últimas palabras con en el HTML ("por código"). Solo apareció mirando los fotogramas.
Intentar sacar el 9:16 de la composición 16:9 con una opción de render.
export HYPERFRAMES_NO_TELEMETRY=1 NO_COLOR=1
cd ${TMPDIR:-/tmp}/ensaio-motion/a8/abertura
npx -y hyperframes@0.8.176 render --resolution portrait --quality draft --output renders/torto.mp4 2>&1 | grep -A2 "incompatible"En una máquina común, el render va de a uno. Ejecuta, interrumpe y ejecuta de nuevo: solo lo que faltó vuelve a la cola.
Simulación en el navegador: nada se renderiza de verdad. La falla es intencional, para mostrar que solo vuelve la etapa que falló.
El ensayo, el error y tu apertura.
Ejecuta el bloque "marca, check, dos renders y conferir".
Listo cuando: OK: 15,0 s · 1920×1080 · 30 fps · sem áudio y OK: 15,0 s · 1080×1920 · 30 fps · sem áudio, cada uno con saída: 0.
Ejecuta el bloque del --resolution portrait.
Listo cuando: ✗ Output resolution incompatible y la línea que termina en use --resolution landscape instead.
En tu proyecto, con tu DESIGN.md: pídele al agente (RISE) la apertura de 15 s en index.html y formatos/vertical.html, revisa los fotogramas, renderiza los dos y ejecuta el verificador en los dos.
Listo cuando: K=~/projetos/formacao-cinema-ia-motion-v72/kit; python3 $K/conferir.py renders/abertura-16x9.mp4 15 1920x1080; python3 $K/conferir.py renders/abertura-9x16.mp4 15 1080x1920; python3 $K/conferir-design.py DESIGN.md abertura.css; echo "saída: $?" → dos líneas que empiezan con OK: 15,0 s, una con OK: 4 seções y saída: 0.
Elige la fecha de inicio y cuánto tiempo tienes por semana.
La explicación aparece después de tu respuesta.
Pregunta 1 de 3
¿Cómo sacar el 9:16 de la misma apertura?
Pregunta 2 de 3
¿Por qué la coreografía lee el ancho de la raíz (data-width)?
Pregunta 3 de 3
El render del 9:16 falló después de que el 16:9 quedó listo. ¿Qué se rehace?
Elige una alternativa. La explicación aparece después de tu intento.