Documentation

Everything about this project - what I built and what I learned.

What I built

A video compressor that works entirely in the browser. No server uploads, no waiting for cloud processing - everything happens right here on your machine using FFmpeg compiled to WebAssembly. The whole point was to make something that respects privacy and works offline once loaded.

How it works

When you drop a video, FFmpeg.wasm loads up and analyzes it - gets the duration, resolution, current bitrate, all that stuff. Then based on your target size, it calculates the best bitrate and re-encodes the video.

The cool part? It supports multithreading so it uses multiple CPU cores if your browser allows it. Chrome and Edge handle this well with SharedArrayBuffer. Firefox works too but might need some flags enabled.

What I learned

  • Web Workers and SharedArrayBuffer - getting multithreading to work was tricky. You need specific headers (COOP/COEP) and not all hosting platforms support them by default.
  • Bitrate calculations aren't simple - it's not just target_size / duration. You gotta account for audio bitrate, container overhead, and leave some headroom or you'll overshoot the target.
  • Next.js 14 with App Router - pretty nice once you get the hang of it. Server components vs client components took some getting used to but makes sense now.
  • Tailwind v4 - the new @import syntax is cleaner than the old @tailwind directives. Also @layer works great for organizing custom styles.

Tech stack

Next.js
TypeScript
Tailwind CSS
FFmpeg.wasm

Features

  • 100% client-side processing - your videos never leave your device
  • Multiple quality presets - from extreme compression to balanced
  • Custom target size - set exactly how big you want the output
  • Resolution scaling - downscale to reduce size even more
  • Quality enhancement option - uses CRF mode for better visual quality