Dev log
DevLog #04: Timeline Multi-Clip, Presets AAA y un Contrato Para IAs — Cada Vez Más Cerca de un Remotion en el Navegador
Hemos convertido el reproductor de un script único en una timeline con clips reales: escenas reutilizables, mapeo determinista global→local, dividir clips gratis por ser f(t) y 10 presets rediseñados bajo un estándar AAA. Crónica técnica de lo que nos acerca a Remotion y de lo que aún falta.
Por Equipo de Ingeniería · Arquitectura WebGPU & Render Offline
- devlog
- remotion
- timeline
- motion graphics
- canvas
- webcodecs
- determinismo
- presets
- video engineering
En el DevLog #03 contamos cómo convertimos animaciones HTML/Canvas/Three.js en MP4 a 60 FPS sin servidores. Pero el reproductor tenía un techo claro: **un único script ocupaba toda la línea de tiempo**. No existía el concepto de escena, ni de clip, ni de recorte. Hoy eso ha cambiado.
Esta actualización trae tres bloques: un **modelo de escenas y clips** con mapeo determinista de tiempo, una **timeline multipista con clips de video editables** (añadir, mover, recortar, dividir, duplicar, borrar con imán) y los **10 presets rediseñados bajo un estándar AAA** con curvas de easing reales, jerarquía tipográfica, safe areas y profundidad. Además, el prompt para IAs ahora es una especificación con checklist.
¿Quieres probar la nueva timeline multi-clip?
Añade clips, recórtalos y exporta a MP4 a 60 FPS. Todo en tu navegador, sin subir nada.
De un script único a un modelo de escenas
El cambio de fondo es conceptual. Antes el estado era un string htmlCode y una duración global. Ahora hay tres piezas: la **Scene** (el activo reutilizable: su HTML, su duración nativa y sus marcadores), el **VideoClip** (una instancia de esa escena colocada en el tiempo con inicio, duración y recorte) y la **VideoTrack** (la pista que contiene clips).
interface Scene { id; name; html; sourceDurationSec; markers? }
interface VideoClip {
id; sceneId; name;
startTimeSec: number // dónde empieza en la timeline
durationSec: number // cuánto dura su ventana
trimStartSec: number // offset dentro de la escena
}
interface VideoTrack { id; name; clips: VideoClip[] }La clave: **el HTML nunca se corta**. Un clip es metadata. La escena sigue siendo una función pura del tiempo y el clip es solo una ventana sobre ella. Eso hace que editar sea instantáneo y que el export sea idéntico a lo que ves en vivo.
El mapeo que hace todo posible: de tiempo global a tiempo local
El motor resuelve, para cada instante global t, qué clip está activo y a qué tiempo local de su escena corresponde. Es una única fórmula, compartida por la reproducción en vivo y por el renderizado offline:
const clipActivo = clips.find(c =>
t >= c.startTimeSec && t < c.startTimeSec + c.durationSec
)
const tLocal = (t - clipActivo.startTimeSec) + clipActivo.trimStartSec
// Con 1 clip en 0 y sin recorte: tLocal === t (paridad exacta)Dividir un clip es gratis (y esta es la razón)
Con video real, cortar un clip implica re-codificar: costoso y con pérdida. Aquí no. Si tienes un clip que va del segundo 4 al 9 y lo divides en el 6.5, solo se parte la ventana temporal:
Clip A: start 4.0 duration 2.5 trim 0.0
Clip B: start 6.5 duration 2.5 trim 2.5
En t = 6.5 → B calcula (6.5 - 6.5) + 2.5 = 2.5
Exactamente donde terminó A. Continuidad perfecta.Esto solo funciona porque las escenas son deterministas: seekTo(t) redibuja cualquier instante sin depender de tiempo real, acumuladores ni aleatoriedad. El split es aritmética de ventanas, no edición de medios. La ventaja práctica: dividir, recortar y duplicar son instantáneos incluso en animaciones pesadas.
Qué se puede hacer hoy en la timeline
La pista V1 acepta varios clips. Con el botón + Clip añades la escena activa al final, y cada clip se puede **arrastrar** para moverlo, **recortar** por sus dos bordes (el borde izquierdo conserva el frame de contenido), **dividir** en el cabezal, **duplicar**, **eliminar** y **encajar con imán** a otros bordes, al cabezal y a los marcadores. El menú contextual del clip concentra duplicar, dividir y eliminar. El playback y el MP4 exportado respetan offsets y recortes porque comparten el mismo mapeo.
Presets AAA: qué cambió realmente
Los 10 presets se rediseñaron bajo un estándar interno: **movimiento no lineal** (easeOutExpo, easeInOutCubic, resortes con overshoot y stagger por elemento), **jerarquía tipográfica** con escala modular y tracking, **safe areas** al 90% para que nada muera en los bordes recortados por las redes, **profundidad** con sombras, glow, viñeta, grano y parallax, y **grading de color** coherente. Todo con un presupuesto de rendimiento estricto: 60 FPS, sin reservas de memoria por frame y DPR limitado a 2.
El contrato de escena se mantiene intacto: seekTo(t) determinista, getDuration() y getMarkers() opcional. En la auditoría se verificaron dos cosas incómodas pero necesarias: cero usos de Date.now() o Math.random() dentro del render, y que las técnicas anunciadas existieran de verdad en el código. Una de ellas no existía (un RGB split prometido), se detectó y se implementó de verdad: canales R/G/B desplazados con composición aditiva.
Un contrato claro para IAs: la spec 2.0
La pieza que más pedían los creadores: que ChatGPT o Claude generen animaciones que funcionen a la primera. El prompt del sistema ahora es una especificación completa con contrato de escena (incluyendo que una escena se monta como clip con recorte, así que no debe asumir que empieza en el segundo 0 del proyecto), estándar visual AAA, reglas de rendimiento, prohibiciones explícitas y un **checklist de 10 puntos** que el modelo debe repasar antes de entregar.
[ ] Contrato completo: seekTo + getDuration + getMarkers
[ ] Determinismo: sin Date.now() ni acumuladores
[ ] Easings reales (expo/cubic/spring), no lerp lineal
[ ] Stagger y jerarquía tipográfica
[ ] Safe areas 90% / 80%
[ ] Profundidad: sombra, glow, viñeta, grano…
[ ] 60 FPS sin allocations por frame + DPR cap 2En qué nos acercamos a Remotion y qué falta
Remotion demostró que programar video con composiciones, secuencias y funciones puras del tiempo es un modelo superior. Nuestro enfoque comparte esa columna vertebral: **composiciones (escenas), clips con recorte, render determinista f(t) y un mismo render para preview y export**. La diferencia es que aquí no hay Node, ni React, ni build: cada escena es un HTML autocontenido que corre en el navegador.
Lo que aún falta para igualar el modelo completo: **escenas distintas por clip** (pool de iframes), **transiciones** entre clips (crossfade, wipes), **pistas de video múltiples** con reglas de composición, y **composiciones reutilizables** con parámetros. Nada de eso exige servidores: es timón y motor, y va en la hoja de ruta.
Exportar a disco: el fin del límite de memoria
El segundo cambio grande está en la exportación. Antes, el MP4 se construía completo en memoria antes de ofrecerte la descarga: un video largo a alta resolución podía agotar la RAM del navegador. Ahora, al exportar en Chrome o Edge, el sistema te pide **dónde guardar** y escribe el archivo directamente en esa carpeta mientras codifica, usando la File System Access API junto al target de streaming de mp4-muxer. El MP4 ya no tiene que caber en memoria.
Timeline más AAA: razor, atajos y marcadores interactivos
La edición ahora se siente como un NLE: un botón de tijera (o las teclas **S** / **Ctrl+K**) divide el clip que está bajo el cabezal, con un aviso claro si el cabezal está fuera de cualquier clip en vez de fallar en silencio. **Delete** borra con prioridad marcador → clip de video → audio, **Ctrl+D** duplica el clip seleccionado y **Escape** limpia la selección. Los **marcadores** ya no son decorativos: se arrastran sobre la regla, se renombran con doble clic, se recolorean y se eliminan desde el menú contextual, distinguiendo los marcadores que vienen de la escena (rombo hueco) de los que creas tú (pin relleno).
La timeline multi-clip y los 10 presets AAA ya están en vivo
Pega código de IA, divídelo en clips, añade audio y exporta MP4 a 60 FPS sin subir un solo byte.
Prueba el editor tal como está hoy
Todo lo que lees en el dev log ya corre en la beta pública.