Communitygithub.com

product-video

Produce un video narrado de producto, demostración o para inversores con HyperFrames desde una aplicación web en vivo, un prototipo o un archivo público de Figma.

¿Qué es product-video?

Esta skill automatiza la creación de videos narrativos de producto de 60 a 120 segundos, generando un proyecto HyperFrames (con `index.html` y activos) y un MP4 renderizado. El flujo de trabajo cubre desde la identificación de fuentes (aplicaciones web en vivo, archivos Figma públicos o prototipos) y la escritura de un guion con tabla de afirmaciones verificables, hasta la captura de capturas de pantalla, grabaciones de interacción y frames de Figma. Incluye la generación de voz mediante servicios TTS (ElevenLabs u otros por MCP) o narración suministrada, alineando las marcas de tiempo con el guion para subtítulos precisos. La composición en HyperFrames ancla las animaciones a frases de la narración, muestra pantallas reales dentro de maquetas y verifica sincronización, contraste y volumen antes de entregar el video final con un README detallado.

Compatible con✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/arven-org/product-video-skill/tree/main

Preguntar en tu IA favorita

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

Documentación

Video de producto

Construye un video narrado de 60 a 120 segundos que presente un producto usando sus pantallas reales. El resultado es un proyecto HyperFrames (un index.html generado más activos) y un MP4 renderizado.

Escribe cada entrega (guion, texto en pantalla, README) en el idioma de la audiencia. Este archivo está en inglés solo porque son instrucciones.

Estructura de salida

Crea una carpeta por video, fuera de cualquier repositorio de código a menos que el usuario indique lo contrario:

<Product>-video/
  ROTEIRO.md | SCRIPT.md     guion, tabla de afirmaciones, puntos a confirmar
  LEIA-ME.md | README.md     qué es real, qué está reconstruido, límites, cómo volver a ejecutar
  01-.. 0N-..                activos capturados, una carpeta por fuente
  voz/ | voice/              segmentos de narración (texto y audio por escena)
  ferramentas/ | tools/      configuraciones y gen.js (el generador de composición)
  hyperframes/
    index.html               GENERADO. Nunca editar a mano.
    assets/{img,video,audio,fonts}
    renders/

Flujo de trabajo

Ejecuta las fases en orden. Cada una termina con una verificación; no comiences la siguiente fase hasta que la verificación pase.

P1. Fuentes

  1. Localiza cada fuente que el usuario haya nombrado. Una ruta de otra máquina no existirá: busca el mismo proyecto en las carpetas del usuario actual e indica cuál usaste.
  2. Clasifica cómo se puede mostrar el producto:
    • Aplicación en vivo, accesible: captúrala (P3, site-capture.cjs, record-interaction.cjs).
    • Archivo Figma público: captura frames a través de la vista de prototipo (P3, figma-frames.cjs). No se necesita token.
    • Detrás de un inicio de sesión sin acceso: pide capturas de pantalla o una cuenta de prueba. No reconstruyas pantallas de memoria.
  3. Extrae las palabras propias del producto: texto de la página de inicio, nombres de funciones, números, FAQ, términos. Estas son la única fuente permitida para afirmaciones.

Verificación: puedes nombrar la audiencia, los módulos del producto y la fuente de cada hecho que planeas usar.

P2. Guion

Lee references/script.md y escribe el archivo de guion a partir de su plantilla. Las reglas más importantes:

  • Presupuesto de 2.3 a 2.6 palabras habladas por segundo. 250 palabras son aproximadamente 100 segundos.
  • Una idea por escena, de 8 a 16 segundos por escena, de 6 a 9 escenas.
  • Cada afirmación en la narración tiene una fila en la tabla de afirmaciones con su fuente. Omite cualquier cosa que las fuentes no puedan respaldar.
  • Escribe para la voz: nombres de marca como se pronuncian, números deletreados, sin abreviaturas que la voz deletrearía letra por letra.

Verificación: la tabla de afirmaciones no tiene celdas de fuente vacías, y la lista de "puntos a confirmar" nombra cada número que provino del texto de marketing.

