Vídeo de demostración
Una demostración de producto, una vista previa de tienda o un bucle de funcionalidad construido a partir de la grabación de pantalla real del usuario. La interfaz nunca se regenera: la grabación se corta, acelera, amplía, enmarca, subtitula y locuta. Apple establece la misma regla para las vistas previas (2.3.4: se permiten capturas de vídeo de la propia aplicación, narración y superposiciones). Un cut.json contiene las grabaciones, las escenas ordenadas y las variantes; democut.py lo convierte en archivos con ffmpeg local, y volver a cortar es gratuito.
Paso 0 — Verificación previa
Una vez por sesión:
python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" tools
kind: "ffmpeg_missing"→ no es posible cortar localmente. Dilo y ofrece la ruta de utilidad de pago enreferences/routing-utility.md, o pide al usuario que instale ffmpeg. Nunca improvises con otras herramientas.- Mantén
can.burn_captions(libass),can.duck(sidechaincompress),can.webm. Los que falten cambian lo que prometes, nunca lo que afirmas. - Solo cuando se vaya a generar algo (narración, música, sonido, doblaje, una placa):
command -v genmedia python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" preflightblockersno vacío, CLI faltante o más antiguo que 0.7.0 →/genmedia-skills:setup. Clave faltante → el usuario ejecutagenmedia setupo exportaFAL_KEYél mismo; espera. Nunca leas, imprimas, solicites ni escribas una clave. Manténconfig.announce_above_usdyconfig.confirm_above_usd(valores predeterminados 0.50 y 2). - Reanuda primero: si existe
.genmedia/projects/<slug>/demo-video/cut.json→ continúa desde ahí, nunca inicies un segundo corte para el mismo producto.
Reglas de UX
- Responde en el idioma del usuario. La narración, las líneas de
sayy el texto en pantalla permanecen en el idioma en el que se entregan; las indicaciones del modelo están en inglés. Las rutas, los identificadores y los nombres de campo permanecen como están. - Sin JSON, gráficos de filtro, ID de solicitud ni narración de herramientas en el chat. Como máximo una línea de estado por paso largo.
- Presupuesto de preguntas: 2, una a la vez, opciones etiquetadas, solo cuando falte la respuesta:
- P1 la grabación, cuando no se haya dado ningún archivo: pide las rutas y pasa la lista corta de captura de
references/recording-tips.md. No hay valor predeterminado para el metraje. - P2 el destino, cuando la solicitud no lo especifique: A Demostración web (16:9) · B Vista previa de App Store · C Vídeo de encabezado o resultados de búsqueda de App Store · D Promo de Google Play · E Vídeo de lanzamiento de Product Hunt · F Un bucle silencioso o GIF. Se pueden elegir varios; un solo corte sirve para todos. Todo lo demás es un valor predeterminado que indicas en la entrega: 60 s para una demo, 20 s para una vista previa de tienda, 12 s para un vídeo de encabezado o búsqueda de App Store, 6 s para un bucle; narración activada para una demo, desactivada para un bucle o un vídeo de encabezado o búsqueda; música desactivada a menos que se solicite; subtítulos como archivo secundario; cortes, no fundidos; sin marco de dispositivo a menos que un destino de tienda o red social lo requiera.
- P1 la grabación, cuando no se haya dado ningún archivo: pide las rutas y pasa la lista corta de captura de
- La tarjeta de corte es una parada obligatoria. Muestra la lista de escenas (tiempos, qué sucede, qué se dice, duraciones) y espera un «sí» antes de generar o renderizar algo. El silencio no es aprobación, y un «sí» a una versión anterior no es un «sí» a esta.
- La narración antes que la imagen. Genera la voz por escena, deja que
timela mida y corta la imagen para que coincida. Nunca cronometres una escena adivinando cuánto tarda una oración (references/narration-and-audio.md). - Mira antes de entregar. Lee el fotograma de póster y una hoja de contactos del archivo terminado, y lee el primer fotograma de cualquier GIF. Una demo que se valida pero muestra la pantalla incorrecta sigue siendo incorrecta.
- Los hechos y la privacidad provienen del usuario. Las calificaciones, recuentos, premios, nombres de clientes y logotipos aparecen solo cuando el usuario los ha proporcionado. Si un fotograma muestra datos reales, la solución es una nueva grabación, no un desenfoque; dilo claramente.
- Coste: el corte, los fotogramas, los bucles y cada comprobación cuestan USD 0. Antes de cualquier generación, estima y aplica el límite de la verificación previa: por debajo de
announce_above_usd→ ejecuta e indícalo; hastaconfirm_above_usd→ una línea, luego ejecuta; por encima → «sí» explícito. Nunca cotices un precio de memoria. - Acotado: como máximo 3 intentos de reparación por paso, algo cambia cada vez; un rechazo por política de contenido nunca se reenvía sin cambios; un trabajo con un ID de solicitud se reanuda, nunca se reenvía.
Barrera de descubrimiento
scripts/video-surfaces.json es una caché con fecha (verified_on, leído por democut.py specs): un null es un número que nadie leyó de la página oficial, nunca lo rellenes de memoria, y cuando una tienda rechaza un archivo, la página oficial gana y la fila se corrige.
Antes de la primera llamada de pago a un endpoint en una sesión:
genmedia models --endpoint_id <endpoint_id> --json
python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" schema <endpoint_id>
status debe ser active; los campos, enumeraciones y límites provienen del esquema. Si no está activo → el siguiente nivel de esa tarea en references/routing-audio.md. Nunca genmedia run con una indicación en lugar de un ID de endpoint. Las nuevas versiones se encuentran bajo espacios de nombres de proveedores, no solo fal-ai/.
Enrutamiento
| Necesidad | Cómo | Por qué |
|---|---|---|
| Recortar, acelerar, ampliar, enmarcar, unir, superponer, mezclar, volumen, GIF, comprobaciones | democut.py (ffmpeg local) | exacto, gratuito, repetible; los píxeles del producto nunca pasan por un modelo |
| Mirar una grabación o un resultado sin verlo | democut.py analyze, sheet, grab; frames.py sheet | detectores y hojas de contactos en lugar de suposiciones |
| Narración | fal-ai/elevenlabs/tts/eleven-v3; Turco: fal-ai/gemini-3.1-flash-tts | TTS predeterminado; la ruta turca está verificada por esquema |
| Música de fondo, sonidos de interfaz | elevenlabs/music/v2.5 (duración exacta), fal-ai/elevenlabs/sound-effects/v2 | control de duración; económico por segundo |
| Sincronización de subtítulos precisa por palabra | fal-ai/elevenlabs/speech-to-text/scribe-v2 → audiokit.py captions | marcas de tiempo por palabra |
| Otro idioma para un archivo terminado | fal-ai/elevenlabs/dubbing | una llamada por idioma |
| Marco de dispositivo, tarjeta final, texto exacto en imagen | /genmedia-skills:launch-graphics (layers, PNGs compuestos) | el texto se compone donde es exacto, nunca se genera |
| Placa de fondo detrás de un dispositivo enmarcado | bytedance/seedream/v5/pro/text-to-image | una placa por vídeo, sin letras |
| Sin ffmpeg local | fal-ai/ffmpeg-api/* en references/routing-utility.md | céntimos por llamada, un plan de respaldo y no el predeterminado |
Desempates y trampas:
- La interfaz nunca se genera, rediseña, reenmarca ni «mejora».
video-reframe,video-edity los upscalers repintan el texto de la interfaz de usuario: son para metraje generado, no para una grabación. - Zoom en fracciones del fotograma de origen, leído de
grab --gridosheet --grid;holdpara detalle,pushuna vez para guiar la vista,pulluna vez para revelar contexto (references/editing.md). - Una vista previa de tienda no es la demo con un final más corto: es su propia variante con su propio subconjunto de escenas.
- Play y Product Hunt requieren una URL de YouTube, no un archivo: entrega el archivo y di quién lo sube.
- Un vídeo de encabezado o resultados de búsqueda de App Store (activo creativo de iOS 27) es su propia variante silenciosa y en bucle:
appstore-header-video(3840x1646) oappstore-search-video(3:2), 30 o 60 fps, 5-30 s, una idea, escenas de 2 s o más, terminando donde empezó. Apple no enumera un vídeo universal; las imágenes fijas son trabajo delaunch-graphics(references/surfaces.mdsección 1a). - Una grabación de teléfono necesita un marco de teléfono;
timerechaza una discrepancia de aspecto del 30 %. - Quemar solo cuando
can.burn_captions; de lo contrario, un archivo secundario, o la ruta de subtítulos de pago, dicho en voz alta. - El usuario nombró un modelo → úsalo después de la comprobación en vivo.
Flujo de trabajo
- Ingesta. Objetivo, destinos, grabaciones, marca. Lee cada archivo que el usuario nombró. Luego, por grabación:
La respuesta incluye tamaño, fps, duración, audio, cualquier letterboxing incorporado y los destinos que se ajustan al aspecto. Una grabación más pequeña que el destino, o que muestra datos reales, recibe una solicitud de regrabación ahora, no después de la edición (python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" init --slug <slug> --name "<Product>" --target web-16x9 python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" source add --slug <slug> --id app --file ./recordings/demo.mov --os desktopreferences/recording-tips.md). - Mírala.
Lee la hoja.python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" analyze --slug <slug> --source app python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" sheet --slug <slug> --source app --count 12 --cols 4 --griddead_spansykeep_spansson candidatos, nunca una edición: una pantalla estática a veces es el punto.grab --at <s> --gridpara cualquier fotograma en el que vayas a hacer zoom. - Tarjeta de corte. Escenas en orden: id, entrada/salida de origen, velocidad, zoom, qué ve el espectador, qué dice la voz, duración; luego las variantes, qué se genera, qué se necesita del usuario y las suposiciones. Muéstrala, para, espera un «sí» (
references/editing.md). - Narración, medida (solo si la demo tiene voz). Precio y ejecuta un lote por
references/narration-and-audio.md, un archivo por escena, luego deja que los números decidan la imagen:python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" price fal-ai/elevenlabs/tts/eleven-v3,elevenlabs/music/v2.5 --explain python3 "${CLAUDE_SKILL_DIR}/scripts/gm.py" batch --plan .genmedia/projects/<slug>/demo-video/voice-plan.json - Escribe el corte. Edita
.genmedia/projects/<slug>/demo-video/cut.jsoncon la herramienta de Escribir o Editar:scenes,audio,variants. Cada campo:references/cut-json.md. Los marcos de dispositivo provienen delaunch-graphics layers(references/frames-and-loops.md). - Compuerta.
Corrige cada error antes de renderizar:python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" time --slug <slug>scene_shorter_than_voice(alarga el intervalo, reduce la velocidad o corta palabras — nunca aceleres la voz),duration_out_of_rangeen un destino de tienda,wrong_size,fps_not_allowed,transition_too_long,frame_aspect_mismatch,overlay_invisible. Actúa sobre las advertencias (quick_cut,fast_motion,narration_muteden un vídeo de activo creativo) o explica las que mantengas. - Construir.
Tiempo de espera de Bash de 600000 ms. Las escenas se almacenan en caché por contenido: una revisión vuelve a renderizar solo lo que cambió (python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" build --slug <slug>--scene <id>,--force). Luego subtítulos y bucles:python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" captions --slug <slug> --variant <id> --formats srt,vtt python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" gif --slug <slug> --variant loop-16x9 --budget-mb 3 --seconds 6 - Mira el resultado. Lee el fotograma de póster, luego una hoja de contactos del archivo terminado, luego el primer fotograma del GIF:
Verifica los primeros 3 segundos, los fotogramas ampliados (¿legibles?), el último fotograma (¿estable?), cada fotograma en busca de datos privados y lee el archivo de referencia letra por letra.python3 "${CLAUDE_SKILL_DIR}/scripts/frames.py" sheet genmedia-output/<slug>/demo-video/<variant>/<slug>.mp4 --count 9 --cols 3 - Validar y entregar.
Tamaño exacto, fps, duración dentro de la ventana de la plataforma, códec y perfil, límite de bytes, configuración de audio, volumen medido y pico verdadero, y en un destino de bucle la costura (python3 "${CLAUDE_SKILL_DIR}/scripts/democut.py" validate --slug <slug>loop_seam). Luego el mensaje de entrega. Revisiones: edita el corte, vuelve a construir, valida de nuevo.
Entrega
<Product> demo: genmedia-output/<slug>/demo-video/
Master 16:9: web-16x9/<slug>.mp4 (1920x1080, <n> s) · póster web-16x9/<slug>-poster.png
Vista previa App Store: appstore-iphone/<slug>.mp4 (886x1920, <n> s, H.264 High, AAC 256k) <solo si se construyó>
Vídeo de encabezado / búsqueda App Store: appstore-header-video/<slug>.mov (3840x1646, <n> s, <fps> fps, bucle silencioso) · fotograma de póster para seleccionar en App Store Connect: <t> s <solo si se construyó>
Promo Play / Product Hunt: el mismo master — ambas plataformas aceptan una URL de YouTube, así que súbelo y pega el enlace <solo si se construyó>
Bucles: loop-16x9/<slug>-loop.mp4 · <slug>-loop.gif (<n> MB, <w>px@<fps>) · primer fotograma <slug>-loop-first.png <solo si se construyó>
Subtítulos: <variant>/<slug>.srt, .vtt (<language>) <solo si se construyó> · manifest.json
Tu grabación, sin cambios: cortada, <acelerada donde esperaba>, ampliada en <qué>, <enmarcada en un dispositivo dibujado>. Nada en la interfaz se regeneró.
Elegido para ti: <duración, número de escenas, narración activada/desactivada, música, subtítulos, marcos, ajuste — todos los valores predeterminados que el usuario no estableció>
Notas de tienda: <una línea cada una que corresponda: las vistas previas de App Store son de 15-30 s, hasta 3 por dispositivo, solo capturas de pantalla (2.3.4) · los vídeos de encabezado y búsqueda se repiten silenciados (búsqueda: nunca sin silenciar), se muestran en iOS 27 y iPadOS 27 o posterior, y su fotograma de póster se fija una vez aprobado · solo los primeros 30 s de una promo de Play se reproducen automáticamente · las imágenes de Product Hunt, incluido el GIF, deben pesar menos de 3 MB y el GIF se anima al pasar el ratón por encima>
Generado: <ninguno, USD 0 | narración <n> líneas en <modelo>, música, est. USD <x>> · Los archivos son locales; no se subió nada.
Siguiente: nombra una escena y qué cambiar (entrada/salida, velocidad, zoom, palabras); volver a cortar es gratuito.
Tradúcelo; mantén las rutas, tamaños y texto en pantalla sin cambios.
Errores
| Señal | Haz |
|---|---|
kind: "ffmpeg_missing" | Sin ffmpeg local. Di que el corte no se puede hacer aquí; ofrece la ruta ffmpeg-api de fal (references/routing-utility.md) o pide al usuario que lo instale. |
source_changed | La grabación se movió o cambió. source add --replace, luego vuelve a verificar cada entrada/salida: los tiempos antiguos ya no significan nada. |
check_failed de time | Cada entrada nombra una escena y un número. Arregla el corte; nada se renderiza mientras haya un error. |
scene_shorter_than_voice | Alarga el intervalo, reduce speed o corta palabras. Nunca aceleres la narración para que encaje. |
duration_out_of_range | Se incumplió una ventana oficial (vistas previas de App Store 15-30 s, vídeos de encabezado y búsqueda 5-30 s). Elimina o acorta escenas solo para esa variante. |
wrong_size, fps_not_allowed, fps_too_high | El tamaño o fps de la variante rompe su fila. Elimina la anulación o elige un valor que la fila acepte (specs). |
loop_seam de validate | El bucle salta en su reinicio. Termina en el estado inicial o mantén la misma región, construye, valida de nuevo. |
frame_aspect_mismatch | La relación de aspecto de la grabación no coincide con el destino. Elige un destino que coincida (specs) o pide una regrabación. El usuario debe saber qué destinos se ajustan. |
overlay_invisible | La imagen de superposición (marco, tarjeta final) no es visible en el fotograma de origen. Aumenta la escala o elige una superposición diferente de launch-graphics. |
Referencias
(Las referencias se encuentran en los archivos indicados. La ruta es relativa al directorio del skill funi-ai/demo-video.)