Communitygithub.com

igm61799-cloud/voiceover-to-animation

Transforme um arquivo de áudio de narração em um vídeo animado 2D totalmente codificado (MP4), sem usar modelos de vídeo ou imagens de arquivo — cada quadro é desenhado por código (Canvas 2D), sincronizado com as palavras exatas da narração e renderizado com Chromium headless + ffmpeg.

O que é voiceover-to-animation?

Esta skill permite converter qualquer arquivo de áudio de narração (como voiceover.mp3, lektor, podcast clip) em um vídeo animado 2D completo (MP4) usando apenas código. Diferente de abordagens que dependem de geração de vídeo por IA ou imagens de arquivo, cada quadro é desenhado manualmente via Canvas 2D, proporcionando controle total sobre a estética e sincronia com a fala. O processo é totalmente determinístico: cada cena é uma função pura do tempo, permitindo renderização paralela, revisão de frames individuais e sincronia perfeita com o áudio. A skill suporta o uso de ferramentas como faster-whisper para transcrição, Playwright + Chromium headless para renderização, e ffmpeg para empacotamento final. Ideal para criar vídeos explicativos, animações curtas, motion graphics ou conteúdo no estilo 'Kurzgesagt', partindo apenas de um áudio ou roteiro. O fluxo de trabalho inclui transcrição das palavras com timestamps, storyboard baseado no texto, desenvolvimento de cenas em JavaScript puro (com engine de animação fornecida), revisão por contact sheets de imagens estáticas e renderização final. A skill enfatiza qualidade visual com paletas de cores limitadas, animações com easing, movimentação de câmera e elementos secundários, além de fornecer referências detalhadas para evitar erros comuns.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/igm61799-cloud/voiceover-to-animation/tree/HEAD

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Narração → curta animado codificado em 2D

Você está fazendo um curta-metragem, não uma apresentação de slides. A narração é fixa; seu trabalho é inventar o que o espectador vê a cada momento, desenhar isso em código e entregar um MP4 cujos cortes e batidas visuais coincidam com as palavras certas.

Todo o pipeline é determinístico: cada cena é uma função pura do tempo, então qualquer quadro pode ser renderizado individualmente. Essa propriedade lhe dá todo o resto – imagens instantâneas para revisão, renderização paralela, sincronia de áudio perfeita.

O que você precisa na máquina

Verifique estes antes de começar; são as únicas peças móveis.

python -c "import faster_whisper, playwright, PIL; print('ok')"
ffmpeg -version

Peças faltando: pip install faster-whisper playwright pillow, depois python -m playwright install chromium. ffmpeg deve estar no PATH. Se algo não puder ser instalado, diga ao usuário o que está faltando em vez de mudar para uma abordagem mais fraca.

O fluxo de trabalho

Mantenha a visão do usuário simples: ele lhe deu um áudio e quer um filme. Siga estas etapas em ordem e mantenha uma lista de tarefas visível.

1. Ouça primeiro: timings das palavras

python <skill>/scripts/transcribe.py voiceover.mp3 work

Isso imprime frases com horários de início/término e cada palavra como palavra@início, e salva work/words.json. Tudo a jusante é planejado com base nesses números. Observe a duração total.

2. Configure o projeto ao lado do áudio

Copie <skill>/assets/template/ para a pasta de trabalho para que fique assim:

voiceover.mp3
render.py
src/index.html  src/engine.js  src/scenes.js  src/main.js

Leia src/engine.js uma vez (é curto) e folheie references/engine-api.md para saber o que você já tem: easing, aleatoriedade com semente, uma câmera, desenho de caminhos parciais e motivos no estilo de impressão (nuvens, chuva, relâmpago, fumaça, skyline).

3. Decida a direção de arte, depois storyboard contra as palavras

Escolha UMA linguagem visual e mantenha-a para todo o filme: uma paleta pequena (cinco ou seis cores), um tratamento para bordas e textura, uma maneira de desenhar pessoas. O template já vem com um visual de linoleogravura/impressão (papel osso, tintas navy, vermelhão, dourado, bordas cortadas à mão que tremem). Use-o, ou reestilize-o mudando a paleta em scenes.js e os switches de POST – mas não misture estilos entre cenas. A variedade vem de qual cor domina cada cena (uma cena noturna, uma cena de papel, uma cena vermelha), não de mudar as regras.

Depois, escreva o storyboard antes de escrever código: uma tabela de tomadas com horários absolutos de início/término, as palavras que cada tomada cobre, o que está na tela e a palavra exata em que cada batida cai. Leia references/storyboarding.md para saber como transformar narração em imagens – é a parte que decide se o filme é bom.

A versão resumida:

  • Uma ideia por frase. Uma frase com três orações geralmente é três tomadas ou três batidas dentro de uma tomada.
  • Mostre a coisa, não a legende. Texto na tela que repete a narração faz o espectador ler em vez de assistir. Padrão: sem texto algum; nomes, dados reais e uma etiqueta neutra curta em um gráfico são as exceções. Se o usuário declarou preferências de texto, elas vencem.
  • Dê ao filme uma espinha dorsal: um personagem ou motivo recorrente, e um retorno no final a algo da abertura.
  • Mude a escala e a câmera propositalmente: plano aberto, close-up, diagrama, mapa, corte transversal. Duas tomadas consecutivas não devem ter a mesma composição.
  • Se a narração terminar com uma piada, adicione 1-2 s de cauda silenciosa após a última palavra para que a imagem final possa pousar. render.py preenche o áudio.

