Skip to content

Rendering in the browser

@ilovevideoeditor/renderer-browser encodes frames with WebCodecs and muxes into MP4 inside a Web Worker. It runs in any recent Chrome, Edge, Firefox, or Safari and returns a Blob you can download, upload, or play back.

Minimal example

javascript
import BrowserRenderer from '@ilovevideoeditor/renderer-browser';
import iLoveVideoEditor from '@ilovevideoeditor/core';

const $ = new iLoveVideoEditor({ width: 1920, height: 1080, fps: 30 });
$.addText({ text: 'Exported from the browser' }).fadeIn('500ms');
$.wait('2s');

const json = await $.compile();
const blob = await BrowserRenderer.render(json);

// Download
const url = URL.createObjectURL(blob);
Object.assign(document.createElement('a'), { href: url, download: 'out.mp4' }).click();

Options

OptionDefaultNotes
signalAbortSignal — abort() cancels cleanly.
onProgress(p: number) => void. p is the fraction of frames done (0..1).
workertrueSet false to run on the main thread (debugging only).
verbosefalseLog frame-level timing to the console.
bitrateautoBits per second. Auto scales with resolution.
codec'avc'`avc

Progress UI

javascript
const ctrl = new AbortController();

const blob = await BrowserRenderer.render(json, {
  signal: ctrl.signal,
  onProgress: (p) => {
    // p is 0..1 (fraction of frames done)
    progressBar.style.width = (p * 100).toFixed(1) + '%';
  },
});

// Cancel from a UI button:
cancelBtn.addEventListener('click', () => ctrl.abort());

WARNING

Memory. A 1080p60 30-second render at AVC ~8 Mbps fits comfortably. For longer clips or 4K, keep an eye on the Worker's memory — prefer chunked muxing (the renderer does this by default) over holding all encoded frames in RAM.

One-shot helper

If you're already in a iLoveVideoEditor instance and don't need to hold the JSON, call $.renderVideo() — it compiles and picks a renderer for you.

javascript
const blob = await $.renderVideo({ onProgress: (p) => console.log(`${Math.round(p * 100)}%`) });

Released under the MIT License.