Motion por código con agente|INEMA.CLUB-PRO

Clase 1 · 15 min

El video es código: composición con tiempo y render determinista

En el motion por código, el video es una página que sabe dibujar cualquier instante. Un navegador sin pantalla pide el fotograma 0, el 1, el 2, y FFmpeg junta todo en un MP4. Si la misma entrada da siempre los mismos fotogramas, puedes rehacer, corregir y versionar el video como código. En esta lección lo compruebas en tu máquina.

Empezar la clase
Tira de película sobre una mesa de luz fría, con un círculo blanco que crece de fotograma en fotograma.

En esta clase vas a

  1. 1Las cuatro piezas: composición, reloj, navegador sin pantalla y codificador
  2. 2Comparar dos renders fotograma a fotograma con un comando
  3. 3Por qué Math.random y Date.now rompen el video
  4. 4Sorteo con semilla: variedad sin perder la repetición

Objetivo: comprobar en tu máquina que la misma composición da los mismos fotogramas y encontrar lo que lo rompe.

01Del código al MP4

Haz clic en cada pieza. HyperFrames (HTML) y Remotion (React) siguen el mismo diseño.

Entre máquinas distintas, la GPU y las fuentes pueden cambiar algunos píxeles; para repetir en otra máquina, el render de la 0.8.176 tiene --docker ("deterministic render") y --no-browser-gpu.

Determinístico = correr dos veces en el mismo entorno y obtener los mismos fotogramas. Es lo que permite corregir un detalle sin rehacer todo lo demás.

02Lo que rompe la repetición

Tres fuentes de azar que el lint de HyperFrames detecta.

1. Sorteo

Cada render sortea de nuevo: los mismos 12 puntos nacen en lugares distintos.

El reemplazo es un sorteo con semilla (mulberry32): la misma semilla da los mismos números, siempre.

Reemplazoconst sorteio = mulberry32(42); luego sorteio() en lugar de Math.random().

03El ensayo: dos renders, comparados fotograma a fotograma

Dos composiciones casi iguales: una usa Math.random, la otra un sorteo con semilla. Cada una se renderiza dos veces y se compara por el hash de cada fotograma.

Git · clonar el curso (una vez)
git clone https://github.com/inematds/formacao-cinema-ia-motion-v72 ~/projetos/formacao-cinema-ia-motion-v72
Terminal · dos renders de cada uno y la comparación
K=~/projetos/formacao-cinema-ia-motion-v72/kit
export HYPERFRAMES_NO_TELEMETRY=1
E=${TMPDIR:-/tmp}/ensaio-motion/a1; rm -rf "$E"; mkdir -p "$E"
for ex in a1-sorteio a1-semente; do
  cp -r "$K/exemplos/$ex" "$E/$ex"; cd "$E/$ex"
  for n in 1 2; do
    npx -y hyperframes@0.8.176 render --quality draft --workers 1 --quiet --output "render-$n.mp4" > /dev/null 2>&1
  done
  echo "## $ex"; bash "$K/comparar-quadros.sh" render-1.mp4 render-2.mp4; echo "saída: $?"
done
Ejemplo del repositorio
## a1-sorteio
DIFEREM: 89 de 90 quadros
saída: 1
## a1-semente
IGUAIS: 90/90 quadros
saída: 0

Son 90 fotogramas (3 s a 30 fps). Con Math.random solo coincide el primero; con la semilla, los 90. El primer render descarga hyperframes@0.8.176 y el navegador, por eso tarda más.

04El lint encuentra el azar antes del render

El mismo par de composiciones pasado por el lint de HyperFrames. Señala la línea y sugiere la semilla.

Terminal · lint de las dos composiciones
K=~/projetos/formacao-cinema-ia-motion-v72/kit
export HYPERFRAMES_NO_TELEMETRY=1 NO_COLOR=1
for ex in a1-sorteio a1-semente; do
  cd "$K/exemplos/$ex"
  npx -y hyperframes@0.8.176 lint; echo "saída: $?"
done
Ejemplo del repositorio
◆  Linting a1-sorteio/index.html

  ✗ [~/projetos/formacao-cinema-ia-motion-v72/kit/exemplos/a1-sorteio/index.html:24:24] non_deterministic_code: Script contains `Math.random()` which produces non-deterministic output. Renders may differ between frames or runs.
    Fix: Use a seeded PRNG (e.g. a simple mulberry32) so renders are deterministic across frames.

◇  1 error(s), 0 warning(s)
saída: 1
◆  Linting a1-semente/index.html

◇  0 errors, 0 warnings
saída: 0

El lint sale con código 1 cuando encuentra un error: puedes usarlo como compuerta antes de cualquier render.

05Práctica

Ensayo, lint y tu semilla.

E1 · Ver el azar y la semilla

10 min

Clona el curso en ~/projetos y ejecuta el bloque "dos renders de cada uno y la comparación".

Listo cuando: a1-sorteio termina en DIFEREM: 89 de 90 quadros y saída: 1; a1-semente en IGUAIS: 90/90 quadros y saída: 0. (En tu computadora el número de fotogramas distintos puede variar; lo que no puede pasar es que la semilla dé distinto.)

E2 · El lint como compuerta

5 min

Ejecuta el bloque del lint.

Listo cuando: a1-sorteio muestra non_deterministic_code y saída: 1; a1-semente muestra 0 errors, 0 warnings y saída: 0.

E3 · Otra semilla, misma garantía

10 min

En /tmp/ensaio-motion/a1/a1-semente, cambia mulberry32(42) por mulberry32(7), renderiza dos veces (render-3.mp4 y render-4.mp4, con el mismo comando del bloque) y compara: 3 con 4, después 1 con 3.

Listo cuando: bash ~/projetos/formacao-cinema-ia-motion-v72/kit/comparar-quadros.sh render-3.mp4 render-4.mp4 → IGUAIS: 90/90 quadros; lo mismo con render-1.mp4 render-3.mp4 → empieza con DIFEREM:.

06Prueba de la clase

La explicación aparece después de tu respuesta.

Pregunta 1 de 4

¿Quién decide qué instante dibuja la composición?

07En tres frases

Composición + relojEl video es una página que dibuja cualquier instante que el motor pida.
DeterminismoMisma entrada, mismos fotogramas: es lo que permite corregir un detalle sin rehacer el resto.
Azar controladoSorteo con semilla, tiempo del motor y datos guardados en la carpeta; el lint vigila.

Para ir más allá

Próxima clase