Communitygithub.com

muneebsajjad/demo-reel

Crea un vídeo de demo de producto pulido (LinkedIn, X, página de lanzamiento, listing de tienda) grabando el producto real en un navegador, para luego encuadrarlo, añadir subtítulos y renderizarlo — de principio a fin, sin editor de vídeo. Úsalo cuando alguien quiera un vídeo demo, promocional, de lanzamiento o de funcionalidad, una grabación de pantalla presentable, o «un vídeo que muestre lo que hace mi extensión / aplicación web». macOS para la grabación.

¿Qué es demo-reel?

Este skill de IA te permite generar vídeos de demostración de productos de alta calidad, completamente automatizados, sin necesidad de edición manual. El flujo de trabajo comienza con la definición de una historia (storyboard) y la escritura de un escenario de grabación (scenario.mjs). Luego, el agente graba la interacción real del producto en un navegador macOS, capturando eventos y posiciones de elementos. El editor (edit.json) define tomas, escenas, subtítulos y marca para un renderizado final profesional. El sistema admite formatos verticales (4:5, 9:16) y horizontales (16:9), genera subtítulos automáticos, música de fondo (con selección automática o pistas propias), y permite previsualizar fotogramas clave para detectar problemas antes del renderizado final. Es ideal para desarrolladores, creadores de contenido y equipos de producto que necesitan vídeos demo rápidos y pulidos.

Compatible con~Claude Code~Codex CLI✓Cursor
npx skills add muneebsajjad/demo-reel

Preguntar en tu IA favorita

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

Documentación

¿Qué hace demo-reel?

Tú produces el vídeo completo: la persona te da el producto y lo que hay que mostrar, y recibe un MP4 que puede publicar. Todo en pantalla es el producto real, grabado en vivo; el pulido (marco de ventana, movimientos de cámara, subtítulos, tarjeta de título y final) se añade después desde la grabación.

El pipeline, y el archivo que genera cada paso:

PasoComandoGenera
1. Storyboardtú, con la persona3–5 funcionalidades, un subtítulo cada una
2. Escenarioescribe scenario.mjslos pasos que daría un usuario
3. Tomabin/reel take scenario.mjs takes/take1take1.mov (imagen + sonido de la app), take1.json (eventos, posiciones de elementos)
4. Ediciónescribe edit.jsonescenas, tomas, subtítulos, marca
5. Fotogramas fijosbin/reel check edit.json, bin/reel layers edit.json, luego bin/reel stills edit.json 1,4,9problemas detectados temprano; fotogramas de previsualización
6. Subtítulosbin/reel subtitles edit.json, luego leer y corregir build/subtitles.srtlo que se dice, como subtítulos
7. Renderizarbin/reel render edit.json renders/x.mp4 --format allel vídeo en cada formato, con su .srt
8. Verificarbin/reel sheet renders/x.mp4 1,4,9,…hoja de contacto, duración, sonoridad

examples/sawt/ es un ejemplo completo resuelto (una extensión de Chrome que lee artículos en voz alta). Abre su scenario.mjs y edit.json antes de escribir los tuyos. docs/edit-format.md es la referencia del archivo de edición; docs/lessons.md enumera lo que falló la primera vez, así que léelo antes de grabar.

0. Configuración (una vez)

Ejecuta bin/reel doctor primero: verifica todas las herramientas y permisos y dice qué corregir. bin/reel setup construye el grabador (Swift, ScreenCaptureKit), instala playwright-core y Chrome para pruebas. También se necesita: ffmpeg, uv, Google Chrome (para renderizar las capas superpuestas). La terminal que te ejecuta necesita permiso de Grabación de Pantalla y Audio del Sistema (Configuración del Sistema → Privacidad y Seguridad); si el grabador informa que no tiene permiso, pídele a la persona que lo conceda y reinicie la terminal.

1. Storyboard