P3. Activos

Lee references/capture.md para ejemplos de configuración.

FuenteScriptSalida
Aplicación web en vivo, estáticascripts/site-capture.cjspliegue inicial, página completa, capturas de paso, videos de desplazamiento, recortes
Aplicación web en vivo, flujosscripts/record-interaction.cjsclips de interacción con cursor o superposición táctil
Archivo Figma públicoscripts/figma-frames.cjsun PNG por frame, recortado al frame

También recopila la marca: logotipo (vector si existe), los archivos de fuente de la marca con su licencia, y los tokens de color del CSS del producto. Lee los estilos que usan las páginas del producto con scripts/page-styles.cjs <url>: familia de titulares, peso, altura de línea y espaciado entre letras, estilos de botones y cualquier superficie de vidrio esmerilado. El video los copia en lugar de adivinarlos.

Verificación: abre algunas capturas y míralas. Una captura que muestre una pantalla de inicio de sesión, un banner de cookies o una superposición de desarrollo es una captura fallida.

P4. Voz

Lee references/voice.md. Pregunta qué voz tiene el usuario antes de generar nada: un servicio pago accesible mediante MCP o una clave API es lo primero, una narración suministrada es lo segundo. Un modelo local gratuito es solo para un usuario que lo solicite, porque instala un modelo en su máquina.

  • Servicio de voz mediante MCP: genera toda la narración como una sola toma continua (un párrafo por escena, una etiqueta de entrega al inicio). Alínea con scripts/voice.py --existing, corta en las pausas con scripts/split-take.py --level, luego une los archivos de escena con scripts/voice.py --parts "voz/cena-{id}.wav". Los límites de las escenas son exactos y el tono se mantiene igual de la primera a la última escena. Una narración solicitada escena por escena cambia el estado de ánimo entre solicitudes.
  • Servicio de voz mediante una clave API: scripts/voice.py --provider elevenlabs --el-voice <id> genera y une. scripts/elevenlabs.py verifica la conexión, clasifica voces y compone música.
  • Narración suministrada: pasa --existing. Los límites de las escenas provienen de alinear la transcripción con el guion.

Con un modelo expresivo, configura la entrega con una [etiqueta de audio] al inicio de la toma. Cada escena lleva text (limpio, para subtítulos) y puede llevar tts (lo que recibe la voz, cuando difiere).

En todos los modos, las marcas de tiempo de las palabras están alineadas con el texto del guion, por lo que los subtítulos nunca muestran un error de transcripción. Lee la lista misheard que imprime: cualquier cosa que no sean números deletreados y homófonos es un problema de pronunciación. Corrige el texto del guion y regenera.

Normaliza la narración a aproximadamente −18 LUFS antes de componer.

Verificación: voiceover.json existe, la duración total está dentro del 10% del objetivo, misheard está explicado, y scripts/voice-tone.py --scenes reporta una dispersión de la mediana del tono entre escenas de aproximadamente 3 semitonos o menos.

P5. Composición

Lee references/hyperframes.md (las reglas que aplica el renderizador) y comienza desde assets/gen-template.js.

  • Genera index.html desde un script. Los cambios de tiempo ocurren cada vez que cambia la voz; un generador absorbe eso, las ediciones manuales no.
  • Ancla cada animación a una frase de la narración (at(3, 'No painel')), nunca a una sola palabra corta. "no", "e" y "um" aparecen varias veces por escena y la primera coincidencia es la incorrecta.
  • Reserva el 17% inferior del marco para subtítulos. Nada más entra en esa banda.
  • Muestra pantallas reales dentro de una ventana de navegador o maqueta de dispositivo. Coloca la explicación al lado, no encima.
  • Prefiere un resaltado claro por oración (un círculo, un zoom, un movimiento del cursor) sobre muchos pequeños.
  • Los titulares toman el estilo de titular propio del producto y las etiquetas toman su lenguaje de superficie, ambos leídos en P3. No uses por defecto el peso más pesado.
  • Para historias, reels o shorts, lee references/vertical.md y construye una segunda composición vertical a partir de la misma narración, comenzando desde assets/gen-vertical-template.js. Nunca recortes la composición 16:9.

