Show HN: Tools.video – Browser-native video processing at 50 GB scale
2 points
1 hour ago
| 0 comments
| HN
Hi HN, I built tools.video (https://tools.video) — 18 free video and audio tools that run entirely in your browser. Files never leave your machine.

Compress, convert, trim, crop, resize, merge, rotate, reverse, speed change, screenshot, mute, video-to-GIF, audio extract/trim/convert/merge/speed, and media info.

The interesting technical problem: FFmpeg compiled to WASM works, but it tops out around 4 GB, runs single-threaded, and is 10x slower than native browser APIs for the same operations. I wanted to handle 50 GB files and actually use the hardware (theoretically there's no limit at all).

So I built a hybrid engine:

- Most tools use WebCodecs (via MediaBunny) — the browser's native hardware-accelerated video encoder/decoder. H.264, HEVC, VP9, AV1 with GPU acceleration when available. This is what makes it fast. - Three tools (speed, merge, video-to-GIF) still use FFmpeg WASM where WebCodecs can't do the job. - The engine auto-detects which path to use and falls back gracefully — if hardware encoding fails, it retries in software; if WebCodecs can't handle a codec, it routes to FFmpeg.

How 50 GB works in a browser:

Files are streamed through OPFS (Origin Private File System) with chunked I/O. Small files (<256 MB) stay in memory. Larger files write to OPFS-backed storage. The biggest files use StreamTarget for chunked streaming so you never buffer the entire output in RAM. Stale temp files auto-clean after 6 hours, and quota-exceeded errors trigger aggressive cleanup mid-operation.

Other details HN might find interesting:

- Processing runs in a Web Worker with stall detection (180s timeout). If the worker crashes, it falls back to main thread automatically. - Audio extraction with stream copy (no re-encoding) skips disk I/O entirely — zero-copy transmux via BufferTarget. - Codec extensions (MP3, FLAC, AAC, AC3 encoders as WASM) are loaded on demand but can't run in the Worker — esbuild corrupts their inline WASM binaries during double-bundling, so they route to main thread. - 30+ formats, 5.1/7.1 surround audio preserved, 19 languages.

There's a /benchmark page if you want to compare the WebCodecs path vs FFmpeg WASM directly with audio extraction.

Built with Next.js 15, React 19, TypeScript, Tailwind v4, Zustand.

Would love feedback — especially on formats/codecs you'd want supported, or edge cases where processing fails.

No one has commented on this post.