Communitygithub.com

Narrated A/B video

Crea un video narrado de prueba A/B de un PR o funcionalidad: graba cada lado con Playwright, genera tarjetas de título/evidencia/veredicto y banderas A/B, narra cada segmento con la voz de macOS, acelera las esperas del modelo, congela el último fotograma para ajustar la narración y concatena todo en un solo mp4.

¿Qué es B video?

Este skill permite a un agente de IA (como Claude Code) crear videos narrados de pruebas A/B para documentar visualmente el comportamiento de dos variantes de una funcionalidad (por ejemplo, PR base vs. PR con cambios). Está diseñado para macOS con Apple Silicon, utilizando herramientas nativas como `say` para la narración y Playwright para la grabación del navegador. El flujo de trabajo incluye: preconfiguración automática de dependencias (Chromium, ffmpeg, Playwright), grabación de escenarios para cada lado A y B, generación de tarjetas gráficas (título, evidencia, veredicto) con banderas A/B superpuestas, y un script en Python que acelera los tiempos de espera del modelo, congela el último fotograma para sincronizar narración y video, y concatena todo en un solo archivo mp4. Es especialmente útil para demostraciones de equipo, revisiones de PR y documentación visual de resultados, evitando problemas comunes como la falta de filtros `drawtext` (usa PNGs en su lugar) o la desincronización entre narración y metraje. Soporta voces personalizadas vía ElevenLabs y puede usarse para demos de un solo lado (sin A/B).

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/sblattj/agent-chandlery/tree/main/skills/narrated-ab-video

Preguntar en tu IA favorita

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

Documentación

¿Qué hace B video?

Más disparadores

video walkthrough del PR, hacer una demo grabada, demo con locución, grabar ambas pilas, video explicativo, sin filtro drawtext, Playwright recordVideo, headless shell faltante

Un mp4 por conjunto de afirmaciones: tarjeta de título, clip A, clip B, tarjeta de evidencia, tarjeta de veredicto, cada una con locución.

Construido para macOS en Apple Silicon (say, el caché de Playwright en ~/Library/Caches/ms-playwright, chrome-mac-arm64). En otros sistemas, configura CHROMIUM_EXE y usa --eleven para la voz. Necesita Bun, ffmpeg y Python 3.

Haz esto

S=${SKILL_DIR:-~/.claude/skills/narrated-ab-video}
$S/preflight.sh /tmp/vid                                  # chromium, playwright ffmpeg, ffmpeg, say voice
bun $S/record.ts a.json raw/a-run                         # un escenario por lado (copia examples/scenario.json)
bun $S/record.ts b.json raw/b-run
bun $S/cards.ts cards.json cards                          # title/evidence/verdict PNGs + banner-A/B.png
python3 $S/build.py plan.json                             # [--voice Samantha] [--rate 182]
abrir -a "QuickTime Player" demo.mp4                     # abre en pausa; nunca lo reproduzcas tú mismo

Ejemplos en examples/: scenario.json (pasos: wait, select, click, clickIfPresent, type, send, waitStable, expand, fetchText, waitText, probeEnabled, reload; consulta el encabezado de record.ts), cards.json, plan.json. Las rutas del plan son relativas al archivo del plan. Validado de extremo a extremo en una compilación de 4 segmentos, 40s a partir de dos clips reales.

