Communitygithub.com

erencalik/motion-graphics-video-generator-claude

Produz um vídeo animado MP4 com gráficos em movimento e música a partir de uma única solicitação (9:16 Reels ou 16:9), renderizando uma animação HTML/CSS/JS quadro a quadro e juntando com ffmpeg. Ideal para motion graphics, tipografia cinética, estatísticas animadas e animações para Reels.

O que é motion-graphics-video-generator-claude?

Esta skill permite que um agente de IA (como Claude) produza vídeos MP4 completos com gráficos em movimento e música, diretamente no ambiente de código, sem necessidade de software de edição ou filmagens. Ela funciona criando uma animação HTML/CSS/JS onde cada elemento é calculado deterministicamente a partir do número do quadro (`window.renderFrame(f)`), dispensando transições CSS ou temporizadores. O headless Chrome (Playwright) captura cada quadro, e o ffmpeg os compila em um MP4 (H.264). A música é sintetizada em código (Python) e sincronizada com as transições. A skill suporta os formatos 9:16 (para Reels/TikTok/Shorts) e 16:9 (para YouTube/portfólio), com duração ideal de 15 a 20 segundos. O usuário pode fornecer logotipos, fotos, cores e fontes para personalização, além de especificar estilos como tipografia cinética, infográficos animados, partículas, halftone, mapas e contadores. Um checklist de solicitação orienta o processo, e a skill inclui modelos testados em JavaScript (render.js), Python (audio.py) e comandos de junção ffmpeg.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/erencalik/motion-graphics-video-generator-claude/tree/HEAD

Perguntar na sua IA favorita

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

Documentação

Vídeo com Gráficos em Movimento

Produz um MP4 de ponta a ponta dentro do ambiente de código do Claude, sem nenhum software de edição ou filmagem. Requer execução de código e criação de arquivos (no claude.ai: Configurações > Capacidades). Para um vídeo de marca, faça upload do logotipo, fotos, cores e fontes, ou aponte para um arquivo de estilo da marca. Responda no idioma do usuário.

Como funciona

  1. A animação é escrita como uma única página HTML. A posição, tamanho, cor e opacidade de cada elemento são calculados a partir do número do quadro (window.renderFrame(f)); sem transições CSS, setTimeout ou requestAnimationFrame. Isso torna a renderização determinística.
  2. O Chrome headless (Playwright) captura cada quadro. 20 s × 60 fps = 1.200 quadros.
  3. O ffmpeg transforma os quadros em um MP4 (H.264, yuv420p).
  4. A música é sintetizada em código, sincronizada com as transições e adicionada ao vídeo.

Checklist da solicitação (pergunte uma vez o que estiver faltando)

  1. Duração: 15–20 s é o ideal.
  2. Formato: 9:16 (1080x1920) para Reels/TikTok/Shorts, 16:9 (1920x1080) para YouTube/portfólio.
  3. Material de origem: um site, fotos enviadas, um logotipo ou nada.
  4. Estilo: nomeie a técnica: tipografia cinética, infográfico/estatísticas animadas, partículas, halftone, mapa/topografia, contador, linha do tempo. Uma técnica nomeada fornece resultados mais confiáveis.
  5. Regras e exclusões: cores a combinar, coisas a deixar de fora (ex.: preços, texto extra).
  6. Ambição: se o usuário disser "faça o seu melhor", o Claude escolhe o conceito, a paleta e a música e ousa mais.

Estrutura pronta para um Reel de história: logotipo/intro de gancho (0–2 s) → frase da história em tipo cinético → um número crescendo em um contador → linha do tempo ou mapa → cartão de encerramento (identificador da conta). Mantenha o texto na tela dentro da área segura dos Reels (topo 210 px, fundo 310 px, direita 84 px limpa). Números e datas devem ter origem; nunca anime um número inventado.

Etapas de produção

  1. Escreva o plano de cena segundo a segundo (tabela: tempo | o que está na tela | transição | batida de áudio) e mostre-o.
  2. Escreva scene.html. Regras: tamanho fixo em pixels, defina window.TOTAL (total de quadros) e window.renderFrame(f); interpole com funções de easing; incorpore fontes como woff2 base64 (o ambiente pode não acessar o Google Fonts) e imagens como base64.
  3. Capture 3–4 quadros PNG primeiro e inspecione-os você mesmo (texto transbordando, fonte errada, quadro vazio). Depois faça a renderização completa.
  4. Sintetize a música com audio.py; coloque as batidas nas transições de cena. Se o usuário enviar sua própria música, use essa.
  5. Junte, verifique duração/resolução com ffprobe, verifique visualmente um quadro do meio, entregue o MP4.

Tempo de renderização: 20 s a 60 fps leva aproximadamente 8–10 minutos. Use 30 fps para rascunhos rápidos, 60 fps para o final. Aceite solicitações de revisão por timecode ("faça o contador em 0:07 mais devagar").

