Communitygithub.com

gnipbao/framevelo

Render code-driven videos to MP4 fast with FrameVelo, on the GPU and the hardware encoder - HyperFrames projects, code-video compositions (defineComposition), and any HTML/CSS/GSAP or Canvas/WebGL page that is a pure function of time. Use when the user wants such a page or project rendered, exported or previewed as a video (rendering video, exporting MP4, producing a video clip, previewing), wants a render to be faster or lighter on CPU and memory (accelerating rendering), or wants an HTML animation made renderable frame by frame. Not for editing existing video files or generating video with AI models.

What is framevelo?

FrameVelo is a high-performance GPU-accelerated tool for converting code-driven HTML pages or HyperFrames projects directly into MP4 videos. It leverages `drawElementImage` and the hardware encoder to keep frames on the GPU, drastically reducing CPU and memory usage compared to traditional screenshot-based renderers. It supports any page that is a pure function of time, including those using GSAP timelines, Canvas/WebGL, or custom time-based APIs (`window.__framevelo`). Available as an MCP plugin (tools: `render`, `doctor`, `install_browser`) or as a CLI command, FrameVelo can quickly preview slices, render full compositions at high resolution (e.g., 4K), and apply motion blur, custom audio, and selective element capture. It is especially useful for developers working on HyperFrames projects or code-video compositions who need fast, efficient, and repeatable video export without heavy memory overhead.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/gnipbao/framevelo/tree/HEAD/plugin/skills/framevelo

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Preview

From the skill README

Documentation

What does framevelo do?

FrameVelo turns a page that draws its frames from code into an MP4. Frames stay on the GPU (drawElementImage or the page's canvas) and go straight to the hardware encoder, so a render takes a fraction of the CPU and memory of screenshot-based renderers. HyperFrames projects are compiled by the official HyperFrames pipeline; FrameVelo replaces only capture and encoding.

Calling it

Use the MCP tools of this plugin when they are available. On its very first start the plugin installs FrameVelo into ~/.cache/framevelo (about a minute); if the tools are missing right after installing the plugin, wait and reconnect (/mcp), or use the CLI below.

  • render: renders; returns the output path, frame count, size, timings, warnings and the last log lines.
  • doctor: checks Node, FFmpeg, Chrome, drawElementImage, the hardware encoders and HyperFrames support.
  • install_browser: downloads chrome-headless-shell (about 100 MB) when no Chrome 151+ is installed.

Without the tools, run the CLI. --json prints the result (or {"error": ...}) on 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

The first npx run installs for about half a minute. If you will render often, suggest that the user install it once: npm install -g github:gnipbao/framevelo @hyperframes/[email protected] @hyperframes/[email protected]. The CLI takes the same options as the tool, as flags (--frames 30 --quality draft). framevelo render --help lists them.

Use absolute paths. Run one render at a time: they share the single hardware encoder, and the MCP server queues them anyway.

Workflow

  1. Find the input: a project directory with index.html, or an .html file. Duration, fps and size come from the page (HyperFrames data-duration/data-fps/data-width, window.__framevelo.duration, the GSAP timeline length, window.__comp). Pass them only to override.
  2. Preview a slice when the composition is new or just changed: { input, output: "/tmp/preview.mp4", start: 2, frames: 30, quality: "draft" }. This takes seconds. Look at a frame: ffmpeg -v error -ss 0.5 -i /tmp/preview.mp4 -frames:v 1 /tmp/preview.png, then view the PNG.
  3. Render in full with defaults. Add scale: 2 for 4K from a 1080p layout, or subframes: 3 for motion blur.
  4. Check the result: frames is the count you expected; audio is true when the composition has sound; read warnings. screenshotFrames > 0 means some intervals failed verification and were captured by screenshot (still correct, just slower).
  5. Report the output path, length, size and how long it took (wallMs).

Making a page renderable

Every frame must be a pure function of time. FrameVelo seeks the page through the first of these it finds:

  1. window.__framevelo = { seek(t), duration, fps }. seek may return a promise.
  2. window.__seek(t), with an optional window.__duration.
  3. A paused GSAP timeline on window.__timelines.main (or the first key).
<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>
  • Put footage on the timeline with <video data-start="1.5" src="clip.mp4"> (optional data-media-start, data-duration, data-playback-rate). FrameVelo seeks it to the exact frame; long-GOP sources get a cached all-intra proxy.
  • Math.random is seeded, so renders repeat.
  • requestAnimationFrame loops, CSS transitions, Date.now() and performance.now() animations cannot be seeked. Move them onto seek(t) or a paused GSAP timeline.
  • Wait for assets inside the page (fonts, images) before exposing the driver, or return a promise from seek.

Options worth knowing

NeedArguments
Quick checkframes: 30, quality: "draft", start: <s>
4K from a 1080p layoutscale: 2
Vertical page without declared sizeviewport: "1080x1920"
Smaller filescodec: "hevc"
Motion blursubframes: 3 (and shutter, default 0.5)
Replace the soundtrackaudio: "/abs/music.m4a"
Capture one elementselector: "#stage"
Transparent DOM over a colorbackground: "#000"
code-video skill not foundmounts: {"/@skill/": "/abs/path/to/code-video"}
HyperFrames project as a plain pagehyperframes: false

When it fails

MessageDo this
Chrome not foundCall install_browser (or run framevelo browser install), then render again.
FFmpeg / FFprobe failing in doctorAsk the user to install FFmpeg (brew install ffmpeg). Don't install system software yourself.
The page exposes no way to seek timeThe page needs a time driver; see "Making a page renderable".
Unknown durationPass duration or frames, or declare the duration in the page.
The composition failed to set upA script error in the composition. Fix the page; the message carries the page error.
No element matches selector / Nothing to capture / has no sizePoint selector at a visible element with a size, or fix the layout.
Rendering a HyperFrames project needs ... @hyperframes/producerUse the npx -p @hyperframes/... command above, or install the packages next to FrameVelo.
No paint event within ...The page stopped painting; usually a hung script. Check it in a browser.

Renders are atomic: a failed or cancelled render leaves no output file.

Related Skills