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
- 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. - Chrome sin cabeza (Playwright) captura cada cuadro. 20 s × 60 fps = 1200 cuadros.
- ffmpeg convierte los cuadros en un MP4 (H.264, yuv420p).
- 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)
- Duración: 15–20 s es ideal.
- Formato: 9:16 (1080x1920) para Reels/TikTok/Shorts, 16:9 (1920x1080) para YouTube/portafolio.
- Material de origen: un sitio web, fotos subidas, un logotipo o nada.
- 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.
- Reglas y exclusiones: colores a igualar, cosas que omitir (por ejemplo, precios, texto extra).
- 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
- Escribe el plan de escenas segundo a segundo (tabla: tiempo | qué hay en pantalla | transición | golpe musical) y muéstralo.
- Escribe
scene.html. Reglas: tamaño de píxel fijo, definewindow.TOTAL(cuadros totales) ywindow.renderFrame(f); interpola con funciones de easing; incrusta fuentes como base64 woff2 (el entorno puede no alcanzar Google Fonts) e imágenes como base64. - Captura primero 3–4 cuadros PNG e inspecciónalos tú mismo (texto desbordado, fuente incorrecta, cuadro vacío). Luego haz el renderizado completo.
- 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. - 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.