Compress audio to MP3 on the web: a guide for developers
If you build web apps that accept audio uploads, sooner or later you'll need a flow to convert and compress to MP3 with a good balance of size and quality. In this guide you'll see when to use FFmpeg on the server, when to go with ffmpeg.wasm in the browser, and which presets and bitrates work best for voice and music—especially for audio coming from WhatsApp or Telegram.
🎯 Just want to do it right now?
Free • Online • Works on mobile and desktop
Architectures: client vs server
There are two main approaches to convert/compress audio in a web app. Choosing one or the other depends on file sizes, budget, and the compatibility you need.
Server with FFmpeg
- Robust, fast, and low client-side usage.
- Scales with queues (RabbitMQ, SQS) and workers.
- Full control over codecs, filters, and normalization.
Ideal for heavy loads, existing backends, or controlled workflows.
Browser with ffmpeg.wasm
- Privacy: the file never leaves the device.
- Less infrastructure and no queues.
- More CPU/RAM usage on the client; run inside Web Workers.
Useful for voice notes or light tasks; avoid long processing on older phones.
Recommended quality presets
- Voice (notes, interviews): 64–128 kbps, mono optional. Good balance of clarity and size.
- Light music or voice with background: 128–160 kbps CBR or high VBR.
- Full music: 192 kbps or higher if the audience expects it.
- Ultra-light files: 64 kbps for voice when size is critical.
Code examples
FFmpeg CLI (server)
# Clear voice (mono) at 96 kbps
ffmpeg -i input.m4a -ac 1 -c:a libmp3lame -b:a 96k output.mp3
# Music at 192 kbps CBR
ffmpeg -i input.wav -c:a libmp3lame -b:a 192k output.mp3
# High-quality VBR (~170–210 kbps)
ffmpeg -i input.wav -c:a libmp3lame -q:a 2 output.mp3
Node.js (fluent-ffmpeg)
import ffmpeg from "fluent-ffmpeg";
function toMp3Voice(inputPath, outPath) {
return new Promise((res, rej) => {
ffmpeg(inputPath)
.audioChannels(1)
.audioCodec("libmp3lame")
.audioBitrate("96k")
.on("end", res)
.on("error", rej)
.save(outPath);
});
}
Python (pydub + FFmpeg)
from pydub import AudioSegment
audio = AudioSegment.from_file("input.opus")
audio.set_frame_rate(44100).set_channels(1).export("out.mp3", format="mp3", bitrate="96k")
In the browser with ffmpeg.wasm
import { createFFmpeg, fetchFile } from "@ffmpeg/ffmpeg";
const ffmpeg = createFFmpeg({ log: false });
async function convertClientSide(file) {
if (!ffmpeg.isLoaded()) await ffmpeg.load();
ffmpeg.FS("writeFile", "in.m4a", await fetchFile(file));
await ffmpeg.run("-i", "in.m4a", "-ac", "1", "-c:a", "libmp3lame", "-b:a", "96k", "out.mp3");
const data = ffmpeg.FS("readFile", "out.mp3");
return new Blob([data.buffer], { type: "audio/mpeg" });
}
Tip: run ffmpeg.wasm inside a Web Worker to avoid blocking the UI and show progress using
ffmpeg.setProgress
.
UX for mobile audio (WhatsApp/Telegram)
- “Drag & drop” button + file picker:
accept="audio/*,.opus,.m4a,.aac,.ogg,.amr"
. - Detect common sources: if
.opus
or.ogg
, suggest the OPUS → MP3 guide. - Alternate CTA for “reduce the size of an MP3” (popular query in Analytics).
- Explain bitrates in plain language and save the last choice in localStorage.
Performance, cost, and security
Performance
- Normalize to 44.1 kHz when the source allows it to avoid reprocessing.
- Process via queue and respond with a webhook for large files.
- Cache repeated results by hash (MD5/SHA-256).
Security & privacy
- Validate MIME and extension; limit duration/size.
- Delete temporary files after conversion.
- Offer local processing with ffmpeg.wasm when privacy is key.
🔁 Ready-to-use tools
Frequently asked questions
CBR or VBR for the web?
For voice, CBR 64–128 kbps is predictable and stable; for music, high VBR (-q:a 2
) preserves quality with modest sizes.
What about WhatsApp OPUS/OGG?
Convert to a universal format for car/TV compatibility. Follow this OPUS → MP3 guide.
Can I recompress an MP3 to make it smaller?
Yes, but avoid multiple passes. Do a single conversion to your target (for example, compress an existing MP3).
Online • Free • Works on mobile and desktop