Online video compressors are usually frustrating: you have to upload a 100MB personal video to a remote cloud server, wait in an artificial processing queue, deal with intrusive popup ads, and download a watermarked video.
I wanted to see if modern browser technology was fast enough to run desktop-grade video compression entirely on the user's computer with zero server uploads.
Here is the technical breakdown of how I built clipshrink.com using Next.js 16, React 19, and FFmpeg compiled to WebAssembly (WASM).
- The Architecture: In-Browser Sandboxing
Traditional cloud tools rely on multi-core backend server clusters. ClipShrink takes the opposite approach: **0 bytes ever leave the user's device.
[User Selects Video (.mp4, .mov, .webm)]
│
▼
[Local Browser RAM Sandbox] ◄─── (0 bytes sent to external cloud servers)
│
▼
[Dynamic Target Bitrate Math] ◄─── Bitrate = (Target MB × 8192) / Duration
│
▼
[FFmpeg WebAssembly Pipeline] ◄─── Local CPU software re-encoding
│
▼
[Instant Local MP4 Download] ◄─── Encoded with '+faststart' web streaming
- The Tech Stack
Framework: Next.js 16 (App Router)
Interactive Core: @ffmpeg/ffmpeg and @ffmpeg/util
Styling: Tailwind CSS v4
Hosting:** Vercel (Edge network)
- Engineering Challenges & Solutions
A. Eliminating Third-Party CDN Latency
Originally, the app loaded @ffmpeg/core from public CDNs (unpkg.com). This created a single point of failure: privacy extensions and ad-blockers regularly blocked external CDN requests.
The Solution: Self-hosting the .wasm and .js binaries in the /public/ffmpeg/ directory with immutable edge caching:
typescript
await ffmpeg.load({
coreURL: await toBlobURL("/ffmpeg/ffmpeg-core.js", "text/javascript"),
wasmURL: await toBlobURL("/ffmpeg/ffmpeg-core.wasm", "application/wasm"),
});
B. Mobile Safari Memory Guard
iOS Safari enforces a strict WebAssembly heap allocation limit (typically 1GB–1.5GB). Attempting to process a 4K 60fps file directly in browser memory causes the tab to crash.
To protect the user experience, we implemented client-side file size guards before allocating memory:
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
if (isMobile && file.size > 150 * 1024 * 1024) {
setError("Files over 150MB may exceed mobile browser memory. Please use a desktop browser.");
return;
}
C. Fast Bilinear Downscaling
4K video has 8.3 million pixels per frame. Using FFmpeg's default bicubic scaler inside single-threaded WebAssembly resulted in long encoding times.
By introducing -sws_flags fast_bilinear and -preset ultrafast, we cut downscaling CPU cycles by 60% to 70% while maintaining crisp 720p HD output for platform limits like:
Discord 8MB Limit
WhatsApp 16MB Limit
Gmail / Outlook 25MB Attachments
Top comments (1)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.