Acuerda, en pocas líneas, antes de grabar nada:

  • las funcionalidades, en orden, cada una con un subtítulo: un breve encabezado ("Zoom de palabras") y un título de como máximo dos líneas cortas, con el beneficio en <b> ("Sigue la lectura. Cada palabracrece mientras se habla.");
  • qué contenido real mostrar: una página pública, una cuenta de ejemplo, datos semilla. Elige contenido que haga lucir mejor la funcionalidad y verifica que funcione (para Sawt: un artículo cuyas palabras difíciles tengan tarjetas, en un sitio donde las tarjetas tengan espacio junto a la columna);
  • la marca: color de acento, variante clara, tonos de fondo, logotipo; texto de tarjeta de título y final.

Formato predeterminado: 1080×1350 (4:5), 25–35 s — llena la mayor parte de un feed de teléfono, y la mayoría ve sin sonido, así que los subtítulos deben contar la historia por sí solos. Pregunta dónde se publicará: 1:1, 9:16 y 16:9 se obtienen de la misma edición (--format), así que ofrécelos. Revisa los fotogramas fijos de cada formato que renderices: una toma que encuadre bien en 4:5 puede cortar un encabezado en 1:1; ajústalo por formato ("1:1": {"dy": 20}).

Cuando el producto hable (o la toma tenga narración), crea subtítulos: reel subtitles, luego lee el .srt y corrige nombres y jerga antes de renderizar — la transcripción es buena, no perfecta. Pon las palabras difíciles en subtitles.words para guiarla.

2. Escenario

Un escenario es un módulo ES (consulta drive/take.mjs para la API completa):

export const config = { url: "https://…", width: 1700, height: 1090, extension: "./ext" };
export async function setup(api) { /* ajustes, inicio de sesión; api.rect("title", "h1") para objetivos de cámara */ }
export async function run(api)   { /* la demo; api.mark("paso") en cada momento en que vayas a cortar */ }
export async function after(api) { /* fotogramas fijos para mostrar como escenas de imagen, p.ej. un popup a 3x */ }
  • Marca cada momento en que vayas a cortar o mover la cámara (api.mark("oración", {n})). La edición se ancla a estas marcas, así que una toma que vaya más rápida o lenta seguirá cortando en el lugar correcto.
  • Graba objetivos de cámara con api.rect(nombre, selector | fn, arg) en píxeles del viewport. Los elementos dentro de un shadow root cerrado no se pueden medir: calcula dónde estarán (consulta las tarjetas de Sawt).
  • Los productos basados en clics necesitan un puntero visible. La automatización no mueve un cursor real, así que las formas aparecen y los botones se presionan solos. Llama a api.pointer.show() en setup, luego dirige con api.pointer.click(selector | [x, y]), .drag(from, to), .move(x, y), .type(texto) y .key(k): una flecha en la página sigue, los clics se ondulan, los movimientos son suaves y la escritura tiene ritmo humano. Controla los clics por selector (un title o aria-label suele ser estable) para que sus posiciones provengan de la página.
  • Contenido en canvas (dibujos, gráficos, mapas) no tiene elemento que medir: graba el cuadro en el que dibujaste con api.rect(nombre, {x, y, ancho, alto}) en px CSS.
  • Extensiones de Chrome: ejecuta acciones a través del propio código de la extensión con api.inWorker(fn). Una extensión que dependa de activeTab necesita una copia de grabación con acceso al host, porque la automatización no puede presionar los atajos del navegador (consulta examples/sawt/prepare.sh). No cambies nada que vea un espectador.
  • Popups y otras IU pequeñas: captúralos en after() con deviceScaleFactor 3 mediante CDP (consulta el ejemplo), y muéstralos como una escena de imagen. Captura ambos estados de un toggle en el mismo momento haciendo clic en el control real, no recargando la página.

Ejecútalo, luego mira la toma antes de editar: ffmpeg -ss 6 -i takes/take1.mov -frames:v 1 x.png y lee el PNG. Verifica que la página esté estilizada, que la funcionalidad se haya disparado, que nada la cubra. Vuelve a grabar libremente: una toma cuesta un minuto.

3. Edición

