MÓDULO 1.1

🕐 O motor do tempo

No Remotion não existe "play". Existe uma pergunta repetida muito rápido: "que imagem desenhar no frame N?". Entender essa virada mental é o que destrava todos os outros 80 templates.

6
Tópicos
40
Minutos
Básico
Nível
Teoria
Tipo
linha do tempo (durationInFrames = 90 · 30fps = 3s) 0 1 2 3 frame 42 seu componente desenha o frame 42 imagem um quadro do vídeo Repetir para todos os 90 frames → o player junta tudo num vídeo de 3 segundos. Nenhum frame depende do anterior — cada um se calcula sozinho.
1

🕐 useCurrentFrame() — o relógio

Em uma página web você usaria requestAnimationFrame ou um setInterval e acumularia estado. No Remotion, esquece tudo isso. Você só pergunta: "em que frame estou agora?" — e useCurrentFrame() responde com um número inteiro que cresce de 0 até o fim do vídeo.

🎯 A ideia central

O frame é a entrada e a imagem é a saída. Mudou o frame, recalcula tudo do zero. Esse hook é o ponto de partida de praticamente todo template da biblioteca.

  • Retorna um número: 0 no começo, e cresce de 1 em 1.
  • O componente é re-executado para cada frame durante o render.
  • Você nunca "avança" o tempo — o Remotion faz isso por você.
Componente mínimo MyVideo.tsx
import { useCurrentFrame } from "remotion";

export const MyVideo = () => {
  const frame = useCurrentFrame();   // 0, 1, 2, 3 …
  return <div>Frame atual: {frame}</div>;
};

💡 Dica prática

Quer testar? Abra o Remotion Studio e arraste a barra de tempo. O número que aparece é exatamente o que useCurrentFrame() devolve. Ver o número mudar enquanto você arrasta torna o conceito concreto.

Retorno
Número inteiro ≥ 0
Reatividade
Recalcula por frame
Sem estado
Não acumula nada
Base de
interpolate, spring
2

⚙️ fps e durationInFrames — a régua

O frame sozinho não diz quanto tempo passou. Quem dá escala é o fps (frames por segundo). A 30fps, o frame 30 é "1 segundo". O durationInFrames diz quantos frames o vídeo tem no total — é o seu limite de tempo.

📊 Conversões que você vai usar toda hora

  • segundos × fps = frames — 2s a 30fps = 60 frames
  • frames ÷ fps = segundos — 90 frames a 30fps = 3s
  • 30fps — padrão web/social, leve para renderizar
  • 60fps — mais fluido, dobra o custo de render

✓ O que FAZER

  • Definir fps e duração na <Composition>.
  • Derivar tempos a partir do fps (fps * 1.5 para 1,5s).
  • Pensar a animação dentro da janela de durationInFrames.

✗ O que NÃO fazer

  • Cravar "frame 45" sem lembrar que isso muda se o fps mudar.
  • Animar além de durationInFrames (some no render final).
  • Misturar 30 e 60fps entre cenas sem converter.
fps
Frames por segundo
duração
Total em frames
Padrão
30fps
Regra
s × fps = frames
3

📐 useVideoConfig() — dimensões e fps

Como saber o fps dentro do componente, sem hardcode? E a largura, para centralizar algo? O useVideoConfig() devolve tudo: width, height, fps e durationInFrames da composição que está sendo renderizada.

Responsivo ao formato Centered.tsx
const { width, height, fps } = useVideoConfig();
const frame = useCurrentFrame();

// "1 segundo" funciona em 30 ou 60fps:
const apareceu = frame > fps;
// centralizar sem saber o tamanho exato:
const cx = width / 2;

💡 Por que isso importa

O mesmo componente pode rodar em 16:9 (1920×1080) e 9:16 (1080×1920) sem mudar uma linha — se você ler width/height de useVideoConfig() em vez de cravar números. É assim que um template vira reutilizável entre YouTube e Reels.

width
Largura em px
height
Altura em px
fps
Sem hardcode
Ganho
Multiformato
4

🎯 O frame como fonte de verdade

Aqui está a regra de ouro: a imagem de um frame depende SÓ do número do frame. Nada de useState acumulando, nada de timers, nada de "quanto tempo passou desde que cliquei". Cada frame é uma função pura.

1

O render pede frames fora de ordem

Para ir rápido, o Remotion renderiza vários frames em paralelo — pode calcular o frame 80 antes do 20. Só funciona porque cada um é independente.

2

Estado de tempo real quebra isso

Um setInterval assume que o tempo corre continuamente. No render isso não existe — cada frame é um cálculo isolado. Por isso a animação vem do frame, não de timers.

3

Tudo deriva de uma entrada

Posição, opacidade, cor, escala — todos são funções do frame. Mudou o frame, recalcula. Essa disciplina é o que mantém o vídeo consistente.

Função pura
frame → pixels
Sem timers
Nada de setInterval
Paralelizável
Render rápido
Previsível
Sempre igual
5

🔁 Determinismo — mesmo frame, mesma imagem

Consequência direta da regra anterior: renderizar o frame 42 hoje, amanhã ou em outra máquina produz exatamente o mesmo pixel. Isso se chama determinismo — e tem um inimigo claro: a aleatoriedade não-semeada.

⚠️ Atenção: o que destrói o determinismo

  • Math.random() — dá um valor diferente em cada cálculo, faz partículas "piscarem".
  • Date.now() / new Date() — muda a cada execução.
  • Qualquer dado externo que varie entre renders.

A solução: random() semeado

O Remotion oferece random("seed"): dada a mesma semente, devolve sempre o mesmo número. Você ganha "aleatoriedade" visual sem perder reprodutibilidade.

import { random } from "remotion";
// mesma seed → mesmo valor, sempre:
const x = random("particula-7") * width;
Determinismo
Sempre reprodutível
Vilão
random sem seed
Solução
random("seed")
Ganho
Render paralelo OK
6

⏱️ Pensar em frames, não em segundos

Última mudança de hábito do módulo: a sua unidade de trabalho passa a ser o frame. "O título entra em meio segundo" vira "o título entra em 15 frames". Segundos só aparecem na borda do sistema — quando um humano digita um valor.

✓ Mentalidade frame

  • "Aparece do frame 0 ao 15" — direto na API.
  • Stagger: item N começa no frame N×5.
  • Converter segundos só na entrada: 0.5 * fps.

✗ Mentalidade segundo

  • Calcular "0,5s" no meio da animação toda hora.
  • Misturar segundos e frames na mesma conta.
  • Esquecer que mudar o fps reescala tudo em segundos.

💡 Regra de bolso

A 30fps: 15 frames = 0,5s, 30 frames = 1s, 45 frames = 1,5s. Decore esses três e você estima qualquer timing de cabeça.

Unidade
O frame
Segundos
Só na borda
Conversão
× fps
Decore
15 / 30 / 45

📌 Resumo do módulo

useCurrentFrame() — o número do frame atual é a única entrada de tempo que importa.
fps e durationInFrames — convertem segundos em frames e definem a janela do vídeo.
useVideoConfig() — dá width/height/fps sem hardcode, tornando o template multiformato.
Função pura e determinismo — cada frame se calcula sozinho; use random("seed") para aleatoriedade segura.
Pensar em frames — frame é a unidade; segundos só na borda.

Próximo módulo:

1.2 — interpolate(): transformar o número do frame em opacidade, posição e escala.