Communitygithub.com

vribeirocmp/grabación-de-videos-de-demostración

Úsalo cuando te pidan grabar una demo automatizada, POC, presentación o video guiado de una app web (también "gravar vídeo de demonstração / apresentação de fluxo") — grabación de pantalla con Playwright, subtítulos en pantalla, opcional narración por voz (TTS en inglés o portugués), salida en mp4.

¿Qué es grabación-de-videos-de-demostración?

Esta skill permite generar videos de demostración automatizados de aplicaciones web utilizando Playwright. En lugar de una captura manual, la skill crea un script de Playwright que controla el navegador, añade subtítulos y resaltes visuales, y puede incluir narración por voz mediante TTS (Text-to-Speech). Está diseñada para POCs, demos para inversores o clientes, y documentación de flujos, pero no para pruebas automatizadas ni captura de audio del navegador. Soporta dos modos: 'Silent' (solo subtítulos) y 'Narrated' (con voz TTS en inglés o portugués, usando motores offline como Kokoro o en línea como Edge). La skill enfatiza que el video debe ser un 'pitch' convincente, no una prueba E2E: cada escena debe probar un argumento. El proceso incluye escribir un guion de 4 actos, adaptar una plantilla (con ayudas para subtítulos, resaltes, login y sincronización), grabar, y verificar manualmente cada fotograma del video resultante (con ffprobe y ffmpeg). También detalla numerosos errores comunes y cómo evitarlos, como subtítulos que describen la interfaz en lugar de narrar el argumento, falta de verificación de fotogramas, y problemas de sincronización en modo narrado.

Compatible con~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/vribeirocmp/recording-demo-videos/tree/HEAD/skills/recording-demo-videos

Preguntar en tu IA favorita

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

Documentación

Grabación automatizada de videos de demostración (Playwright)

Modo (decidir PRIMERO)

Argumentos recibidos: $ARGUMENTS

ArgumentosModoPlantilla
contienen audio (o la solicitud pide voz / narración hablada)Narrado — Voz TTS + subtítulosrecord-demo-narrated-template.mjs + narrate.py
vacíos / cualquier otra cosaSilencioso — solo subtítulos (predeterminado)record-demo-template.mjs

Modo narrado: idioma en (predeterminado) o pt (portugués brasileño); motor auto (predeterminado: inglés → kokoro offline; portugués → edge, con fallback a kokoro cuando está offline), o forzar kokoro / edge. Ejemplos: audio, audio pt, audio pt kokoro, audio en edge. También sigue el Modo narrado más abajo.

Escribe subtítulos y narración en el idioma elegido (en a menos que se haya dado pt o el usuario escriba en portugués).

Resumen

Un video de demostración es código, no una captura manual: un script de Playwright controla el navegador con grabación nativa, subtítulos superpuestos y resaltes visuales. Se puede volver a grabar cuando el producto cambie (npm run demo:record), con ritmo e historia controlados.

Principio fundamental: el video es un pitch, no una prueba E2E. Cada escena existe para demostrar un argumento — y el trabajo solo termina después de VERIFICAR el video generado fotograma a fotograma.

Cuándo usar / no usar

  • ✅ POC/Demo de producto web para inversores, clientes, partes interesadas, onboarding
  • ✅ Documentar un flujo completo que sigue evolucionando (regrabable)
  • ✅ Con voz: modo narrado (TTS local/offline) — ver arriba
  • ❌ Pruebas automatizadas (usar Playwright Test) · ❌ aplicaciones no web · ❌ capturar el sonido propio de la app (Playwright no graba audio del navegador)

Proceso

  1. Estado determinista primero. El video realiza acciones reales (inicios de sesión, clics, escrituras en BD). Asegura datos de semilla/demo idempotentes y cuentas dedicadas antes de grabar. Ejecuta el servidor en modo producción (build && start) o calienta las rutas en desarrollo — la compilación diferida aparece como una pantalla blanca en el video.
  2. Escribe el guion ANTES de codificar. Un arco de pitch de 4 actos: la visión (apertura) → cómo funciona (el diferenciador, por dentro) → la experiencia del usuario final → la prueba/resultado (cierra con la visión). Cada escena = 1 argumento + 1 subtítulo (titular fuerte + texto explicativo). Objetivo: 60–120s en total, 3–5s en cada pantalla clave.
  3. Adapta la plantilla — ayudas preparadas para subtítulos, resaltes, inicio de sesión, ritmo y conversión. Usa los colores de marca del proyecto para el subtítulo.
  4. Graba, y trata los fallos de selectores como un script roto (arréglalo, no lo rodees).
  5. VERIFICA el video — obligatorio. Duración y escenas:
    ffprobe -v error -show_entries format=duration -of csv=p=0 demo.mp4
    # captura 1 fotograma por escena y MIRA cada uno (¿subtítulo correcto? ¿pantalla correcta? ¿nada roto?)
    ffmpeg -y -ss <t> -i demo.mp4 -frames:v 1 -vf scale=800:-1 frame_<t>.png
    
    Solo entrega después de inspeccionar los fotogramas. Si una escena falló, vuelve a grabar.
  6. Entrega .mp4 (funciona en PowerPoint/Slack/WhatsApp) además del .webm. Deja un script npm (demo:record) y agrega la salida a gitignore (es regenerable).

