Convert MP3 to OGG
Produce an Ogg Opus file for a destination that will take nothing else.
How it works
The reason to make an Ogg file is almost always a form that refuses everything else. WhatsApp's Cloud API takes audio as .aac, .amr, .mp3, .m4a or .ogg, but a voice message — the one that arrives as a waveform with a play button rather than an attachment — has to be Ogg carrying the Opus codec. The upload has to declare its type as `audio/ogg; codecs=opus`; a bare `audio/ogg` comes back as error 131053. Meta's own documentation adds that a file encoded with any other codec fails voice transcription.
Wikimedia Commons is the other place where the format is the gate rather than a preference. Commons names Opus as the preferred audio codec for the Ogg container and asks that such uploads carry a .opus or .oga extension. MP3 is accepted there only from accounts holding Autopatrol rights or above, a restriction Commons attributes to how much copyright checking its community can absorb. Below that threshold an MP3 will not upload at all. Commons separately warns against re-encoding audio that is already in a free codec, so this page is for material that arrived as MP3 and has nowhere else to go.
Telegram sits between the two. Its Bot API documents sendVoice as accepting an .OGG file encoded with OPUS, or an .MP3, or an .M4A, so Ogg is the first-named option rather than the only one, and a 50 MB ceiling applies whichever you pick.
Two destinations that will refuse it
Godot looks like a match and is not. The engine imports WAV, Ogg Vorbis and MP3; Opus inside an Ogg container is absent from that list, having been dropped from the engine years ago, and its importer will reject a file from this page. Keep the MP3, because Godot reads that.
Safari is the second. It has decoded Opus in a WebM container since version 15 on iOS 15 and macOS 12, and in Apple's CAF since 2017, but it has never decoded Opus inside Ogg on any version. Chrome, Edge and Firefox all do. An `<audio src="…ogg">` that works on a desktop test therefore goes silent on an iPhone, so a site serving these files needs a second source element.
The arithmetic that sets the bitrate
An MP3 has already discarded detail according to one psychoacoustic model, and Opus discards according to a different one. The two carve the spectrum differently. MP3's polyphase filter bank splits a 44.1 kHz signal into 32 equal subbands of 689 Hz apiece before its MDCT runs. Opus's CELT layer uses bands that follow the Bark scale and grow wide towards the top, and it preserves each band's measured energy rather than the fine structure inside it.
The consequence is that the second encoder buys artefacts at full price. Where MP3 replaced the inside of a band with quantisation noise, CELT reads energy that is genuinely present and spends bits reproducing it faithfully. The disagreement is loudest on material that is noise-like under both models: cymbals, applause and sibilance, none of which has a tonal structure either codec can describe cheaply.
The defence is headroom, and it is read off the source rather than guessed. Two files measured in this session: a nine-second sample at 44.1 kHz joint stereo held 369 MPEG-1 Layer III frames averaging 127.8 kbps across 154,062 bytes, and a six-minute track ran a constant 192 kbps over 14,268 frames. A 128 kbps source wants 160 or 192 kbps out. A 192 kbps source wants 192 at the floor, and 256 if the material is percussive.
Both were then converted at 192 kbps, and both came out larger. The nine-second file went to 228,680 bytes from 154,062, and the six-minute track to 9,034,393 bytes from 8,945,229, taking 98 ms and 3.1 seconds. Growth is the expected result of buying headroom, and a page promising a smaller file at this step would be describing a worse one.
What the tags cannot carry
The two formats describe themselves through unrelated systems. An MP3 carries ID3v2: binary frames with four-character identifiers, TIT2 for title and TPE1 for artist, sitting ahead of the first audio frame. The two files measured above held 45 and 67 bytes of it. Ogg Opus uses the OpusTags packet instead, a list of UTF-8 `FIELD=value` strings in the Vorbis comment format that RFC 7845 requires of every stream.
They overlap on the obvious fields: title, artist, album, track number, genre, date and a free comment. Both can hold cover art, by different means, since ID3v2 uses a binary APIC frame where a Vorbis comment holds a base64 METADATA_BLOCK_PICTURE string.
Outside that overlap there is no mapping to make. POPM ratings, PCNT play counts, user-defined TXXX frames and CHAP chapter markers have no counterpart, so an audiobook loses its chapter list and a library loses its stars. Converting the six-minute track above carried its ARTIST, DATE and GENRE values into the OpusTags packet and left the rest behind. Set anything else again at the destination, or keep the MP3 alongside it.
Questions
Does the file leave the tab?
No, and this page fetches less than most here to do the work. Opus encoding is part of WebCodecs, so unlike the MP3 and FLAC pages there is no WebAssembly encoder to download first. Open the Network tab, drop a file and convert: every request is a same-origin JavaScript module belonging to the page itself, all of them GETs, and none carries audio. The decode and the encode both run in a Web Worker on your own machine.
Which codec ends up inside the .ogg?
Opus, in every case, and the extension does not say so. That is why destinations disagree about what they expect: Commons asks for .opus or .oga on an Ogg Opus upload, WhatsApp wants the type spelled out as audio/ogg; codecs=opus, and Godot's importer reads Vorbis and refuses this file. Rename the download or restate its MIME type wherever the destination is specific about it.
Should I set the sample rate to 44.1 kHz to match the MP3?
No. Opus codes at 48 kHz internally whatever it is handed, and RFC 7845 stores the input rate in the header as documentation, stating plainly that it is not the rate to use for playback. The output measured here shows both halves of that: its OpusHead records an input sample rate of 44,100, and the same header carries a pre-skip of 312 samples, a figure RFC 7845 counts in 48 kHz units. Asking for 44.1 kHz buys a resample and no change to the stream. The lower rates do have an effect, because they cap the coded bandwidth: 16 kHz input holds Opus to wideband, a genuine saving on speech and audible damage on music.
Why is the Ogg no smaller than the MP3?
Because the bitrate is set at or above the source's, which is what keeps the second encode inaudible. Opus is the more efficient codec and would beat MP3 by a wide margin starting from an untouched recording, but an MP3 is not an untouched recording. If size is the goal and the format is incidental, lower the bitrate here and check the result on a passage with cymbals or applause in it, where the damage shows up first.