Verificación: npx hyperframes lint tiene 0 errores.

P6. Verificar

  1. npx hyperframes check debe terminar con "Check passed" (lint, tiempo de ejecución, diseño, movimiento, contraste).
  2. npx hyperframes snapshot --no-end --at <un tiempo por escena, más cada resaltado> y mira cada frame. Construye hojas de revisión 2×2 con ffmpeg para revisar más rápido.
  3. Compara cada frame con lo que dice la narración en ese segundo. Los defectos habituales: pantalla incorrecta para la oración, un resaltado en el elemento equivocado, texto que se ajusta mal, un elemento dentro de la banda de subtítulos.
  4. Renderiza un borrador (render -q draft), luego verifica el MP4 en sí: ffprobe para duración y flujos, loudnorm para sonoridad (objetivo −16 a −17 LUFS con música), y frames extraídos con ffmpeg.

Verificación: has mirado un frame de cada escena tomado del MP4, no solo de las instantáneas.

P7. Entregar

Escribe el README con: qué es real (capturado), qué se reconstruyó en HTML con datos reales, qué es conceptual, límites conocidos, los comandos para previsualizar, verificar y renderizar, y cómo cambiar la voz. Luego informa al usuario: qué se hizo, qué se verificó y qué aún necesita una decisión humana (números no confirmados, música, calidad de voz).

Errores ya pagados

