DEV Community

Javid Jamae
Javid Jamae

Posted on • Originally published at ffmpeg-micro.com

ffmpeg.wasm vs a Hosted FFmpeg API: Where Browser-Side Breaks

Originally published at ffmpeg-micro.com

ffmpeg.wasm looks like magic the first time you see it. Run FFmpeg right in the browser. No server, no install, no infrastructure. Your user picks a file, you process it client-side, and nobody's video ever leaves their machine.

Then someone uploads a 200MB file and the tab crashes.

What ffmpeg.wasm actually is

ffmpeg.wasm is a WebAssembly port of FFmpeg that runs entirely in the browser. Your JavaScript can do this:

import { FFmpeg } from '@ffmpeg/ffmpeg';

const ffmpeg = new FFmpeg();
await ffmpeg.load();
await ffmpeg.writeFile('input.mp4', videoData);
await ffmpeg.exec(['-i', 'input.mp4', '-vf', 'scale=640:360', 'output.mp4']);
const data = await ffmpeg.readFile('output.mp4');
Enter fullscreen mode Exit fullscreen mode

No server call. No API key. The entire operation happens in the user's browser tab.

Where ffmpeg.wasm works well

For small, quick operations on small files:

  • Thumbnail extraction from short clips (under 50MB)
  • Format detection and metadata inspection
  • Quick trims of short videos
  • Privacy-sensitive workflows where video can't leave the device

The five walls you'll hit

1. Memory ceiling

A 500MB video needs at least 500MB of RAM just for the input. The practical limit is roughly 100-200MB per file on desktop, less on mobile.

2. Single-threaded performance

A transcode that takes 30 seconds on a server can take 5-10 minutes in the browser. Multi-threaded builds require SharedArrayBuffer and specific CORS headers that break third-party embeds.

3. Codec limitations

The Wasm build doesn't include every codec. Licensing and binary size constraints mean you get a subset.

4. Mobile is unreliable

Mobile browsers have tighter memory limits and more aggressive tab killing. A transcode that works on your MacBook will crash Safari on an iPhone 12.

5. No batch processing

Processing 50 files means the user keeps the tab open. Any browser crash kills the entire batch.

Comparison table

Factor ffmpeg.wasm Hosted FFmpeg API
Max file size ~100-200MB No practical limit
Processing speed 5-10x slower Server-grade
Mobile support Unreliable Works everywhere
Batch processing Manual, fragile Built-in queuing
Privacy Video stays on device Video uploaded to server
Cost Free (client CPU) Pay per minute processed

The hybrid approach

Use ffmpeg.wasm for lightweight client-side ops and route heavier work to an API:

const FILE_SIZE_THRESHOLD = 50 * 1024 * 1024; // 50MB

async function processVideo(file) {
  if (file.size < FILE_SIZE_THRESHOLD) {
    return processClientSide(file); // ffmpeg.wasm
  }
  return processServerSide(file);   // FFmpeg Micro API
}
Enter fullscreen mode Exit fullscreen mode

Read the full post with detailed analysis on ffmpeg-micro.com.

Top comments (0)