Por qué está construido así (fricciones resueltas)

  • El headless shell fijado de Playwright a menudo no está descargado. record.ts y cards.ts lanzan la compilación completa chromium-* más reciente en caché (o $CHROMIUM_EXE) en lugar de fallar.
  • recordVideo necesita su propia compilación de ffmpeg. Si falta, no hay webm. preflight lee la revisión de browsers.json y ejecuta bunx playwright install ffmpeg.
  • ffmpeg de Homebrew puede carecer de drawtext. Las banderas son PNGs transparentes de cards.ts, superpuestos en build.py. Sin búsqueda de fuentes ni filtros.
  • Las respuestas del modelo toman de 10 a 60 segundos de silencio. send marca "enviado" y waitStable marca "respondió". build.py reproduce ese intervalo a speed (por defecto 10x) y el resto a 1x.
  • La narración suele ser más larga que el clip. build.py mantiene el último fotograma (tpad stop_mode=clone) hasta que la voz termina, así una respuesta permanece en pantalla mientras se explica.
  • Entrada dinámica (códigos OTP, IDs de turnos anteriores): pon {{fn:NAME}} en un paso type y exporta NAME(page, state) desde hooks.ts junto al escenario. state.lastJson contiene el último JSON POST que coincida con captureJsonFrom.
  • Selectores: los botones se emparejan por rol y nombre con expresión regular ("Herramientas usadas", "^Enviar$"). CSS solo para inputs y selects. Encuentra nombres con una captura de pantalla rápida antes de escribir el script.
  • La concatenación necesita codificaciones idénticas. Cada segmento se recodifica con el mismo códec, tasa y disposición de audio, luego se unen con -c copy.
  • Voz mejorada: ELEVENLABS_API_KEY=... build.py plan.json --eleven <voice_id> (modelo eleven_multilingual_v2; los clips se cachean por hash de voz+texto, así que las reejecuciones no gastan caracteres). Guarda la clave en un archivo 0600, nunca en el plan, y bórralo después.
  • Demo de un solo lado (sin A/B): graba un escenario, da a cards.json una sola bandera, y corta el mismo clip en varios segmentos del plan, una afirmación cada uno, con spans acelerando las esperas (ej. 5x). Misma compilación, sin lado A.
  • El usuario puede pegar solo <voice_id> <key>. Eso significa reconstruir con --eleven <voice_id>. Una voz más lenta alarga el video (72s con say se convirtieron en 92s), ya que build.py mantiene el último fotograma hasta que la voz termina.
  • Reconstruir una demo desmontada antes de filmar: la autenticación de corta duración (JWTs locales, URLs de túneles, recursos temporales en la nube) suele estar muerta al día siguiente. Verifica de nuevo con una ejecución de API antes de grabar; un 401 "JWT token expired" habría filmado un turno cuyos resultados nunca llegan.
  • Clip sin procesar perdido: corta el metraje de ese lado de un mp4 de salida anterior (encuentra su span muestreando el color de la esquina de la bandera), guárdalo como <dir>/a.webm con -f mp4 y un marks.json vacío, y usa un span explícito. Omite la banner ya que está incluida.
  • Audio: say -o solo escribe archivos. Nunca reproduzcas el video ni ningún audio sin la aprobación explícita del usuario. Ábrelo en pausa y entrégalo.
  • Prueba antes de filmar. Ejecuta el A/B y confirma el resultado (API o registro) primero. El video muestra un resultado probado; no es la prueba.
  • Las tarjetas deben coincidir con el tamaño del clip. build.py no escala. Grabar con "viewport": [1440, 900] necesita "size": [1440, 900] en cards.json, o la concatenación tendrá tamaños de fotograma mezclados.
  • UIs asíncronas necesitan marcas, no esperas fijas. waitText marca cuando aparece una expresión regular (o timeout:<mark>), probeEnabled con waitMs sondea un botón y registra probes[] en marks.json, tryMs en type/send/click marca skipped:<step> en lugar de abortar, así un lado "permanece deshabilitado" aún termina el clip.
  • Sondea el mismo elemento que haces clic. Un sondeo CSS (button[aria-label=...]) encontró un botón diferente al del role-name send y leyó deshabilitado mientras el envío se realizaba; usa "role" en probeEnabled.
  • Superposiciones de modo desarrollo (query devtools, toasts de error) aparecen en el clip. Añade {"clickIfPresent": "^Cerrar .* devtools$"} después de la primera espera.
  • Esperar una respuesta que nunca se "estabiliza": una insignia de tiempo transcurrido en vivo cambia el cuerpo del texto cada segundo. Revisa marks.json en busca de una marca replied antes de compilar.
  • Verifica que la prueba esté en texto visible. Las tarjetas de herramientas colapsadas pueden no expandirse (expand hace clic en silencio sin éxito). Lee marks.json body para la cadena de la afirmación. Si falta, cambia el prompt o pruébalo en una tarjeta en su lugar.
  • Prueba la paridad antes de filmar una afirmación "base falla". Una vez una base local falló por una razón (un flag activado localmente, desactivado remotamente) que el entorno real nunca encuentra, y la narración lo afirmó. Iguala primero los flags remotos, luego filma.
  • Tarjeta de título: commits probados y flags en cada lado. Una afirmación por segmento de clip. Termina en una tarjeta de veredicto.

Relacionados

  • narrated-screenshot: una sola imagen anotada en lugar de un video.
  • pr-ab-evidence: el método A/B rojo/verde cuyo resultado este skill filma.

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Skills relacionados