CódigoSíntomaCausa y solución
X1Las pantallas cambian un segundo antesat() coincidió con el primer "no" o "e". Ancla en frases.
X2Un elemento permanece oculto durante escenas enterasDos interpolaciones fromTo en el mismo elemento; la posterior renderiza su estado "from" inmediatamente. Usa un elemento por aparición, o to() desde un estado inicial CSS.
X3El sitio responde 403 al script pero se abre en un navegadorAgente de usuario headless. Usa lib/browser.cjs, que envía un UA de escritorio.
X4"El ejecutable no existe" al iniciarLa compilación del navegador instalada difiere de la versión de Playwright. lib/browser.cjs recurre al Chromium local más nuevo, luego a Chrome.
X5La captura de página completa se corta en un pliegueLa aplicación desplaza un contenedor interno. Encuentra el elemento desplazable más grande y aumenta el viewport a su altura.
X6La grabación de desplazamiento se entrecortaLa tasa de fotogramas del screencast es variable. Renderiza los desplazamientos fotograma a fotograma.
X7Revisas un archivo que nunca cambiaEl grabador escribe en una carpeta diferente a la que inspeccionas. Imprime y verifica la ruta de salida.
X8Un contador se renderiza diminuto junto a un "%" enormeUn selector descendente (.num span) también coincidió con el span del contador interno. Usa selectores de hijo para las etiquetas.
X9Los subtítulos muestran una palabra incorrectaLos subtítulos provinieron de la transcripción bruta. Alinea los tiempos con el texto del guion (voice.py hace esto).
X10La voz pronuncia mal la marca o un términoEscríbelo como se habla (una marca escrita como una palabra se narra como dos, un término extranjero recibe una frase nativa), deletrea los números, expande las abreviaturas.
X11Una segunda ejecución de captura borró el índice de la primeraFusiona los archivos de índice entre ejecuciones en lugar de sobrescribir.
X12El video dentro de un contenedor con tiempo falla la verificaciónEl medio temporizado lleva class="clip" él mismo; su contenedor no tiene tiempo.
X13La captura del prototipo incluye un toast o barra de cookiesCierra y oculta las superposiciones antes de la captura de pantalla, luego recorta al frame.
X14La grabación muestra botones solo de prototipoOculta los controles de prueba y desarrollo por selector o prefijo de texto antes de grabar.
X15Afirmaciones que el producto no puede probar"Primero", "total", "garantizado" necesitan una fuente. Déjalas fuera o muévelas a "puntos a confirmar".
X16Un número de marketing no tiene baseVerifica de dónde vino antes de usarlo: busca en los documentos y en el historial de git de la página (git log -S'<número>'). Un número añadido a mano en una edición de texto no es evidencia. Deséchalo.
X17El corte vertical es ilegibleUna pantalla de escritorio en 9:16 tiene texto de 9 px, y un recorte todavía parece de escritorio. Muestra un elemento adaptado a la vez en un panel, como lo hace la página de inicio móvil del producto (references/vertical.md).
X18La narración suena dramática o eufóricaLas etiquetas no verbales ([suspira]), [emocionado] y [serio] se exceden en un video de producto. Usa [calmado] y [cálido], regenera solo las escenas nombradas y compara tomas con scripts/voice-tone.py.
X19El diseño parece una página webColumna alineada a la izquierda, etiquetas de sección sobre titulares, un logotipo pequeño en una esquina. En video vertical: centra todo, quita las etiquetas, haz el logotipo más grande y centrado.
X20El eslogan está lejos del logotipoLa exportación del logotipo tiene relleno transparente. Recorta el archivo y posiciona contra la marca real.
X21La narración es plana en algunas escenas y emocionada en otrasCada escena fue una solicitud separada con su propia etiqueta, por lo que cada una fue una interpretación separada. Genera una sola toma continua con una etiqueta, córtala en las pausas con scripts/split-take.py y mide con scripts/voice-tone.py --scenes. Una dispersión de 5 semitonos entre escenas se percibió como cambios de humor, 2 como uniforme.
X22Los titulares se ven pesados y diferentes al productoSe asumió el peso (800). Lee el estilo de titular propio del producto con scripts/page-styles.cjs y copia familia, peso, altura de línea y espaciado entre letras.
X23Las palabras se juntan en un titularEl espaciado ajustado entre letras copiado de una página web cierra los espacios entre palabras en tamaños de video. Agrega word-spacing: .07em.
X24Una etiqueta de vidrio parece blanca sólida, o su desenfoque aparece después del fundidoEl fondo es demasiado opaco (mantén la parte inferior cerca de 0.6), o el fundido está en un padre: la opacidad por debajo de 1 en un ancestro corta el elemento de lo que está detrás. Anima el elemento que tiene backdrop-filter.
X25La verificación de contraste falla en texto que se ve bienLa verificación muestreó un frame en medio de un fundido. Toma una instantánea en el momento reportado. Si el elemento está a medio entrar, mueve la entrada unos frames y vuelve a ejecutar la verificación. Las composiciones muy cortas sufren más esto.

Archivos en esta skill

  • references/script.md: plantilla de guion, ritmo, tabla de afirmaciones, tabla de pronunciación.
  • references/capture.md: configuraciones para los tres scripts de captura, especificaciones de captura, activos de marca.
  • references/voice.md: configuración de TTS, voces, alineación, sonoridad, música, intercambio de narración.
  • references/hyperframes.md: reglas de composición, comandos CLI, zonas de diseño.
  • references/vertical.md: versión 9:16 para historias: área segura, cámara en la pantalla, subtítulos, división en partes.
  • assets/gen-template.js: generador de composición 16:9 para copiar en la carpeta de herramientas del proyecto.
  • assets/gen-vertical-template.js: generador vertical con una edición completa y una corta.
  • scripts/lib/browser.cjs, scripts/site-capture.cjs, scripts/record-interaction.cjs, scripts/figma-frames.cjs, scripts/element-shots.cjs, scripts/page-styles.cjs, scripts/voice.py, scripts/split-take.py, scripts/voice-tone.py, scripts/elevenlabs.py, scripts/lib/eleven.py.

El código de la API de ElevenLabs (--provider elevenlabs, elevenlabs.py) fue escrito sin una clave para probar. Su primera ejecución real puede necesitar una corrección; la ruta --parts y la ruta local están probadas.

Skills relacionados