Modelos (testados; também fornecidos como arquivos ao lado deste SKILL.md)

scene.html (esqueleto)

<!doctype html><html><head><meta charset="utf-8"><style>
html,body{margin:0;width:1080px;height:1920px;overflow:hidden;background:#0E0E10;font-family:'Montserrat',Arial,sans-serif}
#s{position:relative;width:1080px;height:1920px}
.t{position:absolute;left:90px;right:90px;color:#F5F1E8;font-weight:800;line-height:1.05}
</style></head><body><div id="s">
<div class="t" id="a" style="top:520px;font-size:120px">5,126</div>
<div class="t" id="b" style="top:680px;font-size:64px;color:#FF5A1F">FAILED PROTOTYPES</div>
</div><script>
const FPS=30,DUR=3;window.TOTAL=FPS*DUR;
const clamp=(x,a=0,b=1)=>Math.min(b,Math.max(a,x));
const easeOut=t=>1-Math.pow(1-t,3);
window.renderFrame=f=>{const t=f/FPS;
 const p=easeOut(clamp(t/0.6));a.style.opacity=p;a.style.transform=`translateY(${(1-p)*80}px)`;
 a.textContent=Math.round(5126*easeOut(clamp(t/1.5))).toLocaleString('en-US');
 const q=easeOut(clamp((t-0.8)/0.5));b.style.opacity=q;b.style.transform=`scale(${0.8+0.2*q})`;};
</script></body></html>

render.js: node render.js scene.html video.mp4 30 (se Playwright estiver faltando: npm i playwright && npx playwright install chromium; senão, construa o mesmo loop com Python Playwright)

// node render.js scene.html out.mp4 [fps]
const {chromium}=require('playwright');const {spawn}=require('child_process');const path=require('path');
(async()=>{const [,,html,out,fpsArg]=process.argv;const fps=+(fpsArg||30);
const b=await chromium.launch();const p=await b.newPage({viewport:{width:1080,height:1920}});
await p.goto('file://'+path.resolve(html));await p.evaluate(()=>document.fonts.ready);
const total=await p.evaluate(()=>window.TOTAL);
const ff=spawn('ffmpeg',['-y','-f','image2pipe','-framerate',String(fps),'-i','-','-c:v','libx264','-pix_fmt','yuv420p','-crf','18','-preset','medium',out],{stdio:['pipe','inherit','inherit']});
for(let f=0;f<total;f++){await p.evaluate(f=>window.renderFrame(f),f);ff.stdin.write(await p.screenshot({type:'jpeg',quality:92}));}
ff.stdin.end();await new Promise(r=>ff.on('close',r));await b.close();console.log('frames',total);})();

Para 16:9, altere o viewport e o tamanho da página para 1920x1080.

audio.py: python3 audio.py music.wav <segundos> (síntese numpy: pad + batidas)

# python3 audio.py music.wav 3   -> pad sintetizado + batidas
import sys,wave,numpy as np
out,dur=sys.argv[1],float(sys.argv[2]);sr=44100;t=np.arange(int(sr*dur))/sr
pad=sum(np.sin(2*np.pi*f*t) for f in (110,164.8,220))*0.08*np.minimum(1,t/0.5)
def hit(at,f0=60):
    x=np.zeros_like(t);m=t>=at;tt=t[m]-at;x[m]=np.sin(2*np.pi*f0*tt*(1+3*np.exp(-tt*30)))*np.exp(-tt*8)*0.6;return x
y=pad+hit(0.0)+hit(0.8,90)
y=y/np.max(np.abs(y))*0.8;fade=np.minimum(1,(dur-t)/0.4);y*=fade
w=wave.open(out,'wb');w.setnchannels(1);w.setsampwidth(2);w.setframerate(sr);w.writeframes((y*32767).astype(np.int16).tobytes());w.close()

Juntar

ffmpeg -y -i video.mp4 -i music.wav -c:v copy -c:a aac -b:a 192k -shortest final.mp4

Limites

  • Efeitos podem ser aplicados a fotos (partículas, halftone, recortes); pessoas não podem ser animadas e sincronização labial não é possível (use um modelo dedicado de avatar/vídeo para isso).
  • A música sintetizada é eletrônica; para instrumentos reais ou vocais, envie um arquivo de áudio.
  • Nenhum personagem ou logotipo protegido por direitos autorais que o usuário não possua. Um logotipo de empresa real apenas em contexto de notícias/comentário, com sua fonte.

Crédito: baseado no método do guia de Michael Ly "How to Generate Motion Graphics Videos with Claude" (milleemd.com/guides/motion-graphics-videos); os modelos de código foram escritos para esta skill.

Habilidades Relacionadas