O que Vídeo de anúncio de produto, feito em código faz?
Um pipeline para anúncios de produto de 15–20 s sem editor de vídeo: cada quadro, som e linha de narração é gerado por scripts, então tudo é reproduzível e editável como texto.
dados do projeto ─► brief + storyboard ─► visuais ─────────────► Render Remotion ─► MP4
├ 2D: React (Remotion) ▲
└ 3D: Blender (headless) ─► quadros JPG
som: scripts/score.py ─► WAV ┘
voz: scripts/kokoro_tts.py ─┘
Exemplo prático (GhostCommits, arquivos reais): examples/ghostcommits/.
Passo 1 — Entender o produto, escrever o brief
Leia o README, a landing page e o código. Extraia: pitch de uma linha, 3–4 pontos de prova concretos (números vencem adjetivos: "1 arquivo", "0 logins"), as cores da marca do CSS, logotipo SVG, URL. Anote o que NÃO pode ser afirmado (ex.: "apenas testnet", "não anônimo", sem contagens de usuários). Cada linha na tela e na narração é verificada contra esta lista. Pergunte ao usuário para escolher uma paleta/estilo somente se a marca já não definir uma.
Passo 2 — Storyboard (escreva em um arquivo .md antes de construir)
18 s a 30 fps = 540 quadros. 5–6 tomadas de ~2,5 s (75 quadros, = uma barra a 96 BPM, então os cortes
caem na batida). Cada tomada: quadros, câmera/movimento, texto na tela, som. Termine com um cartão final
de 3–4 s (nome, tagline, URL). Modelo: references/storyboard.md.
Passo 3a — Estilo 2D (Remotion)
Tipografia cinética + formas planas, energia "Spotify Wrapped". Veja references/remotion-2d.md.
npx create-video@latest --yes --blank --no-tailwind video depois um componente por anúncio,
acionado apenas por useCurrentFrame() + interpolate com easing. Sem transições CSS.
Passo 3b — Estilo 3D (Blender, headless)
Objeto herói brilhante em um vazio preto, close-ups macro, listras de luz na superfície, cortes
secos, estatística grande + legenda pequena no canto inferior esquerdo. Veja references/blender-3d.md.
Um script Python constrói a cena, anima cada tomada e renderiza os quadros:
blender -b --factory-startup -P scene.py -- anim ../public/frames. Remotion sobrepõe o
texto nos quadros (examples/ghostcommits/GhostAdV2.tsx). Renderize 2–3 imagens primeiro e
observe-as antes da animação completa.
Passo 4 — Som (scripts/score.py)
Escreva uma planilha de cues em JSON: uma entrada por evento visual, indexada pelo número do quadro
obtido do código de animação (corte → cut_hit, objeto voa → whoosh, pousa → click/lock, listra
de luz → glint, cartão final → impact, acúmulo → riser). Depois python scripts/score.py cues.json.
Ele sintetiza tudo (sem samples, sem licenças), adiciona uma trilha musical a 96 BPM que cai em
break_frame e resolve em end_frame, e imprime volume por segundo para você verificar a sanidade
sem escutar. Detalhes e orientação de ganho: references/sound.md.
Passo 5 — Narração (opcional)
Linhas curtas, ≤ 6 palavras, uma por tomada, combinando com o texto na tela. Melhor opção gratuita:
python scripts/kokoro_tts.py lines.txt vo/ (Kokoro hospedado, 3 vozes para comparar). Adicione os
arquivos à lista voiceover da planilha de cues com tempos de início = quando o texto daquela tomada
aparece; score.py corta silêncio e abaixa a música sob a narração. Meça a duração de cada linha e
garanta que ela termina antes da próxima começar. Opções e lições: references/voiceover.md.
Passo 6 — Renderizar e entregar
<Html5Audio src={staticFile("audio/soundtrack.wav")} /> na composição, depois
npx remotion render <CompositionId> out/ad.mp4. Envie o MP4 para o usuário. Diga claramente
que você não pode ouvir o áudio: níveis e sincronia foram verificados numericamente, não de ouvido.
Regras importantes
- Cópia honesta: nenhuma afirmação que o produto não possa comprovar; mantenha ressalvas (beta, testnet) na tela.
- Não recrie o anúncio de uma marca específica (logotipos, música, personagens) — pegue emprestado apenas o estilo.
- Texto ≥ 48 px a 1080p, na tela ≥ 1,2 s, canto inferior esquerdo ou centralizado, nunca sobre o rosto do herói.
- Renderize imagens antes da renderização completa; verifique um quadro de cada tomada.
- Mantenha quadros/áudio gerados fora do git (
.gitignore); confirme scripts + storyboard.