Video de capacitación de aplicación
Crea un video de capacitación profesional de una aplicación real. El video es de aproximadamente 1920 × 1080 H.264 con narración AAC. Cada oración hablada tiene subtítulos, cada capítulo abre con una tarjeta y los tiempos de espera largos se eliminan. Es reproducible: cuando la interfaz de usuario cambia, se vuelve a ejecutar la captura y el renderizado y el video vuelve a estar actualizado.
Cómo funciona:
- Un storyboard contiene el texto de la narración, los capítulos y la marca.
narrate.pyreproduce cada segmento con la voz offline Kokoro: sin servicio en la nube, sin cuenta, sin costo.- Un script de captura controla la aplicación real con Playwright (movimiento real del mouse, un cursor visible y ondas de clic). Graba los fotogramas de screencast de Chrome y mantiene cada segmento hasta que termina su narración.
render.pyensambla los clips, las tarjetas, la banda de subtítulos y la pista de narración con normalización de volumen.review.pyverifica el resultado y construye una hoja de contactos para revisar antes de publicar cualquier cosa.
Los scripts están en scripts/ junto a este archivo. Lee references/storyboard.md antes de escribir la
narración y references/capture-guide.md antes de escribir el script de captura. Ambos contienen lecciones que
evitan las regrabaciones habituales.
0. Configuración inicial
bash <skill>/scripts/setup.sh
Esto crea ~/.cache/app-training-video/ (se puede sobrescribir con TRAINING_VIDEO_HOME) que contiene:
- un entorno privado de Python 3.10–3.13 con paquetes fijados;
- el modelo de voz Kokoro (~350 MB) y la tipografía Inter, verificados con SHA-256;
- Chromium.
Ejecuta cada script con el Python de ese entorno (PY=~/.cache/app-training-video/venv/bin/python) y
pasa la ruta del storyboard. Si los archivos del modelo ya existen en algún lugar, ejecuta primero MODEL_SOURCE=<dir> para
reutilizarlos. ffmpeg viene incluido (imageio-ffmpeg); no se instala nada a nivel de sistema.
1. Entiende la aplicación y la audiencia
Antes de escribir nada, usa la aplicación tú mismo (o lee su guía de usuario) y averigua:
- Quién mira: nuevos clientes, personal de campo, usuarios internos.
- El único flujo de trabajo que deben dominar: desde la entrada hasta el resultado.
- Qué datos de demostración se pueden mostrar sin riesgo.
- Cómo iniciar la aplicación en un estado limpio: URL o comando de lanzamiento, más una carpeta de datos nueva o cuenta demo.
- Marca: nombre de la empresa, nombre del producto, versión, logotipo PNG, color de acento, líneas de contacto para el final.
Pregunta al usuario cualquier cosa que no puedas encontrar. De seis a siete minutos es lo adecuado para un flujo de trabajo completo, y 60–90 segundos para una sola función.
2. Escribe el storyboard
Copia assets/storyboard.example.json junto al proyecto como storyboard.json y escríbelo siguiendo
references/storyboard.md. En resumen:
- 10–35 segundos de habla por segmento;
- capítulos
"n · Título", concard: "chapter"en el primer segmento de cada capítulo; - tarjetas de
introyoutro; - los acrónimos se escriben para la voz, con
caption_replacementsque restauran la forma escrita.
Muestra la narración al usuario antes de filmar: es barato cambiarla ahora y caro después.
3. Narra
$PY <skill>/scripts/narrate.py storyboard.json
Imprime la duración de cada segmento. Solo vuelve a hablar segmentos cuyo texto haya cambiado. Escucha uno
o dos WAVs en video-build/audio/ si la pronunciación es importante, ajusta la ortografía y vuelve a ejecutarlo.
4. Escribe y ejecuta el script de captura
Copia scripts/capture_template.py a capture.py junto al storyboard, establece la ruta a la carpeta
scripts/ de la skill, y escribe un bloque with rec.segment('<id>'): por segmento filmado, en orden del storyboard.
Dentro de él, realiza exactamente lo que describe la narración:
rec.click,rec.hover,rec.type,rec.drag,rec.scroll,rec.park;rec.cut()alrededor de cualquier cosa lenta, esperando un resultado visible.
El grabador rechaza una carpeta frames/ no vacía, por lo que nunca se mezclan fotogramas antiguos.
$PY capture.py storyboard.json
Cada segmento imprime su duración filmada frente a su narración. La ejecución falla (estado incomplete) en el
primer paso roto, cualquier error de página o cualquier segmento que no se haya filmado. Corrige el paso, vacía
video-build/frames/ y vuelve a ejecutarlo.
5. Renderiza y revisa
$PY <skill>/scripts/render.py storyboard.json
$PY <skill>/scripts/review.py storyboard.json
Resultados en la carpeta de build:
<output_name>.mp4- subtítulos
.srt -chapters.txt(pégalo en una descripción de YouTube)-poster.jpg-timeline.json-review.jpg: una imagen por segmento.
Abre la hoja de contactos y mírala, y verifica el MP4 con muestras aleatorias. Comprueba:
- la pantalla correcta en cada segmento;
- sin banners de error, gráficos vacíos o diálogos sueltos;
- el cursor nunca tapa lo que se está explicando;
- subtítulos que se lean correctamente.
Los selectores pueden coincidir mientras la pantalla es incorrecta, por lo que esta revisión es obligatoria antes de dar el video por terminado.
6. Entrega
Entrega al usuario el MP4, el SRT (la mayoría de los reproductores lo cargan automáticamente cuando los nombres coinciden) y la
lista de capítulos. Menciona la duración y el tamaño. Para publicar, sube el MP4 y el SRT juntos. Guarda
storyboard.json y capture.py con el proyecto: después del siguiente cambio de interfaz, vuelve a ejecutar los pasos 4–5 (y
el paso 3 si el texto cambió).
Solución de problemas
| Síntoma | Solución |
|---|---|
Need Python 3.10–3.13 | Instala python3.12, o establece PYTHON= antes de ejecutar setup.sh |
launch() agota el tiempo de espera aunque la aplicación inició | La aplicación almacena en búfer su salida: ejecuta servidores Python con python -u, o verifica la expresión regular ready |
| Chromium no inicia en Linux | $PY -m playwright install --with-deps chromium |
| El localizador agota el tiempo de espera o coincide con dos elementos | Limítalo a una región, o usa get_by_role con exact=True (consulta la guía de captura) |
| Segmento mucho más largo que su narración | Algo lento no está dentro de rec.cut() |
| Pronunciación incorrecta | Vuelve a escribirla en speech, agrega una regla de caption_replacements, vuelve a ejecutar narrate.py |
| Subtítulos desincronizados | El tiempo de los subtítulos sigue la duración de la narración: acorta las oraciones largas, o divide el segmento |