Escribe edit.json (referencia: docs/edit-format.md). Reglas para que parezca hecho, no grabado:

  • Corta en las pausas. bin/reel speech take1.mov lista dónde hay sonido; las piezas de la toma comienzan justo antes de un paso y terminan antes de que comience el siguiente. Anclalas a las marcas: "oración#5-0.15".
  • El contenido lado a lado no cabe en ventanas altas. Una barra de herramientas a la izquierda y un diagrama a la derecha pueden necesitar más ancho del que muestra una ventana 4:5; reel check advierte, por formato, cuánto perderá una toma ajustada. Ajusta menos cosas o desplaza la toma para ese formato.
  • Tomas desde rectángulos. {"fit": ["title", {"rect": "card1", "dh": 330}], "pad": 60}. Un plano general amplio, luego acerca a lo que habla el subtítulo. Mantén el texto al menos ~20 px de alto en la salida; un plano general puede ser más pequeño por un momento, nunca por mucho tiempo.
  • Un subtítulo por escena, presente durante toda la escena; cambia los subtítulos solo con un movimiento de cámara.
  • Deja respirar los movimientos: 1.0–1.5 s por movimiento de cámara, mantén al menos 1.5 s después de que se detenga.
  • Tarjeta de título 2–2.5 s, tarjeta final 3–3.5 s. Escenas de imagen (un popup, un panel de ajustes) 3–4 s.

Velocidad

Un renderizado de 30 segundos en 4:5 tarda unos 3 minutos en un portátil de 6 núcleos: los fotogramas se renderizan en fragmentos paralelos (4 por defecto; --jobs N), se unen sin recodificar y las capas sin cambios se reutilizan. Mientras la edición aún se mueve, usa reel render … --draft (15 fps, codificador rápido, aproximadamente la mitad del tiempo) y reel stills; renderiza la versión real una vez que los fotogramas fijos se vean bien.

4. Verificar, siempre

  1. bin/reel layers y bin/reel stills al principio, en medio y al final de cada escena y en cada movimiento de cámara. Lee cada PNG. Busca: texto o IU cortados en los bordes del fotograma, un encabezado medio visible en la parte superior, un subtítulo sobre algo importante, un fotograma que sea una página vacía.
  2. Renderiza, luego bin/reel sheet en todo el vídeo y léelo.
  3. La duración debe ser la planeada; la sonoridad alrededor de −16 LUFS cuando el producto hace sonido.
  4. Sincronización: el momento en que aparece un paso en pantalla y su sonido comienza debe coincidir con la toma.

Luego pon el MP4 delante de la persona, con la miniatura (build/layers/title.png), y di claramente qué es real y qué se cambió para la grabación.

Música

Por defecto, el sistema elige una banda sonora que se adapte al vídeo (docs/music.md): perfila el vídeo (duración, habla, ritmo, palabras de los subtítulos), clasifica candidatos instrumentales con licencia — la carpeta music/ de la persona, luego la biblioteca CC0 incluida (library/), luego en línea solo si nada local encaja — por tempo medido, energía y estabilidad, y conserva la mejor. Ejecuta reel music auto edit.json --audition renders/x.mp4 para ver la clasificación y obtener una vista previa de las mejores pistas. Tú no puedes oír, así que pasa las vistas previas a la persona antes de dar el vídeo por terminado. Cuando las mejores pistas sean solo enlace (el sitio bloquea las descargas con script), dale los enlaces a la persona; ella descarga una y ejecuta reel music add <archivo> --candidate N. Si la persona trae su propia pista, registra su licencia con reel music add y ponla en la edición. Siempre dale el .credits.txt junto al renderizado, y di cuándo su licencia necesita un crédito publicado.

Límites

  • La grabación es solo macOS (ScreenCaptureKit). La composición y las capas funcionan en cualquier lugar.
  • Solo productos de navegador hasta ahora; una aplicación de escritorio necesita su propio controlador (scripting de accesibilidad), pero el grabador (--app <id del bundle>) y todo lo posterior ya funcionan para cualquier aplicación.
  • Generar música (reel music generate) necesita un modelo local conectado; se sugiere ACE-Step, pero aún no se ha probado con demo-reel.

Skills relacionados