4. Construa uma cena de ponta a ponta antes de escrever o resto

Escreva a primeira tomada em src/scenes.js, registre-a em SHOTS e veja o resultado:

python render.py stills 0.3,1.5,2.9 first

Depois abra work/first.png com a ferramenta de leitura. Faça isso antes de codificar as outras cenas: prova que o pipeline funciona e, mais importante, permite julgar o estilo enquanto mudá-lo ainda é barato.

5. Escreva as cenas restantes, algumas de cada vez

Regras que mantêm o sistema funcionando (cada uma existe porque quebrá-la causa uma falha específica):

  • Funções puras do tempo. Uma tomada é function name(g, t, u) onde t é segundos absolutos e u é segundos desde o início da tomada. Sem variáveis que acumulam entre quadros, sem Math.random(), sem Date. Use hash(n), noise1(x), rng(seed). Quadros são renderizados fora de ordem por vários navegadores ao mesmo tempo; qualquer coisa com estado aparece como cintilação ou como pedaços que não combinam.
  • Anime com tempos absolutos. Escreva E.out(seg(t, 12.62, 13.1)), usando números diretamente da lista de palavras. Quando o corte muda, as batidas permanecem em suas palavras.
  • Tudo se move um pouco. Um quadro parado parece um bug. Dê a cada tomada uma deriva lenta de câmera (zoom 1 + u * .01 é suficiente) e algum movimento secundário (chuva, fumaça, um objeto balançando).
  • Easing em tudo. E.out para coisas chegando, E.inOut para movimentos de câmera, E.back para pops, E.bounce para pousos. Movimento linear parece mecânico.
  • Desenhe o mundo maior que o quadro sempre que a câmera der zoom out ou tremer; preencha fundos e chão bem além de 0..1920 para que nenhuma borda seja exposta.
  • Impactos recebem três coisas: um flash de tela cheia de 2-3 quadros, um shake que decai e algo que reage (um sopro, um recuo, uma inversão de cor).
  • Divida o código de cena em arquivos (s1.js, s2.js, ...) assim que um arquivo passar de algumas centenas de linhas e adicione-os a index.html antes de scenes.js.

Escreva duas ou três tomadas, renderize uma folha de contato delas, olhe, corrija, continue. Não escreva o filme inteiro às cegas.

6. Revise com imagens estáticas – estes são seus olhos

Você não pode assistir ao vídeo, então a folha de contato é a revisão. Para cada tomada, amostre pelo menos o início, o meio da ação principal e o fim, além do quadro exato de cada batida:

python render.py stills 12.2,13.3,14.3,15.4,16.5 act2     # até ~16 timestamps por folha
python render.py sheet 4                                   # filme inteiro, um quadro a cada 4 s

Leia o PNG e verifique, tomada por tomada: O sujeito é grande o suficiente para ser lido de relance? Algo está cortado, sobreposto ou flutuando? A coisa importante tem contraste contra o que está atrás? Parece projetado, ou metade do quadro está vazio? Depois corrija e re-renderize os mesmos timestamps. references/pitfalls.md lista os erros fáceis de cometer e difíceis de perceber.

Erros de página são impressos por render.py como linhas PAGE ERROR: – um quadro preto ou meio desenhado geralmente significa uma exceção naquela tomada.

7. Renderize e verifique

python render.py full --workers 8

Execute em segundo plano; um filme de 70 s tem cerca de 2.100 quadros e leva alguns minutos. Ele escreve output.mp4 (1920x1080, H.264 + AAC, áudio preenchido até a duração total). Depois verifique o arquivo em si, não apenas as imagens estáticas:

ffprobe -v error -show_entries format=duration:stream=codec_name,width,height -of default=nw=1 output.mp4
python render.py sheet 6

Confirme a duração, que há um fluxo de áudio e que a folha de visão geral não tem quadros vazios. Diga claramente em seu relatório que você verificou as imagens estáticas e as propriedades do arquivo, mas não assistiu ao movimento – o usuário deve assistir uma vez.

8. Entrega

Dê ao usuário o caminho para output.mp4, a folha de visão geral e uma linha sobre como re-renderizar após edições. src/index.html aberto em um navegador é um player ao vivo com o áudio, que é a maneira mais rápida de ele verificar o timing.

Som

Entregue apenas a narração, a menos que o usuário tenha pedido música ou efeitos sonoros. Se pediu, adicione-os como entradas extras do ffmpeg na mixagem final, temporizadas a partir da mesma lista de batidas que você usou para os visuais.

Arquivos de referência

  • references/storyboarding.md – transformar narração em tomadas; posicionamento de batidas; metáforas visuais; o que faz uma cena parecer projetada. Leia antes do passo 3.
  • references/engine-api.md – todos os helpers em engine.js com uso de uma linha. Leia antes do passo 5.
  • references/pitfalls.md – modos de falha descobertos da maneira difícil, com correções. Leia antes do passo 6.
  • references/example-bells/ – um filme completo de 71 segundos (16 tomadas, ~900 linhas de código de cena) com seu storyboard. Leia storyboard.md para ver o nível de planejamento esperado; abra os arquivos src/s*.js quando quiser ver como um efeito específico foi construído (uma câmera que segue um personagem escalando, uma explosão, um mapa, uma pena que desenha uma linha, um olho que aperta).

Habilidades Relacionadas