¿Qué hace framevelo?
FrameVelo convierte una página que dibuja sus fotogramas desde código en un MP4. Los fotogramas permanecen en la GPU (drawElementImage o el canvas de la página) y van directamente al codificador por hardware, por lo que un renderizado consume una fracción de la CPU y memoria de los renderizadores basados en captura de pantalla. Los proyectos HyperFrames son compilados por el pipeline oficial de HyperFrames; FrameVelo solo reemplaza la captura y la codificación.
Cómo llamarlo
Usa las herramientas MCP de este plugin cuando estén disponibles. En su primer inicio, el plugin instala FrameVelo en ~/.cache/framevelo (aproximadamente un minuto); si las herramientas faltan justo después de instalar el plugin, espera y reconecta (/mcp), o usa la CLI a continuación.
render: renderiza; devuelve la ruta de salida, el conteo de fotogramas, el tamaño, tiempos, advertencias y las últimas líneas de registro.doctor: verifica Node, FFmpeg, Chrome,drawElementImage, los codificadores por hardware y el soporte de HyperFrames.install_browser: descarga chrome-headless-shell (aproximadamente 100 MB) cuando no hay Chrome 151+ instalado.
Sin las herramientas, ejecuta la CLI. --json imprime el resultado (o {"error": ...}) en stdout:
npx -y -p github:gnipbao/framevelo -p @hyperframes/[email protected] -p @hyperframes/[email protected] framevelo render /abs/project -o /abs/out.mp4 --json -q
La primera ejecución de npx instala durante aproximadamente medio minuto. Si vas a renderizar con frecuencia, sugiere al usuario que lo instale una vez: npm install -g github:gnipbao/framevelo @hyperframes/[email protected] @hyperframes/[email protected]. La CLI acepta las mismas opciones que la herramienta, como banderas (--frames 30 --quality draft). framevelo render --help las lista.
Usa rutas absolutas. Ejecuta un renderizado a la vez: comparten el único codificador por hardware, y el servidor MCP los encola de todos modos.
Flujo de trabajo
- Encuentra la entrada: un directorio de proyecto con
index.html, o un archivo.html. La duración, fps y tamaño provienen de la página (HyperFramesdata-duration/data-fps/data-width,window.__framevelo.duration, la longitud de la línea de tiempo GSAP,window.__comp). Pásalos solo para sobrescribir. - Previsualiza una porción cuando la composición es nueva o acaba de cambiar:
{ input, output: "/tmp/preview.mp4", start: 2, frames: 30, quality: "draft" }. Esto toma segundos. Mira un fotograma:ffmpeg -v error -ss 0.5 -i /tmp/preview.mp4 -frames:v 1 /tmp/preview.png, luego visualiza el PNG. - Renderiza completo con valores predeterminados. Añade
scale: 2para 4K desde un diseño de 1080p, osubframes: 3para desenfoque de movimiento. - Verifica el resultado:
frameses el conteo que esperabas;audioes verdadero cuando la composición tiene sonido; leewarnings.screenshotFrames > 0significa que algunos intervalos fallaron la verificación y se capturaron mediante captura de pantalla (aún correctos, solo más lentos). - Informa la ruta de salida, duración, tamaño y cuánto tiempo tomó (
wallMs).
Cómo hacer una página renderizable
Cada fotograma debe ser una función pura del tiempo. FrameVelo busca en la página a través del primero de estos que encuentre:
window.__framevelo = { seek(t), duration, fps }.seekpuede devolver una promesa.window.__seek(t), con unwindow.__durationopcional.- Una línea de tiempo GSAP pausada en
window.__timelines.main(o la primera clave).
<canvas id="scene" width="1920" height="1080"></canvas>
<script>
const g = document.getElementById("scene").getContext("2d");
function draw(t) {
g.fillStyle = "#05060a";
g.fillRect(0, 0, 1920, 1080);
g.fillStyle = "#6cf";
g.fillRect(200 + 300 * t, 500, 120, 120);
}
window.__framevelo = { duration: 4, seek: draw };
</script>
- Coloca material de archivo en la línea de tiempo con
<video data-start="1.5" src="clip.mp4">(opcionaldata-media-start,data-duration,data-playback-rate). FrameVelo lo busca hasta el fotograma exacto; las fuentes de GOP largo obtienen un proxy todo-intra en caché. Math.randomestá seedeado, por lo que los renders se repiten.- Los bucles
requestAnimationFrame, las transiciones CSS,Date.now()yperformance.now()no se pueden buscar. Muévelos aseek(t)o a una línea de tiempo GSAP pausada. - Espera los assets dentro de la página (fuentes, imágenes) antes de exponer el controlador, o devuelve una promesa desde
seek.
Opciones que vale la pena conocer
| Necesidad | Argumentos |
|---|---|
| Verificación rápida | frames: 30, quality: "draft", start: <s> |
| 4K desde un diseño de 1080p | scale: 2 |
| Página vertical sin tamaño declarado | viewport: "1080x1920" |
| Archivos más pequeños | codec: "hevc" |
| Desenfoque de movimiento | subframes: 3 (y shutter, predeterminado 0.5) |
| Reemplazar la banda sonora | audio: "/abs/music.m4a" |
| Capturar un elemento | selector: "#stage" |
| DOM transparente sobre un color | background: "#000" |
| Habilidad de code-video no encontrada | mounts: {"/@skill/": "/abs/path/to/code-video"} |
| Proyecto HyperFrames como página plana | hyperframes: false |
Cuando falla
| Mensaje | Haz esto |
|---|---|
Chrome not found | Llama a install_browser (o ejecuta framevelo browser install), luego renderiza de nuevo. |
FFmpeg / FFprobe fallando en doctor | Pide al usuario que instale FFmpeg (brew install ffmpeg). No instales software del sistema tú mismo. |
The page exposes no way to seek time | La página necesita un controlador de tiempo; consulta "Cómo hacer una página renderizable". |
Unknown duration | Pasa duration o frames, o declara la duración en la página. |
The composition failed to set up | Un error de script en la composición. Arregla la página; el mensaje lleva el error de la página. |
No element matches selector / Nothing to capture / has no size | Apunta selector a un elemento visible con un tamaño, o arregla el diseño. |
Rendering a HyperFrames project needs ... @hyperframes/producer | Usa el comando npx -p @hyperframes/... de arriba, o instala los paquetes junto a FrameVelo. |
No paint event within ... | La página dejó de pintar; generalmente un script colgado. Revísalo en un navegador. |
Los renderizados son atómicos: un renderizado fallido o cancelado no deja ningún archivo de salida.