Communitygithub.com

erencalik/motion-graphics-video-generator-claude

Produce un video animado MP4 de gráficos en movimiento con música a partir de una sola solicitud (9:16 Reels o 16:9) renderizando una animación HTML/CSS/JS cuadro por cuadro y uniéndola con ffmpeg. Ideal para gráficos animados, tipografía cinética, estadísticas animadas, animaciones para Reels.

¿Qué es motion-graphics-video-generator-claude?

Esta habilidad permite generar videos completos de gráficos en movimiento (motion graphics) en formato MP4 directamente dentro del entorno de código de Claude, sin necesidad de software de edición ni metraje de archivo. Funciona escribiendo la animación como una única página HTML donde cada elemento (posición, tamaño, color, opacidad) se calcula determinísticamente a partir del número de cuadro (`window.renderFrame(f)`), evitando transiciones CSS, setTimeout o requestAnimationFrame. Luego, usando Playwright (headless Chrome) se capturan todos los cuadros (por ejemplo, 20 segundos a 60 fps = 1200 cuadros), ffmpeg los convierte en un video H.264 y se sintetiza música en código (numpy) que se sincroniza con las transiciones. Soporta formatos 9:16 (1080x1920) para Reels/TikTok/Shorts y 16:9 (1920x1080) para YouTube/portafolios, e incluye plantillas listas para usar para HTML, captura de cuadros (render.js) y síntesis de audio (audio.py). El usuario solo necesita proporcionar la duración, el estilo (tipografía cinética, infografía animada, partículas, etc.), reglas de diseño y materiales de origen (logo, fotos, colores, fuentes). La habilidad está diseñada para funcionar en claude.ai (requiere ejecución de código y creación de archivos) y se basa en el método de Michael Ly.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Video de Gráficos en Movimiento

Produce un MP4 de principio a fin dentro del entorno de código de Claude, sin necesidad de software de edición ni metraje de archivo. Requiere ejecución de código y creación de archivos (en claude.ai: Ajustes > Capacidades). Para un video de marca, sube el logotipo, fotos, colores y fuentes, o señala un archivo de estilo de marca. Responde en el idioma del usuario.

Cómo funciona

  1. La animación se escribe como una única página HTML. La posición, el tamaño, el color y la opacidad de cada elemento se calculan a partir del número de cuadro (window.renderFrame(f)); no se usan transiciones CSS, setTimeout ni requestAnimationFrame. Esto hace que el renderizado sea determinista.
  2. Chrome sin cabeza (Playwright) captura cada cuadro. 20 s × 60 fps = 1200 cuadros.
  3. ffmpeg convierte los cuadros en un MP4 (H.264, yuv420p).
  4. La música se sintetiza en código, sincronizada con las transiciones, y se añade al video.

Lista de verificación para la solicitud (preguntar una vez lo que falte)

  1. Duración: 15–20 s es ideal.
  2. Formato: 9:16 (1080x1920) para Reels/TikTok/Shorts, 16:9 (1920x1080) para YouTube/portafolio.
  3. Material de origen: un sitio web, fotos subidas, un logotipo o nada.
  4. Estilo: nombra la técnica: tipografía cinética, infografía/estadísticas animadas, partículas, medios tonos, mapa/topografía, contador, línea de tiempo. Una técnica nombrada da resultados más fiables.
  5. Reglas y exclusiones: colores a igualar, cosas que omitir (por ejemplo, precios, texto extra).
  6. Amplitud: si el usuario dice "haz lo mejor que puedas", Claude elige el concepto, la paleta y la música por sí mismo y se vuelve más audaz.

Estructura predefinida para un Reel narrativo: logotipo/intro gancho (0–2 s) → frase de la historia en tipografía cinética → un número que crece en un contador → línea de tiempo o mapa → tarjeta de cierre (nombre de cuenta). Mantén el texto en pantalla dentro del área segura de Reels (parte superior 210 px, parte inferior 310 px, margen derecho 84 px). Los números y las fechas deben tener fuente; nunca animes un número inventado.

Pasos de producción

  1. Escribe el plan de escenas segundo a segundo (tabla: tiempo | qué hay en pantalla | transición | golpe musical) y muéstralo.
  2. Escribe scene.html. Reglas: tamaño de píxel fijo, define window.TOTAL (cuadros totales) y window.renderFrame(f); interpola con funciones de easing; incrusta fuentes como base64 woff2 (el entorno puede no alcanzar Google Fonts) e imágenes como base64.
  3. Captura primero 3–4 cuadros PNG e inspecciónalos tú mismo (texto desbordado, fuente incorrecta, cuadro vacío). Luego haz el renderizado completo.
  4. Sintetiza la música con audio.py; coloca los golpes en las transiciones de escena. Si el usuario sube su propia música, usa esa.
  5. Une, verifica duración/resolución con ffprobe, revisa visualmente un cuadro intermedio, entrega el MP4.

Tiempo de renderizado: 20 s a 60 fps toma aproximadamente 8–10 minutos. Usa 30 fps para borradores rápidos, 60 fps para el final. Acepta solicitudes de revisión por código de tiempo ("haz el contador en 0:07 más lento").

Plantillas (probadas; también se incluyen como archivos junto a este 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">PROTOTIPOS FALLIDOS</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 (si falta Playwright: npm i playwright && npx playwright install chromium; si eso falla, construye el mismo bucle con 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, cambia el viewport y el tamaño de la página a 1920x1080.

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

# python3 audio.py music.wav 3   -> pad sintetizado + golpes
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()

Unir

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

Límites

  • Se pueden aplicar efectos a fotos (partículas, medios tonos, recortes); no se pueden animar personas ni es posible la sincronización de labios (usa un modelo dedicado de avatar/video para eso).
  • La música sintetizada es electrónica; para instrumentos reales o voces, sube un archivo de audio.
  • No se permiten personajes con derechos de autor ni logotipos que el usuario no posea. Un logotipo de empresa real solo en contexto de noticias/comentario, con su fuente.

Crédito: basado en el método de la guía de Michael Ly "How to Generate Motion Graphics Videos with Claude" (milleemd.com/guides/motion-graphics-videos); las plantillas de código fueron escritas para esta habilidad.

Skills relacionados