🧱 Estructura del actions.json
Un JSON con la configuración global y la lista de pasos. Es el guion que capture.mjs ejecuta de principio a fin.
El actions.json describe toda la demo en un archivo: adónde ir, en qué tamaño, qué hacer en cada paso y qué decir. Un node capture.mjs actions.json y la captura queda lista.
📺 URL + viewport
Dónde y en qué tamaño. El viewport definido aquí es el espacio de coordenadas de todos los bboxes del video.
agent-browser open <url>. La app debe estar en línea en esa dirección.set viewport W H antes de open. Ancho ≤ ~1280 para que quepa en 16:9.Como el viewport es el espacio de coordenadas de las bboxes, cambiarlo después de capturar rompe la alineación del cursor. Decide el viewport antes de generar las capturas.
Por encima de ~1280 de ancho, la captura sale comprimida o se sale de los bordes del canvas 1920×1080. Reduce el viewport durante la captura en lugar de forzarlo.
📋 La lista de pasos
El array steps en orden: cada elemento es un estado de la pantalla. 5–8 pasos + CTA ≈ 35–50s.
El 1.er paso presenta la app, sin acción — solo la captura de pantalla del estado inicial.
Cada paso ejecuta un do, captura la pantalla y mide la bbox del target.
El último paso de contenido hace un zoom suave en el resultado. El CTA de INEMA.CLUB viene del composition-template.
Además, el video cansa y la captura y edición se convierten en un trabajo pesado. 5–8 pasos + CTA dan un walkthrough de ~35–50s.
⚙️ El campo do:{type}
La acción ejecutada antes de la captura de pantalla. Sin do, el paso solo captura el estado actual.
| do.type | Campos | Qué hace |
|---|---|---|
| fill | selector, valor | Completa input/textarea (CSS selector) |
| click | selector | Haz clic (CSS selector) |
| clickText | tag, texto | Haz clic en el <tag> cuyo texto === text |
| setValue | selector, valor | Define value y activa input/change |
| wait | ms | Espera (p. ej., generación lenta) |
Este fue el caso del campo de altura: fill no bastaba. El setValue dispara input+change para que el framework reaccione. (El fill nativo de Playwright está en la hoja de ruta — módulo 2.4.)
🎯 El objetivo / selector de cada paso
O target es lo que apunta el cursor. Puede ser diferente del elemento que el do activa.
- ✓ Selector CSS:
"textarea" - ✓ CSS por atributo:
"input[name=height]" - ✓ Por texto:
{tag:"button", text:"Gerar"} - ✓ capture lee el bbox del target mediante eval
- ✗ Target sin coincidencia → bbox
null+ aviso en el log - ✗ Evita @eN volátiles en pantallas que cambian
- ✗ El texto con acentos y espacios debe coincidir exactamente
- ✗ No confundas el objetivo del clic con el objetivo de la mira
Puedes completar un campo (do) y apunta al botón de enviar (target). El cursor va al target; la acción ocurre en el do.
🗣️ Texto de narración por paso
caption es el subtítulo en pantalla; narration es la voz. Expande los números y las siglas para que la lectura suene natural.
El texto de cada paso se escribe en assets/txt/sN.txt y Kokoro (voz pf_dora, --speed 0.98) genera los WAV. El texto fonético produce una voz natural.
📦 La salida: steps.json + las capturas PNG
capture.mjs genera las capturas de pantalla y steps.json, el puente entre la captura (T2) y el renderizado (T3).
00-home.png, 01-prompt.png...).O composition-template.mjs (T3) lee steps.json y arma el marco + cursor + resaltado + zoom + CTA, midiendo los WAV con ffprobe: un único timing.
🎯 Resumen del módulo
- ✓ actions.json = url + viewport + window + steps[] + CTA
- ✓ el viewport definido aquí es el espacio de coordenadas de las bboxes
- ✓ do.type: fill / click / clickText / setValue / wait
- ✓ target = lo que apunta el cursor (selector CSS o {tag,text})
- ✓ salida: shots/*.png + steps.json (contrato captura→render)