Sincronização com batida (Beat Sync)
Scripts em scripts/:
beats.py MUSIC --out beats.json [--start S --end E]— tempo, batidas, estimativa de contratempo, onsets fortes (hits), energia RMS por segundo.timemap.py— constrói um mapa de tempo com velocidade variável (rampas de velocidade) e renderiza quadro a quadro com ffmpeg.
1. Analisar a música
python beats.py song.mp3 --out edit/beats.json
Produz tempo, batidas (s), contratempos (a cada 4ª batida a partir da fase mais forte), hits (onsets fortes: caixa/bumbo/quedas), energia a cada 0,5 s.
Interpretando o resultado:
- Período da batida
P = 60 / BPM. A 30 fps, uma batida a 120 BPM = 15 quadros. - Hits nem sempre são batidas. Acentos vocais, finais de risers, quedas. Para tendências de "editar áudio", os pontos de corte são os hits, não o metrônomo.
- O librosa pode travar em metade ou dobro do tempo. Verificação de sanidade: pop típico 90-130 BPM, trap 130-160 (frequentemente sentido em tempo reduzido), EDM 120-128, phonk 130-150. Se a grade detectada parecer errada em um teste de captura de quadro, divida/dobre.
- A curva de energia encontra a queda/refrão: maior salto de RMS após uma seção silenciosa.
2. Escolher a janela da música
- Formato curto: 7-20 s. Inicie a janela em um contratempo e termine em um contratempo ou no final de uma frase (4 ou 8 compassos).
- Coloque o visual mais forte na queda. Se a queda está aos 12 s da música e você a deseja 3 s após o início do reel, a janela começa aos 9 s.
- Sons em alta no Instagram/TikTok: o som do aplicativo começa em um ponto fixo. Se a postagem final usar o som do aplicativo, alinhe sua edição a esse ponto de início e exporte uma versão com o áudio de referência como guia.
- Desvaneça a música em 10-50 ms (evite clique) a menos que a janela comece em um transiente, e desvaneça para fora em 0,3-1,5 s, ou termine em um hit forte.
3. Construir a grade e posicionar eventos
fps = 30
fr = lambda t: round(t * fps) # ajusta cada evento ao quadro mais próximo
U = periodo_batida / 2 # subunidade de batida (colcheias) se a música for movimentada
- Cortes: nas batidas para fluxo, nos hits para impacto. Cortar a cada batida é cansativo; corte a cada 2 ou 4 batidas e use cortes a cada batida apenas para explosões (2-4 s) antes da queda.
- Antecipação: um corte colocado 1-2 quadros antes da batida parece mais preciso em celulares (latência de áudio + percepção). Teste ambos e escolha consistentemente.
- Flashes / tremores / zoom punches: nos hits, 2-6 quadros, com decaimento.
- Texto: a palavra aparece na sílaba vocal ou na batida; segure pelo menos 0,4 s por palavra para palavras únicas, ~0,25 s/palavra para linhas lidas no ritmo.
- Mudança de velocidade / efeito: nos contratempos ou quedas.
- Mantenha uma tabela (
timing.json) de cada evento com sua razão musical; o script de construção a lê.
4. Rampas de velocidade (velocidade)
Uma rampa de velocidade é um mapa de tempo src_t = f(out_t). Construa-a a partir de segmentos com velocidade suavizada:
# curva de velocidade: 1x ... acelera para 4x entre hits ... volta para 0.3x no hit
segmentos = [(inicio_saida, fim_saida, velocidade_inicio, velocidade_fim, suavizacao)]
- Suavize a velocidade com smoothstep/cúbico para entrar/sair; um salto instantâneo de 1x→4x parece um glitch.
- Lento (0,2-0,5x) no hit, rápido (2-5x) entre hits. O próprio quadro do hit mostra a ação chave (impacto, giro, olhar).
- Seções lentas precisam de fontes de alta fps ou interpolação de quadros (
minterpolate, Speed Warp do Resolve, RIFE). - Adicione blur de movimento em partes rápidas (
tmix=frames=3ou mesclagem de quadros no renderizador de mapa de tempo) para evitar tremulação. - Caso real: cena de mesa aérea, partes de movimento de câmera mantidas a 1x, partes estáticas a 5,6x, cada mudança de velocidade em um hit forte; um passo de fluxo óptico (OpenCV LK + similaridade RANSAC) localizou os movimentos da câmera automaticamente (veja
motion-tracking).
timemap.py renderiza um mapa de tempo puxando o quadro fonte correto para cada quadro de saída (com mesclagem opcional de quadros) — exato e mais simples do que encadear filtros setpts.
5. Correspon der ao ritmo de um reel de referência
- Baixe/obtenha a referência; extraia seu áudio.
- Detecte seus cortes:
ffmpeg -i ref.mp4 -vf "select='gt(scene,0.3)',showinfo" -f null - 2>&1 | grep pts_time. - Detecte batidas em seu áudio; expresse cada corte como um índice de batida ou deslocamento → esse é o template rítmico.
- Meça os tempos de ativação/desativação de texto avançando quadros (precisão de 1/30 s) em torno das mudanças.
- Reconstrua com seu material na mesma grade (veja
reference-matching).
6. Verificar
- Detecte cena no render; cada tempo de corte × fps deve igualar seu quadro planejado (±0).
- Sobreponha uma trilha de clique nas batidas em um render de depuração (explosões senoidais
aevalsrc) e capture quadros nos hits. - Você não pode ouvir: relate os números (quadros de corte planejados vs medidos) e peça ao usuário para verificar ouvindo.