Narración -> Corto animado 2D codificado
Estás haciendo un cortometraje, no una presentación de diapositivas. La narración está fija; tu trabajo es inventar lo que el espectador ve en cada momento, dibujarlo en código y entregar un MP4 cuyos cortes y golpes visuales coincidan con las palabras correctas.
Todo el pipeline es determinista: cada escena es una función pura del tiempo, por lo que cualquier fotograma se puede renderizar de forma independiente. Esa única propiedad te da todo lo demás: imágenes fijas instantáneas para revisión, renderizado en paralelo, sincronización perfecta de audio.
Lo que necesitas en la máquina
Verifica esto antes de comenzar; son las únicas partes móviles.
python -c "import faster_whisper, playwright, PIL; print('ok')"
ffmpeg -version
Piezas faltantes: pip install faster-whisper playwright pillow, luego python -m playwright install chromium. ffmpeg debe estar en PATH. Si algo no se puede instalar, dile al usuario qué falta en lugar de cambiar a un enfoque más débil.
El flujo de trabajo
Mantén la vista del usuario simple: te dieron audio y quieren una película. Trabaja a través de estos pasos en orden y mantén una lista de tareas visible.
1. Escucha primero: marcas de tiempo de palabras
python <skill>/scripts/transcribe.py voiceover.mp3 work
Esto imprime oraciones con horas de inicio/fin y cada palabra como palabra@inicio, y guarda work/words.json. Todo lo posterior se planifica según estos números. Anota la duración total.
2. Configura el proyecto junto al audio
Copia <skill>/assets/template/ en la carpeta de trabajo para que se vea así:
voiceover.mp3
render.py
src/index.html src/engine.js src/scenes.js src/main.js
Lee src/engine.js una vez (es corto) y hojea references/engine-api.md para saber lo que ya tienes: easing, aleatoriedad con semilla, una cámara, dibujo de trayectorias parciales y motivos de estilo grabado (nubes, lluvia, relámpagos, humo, horizontes).
3. Decide la dirección artística, luego storyboard contra las palabras
Elige UN lenguaje visual y mantenlo para toda la película: una paleta pequeña (cinco o seis colores), un tratamiento para bordes y textura, una forma de dibujar personas. La plantilla incluye un aspecto de linograbado/impresión (papel hueso, tintas náuticas, bermellón, dorado, bordes temblorosos cortados a mano). Úsalo, o rediseñalo cambiando la paleta en scenes.js y los interruptores de POST, pero no mezcles estilos entre escenas. La variedad proviene de qué color domina cada escena (una escena nocturna, una escena de papel, una escena roja), no de cambiar las reglas.
Luego escribe el storyboard antes de escribir código: una tabla de tomas con horas absolutas de inicio/fin, las palabras que cubre cada toma, lo que está en pantalla y la palabra exacta en la que aterriza cada golpe. Lee references/storyboarding.md para saber cómo convertir la narración en imágenes; es la parte que decide si la película es buena.
La versión corta:
- Una idea por frase. Una oración con tres cláusulas suele ser tres tomas o tres golpes dentro de una toma.
- Muestra la cosa, no la subtitules. El texto en pantalla que repite la narración hace que el espectador lea en lugar de mirar. Por defecto, sin texto; los nombres, datos reales y una etiqueta corta y neutral en un gráfico son las excepciones. Si el usuario ha indicado preferencias de texto, esas ganan.
- Dale a la película una columna vertebral: un personaje o motivo recurrente, y un guiño al final a algo del principio.
- Cambia la escala y la cámara a propósito: plano general, primer plano, diagrama, mapa, sección transversal. Dos tomas consecutivas no deben tener la misma composición.
- Si la narración termina en un remate, añade 1-2 s de cola silenciosa después de la última palabra para que la imagen final pueda aterrizar.
render.pyrellena el audio.
4. Construye una escena de principio a fin antes de escribir el resto
Escribe la primera toma en src/scenes.js, regístrala en SHOTS y mírala:
python render.py stills 0.3,1.5,2.9 first
Luego abre work/first.png con la herramienta de lectura. Haz esto antes de codificar las otras escenas: prueba el pipeline y, más importante, te permite juzgar el estilo mientras aún es barato cambiarlo.
5. Escribe las escenas restantes, de a pocas
Reglas que mantienen el sistema funcionando (cada una existe porque romperla causa un fallo específico):
- Funciones puras del tiempo. Una toma es
function name(g, t, u)dondetson segundos absolutos yuson segundos desde que comenzó la toma. Sin variables que se acumulen entre fotogramas, sinMath.random(), sinDate. Usahash(n),noise1(x),rng(seed). Los fotogramas se renderizan fuera de orden por varios navegadores a la vez; cualquier cosa con estado se manifiesta como parpadeo o fragmentos que no coinciden. - Anima con tiempos absolutos. Escribe
E.out(seg(t, 12.62, 13.1)), usando números directamente de la lista de palabras. Cuando el montaje cambia, los golpes permanecen en sus palabras. - Todo se mueve un poco. Un fotograma sostenido se lee como un error. Dale a cada toma un desplazamiento lento de cámara (un zoom de
1 + u * .01es suficiente) y algo de movimiento secundario (lluvia, humo, un objeto que se balancea). - Aplica easing a todo.
E.outpara cosas que llegan,E.inOutpara movimientos de cámara,E.backpara apariciones,E.bouncepara aterrizajes. El movimiento lineal parece mecánico. - Dibuja el mundo más grande que el encuadre cada vez que la cámara se aleje o se sacuda; rellena fondos y suelo mucho más allá de 0..1920 para que nunca se exponga ningún borde.
- Los impactos reciben tres cosas: un
flashde 2-3 fotogramas a pantalla completa, unshakeque se desvanece, y algo que reacciona (un soplo, un retroceso, un cambio de color). - Divide el código de la escena en archivos (
s1.js,s2.js, ...) una vez que un archivo pase unos cientos de líneas, y agrégalos aindex.htmlantes descenes.js.
Escribe dos o tres tomas, renderiza una hoja de contacto de ellas, mira, corrige, continúa. No escribas toda la película a ciegas.
6. Revisa con imágenes fijas: estos son tus ojos
No puedes ver el video, así que la hoja de contacto es la revisión. Para cada toma, muestrea al menos el inicio, la mitad de la acción principal y el final, además del fotograma exacto de cada golpe:
python render.py stills 12.2,13.3,14.3,15.4,16.5 act2 # hasta ~16 marcas de tiempo por hoja
python render.py sheet 4 # toda la película, un fotograma cada 4 s
Lee el PNG y verifica, toma por toma: ¿El sujeto es lo suficientemente grande como para verlo de un vistazo? ¿Algo está recortado, superpuesto o flotando? ¿La cosa importante tiene contraste contra lo que está detrás? ¿Se ve diseñado, o la mitad del encuadre está vacía? Luego corrige y vuelve a renderizar las mismas marcas de tiempo. references/pitfalls.md enumera los errores que son fáciles de cometer y difíciles de notar.
Los errores de página son impresos por render.py como líneas PAGE ERROR:: un fotograma negro o medio dibujado generalmente significa una excepción en esa toma.
7. Renderiza y verifica
python render.py full --workers 8
Ejecútalo en segundo plano; una película de 70 s son aproximadamente 2100 fotogramas y toma unos minutos. Escribe output.mp4 (1920x1080, H.264 + AAC, audio rellenado a la longitud completa). Luego verifica el archivo en sí, no solo las imágenes fijas:
ffprobe -v error -show_entries format=duration:stream=codec_name,width,height -of default=nw=1 output.mp4
python render.py sheet 6
Confirma la duración, que hay una secuencia de audio y que la hoja de resumen no tiene fotogramas vacíos. Di claramente en tu informe que verificaste imágenes fijas y propiedades del archivo, pero que no lo has visto en movimiento; el usuario debe verlo una vez.
8. Entrega
Dale al usuario la ruta a output.mp4, la hoja de resumen y una línea sobre cómo volver a renderizar después de ediciones. src/index.html abierto en un navegador es un reproductor en vivo con el audio, que es la forma más rápida de que verifiquen la sincronización.
Sonido
Entrega solo la voz en off a menos que el usuario haya solicitado música o efectos de sonido. Si lo hizo, agrégalos como entradas adicionales de ffmpeg en la mezcla final, sincronizados desde la misma lista de golpes que usaste para los visuales.
Archivos de referencia
references/storyboarding.md: convertir narración en tomas; colocación de golpes; metáforas visuales; qué hace que una escena se sienta diseñada. Léelo antes del paso 3.references/engine-api.md: cada ayuda enengine.jscon un uso de una línea. Léelo antes del paso 5.references/pitfalls.md: modos de fallo encontrados de la manera difícil, con correcciones. Léelo antes del paso 6.references/example-bells/: una película completa de 71 segundos (16 tomas, ~900 líneas de código de escena) con su storyboard. Leestoryboard.mdpara ver el nivel de planificación esperado; abre los archivossrc/s*.jscuando quieras ver cómo se construyó un efecto específico (una cámara que sigue a un personaje trepando, una explosión, un mapa, una pluma que dibuja una línea, un ojo que se entrecierra).