Every online audio converter says roughly the same thing on its homepage: fast, free, private. Almost all of them mean the same thing by it — your file is uploaded to a server, converted there, and handed back as a download link. “Private” means they promise to delete it later.
Ours works differently, and the difference is architectural rather than a policy: the file is never sent anywhere, because the converter itself runs inside your browser tab. This post is the engineering walkthrough — what actually executes, the one trick that makes multi-gigabyte files possible, and the honest trade-offs of building it this way.
The conventional design, and what it costs
A server-side converter has a fixed sequence: upload the whole file, wait in a queue, convert, download the result. The conversion is usually the fastest part. The upload is the part you actually feel.
A 600MB WAV export on a typical 20Mbps upstream connection takes about four minutes to upload before any work begins — and that number is on the optimistic side of what home connections actually deliver. Then it sits on infrastructure you do not control, subject to whatever retention window is written in a policy page.
Removing the upload removes all of it at once: the wait, the queue, the retention question, and the per-file cost that forces other converters to cap free usage. That is the whole motivation.
What actually runs: FFmpeg, compiled to WebAssembly
The engine is FFmpeg — the same project that sits underneath most desktop and server-side media tooling — compiled from C to WebAssembly with Emscripten. It ships as a roughly 7.5MB .wasm binary plus a small JavaScript loader, downloaded once and then cached by the browser.
Two details matter more than they might look:
- It runs in a Web Worker, not on the page’s main thread. Audio encoding is a long, CPU-bound loop; on the main thread it would freeze the interface completely. In a worker, the page stays responsive and progress can be reported while the encode runs.
- It is real FFmpeg, not a re-implementation. The build includes LAME for MP3, the native AAC encoder, PCM for WAV output, and the
ipodmuxer that produces proper M4A files. The command lines are ordinary FFmpeg arguments — the same ones you would type in a terminal.
The worker is started lazily, while the page sits idle waiting for you to choose a file, so the binary is usually already warm by the time it is needed.
The trick that makes gigabyte files possible
This is the part that most in-browser converters get wrong, and it is the reason many of them quietly cap you at 100MB or 500MB.
The obvious implementation is to read the selected file into memory as an ArrayBuffer and hand that array to the WebAssembly module. It works beautifully in testing — and then dies on a real 3GB lecture recording, because you have just asked the browser to hold the entire file in the WebAssembly heap, on top of whatever the encoder itself needs.
Instead, the file is mounted as a virtual filesystem inside the worker using Emscripten’s WORKERFS. FFmpeg sees an ordinary path it can open and seek around in. Underneath, every read is served by slicing the browser’s File object and reading just that slice synchronously — the bytes are pulled off disk on demand, in the order the demuxer asks for them, and are never all resident at once.
Two consequences fall out of that:
- Memory use tracks the working set, not the file size. An 8GB source is not meaningfully harder on memory than a 200MB one.
- Conversion starts immediately. There is no read-the-whole-file step before work begins — the first bytes are read the moment FFmpeg wants them.
| Approach | Time before work starts | Practical size ceiling | Where your file goes |
|---|---|---|---|
| Upload to a server | Full upload + queue | Whatever the free tier allows | Their infrastructure |
| In-browser, read whole file into memory | Seconds to minutes | Hundreds of MB | Stays local |
| In-browser + WORKERFS (what we use) | Essentially none | 8GB desktop / 2GB mobile | Stays local |
Step one: probe, then decide
Before converting anything, the worker runs FFmpeg once with just -i pointed at the mounted file. That prints the input banner — container, streams, codecs, duration — which gets parsed out of the worker’s stderr messages.
That one cheap run pays for three things:
- A real progress bar. FFmpeg reports its position as a timestamp, not a percentage. Knowing the total duration up front is what turns
time=00:04:11into a meaningful number on screen. - A useful error instead of a cryptic one. If the file has no audio stream at all, you get told that in plain language rather than watching a conversion fail deep inside the encoder.
- The copy-versus-encode decision, which is the difference between seconds and minutes.
Copy versus encode
Converting audio does not always mean re-encoding it. When the source stream is already in the codec the target container wants, the stream can simply be lifted out and rewrapped — no decoding, no encoding, no quality loss whatsoever.
| Source → target | What runs | Speed | Quality effect |
|---|---|---|---|
| MP3 → MP3 | -c:a copy | Seconds, any size | None — bit-identical stream |
| AAC (most MP4/MOV) → M4A | -c:a copy | Seconds, any size | None — bit-identical stream |
| Anything → MP3 | Decode + LAME at 192kbps | Much faster than real time | One lossy generation |
| Anything → M4A | Decode + AAC at 192kbps | Much faster than real time | One lossy generation |
| Anything → WAV | Decode + PCM 16-bit | Fast; output is large | None beyond the source’s own |
Worked example. Pulling the audio out of a 2-hour, 3GB MP4 lecture recording: the video stream is discarded with -vn, and because the audio inside an MP4 is nearly always AAC, choosing M4A output takes the copy path — a few seconds, and roughly 170MB out. Choosing MP3 instead forces a decode-and-re-encode, which takes a couple of minutes and lands in the same size range. Same file, same page, two very different amounts of work, decided automatically by what the probe found.
This is also why the honest advice about output format is not “always pick the biggest number”. If you want the details of that trade-off, we wrote them up separately in WAV vs MP3: which audio format should you use.
Getting the file back out
FFmpeg writes its output into the WebAssembly module’s in-memory filesystem. When the run finishes, the worker posts that buffer back to the page, where it becomes a Blob and then an object URL that the download button points at. No network request is involved in any of it.
One detail here cost real debugging time and is worth passing on. The buffer that comes back can be padded with trailing zero bytes. Tolerant players — VLC, Chrome — happily ignore the padding. Strict demuxers do not: macOS QuickLook and Windows Media Foundation would reject a file that played perfectly elsewhere. The fix is to walk the MP4 box headers from the start of the buffer, follow each box’s declared size to find where the last real box ends, and truncate there. Payloads that are not MP4-structured simply fall through unchanged.
“It plays in my player” is not the same as “it is a valid file”, and only one of those is good enough to ship.
The honest trade-offs
Running locally is not free of downsides, and it would be dishonest to present it as pure upside.
- You pay a one-time download of about 7.5MB for the engine, on first use.
- It uses your CPU and your battery, not a rack somewhere. On a very old phone, a long re-encode is genuinely slower than a server would be.
- Audio conversion here runs single-threaded, one file at a time — a batch is processed serially rather than in parallel.
- There is still a size ceiling, because browsers impose their own limits on how much a tab may allocate. It is 8GB on desktop and 2GB on mobile rather than 100MB, but it is not infinite.
What you get in exchange: no upload wait, no queue, no account, no watermark, no per-file pricing, and no copy of your recording sitting on someone else’s disk. For voice memos, client interviews, medical or legal recordings and unreleased music, that last point is not a nice-to-have.
Frequently asked questions
How can I verify my file really is not uploaded?
Check it yourself, which is the point of an architecture like this. Open your browser’s developer tools, switch to the Network tab, and convert a file. You will see the page’s own assets and the engine binary load, and no request carrying your audio. For a stronger test, disconnect from the network after the page has finished loading — the conversion still completes, because nothing about it needs a server.
Is WebAssembly slower than a real server?
For the encode step itself, somewhat — WebAssembly typically lands within a small factor of native code, and this build is single-threaded. But end-to-end, the comparison usually favours running locally, because the server route has to move the file across your connection twice before it can start. For a large file, the upload alone tends to exceed the entire local conversion.
Why does the same file sometimes convert in seconds and sometimes take minutes?
That is the copy-versus-encode split above. If the source stream already matches the output container — MP3 into MP3, AAC into M4A — it is rewrapped without re-encoding and finishes almost instantly. Any other combination has to decode and re-encode the audio, which is real work proportional to the recording’s length.
Which formats can it read?
Audio: MP3, M4A/AAC, WAV, FLAC, OGG, Opus and WMA. Video: MP4, MOV, MKV, AVI, WebM, WMV, TS, MPG, FLV and 3GP, with the audio track extracted. Output is MP3, M4A or WAV. Because the engine is real FFmpeg, the input list is a matter of which demuxers were compiled in rather than a hand-written parser per format.
Try it
The whole cluster runs on the pipeline described above: the audio converter if you want to choose the output format, or a fixed-output page like WAV to MP3, MP4 to MP3 or M4A to MP3 if you would rather not make one.
Free, unlimited, no signup — and the file stays on your machine, which you can confirm with the Network tab rather than taking our word for it. More tools at RedPandaCompress.

Fei is a skilled software engineer. He previously worked at Google and now at a startup. His expertise includes web media processing, cloud architecture, complex algorithms, and AI training and deployment. Beyond work, Fei enjoys diving into new knowledge and is a big fan of strategy games.
Leave a Reply