Montagem automática com ffmpeg · Auto-assemble with ffmpeg
storyboard.json → Dublagem (edge-tts) → Ken Burns / corte de vídeo por cena → transições xfade → legendas ASS estilizadas → mixagem BGM com ducking → loudnorm duplo (-14 LUFS) → out/video.mp4 + .srt.
Parte de ecommerce-video-skills · Scripts estão no diretório
scripts/:assemble.py(principal) ·tts_edge.py·make_subs.py·make_bgm.py(BGM sintético livre de royalties) ·make_cards.py(cartão de produto/cartão final com PIL)
Entradas Inputs
storyboard.json(pode ser gerado porselling-point-storyboard), caminhos dos assets relativos a este arquivo- Ambiente: Python 3.9+,
pip install pillow numpy edge-tts, ffmpeg (com libass), fonte CJK
Início rápido Quick start
pip install pillow numpy edge-tts
python scripts/assemble.py examples/aura-bottle/storyboard.json -o out/aura.mp4 # Exemplo do repositório, renderiza em ~30s
python scripts/assemble.py storyboard.json --tts none -o out/preview.mp4 # Pré-visualização offline (sem dublagem, estima duração por contagem de caracteres)
python scripts/assemble.py storyboard.json --size 1080x1080 -o out/main-1x1.mp4 # Vídeo do produto principal 1:1
python scripts/assemble.py storyboard.json --bgm music.mp3 # Usar música com direitos autorais
Campos do storyboard Fields
| Campo | Descrição |
|---|---|
voice / rate / pitch no topo | Timbre, velocidade (ex.: +10%) e tom do edge-tts |
bgm no topo | "auto" (sintetizado internamente, livre de royalties) / caminho do arquivo de música / null |
tag no topo | Adesivo no canto superior esquerdo durante todo o vídeo (marca/modelo/"demonstração") |
image ou video (+start) | Asset; para vídeo, extrai a partir do segundo start pela duração da cena |
line | Texto da dublagem; duração da cena = duração da dublagem + 0,15s de antecipação + pad |
sub | Legenda (padrão igual a line); "" significa sem legenda nesta cena; **destaque**, ` |
title / cta | Texto estilizado / botão de call-to-action |
motion | zoom_in zoom_out pan_left pan_right pan_up pan_down punch static |
fit | auto (se a proporção for próxima, corta para preencher; senão, preenchimento borrado) / cover / blur |
transition | Nome da transição xfade para a próxima cena: fade slideleft slideup smoothleft circleopen wipeleft … |
min / duration / pad | Duração mínima / duração fixa / pausa após a fala (segundos) |
Etapas Steps
- Verificar se todos os assets existem e têm resolução adequada (imagem do produto ≥ 1000px); se faltar cartão final, gerar com
make_cards.py:python scripts/make_cards.py --image main.png --name "Nome do Produto" --points "Ponto 1|Ponto 2|Ponto 3" -o assets/end-card.png - Executar primeiro com
--tts nonepara verificar o ritmo visual, depois renderizar completo. - Após renderização, extrair frames para verificação:
ffmpeg -ss 3 -i out/video.mp4 -frames:v 1 check.png - Entregar para
platform-spec-exportexportar versões para cada plataforma; usarcover-title-abpara criar capa.
Detalhes do pipeline How it works
- Ken Burns: animação quadro a quadro com
scale(eval=frame)+crop, menos tremor quezoompan;punch= aproximação rápida em 0,35 segundos (para ganchos). - Transições: cada cena renderiza metade da duração da transição extra; xfade centralizado no limite entre cenas, o início da dublagem não é cortado pela transição.
- Mixagem: dublagem posicionada no início de cada cena; BGM padrão a -20 dB, comprimido mais 10 dB quando há voz (ducking suave); primeiro compressão/limitador, depois loudnorm duplo para aproximadamente -14 LUFS, TP -1,5 dB.
- Legendas: usa a duração real da dublagem para gerar
build/timing.json→make_subs.py→ libass para queima, além de exportar.srt.
Lista de verificação Checklist
- Duração, resolução e taxa de quadros corretos (
ffprobe out/video.mp4) - Extrair 3 quadros: legenda não sobrepõe produto, não invade área inferior da interface
- Ouvir: dublagem clara, BGM não sobrepõe, sem estouro no início
- BGM com licença comercial (música sintetizada
autopode ser usada com segurança) - Assets (imagens/vídeos/fontes) com licença de uso
Problemas comuns e correções Failure fixes
| Problema | Correção |
|---|---|
ffmpeg failed | Verificar o final do stderr impresso pelo script; comum é caminho errado ou ffmpeg sem libass/libx264 |
| Bordas da imagem borradas | Resolução do asset muito baixa; usar imagens ≥1080px ou reduzir amplitude do movimento (mudar para static) |
| Produto cortado | Definir "fit": "blur" na cena |
| Som cortado na transição | Não ocorre (dublagem alinhada ao início da cena); se duration personalizado for muito curto, aumentar |
| Renderização lenta | Predefinição já usa veryfast para arquivos intermediários; na codificação final, pode alterar -preset medium para fast |
| Deseja 1:1 / 16:9 | --size 1080x1080 / --size 1920x1080, tamanho da legenda ajusta automaticamente na proporção |
Referência e agradecimentos: a ideia foi inspirada no pipeline "script → dublagem → legendas → montagem" do MoneyPrinterTurbo (MIT); esta implementação é uma versão independente e puramente ffmpeg, sem copiar seu código.