Modo narrado (audio)

Mismo proceso que arriba, con estas diferencias:

  • Requisitos previos: uv y ffmpeg en PATH (uv --version, ffmpeg -version). Copia narrate.py en la MISMA carpeta que el script de grabación. La primera ejecución descarga el modelo Kokoro (~120 MB, almacenado en caché en ~/.cache/recording-demo-videos).
  • El ritmo proviene del audio. Cada escena en SCRIPT tiene caption (pantalla) + say (discurso, 1–2 oraciones, tono de pitch). await narrate(page, "id") muestra el subtítulo, coloca el discurso y espera a que termine — no uses un pause() fijo en escenas habladas. Hablar durante una interacción: narrate(page, id, { wait: false }); el siguiente narrate() espera al discurso anterior (sin superposición).
  • Idioma/voz mediante env: DEMO_LANG=en|pt, DEMO_TTS=auto|kokoro|edge, DEMO_VOICE=<voz> (Kokoro: af_heart, am_michael, bf_emma, pf_dora, pm_alex; edge: en-US-AvaMultilingualNeural, pt-BR-FranciscaNeural…). kokoro = offline, Apache-2.0, predeterminado para inglés; su portugués es notablemente menos natural. edge = predeterminado para portugués, mejores voces, pero en línea a través de un endpoint no oficial de Microsoft — adecuado para demos internas; para uso comercial prefiere kokoro o un TTS oficial.
  • La sincronización es automática: la plantilla abre con un destello magenta (syncMarker), mide el retraso real de inicio del video y recorta el destello. Mantén syncMarker como la primera acción; si el registro dice "Sync marker not found", la voz estará desincronizada — verifica que syncMarker sea la primera acción y que nada cubra la pantalla en el primer segundo, luego vuelve a grabar.
  • Salida: demo.mp4 (narrado — el entregable), demo.srt, timeline.json, demo.raw.webm (crudo, silencioso), audio/ (caché: volver a grabar solo resintetiza las líneas cambiadas).
  • Verificación extra (obligatoria): además de los fotogramas, confirma que la voz aterrice en el lugar correcto:
    ffprobe -v error -show_entries stream=codec_type,duration -of csv=p=0 demo.mp4   # debe tener video Y audio
    ffmpeg -i demo.mp4 -af silencedetect=n=-45dB:d=0.6 -f null - 2>&1 | grep silence_end
    # cada silence_end ≈ el atVideo de una escena en timeline.json (±0.2s); captura el fotograma en ese momento y verifica el subtítulo
    

Errores comunes (aprendidos por las malas)

ErrorSolución
El video obtiene un nombre de archivo aleatorioCaptura page.video() ANTES de cerrar; await video.path() DESPUÉS de context.close(); renombra
El subtítulo desaparece al navegarVuelve a inyectar el subtítulo después de cada goto (ayudante caption()), o addInitScript + sessionStorage
Video demasiado rápido para humanosslowMo: 100–150 + pausas explícitas de 3–5s por escena + pressSequentially({ delay: 40–60 }) para escritura visible
mp4 no se abre en PowerPoint/reproductoresffmpeg -c:v libx264 -pix_fmt yuv420p
Video más pequeño/recortadorecordVideo.size DEBE coincidir con viewport
Pantalla blanca/pendiente en el videowaitUntil: "networkidle" + waitForURL después de acciones; calienta rutas en desarrollo
El espectador no sabe dónde mirarResalte ámbar (sombra de caja) en el elemento antes de hacer clic, o un cursor falso inyectado
Volver a grabar duplica datosAcciones idempotentes o una semilla que tolere reejecuciones (slugs con sufijo, upserts)
El inicio de sesión se filtra entre personascontext.clearCookies() entre cambios de usuario
(narrado) Voz desincronizada con la pantallaEl video de Playwright comienza 0.2–1.5s después de la página (varía por ejecución/versión) — usa el syncMarker de la plantilla, nunca un desplazamiento fijo
(narrado) Voz cortada o escenas apresuradaspause() fijo en una escena hablada — reemplázalo con narrate(), que espera al discurso
(narrado) Acrónimo/marca mal pronunciadoEscríbelo fonéticamente en say (ej. "S Q L" o "sequel"); el subtítulo permanece correcto

Errores comunes

  • Saltarse la verificación de fotogramas ("se ejecutó sin errores" ≠ "el video está bien") — siempre mira.
  • Subtítulos que describen la interfaz ("pantalla de inicio de sesión") en lugar de narrar el argumento ("el equipo inicia sesión — control de roles detallado").
  • Grabar sin un guion escrito: obtienes una larga grabación de pantalla sin historia.
  • Credenciales reales codificadas — usa cuentas demo/semilla, inyecta mediante env si son sensibles.

Skills relacionados