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

Aula 2 · 15 min

HyperFrames do zero: HTML com data-* vira MP4

HyperFrames é um motor aberto do HeyGen que renderiza HTML em vídeo. Três atributos dizem o tamanho e a duração, uma timeline GSAP pausada diz o movimento, e o check confere tudo antes do render. Nesta aula você cria o projeto, escreve a primeira composição e sai com um MP4 conferido.

Começar a aula
Notebook aberto numa mesa escura mostrando um quadro de vídeo escuro, com um monitor de referência ao lado.

Nesta aula você vai

  1. 1O que o init cria e por que a versão fica fixa no package.json
  2. 2A raiz com data-composition-id, data-width, data-height e data-duration
  3. 3A timeline GSAP pausada registrada em window.__timelines
  4. 4check, render e o conferidor do kit

Objetivo: criar um projeto HyperFrames, escrever a composição com data-* e renderizar um MP4 que passa no conferidor.

01O caminho de um projeto

Clique em cada etapa.

Clique em cada bloco do diagrama para ver o que ele faz.

Quando a raiz tem data-duration, é ela que manda: uma timeline mais curta segura o último quadro.

02Criar o projeto

O init sem perguntas (--non-interactive) e a telemetria desligada antes de tudo.

Terminal · criar o projeto e ver o que veio
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 -2
Exemplo do repositório
saída: 0
AGENTS.md
CLAUDE.md
hyperframes.json
index.html
meta.json
package.json
    "render": "npx --yes hyperframes@0.8.176 render",

  Status:     disabled

O script render do package.json já chama a versão exata. A telemetria aparece desligada porque o bloco exportou HYPERFRAMES_NO_TELEMETRY=1.

03A primeira composição

Título, filete e subtítulo entrando em ordem. Copie por cima do index.html do init.

Arquivo · kit/exemplos/a2-ola/index.html
<!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">Vídeo é código</h1>
        <div id="linha"></div>
        <p id="sub">Uma página HTML, um relógio, um 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>
Terminal · check, render e conferir
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: $?"
Exemplo do repositório
  ◇ 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

As cinco primeiras linhas ◇ são as partes do check (lint, execução, layout, movimento, contraste); a sexta, disabled, é a captura de quadros, que vem desligada (--snapshots liga). O conferidor lê o MP4 com ffprobe e compara com o que você pediu: 5 s, 1920×1080.

04Para o agente trabalhar com as regras certas

O HyperFrames publica skills para agentes (pesquisa, §5). O init já deixa um AGENTS.md e um CLAUDE.md na pasta do projeto.

Opcional · instalar as skills oficiais no seu agente
npx skills add heygen-com/hyperframes

05Prática

Do init ao MP4 conferido, e uma mudança sua.

E1 · Criar o projeto

5 min

Rode o bloco "criar o projeto e ver o que veio".

Pronto quando: A saída mostra saída: 0, a lista com index.html e package.json, a linha hyperframes@0.8.176 render e Status: disabled.

E2 · Primeiro MP4

10 min

Rode o bloco "check, render e conferir".

Pronto quando: ◇ Check passed, render: 0 e OK: 5,0 s · 1920×1080 · 30 fps · sem áudio com saída: 0.

E3 · Oito segundos

10 min

No index.html do seu projeto, mude data-duration da raiz para 8, troque o título por um seu, rode check e render de novo.

Pronto quando: 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 e saída: 0.

06Teste da aula

A explicação aparece depois da sua resposta.

Pergunta 1 de 4

O que define a duração do MP4 no HyperFrames?

07Em três frases

Raizdata-composition-id, tamanho e duração; clipes com data-start.
Uma timelineGSAP pausada em window.__timelines com a mesma chave da raiz.
Portãocheck antes do render, conferidor depois; versão fixa e telemetria desligada.

Para ir além

Aula anteriorPróxima aula