Batidas Cinematográficas - Estilo de Vídeo
Filosofia Central
Visuais lideram o tempo. Áudio segue. Animações e cenas ASCII ocorrem em seu tempo natural — NÃO são truncadas, aceleradas ou congeladas no quadro final para coincidir com a duração do áudio. O silêncio entre as batidas é um design intencional, não um espaço a ser preenchido.
- TTS: Uma frase por clipe. Máximo sinal-ruído. Nenhuma narração de preenchimento.
- Visuais: Tempo natural completo. Deixe as animações respirarem.
- Cortes: Apenas cortes secos. Sem crossfades.
- Música: Faixas fornecidas pelo usuário com abaixamento automático durante as falas.
- Check-ins: Após cada fase de produção, entregue os assets ao usuário para revisão antes de prosseguir.
Estrutura do Projeto
~/videos/[nome-do-projeto]/
project.md # Documento vivo — storyboard, decisões, notas de revisão
beats/ # Assets individuais de cada batida
beat-01/
visual.mp4 # Visual gerado (imagem com movimento ou animação)
audio.mp3 # Clipe TTS para esta batida (MP3 apenas — consulte Regras Críticas)
note.txt # Descrição de uma linha do que esta batida mostra
beat-02/
...
music/ # Faixas de música de fundo fornecidas pelo usuário
output/ # Renderizações intermediárias e finais
Fase 1: Roteiro de Batidas
Crie project.md com a divisão das batidas. Cada batida = um visual + uma frase TTS.
Escrevendo Batidas
Regras TTS:
- UMA frase por batida. Ponto final.
- Máximo sinal-ruído — cada palavra ganha seu lugar.
- Se um pensamento precisar de duas frases, são duas batidas.
- Alvo: 5-15 palavras por clipe. Mais curto é melhor.
- Sem preenchimento introdutório ("Então...", "Agora vamos ver..."). Comece no ponto.
Regras visuais:
- Descreva o que o visual mostra — não por quanto tempo dura.
- A duração do visual é determinada por sua conclusão natural, NÃO pela duração do TTS.
- Cortes de imagem: imagem estática com movimento Ken Burns (zoom/pan lento). Duração: mínimo 4-6s.
- Cortes animados (p5js/manim/ascii): a animação completa é executada. O que for necessário — 8s, 12s, 15s.
- A duração da batida = max(duração_visual, duração_áudio) + pausa.
Modelo de batida em project.md:
# [Nome do Projeto]
## Conceito
[Um parágrafo — sobre o que é este vídeo e a sensação que queremos transmitir]
## Música
- Faixa: [nome do arquivo ou descrição da música que o usuário fornecerá]
- Clima: [descrição]
## Batidas
### Batida 01
**Visual:** [tipo: image | p5js | manim | ascii] — [prompt/descrição]
**TTS:** "Uma frase concisa."
**Status:** [ ] visual [ ] áudio [ ] aprovado
### Batida 02
...
## Notas
[Registro contínuo de decisões, revisões, feedback do usuário]
Tipos de Corte
| Tipo | Ferramenta | Duração | Melhor Para |
|---|---|---|---|
image | image_generate + Ken Burns | 4-6s | Fotos, cenas, retratos, planos de estabelecimento |
p5js | skill p5js | Natural (8-15s) | Arte generativa, partículas, visualização de dados, campos de fluxo |
manim | skill manim-video | Natural (8-20s) | Animações matemáticas, diagramas, explicadores técnicos |
ascii | skill ascii-video | Natural (6-12s) | Estética de terminal, computação retrô, tópicos de hacking |
caption | drawtext do ffmpeg | 4-8s | Texto TTS centralizado em fundo escuro — foco nas palavras |
CRÍTICO: Antes de produzir qualquer batida p5js/manim/ascii, carregue a skill com skill_view(name) primeiro. Essas skills contêm paletas de marca, regras de fonte e padrões de implementação que devem ser seguidos exatamente.
Fase 2: Portão de Aprovação do Roteiro
PARE. Apresente project.md ao usuário. Não gere assets até que seja explicitamente aprovado.
Atualize a seção de Notas do project.md com o timestamp de aprovação.
Fase 3: Gerar Visuais
Gere todos os assets visuais de acordo com seu tipo. Salve como beats/beat-XX/visual.mp4.
Batidas de imagem (Ken Burns com filtro VHS)
- Gere imagem via
image_generate - Aplique filtro VHS na imagem (grão, linhas de varredura, vinheta, aberração cromática):
python3 scripts/vhs-filter.py \
--input beat-XX-image.png \
--output beat-XX-vhs.png \
--seed 42 \
--intensity 1.0
Requisitos: pip install numpy Pillow (numpy para efeitos de array, Pillow para E/S de imagem).
Níveis de intensidade: 0.7 (sutil — apenas grão + vinheta), 1.0 (padrão — todos os efeitos), 1.5 (pesado — forte aberração cromática, linhas de varredura visíveis). O padrão é 1.0.
- Aplique movimento Ken Burns na imagem com filtro VHS para criar MP4:
ffmpeg -loop 1 -i beat-XX-vhs.png -t 5 \
-vf "zoompan=z='min(zoom+0.001,1.3)':x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)':d=125:s=1920x1080:fps=25" \
-c:v libx264 -pix_fmt yuv420p -r 25 beats/beat-XX/visual.mp4
Por que VHS primeiro, depois Ken Burns? O filtro zoompan embaçaria o grão e as linhas de varredura. Aplique VHS na imagem estática primeiro, depois adicione movimento por cima. O movimento Ken Burns sobre a imagem com filtro VHS cria uma sensação analógica vívida — como assistir a filmagens antigas através de um CRT ligeiramente degradado.
Batidas animadas (p5js/manim/ascii)
Carregue a skill relevante primeiro, depois gere. Salve a saída como beats/beat-XX/visual.mp4.
Resolução: Todos os visuais devem ser 1920x1080 a 25fps. Redimensione saídas do manim:
ffmpeg -y -i raw-manim.mp4 \
-vf "scale=1920:1080:flags=lanczos,setsar=1:1,fps=25" \
-c:v libx264 -pix_fmt yuv420p -r 25 beats/beat-XX/visual.mp4
Agrupe chamadas image_generate em grupos de 6. Se sinalizado, reformule neutramente e tente novamente uma vez.
Referência do Filtro VHS
O filtro VHS (scripts/vhs-filter.py) aplica estes efeitos a uma única imagem:
| Efeito | O que faz | Resultado visual |
|---|---|---|
| Aberração cromática | Deslocamento dos canais R/B (0-2px) | Franjas coloridas nas bordas, como um CRT desalinhado |
| Ruído analógico | ±8 grão por canal (escalado pela intensidade) | Textura cinematográfica em sombras e meios-tons |
| Linhas de varredura | A cada 4ª linha escurecida para 96% | Sobreposição de grade de fósforo CRT |
| Vinheta CRT | Escurecimento das bordas (15-35% com base na intensidade) | Cantos arredondados da tela, como TV antiga |
Para imagens: Todos os efeitos são aplicados uma vez com uma única semente aleatória. Aberração cromática e ruído são visíveis; tremulação/linhas de rastreamento são sutis, pois há apenas um quadro.
Nota: Este filtro é apenas para imagem — não processa entrada de vídeo. Para obter movimento, aplique o filtro a um quadro estático primeiro, depois adicione Ken Burns/zoompan por cima.
Fase 3.5: Portão de Verificação Visual
PARE. Envie cada clipe visual ao usuário para revisão.
Inclua a captura de tela ou MP4 com caminhos MEDIA. Apresente-os numerados:
Batida 01: [caminho MEDIA] — [breve descrição]
Batida 02: [caminho MEDIA] — [breve descrição]
...
Pergunte: "Precisa de alguma edição antes de prosseguirmos para o áudio?"
Não gere TTS até que o usuário aprove os visuais. Registre o feedback nas Notas do project.md.
Se forem solicitadas alterações, regenere apenas as batidas afetadas e faça o check-in novamente.
Fase 4: Gerar Áudio TTS
Gere TODOS os clipes TTS — um por batida. Use a ferramenta text_to_speech com output_path como .mp3. Salve como beats/beat-XX/audio.mp3.
CRÍTICO: Sempre use o formato MP3 para áudio. OGG tem problemas de compatibilidade de codec com entrega no Telegram e operações de concatenação do ffmpeg. Defina o provedor TTS como OpenAI com saída MP3.
Regras:
- Uma frase por chamada. Sem concatenação.
- Meça a duração de cada clipe com ffprobe após a geração.
- Registre as durações no project.md ao lado de cada batida.
ffprobe -v error -show_entries format=duration -of csv=p=0 beats/beat-XX/audio.mp3
Fase 4.5: Portão de Verificação de Áudio
PARE. Apresente os clipes de áudio ao usuário.
Aplicar filtro de voz (obrigatório)
Aplique a cadeia de bitcrush seco/úmido em cada clipe TTS — esta é nossa voz característica. Consulte references/dry-wet-bitcrush.md para técnica completa e armadilhas.
Duas abordagens disponíveis:
A) Mixagem estática (simples, consistente):
# Passo 1: Criar versão triturada via intermediário wav (preserva duração)
ffmpeg -y -i beats/beat-XX/audio.mp3 \
-af "aresample=resampler=soxr:osr=2000,aformat=sample_fmts=u8,aresample=resampler=soxr,lowpass=f=2500" \
temp-crushed.wav
# Passo 2: Misturar seco + úmido com cola de compressão
ffmpeg -y -i beats/beat-XX/audio.mp3 -i temp-crushed.wav \
-filter_complex "[0:a]volume=0.7[dry];[1:a]volume=0.3[wet];[dry][wet]amix=inputs=2:duration=first:normalize=0,acompressor=threshold=0.05:ratio=4:attack=10:release=100[out]" \
-map "[out]" beats/beat-XX/audio-filtered.mp3
rm temp-crushed.wav
B) Mixagem dinâmica (efeito de degradação de sinal — preferido):
Usa script Python (scripts/vibey-mix.py) com upsampling por retenção de ordem zero para bitcrush autêntico no pitch correto.
Requisitos: pip install numpy pydub (numpy para processamento de array, pydub para leitura/escrita de MP3).
Parâmetros fixos (variante dec5-bit8):
- Dizimação: 5× (descarta a cada 5ª amostra, depois repete via retenção de ordem zero)
- Quantização: 8 bits (constante)
- Linha de base seco/úmido: 80% seco / 20% úmido
- Padrão de mergulho: A cada ~1.2s, seco cai para ~35%, úmido sobe para ~65% (duração ~0.25s)
- Tremolo apenas no úmido: Onda triangular 4Hz, profundidade 70% (úmido pulsa entre 30-100%)
- Atraso slapback: 80ms a -18dB (~0.12 volume), aplicado à mixagem final
python3 scripts/vibey-mix.py beats/beat-XX/audio.mp3
cp beats/beat-XX/audio-dynamic.mp3 beats/beat-XX/audio-filtered.mp3
Detalhamento da cadeia: Sinal seco limpo sobreposto com artefatos digitais extremos (dizimação 5×, quantização de 8 bits via upsampling por retenção de ordem zero), mergulhos periódicos elevando o nível úmido para um efeito de "transmissão degradante", tremolo no sinal úmido para pulsação rítmica e atraso slapback para espaço. Mantenha a estrutura da cadeia intacta — ajuste apenas parâmetros individuais se necessário.
Use audio-filtered.mp3 em todas as fases subsequentes. Mantenha o audio.mp3 original para referência.
Registre decisões nas Notas do project.md.
Fase 5: Compor Batidas
Para cada batida, mescle visual + áudio com corte seco (sem transição). A duração da batida é determinada pelo que for maior — visual ou áudio.
Se visual >= áudio:
O áudio toca sob o visual completo. Nenhum preenchimento necessário.
ffmpeg -i beats/beat-XX/visual.mp4 -i beats/beat-XX/audio-filtered.mp3 \
-c:v libx264 -pix_fmt yuv420p -c:a aac \
-shortest -r 25 output/beat-XX-composed.mp4
Se áudio > visual:
O visual mantém seu quadro final para preencher o tempo restante. Use tpad no vídeo:
AUDIO_DUR=$(ffprobe -v error -show_entries format=duration -of csv=p=0 beats/beat-XX/audio-filtered.mp3)
ffmpeg -i beats/beat-XX/visual.mp4 -i beats/beat-XX/audio-filtered.mp3 \
-vf "tpad=stop_mode=clone:stop_duration=$AUDIO_DUR" \
-c:v libx264 -pix_fmt yuv420p -c:a aac \
-t $AUDIO_DUR -r 25 output/beat-XX-composed.mp4
Se nenhum filtro de áudio foi aplicado, use audio.mp3 em vez de audio-filtered.mp3.
Pausa entre batidas
Adicione um curto quadro preto entre as batidas para espaço de respiração:
ffmpeg -f lavfi -i color=c=black:s=1920x1080:d=0.15:r=25 \
-c:v libx264 -pix_fmt yuv420p output/pause-XX.mp4
Batidas de legenda ASCII (foco nas palavras)
Quando a narração em si é o ponto focal — não o visual — use uma batida no estilo ASCII com o texto TTS centralizado na tela. Marque-as no project.md como tipo [caption]:
Modelo de batida:
### Batida 03 [caption]
**Visual:** legenda ascii — texto centralizado, fundo escuro, estética terminal sutil
**TTS:** "As palavras exatas que aparecem na tela."
**Status:** [ ] visual [ ] áudio [ ] aprovado
Gere com drawtext do ffmpeg em um fundo preto/escuro com fonte monoespaçada e texto dourado ALLMIND (#C5A55A):
TEXT="Sua frase TTS aqui"
ffmpeg -f lavfi -i color=c=black:s=1920x1080:d=6:r=25 \
-vf "drawtext=text='${TEXT}':fontsize=42:fontcolor='#C5A55A':fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf:x=(w-text_w)/2:y=(h-text_h)/2" \
-c:v libx264 -pix_fmt yuv420p beats/beat-03/visual.mp4
(Nota: O comando drawtext foi truncado, mas você continuará a partir daí. Se o texto for mais longo, reduza o fontsize ou aumente a duração do clipe. A proporção funciona bem para 5-15 palavras.)