Videoclipe (motion graphics)
Você não pode ouvir a música. Tudo que é visual está atrelado a dados medidos, portanto a primeira tarefa é sempre a pasta da música. Se os dados da música estiverem errados, cada quadro estará errado.
Os helpers estão ao lado deste arquivo. Execute-os com o run.py da pasta da skill (caminho de instalação padrão mostrado; ajuste se instalou em outro local):
python3 ~/.claude/skills/music-video/run.py song-folder SONG.mp3 OUT_DIR [--fps 30] [--lyrics-lang en|tr] [--lyrics-text known.txt]
python3 ~/.claude/skills/music-video/run.py analyze SONG.mp3 # beats/bars/sections as JSON
python3 ~/.claude/skills/music-video/run.py dance2d SONG.mp3 --out DIR --analysis OUT_DIR/song-map.json --start 23.8 --dur 14.3 [--render]
Nunca afirme ter ouvido a música. Diga "a partir da análise".
1. Pasta da música (sempre primeiro)
| Arquivo | Conteúdo | Ferramenta |
|---|---|---|
| passage.<ext> | o áudio, cópia idêntica byte a byte (verificado por sha256); use-o como está na multiplexação final | — |
| song-map.json / .md | bpm, batidas, downbeats/compassos, seções de energia (calma/construção/alta), energia por batida, drops | Beat This! → aubio CLI → tracker numpy embutido |
| stems/ | vocais / bateria / baixo / outros (em cache, execuções repetidas são rápidas) | demucs htdemucs (opcional) |
| envelopes.json | volume por quadro do mix e de cada stem (dB + 0..1) | numpy |
| hits.json | onsets de kick / caixa / chimbau com força 0..1 | fluxo espectral por banda no stem de bateria |
| notes.json | notas da melodia e do baixo (opcional) | basic-pitch |
| lyrics-passage.json / .md | linhas com tempos das palavras | whisper.cpp whisper-cli no stem de vocais |
| song-story.md | TEMPLATE que você preenche: tema, voz, arco de humor, imagem chave por seção | você, a partir das letras + mapa |
| README.md | o que cada arquivo é, unidades (segundos), fps | gerado |
Regras:
- As seções são frases de energia (frases de dois compassos classificadas pela própria energia da música), não verso/refrão. Nomeie-as você mesmo em song-story.md.
--lyrics-textcom as letras reais (uma linha por linha) as alinha às palavras do whisper; palavras que não puderam ser combinadas recebem tempos interpolados (matched: false). Sem ele, as linhas são a saída bruta do whisper: verifique-as. Linhas sobre um stem de vocais silencioso são sinalizadas comosuspect(whisper alucina em instrumentais). Músicas instrumentais pulam o whisper.- Cada etapa pesada degrada em vez de falhar: sem Beat This! → aubio (CLI externo) → tracker numpy
(sem downbeats reais, 4/4 presumido); sem demucs → envelopes e hits apenas do mix; sem basic-pitch → sem
notes.json; sem whisper → sem letras. Os
warningsda execução dizem o que foi pulado. Informe o usuário. - hits.json é bom o suficiente para flashes, tremores e estouros de escala, não uma transcrição de bateria: chimbau também dispara em caixas, notas do baixo podem vazar para a banda da caixa.
- song-story.md nunca é sobrescrito em execuções repetidas. Escreva apenas o que as letras e a análise suportam; deixe um cabeçalho como "desconhecido" em vez de inventar significado.
2. Plano criativo (mostre antes de renderizar)
- Um conceito que vem de song-story.md, um mundo, uma paleta, uma fonte de licença aberta (OFL) para a tipografia das letras.
- Tabela seção → cena: uma mudança de seção = uma cena ou mudança de câmera; o refrão/seção de maior energia recebe a maior ideia visual, repetida com variação a cada vez; drops = corte, flash ou escala no downbeat.
- Tipografia de letras apenas em linhas-chave (palavras cinéticas em seus tempos de palavra), não karaokê para cada linha.
- Em música calma, marque o ritmo por frase e energia; não faça cortes bruscos em cada batida rastreada. O número de tratamentos distintos importa mais que o número de cortes.
- Mostre o plano (tabela + 3–4 stills descritos ou renderizados) e obtenha aprovação antes da renderização completa.
- Blocos de construção que valem a pena ler primeiro: a própria skill
music-to-videodo HyperFrames (github.com/heygen-com/hyperframes,skills/music-to-video/, Apache-2.0) tem um catálogo de primitivas de movimento de corte rítmico (corte flash, zoom abrupto, chicote, divisão cromática, tremor de tela, letras cinéticas…) e layouts de letras.
3. O vídeo de dança 2D embutido
Veja: personagens planos (cabeça redonda escura, membros de traço arredondado, camisa e sapatos coloridos), portas de espelho arqueadas, fundos giratórios de explosão solar em roxo / azul-petróleo / dourado / rosa, palavras de letras em negrito condensado (Anton) com uma palavra de destaque, uma fileira de cópias espelhadas do dançarino em cores diferentes, tira de filme, coroa e adereços de xadrez. Inspirado no vídeo 2D "de baixo esforço" do experimento do YouTube de Devarf de um videoclipe feito em cada nível de esforço.
Planejador (musicvideo/dance2d.py, puro e com semente):
- a janela se ajusta aos downbeats; uma pose chave por batida, a pose CHEGA na batida;
- downbeats recebem uma pose grande (construção: braçosParaCima / apontar / baterPalmas, alta: pular / braçosParaCima) e uma flexão completa de joelhos;
- o conjunto de movimentos (uma frase de 4 batidas) muda a cada compasso por nível de energia e nunca se repete duas vezes seguidas;
- cenas cortam no início da seção e a cada 4 compassos (troca de paleta, velocidade do fundo solar por nível, direção alterna; portas em calma/construção, xadrez + fileira de 5 dançarinos em alta, coroa no líder);
- cópias do dançarino: calma 1, construção 3, alta 5;
- JSON de letras
[{start, end, text, accent}]em segundos da janela → cada palavra cai em uma batida.
Rig (runtime/char2d.js, window.Char2D): grupos SVG com pivôs (quadris > pernas > canelas > sapatos,
tronco > braços > antebraços, cabeça). Ângulos dos membros são graus positivos para fora (0 para baixo, 90 para o lado, 180 para cima)
de modo que uma pose funcione para ambos os lados; um bloqueio de chão mantém o pé inferior no chão (agachamentos descem
por si mesmos), air levanta para pulos. Poses: idle, stepL/R, armsUp, swayL/R, pointL/R, clap, jump,
squat, handsOnHips (mirror(p) troca os lados). poseAt(keys, t) segura, então suaviza nos últimos
≤0,26 s com overshoot em grandes hits. runtime/dance2d.js desenha o plano a partir de window.MV_DANCE; uma
animação GSAP conduz um setter proxy → draw(t), então cada quadro é uma função pura de t.
Saída de dance2d: DIR/plan.json e DIR/project/ (um projeto HyperFrames). Com --render
também DIR/dance2d.mp4: 1920×1080, 30 fps, H.264 yuv420p, o próprio áudio da música para a janela (AAC,
sem fades). Música sob CC BY precisa do --credit na tela.
A renderização é escolha do usuário. --render executa npx hyperframes render, que baixa e
controla um Chrome/Chromium headless. Pergunte antes de usá-lo. Sem ele, tudo até a pasta do projeto
funciona apenas com Python. GSAP não está incluído: coloque gsap.min.js em runtime/ (ou defina
MV_GSAP), caso contrário o projeto carrega GSAP 3.14.2 do CDN jsDelivr no momento da renderização.
4. Personagens além do rig embutido (traga o seu)
Esta skill não fornece modelos 3D. Se o usuário quiser 3D (Three.js):
- use modelos cuja licença permita redistribuição em um vídeo finalizado, por exemplo, modelos CC0, ou personagens e animações que o usuário baixou de sua própria conta Mixamo (ok dentro de um vídeo finalizado; os arquivos brutos não devem ser redistribuídos ou commitados em um repositório público);
- nunca copie modelos de exemplo de outros projetos sem verificar sua licença;
- ou mantenha-se em primitivas procedurais (cápsulas, esferas, caixas em uma cadeia de ossos simples), que não têm
questão de licença alguma.
Determinismo de quadro ainda se aplica:
mixer.setTime(t * rate)a cada quadro, nuncamixer.update(dt);rate = song_bpm / clip_bpm; troque clipes em limites de compasso.
5. Regras de renderização (qualquer renderizador)
- Tudo é uma função pura de
t = frame / fps. SemDate, sem deltas derequestAnimationFrame, semMath.random()sem uma semente. - Pequenos hits (tremor de câmera, flash de luz, estouro de escala) em kick/caixa de hits.json; brilho ou glow de envelopes.json.
- Saída: 1920×1080 (ou 1080×1920 para Reels/Shorts), 30 fps, H.264 yuv420p, AAC, mesma duração da música (ou da janela escolhida).
- Fotosensibilidade: nunca mais de 3 flashes de tela cheia por segundo.
- Orçamento: mais tempo de pensamento dá melhor movimento, mas revise em uma sessão. Loops de revisão multiagente em um único videoclipe queimam tokens rápido e tendem a reiniciar após limites.
6. Verificações antes da entrega
- Reproduz até o fim; duração == duração da música (ou janela) ±1 quadro.
- O stream de áudio é a música original (compare hash PCM decodificado, ou um pico de correlação cruzada no lag 0).
- Verificação pontual de sincronia: renderize 5 quadros nos downbeats do refrão e confirme se a pose / flash de impacto está lá.
- Uma folha de contato por seção (
ffmpeg -i out.mp4 -vf "fps=1,scale=480:-1,tile=4x4" sheet.jpg) e realmente olhe para ela. report.md: o que você fez e por quê, como, o que verificou, do que não tem certeza.