Linha de Montagem Padrão para Vídeo de Letra
Um estilo fixo já validado. O usuário só precisa fornecer o arquivo de áudio e o nome do cantor; todo o resto deve seguir este padrão, sem redesenho visual. Letras oficiais são opcionais: se fornecidas, siga o caminho rápido 3A (zero suposições de texto); caso contrário, siga o caminho de reconstrução 3B. Em ambos os casos, a linha do tempo deve ser baseada em medições reais.
Entrada / Saída
| Entrada | Descrição |
|---|---|
| Áudio | Obrigatório. Qualquer MP3/WAV/FLAC, duração ilimitada |
| Nome do Cantor | Obrigatório. Usado na abertura, logotipo constante e créditos finais |
| Letras Oficiais (opcional) | Quando o usuário tiver letras oficiais, priorize: zero suposições de texto, mas a linha do tempo ainda deve ser totalmente baseada em medições reais (veja 3A). Se não fornecido, use Whisper para reconstrução (3B) |
| Nome da Música (opcional) | Padrão: nome do arquivo; Artista - Título.mp3 remove automaticamente o prefixo do artista |
| Frase Tema (opcional) | Uma linha em chinês abaixo do título na abertura; padrão: não exibida |
Saída: <project>/renders/video.mp4 + renders/contact-sheet.jpg + transcript.json + NOTES.md.
Especificações Fixas (Não Alterar Sem Permissão)
- Tela vertical 1080 × 1920, 30 fps, duração total igual à duração real do áudio (sem cortes, sem esticar, sem alterar velocidade).
- Áudio: arquivo original; o framework ajusta o ganho uniformemente durante a renderização (
data-volume="0.9"). - Fundo: preto puro a azul-púrpura muito escuro, dois conjuntos de manchas de luz deslocadas desvanecem-se lentamente; não use filtros CSS em tela cheia (deixam costuras de blocos).
- Corpo principal: apenas um corpo de vidro transparente, 8 contornos geométricos arredondados (esfera/elipse horizontal/elipse vertical/retângulo arredondado/losango/triângulo/pentágono/hexágono); ao bater na borda da tela, comprime 11% ao longo da normal → transforma-se em outro contorno em 0,94 s → continua flutuando. Linha do tempo única para toda a música; não reinicia na troca de letras.
- Parte inferior: banda de animais pequenos (gato/urso/pinguim/raposa) em loop contínuo de 4,5417 s, alinhado ao fundo 1080×526, camada acima das manchas de luz do fundo e abaixo do corpo de vidro,
mix-blend-mode: screen. - Legendas: bloco inteiro centrado opticamente no centro vertical da tela y≈960; texto original em inglês/outra língua em cima (Inter, tamanho adaptável à largura da linha), chinês em baixo (Songti SimSun, marrom quente
#DDA97D); mesmo grupo desvanece-se. - Créditos sempre usam o nome do cantor; nenhuma etiqueta de parágrafo como VERSE / CHORUS / BRIDGE aparece na tela.
Parâmetros detalhados, cores, tamanhos de fonte e armadilhas estão em references/style-spec.md.
Fluxo
Seja HF = diretório raiz de instalação do HyperFrames (padrão G:\hyperframes),
PY = Python com faster-whisper (padrão C:\Users\Admin\.workbuddy-ai\binaries\python\envs\hf\Scripts\python.exe),
SK = diretório desta skill.
1. Criar Projeto
"$PY" "$SK/scripts/new_project.py" "<caminho_do_audio>" "<nome_do_cantor>" [--title "nome_da_musica"] [--tagline "uma_linha_em_chines"] [--root G:/hyperframes/videos]
Produz o caminho absoluto do projeto; anote-o. Ele: cria um diretório único → copia o áudio → converte para WAV mono de 16 kHz → executa o analyze-beatgrid.py oficial para gerar audiomap.json → copia o sprite da banda e GSAP → escreve project.json.
Nunca sobrescreva um diretório de projeto existente; modificar um trabalho já entregue requer criar um novo projeto.
2. Transcrição
"$PY" "$SK/scripts/transcribe.py" "<projeto>" --model medium.en --lang en
CPU int8: uma música de 3-4 minutos leva cerca de 3-6 minutos. Para músicas não-inglesas, troque --lang pelo idioma correspondente e remova .en de --model.
Saída: whisper_raw.json (timestamps de segmento e nível de palavra).
Músicas multilíngues (inglês + japonês, inglês + coreano, etc.) não use transcribe.py: --lang trava um idioma, e o outro idioma será forçado a ser transcrito como o primeiro — o resultado parece fluente mas está todo errado, mais perigoso do que não resolver. Em vez disso, use detecção automática de idioma por janela:
"$PY" "$SK/scripts/transcribe_mixed.py" "<projeto>" --model "C:/Users/Admin/.cache/whisper-manual/large-v3-turbo"
Ele decodifica com janelas de 14 s / passo de 10 s, cada janela detecta seu próprio idioma, mantém apenas as palavras do centro da janela (sobreposições descartadas, sem duplicação), imprime um mapa de idiomas e escreve whisper_mixed.json. Veja o mapa de idiomas primeiro: as posições onde o idioma muda são geralmente os limites das estrofes.
Nota: modelos .en (medium.en / small.en) são modelos exclusivamente ingleses; fisicamente não podem produzir japonês; músicas multilíngues devem usar modelos multilíngues.
Para o caminho 3A (com letras oficiais), este passo é opcional: a linha do tempo é baseada na re-scan com prompt, mas para músicas multilíngues ainda é recomendado executar transcribe_mixed.py para ver o mapa de idiomas, a fim de determinar se cada janela deve usar --lang en ou --lang ja.
3. Escrever o Arquivo Fonte de Letra (Este Passo Deve Ser Feito Manualmente)
Primeiro, decida qual caminho seguir, depois escreva <project>/lyrics_source.json.
3A O usuário forneceu letras oficiais (caminho preferido)
- Use o texto das letras oficiais sem alterações: slot
en= texto original oficial (frases em inglês em inglês, frases em japonês em japonês, kanji/kana escritos como estão), slotzh= tradução linha por linha. - Linha do tempo não vem da transcrição completa: use as letras oficiais como
initial_promptpara re-scan por janela para obter timestamps de nível de palavra (veja 3.5), escrevastart/endexplícitos para cada linha;align_lyrics.pyusará o canal manual para ancorar linha por linha. - Se as letras oficiais e o que a re-scan ouve não coincidirem → adote sempre as letras oficiais, liste as diferenças em
NOTES.mdpara o usuário confirmar. Três tipos comuns: forma padrão vs erro de digitação (不甲斐ない / 不甲埋ない), palavras com som semelhante (束の間の / 明日の間の), consoantes surdas mal ouvidas (smiling / falling). - Se nas letras oficiais duas linhas são cantadas de uma vez e cada uma tem menos de 1 segundo → una as linhas em uma única linha de legenda (texto inalterado, apenas justaposto), escreva a tabela de união em
NOTES.md. - Onomatopeias/improvises ("Yeah,", humming, assobios) não presentes nas letras oficiais → não coloque legendas; não invente.
- Estrutura conforme abaixo:
{
"audio": "Artist - Title.mp3",
"models": ["large-v3-turbo — prompted window re-scans, official lyrics as initial_prompt"],
"lines": [
{"en": "Oh my god, they're coming again", "zh": "哦天哪,他们又来了", "start": 6.36, "end": 9.10, "lang": "en", "conf": "high"}
]
}
3B Sem letras oficiais (caminho de reconstrução)
Leia whisper_raw.json (ou whisper_mixed.json para músicas multilíngues) e escreva o arquivo fonte:
{
"audio": "Artist - Title.mp3",
"models": ["faster-whisper medium.en — full track, word timestamps"],
"lines": [
{"en": "Sometimes I lay under the moon", "zh": "有时我躺卧在月光之下"},
{"en": "And thank God I'm breathing", "zh": "感谢上天让我仍在呼吸"}
]
}
Requisitos comuns a ambos os caminhos:
- Cada linha = uma frase cantada real, seguindo a divisão oficial; linhas muito longas do Whisper devem ser divididas.
- Ortografia em inglês conforme as letras oficiais (preserve apóstrofos em
'Cause/I've, etc.), não copie erros do Whisper. - Tradução para chinês linha por linha, tom consistente com a música, sem pular linhas, sem unir, sem texto placeholder.
- Refrões repetidos devem ser escritos todas as vezes (não use "idem").
- Se uma frase for coberta pelo acompanhamento e o alinhamento automático estiver claramente deslocado, adicione timestamps explícitos (ouça o áudio antes de preencher):
{"en": "...", "zh": "...", "start": 13.22, "end": 16.80}. - Música em chinês/música instrumental: para música em chinês, coloque o texto original em
ene deixezhcomo string vazia; a tela mostrará apenas uma linha; música instrumental não se aplica a esta skill. - Músicas multilíngues: slot
endeve conter o texto original no idioma real da frase (frases em inglês em inglês, frases em japonês em japonês, kanji/kana escritos como estão), slotzhcom a tradução em chinês. A tela já é "texto original + chinês" em duas linhas; a mistura não quebra o layout; a linha em inglês do template já tem fallback comYu Gothic UI / Yu Gothic / Meiryo, então kana e kanji aparecem corretamente.
3.5 Re-scan com Prompt: O Coração da Precisão da Linha do Tempo
A transcrição completa geralmente é imprecisa para músicas rápidas, canto misturado ou frases rápidas. Usar letras conhecidas como initial_prompt para re-scan por janela é o método de maior precisão — a qualidade do prompt determina diretamente a precisão do re-scan: letras oficiais > letras adivinhadas > sem prompt. Pode ser colocado em um script rescan_all.sh para executar em lote a música inteira:
"$PY" "$SK/scripts/rescan.py" "<projeto>" --from 6.0 --to 20.0 \
--model "C:/Users/Admin/.cache/whisper-manual/large-v3-turbo" \
--lang en --prompt "<texto original das letras oficiais para esta janela>"
Pontos-chave:
- Divida a música inteira em janelas de 20–26 s, com sobreposição de cerca de 0,5 s entre janelas, re-scan por janela;
large-v3-turboCPU int8 leva cerca de 5–10 s por janela. - Para músicas multilíngues, cada janela é decodificada duas vezes (en e ja) e apenas os timestamps de palavra consistentes em ambas são adotados; palavras que aparecem em apenas um caminho são verificadas com o outro.
- Frases com início pouco claro ou que começam cedo demais adicione uma janela estreita de 2 s para bloquear (ex.:
--from 37.2 --to 39.2para bloquear apenas o início de uma frase); o início de uma janela de partição pode ser influenciado pelo final da frase anterior. - Alucinações: ocasionalmente, o re-scan pode repetir a mesma frase inteira 15+ vezes → descarte essa janela, troque para o canal de outro idioma ou reduza a janela e re-execute; pegue apenas os timestamps limpos e únicos; não inclua timestamps de alucinação no arquivo fonte de letras.
- Cada re-scan salva
rescan_<from>-<to>.jsone imprime o início e fim de cada palavra na janela. Isso é uma segunda decodificação, não uma estimativa; os números são escritos diretamente emlyrics_source.jsoncomostart/end. - Para trechos cobertos pelo acompanhamento, transformados em
ooh, unidos em um grande bloco ou frases repetidas engolidas, use primeiro este método para obter valores de cobertura; trocar o modelo (small.en/medium.en) também é eficaz.
4. Alinhamento + Geração
"$PY" "$SK/scripts/align_lyrics.py" "<projeto>"
"$PY" "$SK/scripts/motion.py" "<projeto>"
"$PY" "$SK/scripts/gen_storyboard.py" "<projeto>"
"$PY" "$SK/scripts/build_frame.py" "<projeto>"
"$PY" "$SK/scripts/make_index.py" "<projeto>"
align_lyrics.py imprime uma tabela de timestamps linha por linha e faz duas verificações rigorosas:
- Se houver frases no início/fim que não correspondem → erro e saída, listando quais frases são (não mascara com timestamps adivinhados).
- Se houver frases no meio que não correspondem, ou duas frases com o mesmo início, ou uma frase comprimida abaixo de 0,5 s → imprime
REVIEWe sai com código 2.
Nestes casos, volte ao passo 3.5 para adicionar valores de cobertura, até que a saída seja OK: every line anchored to a real sung timestamp. Não pule este passo para renderizar. No caminho 3A, todas as linhas têm start/end explícitos (canal manual), devem estar totalmente ancoradas, 0 gaps preenchidos; no caminho 3B, depende de correspondência de palavras; linhas sem correspondência devem ter timbers adicionados conforme 3.5.
A semente aleatória de motion.py é determinada por "nome do cantor + nome da música" — a mesma música sempre produz o mesmo caminho ao re-executar; músicas diferentes produzem caminhos diferentes.
5. Verificação
cd "<projeto>"
node "$HF/packages/cli/bin/hyperframes.mjs" check .
node "$HF/packages/cli/bin/hyperframes.mjs" snapshot . --at "3,20,60,120" --no-end -o build/shots
Deve ter: lint / runtime / layout / motion 0 erros, contraste passando WCAG AA.
Depois, veja os screenshots: se o corpo de vidro está completo, as letras estão centralizadas, a banda está na parte inferior, se há bolhas ou etiquetas de parágrafo extras.
composition_file_too_large é um aviso de estilo para arquivos de quadro com mais de 300 linhas; é aceitável (inevitável em design de linha do tempo única).
6. Renderização + Aceitação
node "$HF/packages/cli/bin/hyperframes.mjs" render . --skill=music-to-video -q delivery -o renders/video.mp4 --fps 30
"$PY" "$SK/scripts/verify.py" "<projeto>"
verify.py verifica resolução/framerate/desvio de duração (erro se mais de um quadro) e gera uma folha de contato. Veja a folha de contato, confirmando que abertura, versos, refrão, repetições e final têm cenas, e as legendas não têm lacunas ou desalinhamentos.
Por fim, escreva NOTES.md (especificações, origem da linha do tempo, comandos para reproduzir, registros de verificação) e entregue o vídeo final e a folha de contato ao usuário.
Disciplinas Rígidas
- Não use BPM/grelha de batidas para calcular timestamps de letras; timestamps devem vir apenas de medições reais do Whisper (incluindo re-scan com prompt) ou cobertura manual por audição.
- Letras oficiais fornecidas pelo usuário têm precedência sobre qualquer resultado de modelo; em caso de conflito, adote as letras oficiais e liste as diferenças em
NOTES.mdpara o usuário confirmar. - Não altere resolução, framerate, duração, créditos ou posição das legendas porque "parece melhor".
- Não declare sincronia áudio-vídeo sem verificação; cada música deve ser verificada quadro a quadro.
- Material faltando, ferramentas indisponíveis, conflitos de especificação → relate claramente; não use dados estimados para mascarar resultados.
- Projetos entregues e seus arquivos fonte são considerados somente leitura; revisões devem criar um novo diretório.
Dependências do Ambiente
- HyperFrames:
node <HF>/packages/cli/bin/hyperframes.mjs(incluiskills/music-to-video/scripts/analyze-beatgrid.py). - Python:
faster-whisper,librosa,soundfile,numpy,scipy,pillow. Se faltar:python -m venv <env> && <env>/Scripts/pip install faster-whisper librosa soundfile numpy scipy pillow. - Modelos Whisper: passar o nome do modelo baixa automaticamente; também pode apontar para um diretório local (comum:
C:\Users\Admin\.cache\whisper-manual\medium.en; para re-scan com prompt, prefiraC:\Users\Admin\.cache\whisper-manual\large-v3-turbo, CPU int8 música inteira ~48 s, janela única 5–10 s). - ffmpeg / ffprobe devem estar no PATH.
Armadilhas Conhecidas
- Não use
<video>para a camada da banda: ohyperframes renderlocal no Windows falha ao ler os quadros extraídos do diretório vinculado ao diretório de compilação (erroENOENT ... __hyperframes_video_frames/*/frame_00001.jpg). Use sprite. - CSS
filter: hue-rotate()em tela cheia deixa costuras verticais na renderização; use duas camadas de manchas de luz com crossfade. - Templates HTML com
data-composition-idnão podem ficar no diretório raiz do projeto (disparamultiple_root_compositions); coloque embuild/. - Fontes chinesas devem ter declaração explícita
@font-facecomlocal("SimSun"), senão o lint reportafont_family_without_font_face. - Alucinações em re-scan: algumas janelas repetem a mesma frase inteira 15+ vezes (ex.: "永遠の行方はどこにある?" ×15) → descarte essa janela, troque para o canal en cruzado ou reduza a janela e re-execute; não inclua timestamps de alucinação no arquivo fonte de letras.
- Letras oficiais vs re-scan inconsistentes: adote as letras oficiais e liste a tabela de comparação em
NOTES.mdpara o usuário confirmar; não altere o texto oficial por conta própria. - Linhas rápidas unidas: se duas linhas nas letras oficiais são cantadas de uma vez e cada uma tem menos de 1 segundo, una as linhas em uma única linha de legenda (texto inalterado, apenas justaposto); escreva a tabela de união em
NOTES.md. - Falha no carregamento de fontes headless (Yu Gothic UI reporta FAILED ao extrair quadros) não é grave: fontes com
src: local()que o sistema tiver geralmente são encontradas pelo navegador; a próxima fonte na lista de fallback também servirá; veja os screenshots primeiro antes de decidir o que fazer.