¿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.tsycards.tslanzan la compilación completachromium-*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.jsony ejecutabunx playwright install ffmpeg. - ffmpeg de Homebrew puede carecer de
drawtext. Las banderas son PNGs transparentes decards.ts, superpuestos en build.py. Sin búsqueda de fuentes ni filtros. - Las respuestas del modelo toman de 10 a 60 segundos de silencio.
sendmarca "enviado" ywaitStablemarca "respondió". build.py reproduce ese intervalo aspeed(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 pasotypey exportaNAME(page, state)desdehooks.tsjunto al escenario.state.lastJsoncontiene el último JSON POST que coincida concaptureJsonFrom. - 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.jsonuna sola bandera, y corta el mismo clip en varios segmentos del plan, una afirmación cada uno, conspansacelerando 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 consayse 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.webmcon-f mp4y un marks.json vacío, y usa un span explícito. Omite labannerya que está incluida. - Audio:
say -osolo 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.
waitTextmarca cuando aparece una expresión regular (otimeout:<mark>),probeEnabledconwaitMssondea un botón y registraprobes[]en marks.json,tryMsen type/send/click marcaskipped:<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-namesendy leyó deshabilitado mientras el envío se realizaba; usa"role"enprobeEnabled. - 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.jsonen busca de una marcarepliedantes de compilar. - Verifica que la prueba esté en texto visible. Las tarjetas de herramientas colapsadas pueden no expandirse (
expandhace clic en silencio sin éxito). Leemarks.jsonbodypara 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.