Vídeo de produto como código
Crie vídeos de produto como código: um deck HTML orientado por uma timeline determinística, uma narração por IA, gravações reais de tela do produto e um master de áudio com ffmpeg. Tudo é reproduzível, diferível e rerrenderizável, de modo que revisões custam minutos em vez de uma reconstrução completa.
Isto não é um editor de vídeo. É um pipeline. A saída é um MP4.
A única ideia que importa
Áudio primeiro, depois timing, depois imagem.
Gere a narração antes de decidir quanto tempo cada elemento fica na tela. Meça cada clipe, derive as durações das cenas a partir dessas medições e só então renderize os frames. As alternativas – adivinhar durações ou escrever a narração para se encaixar em um storyboard fixo – produzem visuais que perdem sincronia com a voz e forçam uma nova renderização a cada reformulação de linha.
script.json ──► TTS ──► medida ──► timings.json ──► render ──► composite ──► mux ──► MP4
▲ ▲ ▲
assemble.py render.py composite.py
Para um vídeo sem narração (um título animado, um loop silencioso, um clipe social mudo), pule o estágio 1 e escreva timings.json manualmente. Todo o resto do pipeline permanece inalterado.
Pipeline
| Estágio | Script | Produz |
|---|---|---|
| 1. Narração | sua ferramenta TTS preferida | audio/vo_NN.mp3, um por cena |
| 2. Timing + faixa de voz | scripts/assemble.py | timings.json, out/voice.wav |
| 3. Imagem | scripts/render.py | out/silent.mp4 |
| 4. Gravação de tela (opcional) | scripts/capture/tour.py | capture/clips/*.mp4 |
| 5. Composição (opcional) | scripts/composite.py | out/composited.mp4 |
| 6. Master de áudio | scripts/mux.py | MP4 final |
Leia references/PIPELINE.md para o passo a passo, references/AUDIO.md para voz e música, references/SCREEN-CAPTURE.md para capturas de tela do produto e references/PITFALLS.md antes de depurar qualquer coisa — ele lista as falhas reais que este pipeline já enfrentou.
Tipos de vídeo
Mesmo pipeline para todos; o que muda é a estrutura, o ritmo e quanto do quadro é produto real. Defina qual destes você está criando antes de escrever uma linha, pois isso decide todo o resto.
| Tipo | Duração típica | Forma | Imagens do produto |
|---|---|---|---|
| Explicador de produto | 1-3 min | problema → solução → como funciona → prova → fechamento | poucas, como prova |
| Lançamento de funcionalidade | 30-90s | o que mudou → por que importa → veja como → como obter | quantidade média |
| Demonstração / passo a passo | 2-5 min | uma tarefa real, do início ao fim | predominante |
| Tutorial | 3-10 min | passo a passo, com capítulos, pausas para acompanhar | predominante |
| Notas de versão | 30-90s | um item por batida, denso | capturas de tela ou clipes curtos |
| Onboarding | 1-3 min | o caminho da primeira execução, conforme o usuário o encontra | predominante |
| Título animado / loop | 5-20s | uma ideia, geralmente silencioso | nenhuma |
| Corte para redes sociais | até 60s | gancho primeiro, derivado de um corte maior | curto, impactante |
Regras práticas que decorrem do tipo:
- Demonstrações e tutoriais são prioridade de gravação de tela. O deck é uma moldura ao redor do produto — cartões de título, destaques, quebras de capítulo. Não narre o que a tela já mostra.
- Explicadores e lançamentos são prioridade de narração. As imagens aparecem como evidência de uma afirmação que você acabou de fazer; essa proximidade é o que as faz ter impacto.
- Tutoriais precisam de pausas. Deixe um tempo após cada etapa. Use
--tailgenerosamente; o espectador está acompanhando, não apenas assistindo. - Notas de versão são densas. O texto na tela carrega a mensagem, a narração resume. Um item por batida, sem delongas.
- Cortes para redes sociais são derivados, nunca escritos duas vezes. Construa-os como um subconjunto de cenas do corte longo para que não possam divergir (veja PIPELINE.md).
Início rápido
Configuração, uma vez: pip install -r requirements.txt && playwright install chromium. ffmpeg e ffprobe também devem estar no PATH.
Primeiro, silencioso, para verificar se o deck renderiza:
cp templates/deck.html .
python3 scripts/render.py --preview 2 8 18 # imagens estáticas
python3 scripts/render.py # -> out/silent.mp4
Depois o pipeline completo, assim que a narração existir:
cp templates/script.example.json script.json
# gere audio/vo_01.mp3 ... um por cena, depois:
python3 scripts/assemble.py # timings.json + out/voice.wav
python3 scripts/render.py # out/silent.mp4
python3 scripts/mux.py --final out/final.mp4 # adiciona voz (+ música se audio/bed.mp3 existir)
assemble.py é o único estágio que precisa de áudio; sem ele render.py usa as durações declaradas no deck.
Regras que mantêm isso funcionando
Nunca conduza a timeline com o tempo real do relógio. O renderizador busca um t explícito e captura a tela. render.py chama window.__seek(t) para cada frame, então uma máquina lenta produz um arquivo idêntico a uma rápida. Qualquer coisa usando requestAnimationFrame ou animações CSS com playback irá rasgar ou pular frames sob um loop de captura.
Prenda cada animação a uma batida da narração. Se a voz disser "três coisas" em 4,2s, o terceiro cartão aparece em 4,2s. Após qualquer reescrita, verifique novamente as batidas – uma linha que retorna 3s mais curta deixará seus visuais órfãos. Esse é o maior fator para determinar se o resultado parece dirigido ou genérico.
Renderize em blocos retomáveis. render.py escreve out/parts/part_NNN.mp4 e pula partes concluídas ao ser executado novamente. Uma captura travada custa um bloco, não a passagem inteira. Nunca execute duas renderizações contra o mesmo diretório de partes.
Meça, não suponha. Verifique com números, não com sensações:
- detecção de quadro em branco: conte pixels escuros (
(pixels < 200).mean()), não desvio padrão – uma página de interface de usuário legítima e com muito branco também tem desvio baixo - pronúncia: execute o áudio gerado de volta em um serviço de fala para texto e leia
- níveis:
ffmpeg -af volumedetectno arquivo final, sempre - geometria: leia
getBoundingClientRect()do DOM em vez de codificar valores fixos
Uma fonte, muitos cortes. Selecione subconjuntos de cenas de um único deck com um parâmetro de consulta (deck.html?cut=short) para que uma demonstração longa e um corte de 40 segundos para redes sociais não possam divergir. Veja references/PIPELINE.md.
Combine a marca do produto a partir do seu código
Se o produto tem um código-fonte, leia a marca dele em vez de pedir códigos hexadecimais:
python3 scripts/detect_brand.py ../caminho-do-produto --css
Ele lê arquivos de design tokens, configurações tailwind, propriedades customizadas CSS, variáveis SCSS e Less, objetos de tema JS/TS e o manifesto web, e reporta as fontes, biblioteca de ícones e arquivos de logotipo encontrados. Cole o bloco :root que ele imprime em deck.html.
A saída de build é ignorada, já que uma pasta dist/ está cheia de CSS de bibliotecas de componentes empacotados que não representam a marca. A paleta também é verificada quanto à coerência, em vez de ser confiada apenas pela correspondência de nomes: um repositório que define --surface para seu tema claro e --bg para o escuro, de outra forma, daria um cartão branco sobre um quadro preto. Rejeições são impressas, nunca aplicadas silenciosamente.
Mostre ao usuário o que foi detectado e o que foi rejeitado antes de renderizar.
Orientações de design
O deck é HTML/CSS, então o design é totalmente seu. Duas coisas valem a pena saber:
Contextos sociais e de reprodução automática executam o vídeo sem som. O título na tela deve carregar cada batida por conta própria, e o gancho precisa acontecer no primeiro ou segundo segundo. Trate a narração como aprimoramento, não como o mecanismo de entrega.
Se for solicitado algo visualmente distinto, fundamente-o no próprio universo do assunto – seus artefatos, instrumentos e vocabulário – em vez de recorrer a um fundo escuro com uma cor de destaque brilhante, que é onde a produção genérica se concentra. A skill frontend-design da Anthropic cobre bem isso e compõe-se de forma limpa com esta.