/bw-song-ad — Anúncio Cantado em Cartoon Preto e Branco até o Pacote Final
2026-10-18, procedimento criado com H-OHI-023a da Ohisama Pants. Referência: WhiteHat MRR no X (densidade óssea, cartoon preto e branco, cerca de 4 min.). A reação do autor foi "a música é fogo demais, é divina". A verdadeira natureza do vídeo de referência é: não é um jingle curto, mas sim o roteiro de um VSL longo cantado quase na íntegra.
Ordem (não pular)
Letra → Música (Suno) → Sincronização caractere por caractere → Divisão de cenas → Ficha de personagens → Keyframes → Animação → Exportação do fundo → Remotion → Inspeção de qualidade. A música é o relógio. Se você criar as imagens primeiro, elas não vão se alinhar com a pausa da música e você terá que refazer tudo.
S=~/.agents/skills/bw-song-ad
AD=<pasta_do_projeto>/<ID_do_anuncio> # lyrics.md / captions.txt / song/ / shots.py / keys/ / clips/ / remotion/
cp -R $S/remotion $AD/remotion && cd $AD/remotion && NODE_USE_ENV_PROXY=1 npm install
0. Verifique o estoque primeiro
Se houver imagens ou vídeos feitos anteriormente para a mesma marca, use-os primeiro (consulte a tabela de estoque de ativos ASSETS.md da marca; adicione novos itens conforme forem criados). Quando for necessário gerar algo, informe antes "X imagens, Y vídeos, aproximadamente Z créditos". Resultado desta vez: 61 imagens ~15 créditos, 61 vídeos Grok ~265 créditos.
1. Letra (lyrics.md) — modelo em reference/lyrics.md
- Cante o fluxo do VSL parágrafo por parágrafo. Não rime. Progressão 1:1 com a referência: Abertura do profissional → Clássicos com "não é isso" ×3 → Algo mais importante → A causa não está onde se pensa → Aliados e vilões dentro do corpo → Antes funcionava → Agora os vilões estão vencendo → O problema daqui em diante (cadeia de negligência) → O mercado só tem as mesmas coisas → Mas algo mudou (solução) → Artigo (sem registro) → Estoque → "Não precisa mais..." ×3 → "Tudo bem. Toque abaixo"
- Tudo em hiragana. Números também em hiragana (Suno quebra com kanji e números).
- Não cante o nome do produto (ele aparece no rótulo da tela). Sem valores. As promessas estão no escopo da página do produto.
- Mostre antes de compor.
2. Música (Suno · Playwright)
- Apenas o login é pessoal. Depois, injete a letra, o estilo e o título em
suno.com/create?mode=CUSTOMe crie. - Estilo (funciona):
1930s vintage upbeat jazz, old cartoon soundtrack, swing, clarinet, muted trumpet, ragtime piano, brushed snare, upright bass, warm female vocal, Japanese, clear diction, storytelling sung melody - De cada vez saem 2 músicas. Transcreva ambas com whisper e compare com a letra; escolha a que não estiver distorcida.
- Download: na página da música, More options → Download → MP3 → "Unlock & Download" (usa 1 vez do plano gratuito).
cdn1.suno.airetorna 403, o m4a de reprodução é criptografado. Não extraia o blob do navegador para evitar o limite. - Coloque em
song/song.mp3.
3. Texto das legendas (captions.txt)
- 1 parágrafo da letra = 1 linha. Dentro da linha, separe com
/(1 bloco = texto que aparece uma vez na tela; até cerca de 12 caracteres). - Converta para japonês legível com kanji e kana misturados (a letra está em hiragana, mas as legendas usam notação normal).
- Onde quiser 2 linhas, use
|(ex.:Pelo botão abaixo|leia o artigo).
4. Sincronização caractere por caractere
uv run --python 3.12 --with openai-whisper python $S/scripts/align.py $AD
→ Gera $AD/cap_events.json (tempo de início e fim de cada bloco) e $AD/line_starts.json (início de cada linha cantada).
- Não use os timestamps por linha do whisper-cli. A introdução (alguns segundos sem canto) é tratada como se o canto começasse em 0 segundo, e dentro da linha ele distribui uniformemente, então as legendas avançam "sem cantar".
- Onde a música pausa (mais de 0,8 segundos), apague a legenda.
- Se a taxa de correspondência ficar abaixo de 80%, a música está distorcida ou o captions.txt está desalinhado com a letra.
5. Divisão de cenas (shots.py)
- Defina
STYLE(descrição do estilo visual comum a todos os cortes) eSHOTS = [(número da linha, número do corte naquela linha, cena, movimento), ...]. - Cada corte: 2 a 5 segundos. Linhas longas divida em 2 a 3 cortes. 3 minutos e meio = cerca de 60 cortes.
- Nem tudo precisa ser vídeo em longa duração: misture cortes com imagem estática com zoom lento para reduzir pela metade a geração de vídeos.
- Personagens: Professor (bob avental) / Mamãe (coque baixo, listrado) / Criança (corte chanel) / Dois mensageiros do corpo (macacão listrado, chapéu) / Vilão (círculo preto, chifres, esponja e canudo) / Produto (estampa real).
6. Ficha de personagens e keyframes (Higgsfield gpt_image_2_5 · 9:16 · 0,25 crédito cada)
- Primeiro crie 1 ficha de personagens, depois para todos os cortes seguintes passe a ficha + 1 quadro de referência como
image_references. - No início do prompt, coloque
STYLE: black and white 1930s rubber-hose cartoon, thick clean ink lines, cross-hatching, grayscale only, vintage Fleischer-era look, slightly grainy film, soft dark round vignette, no text. python3 $S/scripts/make_reqs.py $AD image→ gere em lotes de 12 comgenerate_image_batch.- Vista a criança (roupa íntima/fralda cai como NSFW). Se o quadro de referência mostrar roupa íntima, ele sozinho já derruba.
- Escreva a estampa real do produto no prompt (se sair uma estampa inexistente, refaça).
- Veja tudo em uma folha de contato: verifique estilo, sem texto, conforme a ficha.
7. Animação (Grok Imagine grok_video_v15_lite · 720p · apenas start_image · 1 segundo ≈ 1 crédito)
python3 $S/scripts/make_reqs.py $AD video→ gere em lotes de 12 comgenerate_video_batch. Duração: trecho responsável + 0,5 segundo (3 a 8 segundos).- Prompt: "Anime esta imagem: . Mantenha o mesmo estilo, composição e personagens, movimento rubber-hose saltitante, cintilação de filme, câmera fixa, sem cortes, sem novos textos."
- Se cair e retornar um preset, coloque
declined_preset_idnos parâmetros e tente novamente. - Examine todos os quadros finais lado a lado. Se o produto virar de lado ou girar e a estampa distorcer, use apenas até o segundo antes da distorção (
SRC_MAX) ou faça um vaivém da parte frontal.
8. Exportação do fundo (sem texto)
python3 $S/scripts/bg.py $AD # → $AD/bg.mp4 (1080x1920 · 30fps) e shot_starts.json
- A transição de cortes deve coincidir com o início do canto de cada linha (line_starts.json). O primeiro corte começa em 0 segundos.
- Para a introdução sem canto, uma sugestão é usar cortes rápidos de cenas fortes (vilão, enchente, esmagamento com carimbo, etc.) para preencher.
9. Remotion ($AD/remotion)
- Coloque
public/bg.mp4(fundo),public/song.mp3esrc/data.json:python3 $S/scripts/make_data.py $AD --hook-end 29.3 --cta 192.9 --brand 44,46,47,50 --hook-top "Para mães no treino do penico" --hook-main "A fralda não sai" --hook-mark "O verdadeiro motivo" --brand-name "<nome do produto>" --keys "<palavras-chave em amarelo, separadas por vírgula>" - Elementos a colocar (
src/SongAd.tsx):- Hook superior: um cartão de papel (borda preta grossa, sombra deslocada, levemente inclinado) que "para quem + sobre o quê" fique claro no primeiro segundo. Ex.: "Para mães no treino do penico / A fralda não sai o verdadeiro motivo".
- Legendas: cantos arredondados pretos com texto branco em negrito, aparecendo com um pulo. Apenas as palavras-chave em amarelo (a única cor no preto e branco).
- Rótulo do nome do produto: apenas nos cortes em que o produto aparece, pequeno no topo.
- CTA: do último "toque abaixo" até o fim, 3 setas amarelas em cascata descendo e pulando + "Pelo botão abaixo | leia o artigo".
- Exportação (este Mac usa headless Chrome que cai sozinho →
chrome-wrap.sh, fora do sandbox):
cd $AD/remotion && NODE_USE_ENV_PROXY=1 npx remotion render src/index.ts SongAd out/<ID_do_anuncio>.mp4 --browser-executable=./chrome-wrap.sh --concurrency=6 --crf=20
- Entrega: re-encodar com
-crf 23 -movflags +faststart(pesado devido aos grãos do preto e branco; cerca de 200 MB para 3,5 min).
10. Inspeção de qualidade (obrigatório antes de abrir)
- Leia uma folha de contato com aproximadamente 1 quadro a cada 1 segundo: verifique se as legendas não estão dessincronizadas com a música / não aparecem onde não há canto / a estampa do produto não distorceu / as setas do CTA cabem na tela / não há texto extra.
- Veja os primeiros 3 segundos separadamente (o hook é compreendido de relance?).
- Crie uma página de visualização HTML e abra. O nome do anúncio deve ser o nome emitido pelo AdLab (H-XXX-000a) usado diretamente no nome do arquivo.
Problemas enfrentados (medidos desta vez)
- Legenda dessincronizada desde o início: o início do canto era em 4,9 segundos, mas o whisper-cli considerou como 0 segundo → resolvido com
align.py(word_timestamps do openai-whisper + difflib para alinhamento de caracteres). - Keyframes NSFW: criança de roupa íntima, imagem de referência com roupa íntima → vista a criança / use a referência apenas para o estilo descrito.
- Produto girando e distorcendo: Grok frequentemente vira de lado. Use apenas os segundos frontais.
- Excesso de criação: 61 imagens + 61 vídeos usados em um único anúncio. Da próxima vez, reduza à metade com estoque e zoom de imagem estática.
- Último caractere de uma linha longa caindo sozinho na linha seguinte → use
|para especificar a quebra.
Relacionados: reference/lyrics.md (modelo e exemplo de letra), /zackd-ad (tipo animação 3D), AdLab (registre a hipótese antes de criar).