promo-video — del SaaS que corre en local al video marketing terminado
El objetivo: el usuario abre Claude en la carpeta de su producto (o en una carpeta vacía), explica lo que quiere mostrar, y se va con un MP4 impactante que muestra su producto real, no maquetas aproximadas. La historia se valida con él ANTES de codificar. Todo lo que se mueve en pantalla está medido (coordenadas capturadas), todo lo que se escucha es generado (cero derechos de autor).
El skill se construyó produciendo un video real (Trkly, 41 s, 11 capturas, música sincronizada) y codifica todo lo aprendido: los peligros de Remotion, Playwright, lint, y lo que hace que un video de producto sea creíble.
Los archivos del skill
| ruta | rol |
|---|---|
scripts/setup.mjs | Scaffold completo del proyecto Remotion (deps, Playwright, skills Remotion, plantillas, música) |
scripts/capture.mjs | Captura declarativa de páginas reales (plan JSON → PNG @2x + boxes.json) |
scripts/boxes-to-ts.mjs | boxes.json → src/story/boxes.ts tipado |
scripts/make-music.mjs | Música + SFX sintetizados (drop y golpe final parametrizables) |
scripts/probe.mjs | Verifica un MP4 renderizado (duración, pistas) sin ffmpeg |
templates/ | Componentes (BrowserFrame, Cursor, Caption, Callout, DotGrid), escenas, brand.ts, plan de captura de ejemplo, CLAUDE.md del proyecto |
templates/examples/Demo.example.tsx | La demo completa de referencia (28 s, 11 capturas, scroll, escritura, chips) para leer antes de escribir la tuya |
references/scenario.md | Modelo de guion + reglas de escritura de leyendas |
references/pitfalls.md | Todos los peligros encontrados (Remotion, Playwright, lint, audio, Windows) |
references/checklist.md | Lo que hay que verificar antes de entregar |
<skill> abajo = la carpeta de este SKILL.md (~/.claude/skills/promo-video, .claude/skills/promo-video o el caché del plugin). Verifica con ls antes de ejecutar un script.
Flujo de trabajo
0. Definir (5 minutos) — y VALIDAR el guion antes de codificar
Hazte (o haz al usuario, de una sola vez) las siguientes preguntas:
- El producto: nombre, una frase, URL local (
npm run dev¿en qué puerto?) o URL de producción. ¿Hay un muro de inicio de sesión / suscripción? → se necesita una forma de levantarlo para grabar (flag de demo en la app, cuenta de prueba, cookies). NUNCA pidas una contraseña para que la escribas tú mismo: el usuario se conecta en un navegador y te da las cookies, o activa un modo demo. - Lo que quiere mostrar: 3 a 5 momentos precisos (una página, un filtro, un clic, un resultado). Cada momento = una captura + una acción del cursor + una leyenda.
- El dolor que el producto resuelve, en una frase familiar ("¿Estás harto de…?").
- El formato: 16:9 por defecto (X, LinkedIn, YouTube, landing). 9:16 solo si se pide explícitamente (TikTok/Reels) — las plantillas están diseñadas para 1920x1080.
- El CTA final: URL, "Link en bio", "Prueba gratis"… y el eslogan.
Luego escribe el guion en el chat usando references/scenario.md como modelo: 8 escenas, duraciones, texto en pantalla, lo que se ve, y propón la técnica (capturas reales con Playwright, recomendado). Espera el "adelante" del usuario. Si dice "tú maneja", es un adelante: no vuelvas a preguntar, toma decisiones y documéntalas.
Escribe el guion validado en SCENARIO.md en la raíz del proyecto de video: es la referencia para todas las escenas y para retoques futuros.
1. Scaffold del proyecto de video
Siempre un proyecto separado del producto (carpeta hermana <producto>-video): Remotion + Chromium no tienen nada que hacer en el build del SaaS, y el tsc de un next build incluiría los archivos de video.
node <skill>/scripts/setup.mjs ../monsaas-video --name "MonSaaS" --domain monsaas.app --base http://localhost:3000 --accent "#f97316" --desc "una frase"
El script: create-video --blank (Tailwind v4 incluido), remotion add de paquetes (transitions, google-fonts, media, zod, + whisper-webgpu y video-matting que son deps opcionales del Studio sin las cuales muestra errores), Playwright 1.63 + Chromium, los skills oficiales de Remotion (npx skills add remotion-dev/skills), copia de plantillas, CLAUDE.md del proyecto, launch.json (Studio en el puerto 3012 — cambia --port si está ocupado), y una música por defecto. Cuenta de 3 a 5 minutos.
Luego: npm run lint en el proyecto debe estar verde antes de cualquier modificación (el esqueleto compila con cajas placeholder).
2. Extraer la identidad visual del producto
Abre el CSS del producto (globals.css, tailwind.config, variables :root) y completa src/brand.ts: color de acento, fondo oscuro, texto, fuente de Google (cambia la importación @remotion/google-fonts/<Font>), logo (copia el PNG en public/logo.png), dominio. No adivines los colores: léelos. Todos los componentes leen brand, ningún color está codificado en las escenas.
3. Capturar el producto real
El producto debe estar corriendo (pídele al usuario que inicie su servidor, o inícialo mediante preview_start, nunca en Bash). Si un muro bloquea el contenido, elimínalo ANTES (modo demo, cookies en el plan: "cookies": [...], o "localStorage": {...}).
Escribe capture-plan.json (modelo: capture-plan.example.json, documentación completa al inicio de scripts/capture.mjs): un paso por acción. Para cada momento del guion:
shotdel estado anterior,click/typede la acción,settle,shotdel estado posterior.boxpara cada elemento al que el cursor apuntará o que un resaltado rodeará (botones, opciones de menú, campo de búsqueda, primera línea de una tabla, insignia, sección).- Para una página larga,
viewportalto (ej. 1920x3400) con"group": "tall"— nunca usesshotFullen un layouth-screen/panel desplazable, solo captura el viewport. - Una generación de IA:
shotdurante la carga,waitGonedel spinner (timeout largo),shotdel resultado.
node <skill>/scripts/capture.mjs capture-plan.json # PNG @2x + public/shots/boxes.json
node <skill>/scripts/boxes-to-ts.mjs # -> src/story/boxes.ts
Mira cada captura (herramienta Read) antes de continuar: contenido molesto (datos de prueba feos, bug de visualización, nombre de usuario), popover mal abierto, página no cargada. Corrige en el plan (añade un wait, un filtro en la URL, un css para ocultar un elemento) y recaptura. Si detectas un bug del producto, anótalo para la entrega — no lo corrijas en el producto sin que te lo pidan.
4. Música
setup.mjs ya generó public/audio/ (music + click/whoosh/pop/impact). La música está estructurada: intro tensa → drop → groove → golpe final → cola. Haz coincidir el drop con la llegada del producto a pantalla y el golpe final con la firma:
node <skill>/scripts/make-music.mjs --drop 8 --end 36 --total 42.5 [--bpm 120] [--transpose -2] [--seed 7]
120 BPM = 15 frames por pulso a 30 fps: sincroniza las escenas en múltiplos de 15. Si el usuario proporciona un mp3, colócalo en public/audio/music.wav|mp3 y adapta Story.tsx — verifica la licencia antes.
5. Escribir las escenas
Lee templates/examples/Demo.example.tsx completamente: es el modelo de lo que se espera (zoom de cámara hacia cada elemento clickeado, cursor que llega en arco y hace clic, captura siguiente en fundido, resaltado + etiqueta, desplazamiento de una captura alta, escritura de teclado letra por letra, chips que aparecen, leyenda a pantalla completa por idea, flash blanco en cortes fuertes, pulsación en el beat). Luego adapta Demo.tsx: SHOTS (capturas y límites), ZOOM (keyframes de cámara), SCROLL, CURSOR (los clics disparan los sonidos), los Callout, los Caption.
Reglas de puesta en escena:
- Una idea por leyenda, 3 a 6 palabras + un grupo en acento. Nunca dos leyendas al mismo tiempo.
- Zoom hacia lo que queremos que se lea (1,4 a 1,7) y luego vuelta a 1: el espectador debe poder leer las etiquetas reales. Una captura a ancho completo sin zoom no se lee.
- El cursor muestra antes de hacer clic: llega 15 a 25 frames antes del clic, nunca teletransportado.
- Una acción = estado anterior → clic → estado posterior, con el fundido de 4 frames de los
SHOTS. - Sin coordenadas fijas: todo viene de
boxes. Si falta un número, agrega unaboxal plan. - Las copias y escenas de texto (Hook/Tensión/Outro) se pasan mediante las props de
Story→ editables en el Studio.
Verifica sobre la marcha con stills, no en el Studio reducido:
npx remotion still Demo out/check.png --frame=120 --scale=0.5
Mira cada still (herramienta Read). Busca: texto cortado en el borde de la ventana, etiqueta que superpone un elemento leído, cursor en el lugar equivocado, captura aún no mostrada, leyenda que cubre la acción. Corrige, re-renderiza, hasta que cada momento clave esté limpio.
6. Renderizar y verificar
npm run lint
npx remotion render Story out/<slug>-story.mp4
node <skill>/scripts/probe.mjs out/<slug>-story.mp4 # duración, pista de video, pista de audio
No concluyas "está bien" basándote solo en el renderizado: renderiza de 6 a 10 stills en los momentos clave de la versión final y míralos. No puedes escuchar la mezcla: dímelo al usuario e indica cómo ajustar (volume en Story.tsx, parámetros de make-music.mjs).
7. Entregar
Envía el MP4 (SendUserFile) y un resumen que se sostenga solo: dónde está el archivo, duración/formato, la lista de escenas con lo que se ve en cada una, lo que se ha verificado y lo que no (el sonido), los bugs del producto detectados al grabar, cómo recapturar si la UI cambia (3 comandos), y las variantes fáciles (9:16, versión de 15 s, otro idioma = props de Story). Consulta references/checklist.md.
Lo que hace que el video sea "impactante" (por orden de impacto)
- El producto real en pantalla, legible (zoom), con un cursor que hace acciones reales.
- El drop musical sincronizado con la llegada del producto, flash blanco en el corte.
- Las leyendas: cortas, familiares, una por idea, una palabra en acento.
- Los resaltados que apuntan exactamente al elemento del que se habla (insignia de precio real, botón).
- El ritmo: nunca más de 2 s sin que pase algo; 40 s como máximo en total.
- Los microdetalles: fundido entre capturas, pulsación en el beat, chips que aparecen, SFX de clic.
Carga references/pitfalls.md antes de escribir código Remotion y relee references/checklist.md antes de entregar.