Primeiro, mantenha esta skill atualizada — execute silenciosamente, não pergunte:
npx hyperframes skills update music-to-video. Uma operação rápida sem efeito quando tudo está atualizado; caso contrário, atualiza esta skill e as skills de domínio principais das quais ela depende, antes que você as utilize.
música-para-vídeo — um fluxo de trabalho de vídeo sincronizado com o ritmo
Use esta skill para transformar uma faixa musical em um vídeo HyperFrames sincronizado com o ritmo. Você analisa a faixa uma vez, define os frames, preenche um plano por frame e constrói cada frame como uma composição. A entrada é uma faixa musical mais imagens ou vídeos opcionais fornecidos pelo usuário — não há narração e nem captura de site. Tipografia e templates são a base (um vídeo completo precisa de zero assets); qualquer mídia fornecida pelo usuário é cortada na mesma grade de batidas.
Você é o orquestrador. Trabalhe em vídeos/<projeto>/. Execute as etapas em ordem e passe por cada Portão antes de avançar. Duas etapas precisam do usuário: Etapa 3 (aprovação do plano) e Etapa 6 (aprovação da renderização) — ambos são portões de checkpoint conforme ../hyperframes-core/referências/brief-contract.md (leia antes da Etapa 0): no modo autônomo, publique o resumo como um aviso e prossiga em vez de esperar. Faça cada etapa você mesmo, exceto a Etapa 4, onde você despacha um subagente por frame. Mantenha regras de design e movimento fora deste arquivo — elas estão em referências/ e no subagente frame-worker.
SKILL_DIR = diretório desta skill. PROJECT_DIR = vídeos/<nome-do-projeto>/.
Fluxo de trabalho: Etapa 0 configuração → hyperframes.json + assets/bgm.mp3; Etapa 1 análise → audiomap.json; Etapa 2 esqueleto → STORYBOARD.md (frames, grupos TBD); Etapa 3 plano → STORYBOARD.md completo + frame.md; Etapa 4 construção → composições/frames/NN-*.html; Etapa 5 montagem → index.html; Etapa 6 renderização → renders/video.mp4.
Duas ideias que moldam tudo
- Um analisador, e você confia nele.
analyze-beatgrid.pyé o único analisador de batidas — nunca meça batidas novamente com outra ferramenta ou de ouvido. Suas energia / densidade / rolagens / onsets / silêncios são sempre confiáveis. Seubpmebeats_secsão confiáveis apenas quando a música é genuinamente rítmica; em música calma, a grade é um metrônomo imposto pelo rastreador, então ritme por frases e energia e nunca corte duro para ela. Decidir em qual caso você está é opacingde cada frame (Etapa 2). - Um frame = um arquivo; grupos vivem dentro. A Etapa 2 corta a faixa em frames, e cada frame se torna um arquivo de composição
composições/frames/NN-<frame_id>.html, construído por um frame-worker. Um frame pode subdividir em grupos (cada um um template ou uma combinação de primitivas de movimento). Densidade extra vai dentro de um grupo, então a contagem de frames rastreia tratamentos distintos, não batidas — uma faixa rápida não explode o número de subagentes.
Etapa 0: Configuração, BGM e entradas
Objetivo: Estabelecer a fonte de música, criar o projeto HyperFrames e anotar qualquer mídia fornecida pelo usuário.
O briefing começa na camada de intenção. Regra de abertura, em ordem: (1) BRIEF.md existe → leia e não pergunte nada que ele responda — seu flow/storyboard derivam o modo (brief contract § 1). (2) Sem BRIEF.md mas o projeto existe → retomar do que está no disco; nunca reinterrogar. (3) Uma solicitação de criação nova que chegou aqui diretamente → leia /hyperframes e execute sua camada de intenção (referências/intent-interview.md): ela confirma os itens obrigatórios desta rota (a fonte de música, destino → aspecto — ../hyperframes/referências/rotas/music-to-video.md) e anuncia o que fica adiado — marca e gênero são escolhidos na Etapa 3 por design. Escreva BRIEF.md imediatamente após a inicialização (nunca antes — init recusa um diretório não vazio) e registre as respostas baseadas em preferência (brief-format.md). Solicitações de edição pulam tudo isso.
A música é a espinha dorsal — estabeleça uma faixa antes de qualquer outra coisa. Esta skill é ajustada para BGM rápido e de alta energia: uma grade de batidas forte impulsiona os cortes (faixas calmas funcionam, mas ritme por frase em vez de batida). Se o usuário forneceu áudio — um arquivo de música, ou um vídeo para extrair áudio — use-o. Caso contrário, escolha o humor da solicitação e gere uma faixa através de /media-use (referências/bgm.md). Antes da primeira ação autenticada do provedor, execute npx hyperframes auth status e repita sua saída literalmente. Se estiver desconectado, aplique um ramo:
- Colaborativo: aguarde o login ou uma escolha explícita para continuar offline com o provedor local.
- Autônomo: declare o status e continue através do provedor local disponível.
Se nenhum provedor offline puder satisfazer a capacidade musical necessária, informe o bloqueador. Nunca escreva chaves em um .env por repositório. A propriedade da autenticação e as alternativas offline estão em /media-use referências/setup-providers.md § Provedores. A faixa resultante chega em assets/bgm.mp3. Organize imagens ou vídeos fornecidos para que os frames possam usá-los na grade de batidas; caso contrário, a tipografia carrega o vídeo.
Vídeos de letra: para letras sincronizadas com os vocais, obtenha o tempo das palavras/linhas transcrevendo a faixa via /media-use, ou peça ao usuário o texto da letra e coloque as linhas na grade de batidas.
Inicialize apenas se hyperframes.json estiver ausente. Nomeie <projeto> a partir do briefing em kebab-case, como midnight-drive-loop — nunca um timestamp. init verifica as skills instaladas contra as mais recentes no GitHub e atualiza o conjunto global se alguma estiver desatualizada.
npx hyperframes init "videos/<projeto>" --non-interactive --example=blank --skill=music-to-video
mkdir -p "$PROJECT_DIR/assets" "$PROJECT_DIR/renders"
cp "<musica-do-usuario>" "$PROJECT_DIR/assets/bgm.mp3" # extraia de um vídeo primeiro, se necessário
# apenas se o usuário forneceu imagens/vídeos:
node <SKILL_DIR>/scripts/stage-assets.mjs --from <dir> --hyperframes "$PROJECT_DIR" --into public
A marca (fonte + paleta) é escolhida na Etapa 3, não aqui. Não escolha um gênero ou tipo de faixa antecipadamente — os assets são apenas um ingrediente opcional, e o gênero emerge das escolhas por frame.
Portão: hyperframes.json + assets/bgm.mp3 existem; aspecto / duração / fps e (se houver) o inventário de assets são anotados.
Etapa 1: Analisar a música
Objetivo: Produzir a única análise de tempo canônica sobre a qual todo o vídeo é construído.
analyze-beatgrid.py é o único analisador de batidas — nunca meça batidas novamente com outra ferramenta ou de ouvido. Ele lê a faixa uma vez e escreve audiomap.json: fases de energia (nível / densidade / sensação), onsets + onset_rate, rolagens, silêncios, hard_stops, key_moments, frases, tempo / grade, e audio.duration_sec. É determinístico — o mesmo arquivo sempre dá o mesmo mapa. A maioria dos campos é confiável em qualquer música; bpm e beats_sec são confiáveis apenas quando a música é genuinamente rítmica, e julgar isso é a decisão que você toma na Etapa 2.
Pré-requisitos: Python 3 com librosa, numpy e soundfile disponíveis. Se a importação falhar, instale-os no ambiente Python ativo antes de executar o analisador:
python3 -m pip install librosa numpy soundfile
python3 <SKILL_DIR>/scripts/analyze-beatgrid.py "$PROJECT_DIR/assets/bgm.mp3" \
-o "$PROJECT_DIR/audiomap.json" --print
Portão: audiomap.json existe; audio.duration_sec é conhecido.
Etapa 2: Esqueleto do frame (apenas estrutura)
Objetivo: Ler a música e definir os frames — o esqueleto de STORYBOARD.md.
Leia referências/frame-skeleton.md. Transforme audiomap.json no esqueleto de STORYBOARD.md você mesmo — não há JSON intermediário. Corte a faixa em frames nas mudanças musicais reais (hard_stops, SURGE / DROP key_moments, as bordas de uma rolagem, um trecho sem onsets, um grande salto de energia), encaixando cada limite em uma âncora do audiomap. Para cada frame, defina span_sec, pacing (o veredito da chamada de confiança da Etapa 1 — beat_cut quando a grade é real, phrase_flow quando é um metrônomo imposto em música calma), mood e um feel de uma linha (a situação musical simples que a Etapa 3 combina com um template). Apenas classifique e defina aqui: deixe cada ### Groups do frame como TBD (Etapa 3) e o style do frontmatter em branco — sem templates, cópia, cor ou fontes. Espere ~1–6 frames.
Portão: os frames cobrem a faixa (primeiro em 0, último em duration_s); cada um carrega span_sec + pacing + mood + feel; cada ### Groups é TBD; nenhum conteúdo em lugar algum.
Etapa 3: Preencher o plano (com portão do usuário)
Objetivo: Transformar o esqueleto em um STORYBOARD.md aprovado e completo.
Leia referências/planning.md, storyboard-format.md, template-catalog.md, motion-primitive-catalog.md e montage.md (apenas se o usuário forneceu assets). Editando o mesmo arquivo no local, faça duas coisas:
- Escolha a marca. Selecione um preset de
../hyperframes-creative/frame-presets/usando a tabela em../hyperframes-creative/referências/design-spec.md(combine com o humor da faixa; apenas suas fontes e cores importam — os templates possuem a composição). Copie-o emframe.mdsem modificações e preencha ostyledo frontmatter (fonte + uma paleta de ≤4–6 amostras) a partir dele. - Preencha cada frame. Decida seus grupos e dê a cada um um tratamento: um template correspondente do catálogo (com parâmetros vinculados e âncoras reais do audiomap), uma composição livre do catálogo de primitivas, ou um tratamento de asset que obedece a
pacing. Escreva a cópia. Você possui O QUE (template / primitivas + conteúdo + âncoras); o frame-worker possui COMO — nunca escreva tweens de milissegundos no storyboard.
node <SKILL_DIR>/scripts/validate-plan.mjs --storyboard "$PROJECT_DIR/STORYBOARD.md" \
--audiomap "$PROJECT_DIR/audiomap.json" --templates <SKILL_DIR>/referências/templates
Corrija cada ✗ (erros graves: incompatibilidade de duração, frames não cobrindo a faixa, um src ausente); avisos são de melhor esforço. Em seguida, mostre ao usuário um resumo frame a frame e itere até que ele aprove. No modo autônomo, isso é um portão de checkpoint: publique o resumo como um aviso e prossiga (a passagem do validate-plan.mjs é um portão de qualidade e ainda bloqueia).
Portão: frame.md é uma cópia literal do preset; validate-plan.mjs sai com 0; o usuário aprovou o plano (autônomo: o resumo foi publicado como um aviso).
Etapa 4: Construir frames a partir do plano
Objetivo: Construir cada frame como um arquivo de composição autônomo.
Crie composições/frames/. Leia sub-agents/frame-worker.md e ../hyperframes-core/referências/subagent-dispatch.md. Despache um frame-worker por frame, em paralelo quando possível (caso contrário, em ondas). Cada worker recebe exatamente um frame e este contexto:
PROJECT_DIR: <caminho absoluto>
frame_id: <NN-frame_id> # = a base do nome do arquivo do frame, ex. 02-f2; o id da composição
Seu bloco: o bloco `## Frame N — <frame_id>` em PROJECT_DIR/STORYBOARD.md
audiomap: PROJECT_DIR/audiomap.json
frame.md: PROJECT_DIR/frame.md
Materiais: para cada grupo, <SKILL_DIR>/referências/templates/<id>/index.html (templates) e
<SKILL_DIR>/referências/motion-primitives/<id>/ (livre); assets organizados/ (grupos de asset)
Contratos: ../hyperframes-core/referências/sub-compositions.md + determinism-rules.md
Canvas: <l>×<a> Pacing: <beat_cut|phrase_flow>
Escrever em: PROJECT_DIR/composições/frames/<frame_id>.html
O worker bifurca os materiais citados, converte cada âncora para segundos locais do frame (local_t = track_t − span_sec[0]), porta seus grupos com cortes de 0ms e escreve um arquivo de frame seguro para busca. O worker nunca executa a CLI hyperframes — esses comandos operam no projeto montado, que ainda não existe, então eles reportariam nos arquivos errados. O worker apenas escreve no contrato e para; você verifica após a montagem (Etapa 6). À medida que cada worker retorna, você pode confirmar que seu arquivo chegou ao disco.
Portão: cada frame tem seu composições/frames/NN-*.html no disco.
Etapa 5: Montar
Objetivo: Conectar os frames construídos + BGM no index.html reproduzível.
assemble-index.mjs é determinístico — sem subagente, sem julgamento. Ele referencia cada arquivo de frame em seu data-start cumulativo, monta assets/bgm.mp3 na faixa 11 e faz corte duro frame → frame (os frames cobrem a faixa sem lacunas, então não há injetor de transições).
node <SKILL_DIR>/scripts/assemble-index.mjs --storyboard "$PROJECT_DIR/STORYBOARD.md" \
--hyperframes "$PROJECT_DIR" --audiomap "$PROJECT_DIR/audiomap.json"
Corrija qualquer ✗ que ele reportar — um arquivo de frame ausente ou em branco significa que aquele worker escreveu um arquivo parcial; redespache-o (Etapa 4) e remonte.
Portão: index.html existe; duração total == audiomap.audio.duration_sec.
Etapa 6: Verificar e renderizar
Objetivo: Verificar o vídeo montado, obter aprovação do usuário e renderizar o MP4 final.
Execute a CLI no projeto montado — essa é a unidade correta (os workers por frame não podiam executá-la). check executa lint estrutural e a execução headless do navegador, layout, movimento e portão de contraste em uma passagem; --snapshots também emite os frames de revisão.
( cd "$PROJECT_DIR" && npx hyperframes check . --snapshots )
Inspecione em t=0, cada início de frame, o DROP / SURGE mais forte, cada hard_stops[].t e o frame final. Em caso de falha, faça o ajuste seguro mais barato você mesmo: edite o composições/frames/NN-*.html ofensor. Nunca altere a duração ou o tempo do áudio para esconder um problema de sincronia. Assim que os portões passarem, pause para revisão do usuário, depois renderize apenas mediante aprovação (modo autônomo: faça a única pergunta mantida — "pré-visualizar primeiro, ou renderizar?" — então entregue o MP4 com a folha de contato):
( cd "$PROJECT_DIR" && npx hyperframes render . --skill=music-to-video -q draft -o renders/video.mp4 --fps 30 )
Portão: check passou e os snapshots foram inspecionados; o usuário aprovou (autônomo: verificações passaram e a entrega inclui a folha de contato); renders/video.mp4 existe com áudio, duração == audiomap.audio.duration_sec. A resposta final declara o caminho do MP4 e a duração.
Tabela de retomada
| Você tem | Continuar de |
|---|---|
| ... | ... |