Browser Audio Format Support
Supplemental reference for Listen Here (browser-side playback).
It covers exactly the audio extensions GET /stream serves.
This table is documentation, not configuration
The product never reads it. The play page asks each browser live via
canPlayType and only a definite “no” blocks a track — so when a browser
gains a codec, Listen Here picks it up with zero code change. This page exists so humans can
reason about what listeners will experience.
The table
As of July 2026, current browser versions. ✅ plays · ⚠ see note · ❌ does not play
| Extension | Codec / container | Chrome / Edge | Firefox | Safari macOS | Safari iOS |
|---|---|---|---|---|---|
| .mp3 | MPEG-1 Layer 3 | ✅ | ✅ | ✅ | ✅ |
| .aac | AAC (ADTS) | ✅ | ✅ | ✅ | ✅ |
| .m4a | AAC in MP4 | ✅ | ✅ | ✅ | ✅ |
| .m4a | ALAC in MP4 | ❌ | ❌ | ✅ | ✅ |
| .flac | FLAC | ✅ 56+ | ✅ 51+ | ✅ 13+ | ✅ iOS 11+ |
| .ogg / .oga | Vorbis in Ogg | ✅ | ✅ | ✅ 18.4+ ⚠ | ✅ 18.4+ ⚠ |
| .opus | Opus in Ogg | ✅ 33+ | ✅ 15+ | ⚠ 18.4+ | ⚠ 18.4+ |
| .wav | PCM | ✅ | ✅ | ✅ | ✅ |
| .aiff / .aif | PCM (AIFF) | ❌ | ❌ | ✅ | ✅ |
| .wma | Windows Media | ❌ | ❌ | ❌ | ❌ |
| .ape | Monkey’s Audio ⚠ | ❌ | ❌ | ❌ | ❌ |
| .mpc | Musepack ⚠ | ❌ | ❌ | ❌ | ❌ |
| .wv | WavPack ⚠ | ❌ | ❌ | ❌ | ❌ |
| .dsf / .dff | DSD ⚠ | ❌ | ❌ | ❌ | ❌ |
Notes
- FLAC — broadly supported since ~2017: Chrome 56+, Edge 16+, Firefox 51+, Safari 11+ on iOS, but only Safari 13+ (Catalina) on macOS. Source: caniuse.com/flac.
- Ogg Vorbis — native in Safari only from 18.4 (macOS Sequoia 15.4 / iOS 18.4, March 2025). Safari 14.1–18.3 was partial: playback depended on the system’s AudioToolbox components, so it worked on some Macs and not others. Source: caniuse.com/ogg-vorbis.
- Opus — Safari 18.4 release notes claim Opus-in-Ogg support (previously Opus played only inside CAF or WebM containers on Apple platforms); at least one field report says it still fails in practice. Treat Safari Opus as unknown-leaning-yes on 18.4+ — exactly the case the live probe decides better than any table. Opus-in-MP4 remains unplayable on Safari. Source: caniuse.com/opus.
- ALAC in .m4a — Apple-ecosystem only; Chromium and Firefox decode the MP4
container’s AAC branch but not ALAC. This is also the classic container-vs-codec trap:
canPlayType('audio/mp4')answers “maybe” for both, so the probe cannot settle it. What settles it is MusicBee’s Kind, which names the codec rather than the container: see conversion below. With conversion off, an ALAC track is attempted and the failure is shown on the output chip rather than guessed at. - AIFF — Safari plays PCM AIFF; Chromium and Firefox do not.
- WMA — no browser plays WMA. With format conversion turned on it no longer matters: the file is converted on the way out and plays anywhere that plays FLAC. With conversion off (the default) the older behavior stands — WMA tracks never enter the device queue and playback steps past them, noted on the output chip.
- APE, Musepack, WavPack, DSD — archival and audiophile formats that no browser has ever shipped a decoder for, and that conversion does not currently cover either. They also fail later than the rest of this table: the play page recognizes the ten-odd extensions above and refuses those upfront, but it has no entry for these, so a track is queued, attempted, and reported on the output chip when the browser gives up. Listen Here is not the way to hear them; MusicBee itself plays them all.
What the play page actually probes
Per extension, Listen Here probes candidate MIME strings and blocks only when
every candidate returns '' (a definite no):
| Extension | Candidates probed |
|---|---|
| .opus | audio/ogg; codecs="opus", audio/opus |
| .flac | audio/flac, audio/ogg; codecs="flac" |
| .m4a | audio/mp4, audio/mp4; codecs="mp4a.40.2" |
| others | the single MIME type /stream sends as Content-Type |
The .opus double-probe exists because audio/opus is the
RTP payload type, not the file type — Chromium answers it '' while playing the file
fine; audio/ogg; codecs="opus" is the honest question.
When the browser says no: conversion
The probe only answers “can this browser decode the original”. What happens next depends on whether the hub can convert:
- The hub says whether it can.
GET /system/featurescarriestranscode, true only when format conversion is turned on and ffmpeg actually resolves. The page reads it once per load; if the read fails it is treated as false. - The page says what it cannot do. For a track the probe refused, the page
asks for
/stream/{path}?compat=1. That parameter is a capability statement — “this caller cannot play the original” — and not a format request: there is no format parameter, and the server picks the target. - The server converts only what needs it. WMA, AIFF, Ogg Vorbis and Opus by
extension; ALAC by codec, read from MusicBee’s Kind. The result is FLAC, cached
so a track converts once, served with
Content-LengthandRangeso seeking and CUE offsets keep working. The source file is never touched. A file that needs no conversion is served as its original bytes even when?compat=1is present, and a request without the parameter is served exactly as before. - ALAC. The extension cannot separate it from AAC and neither can the probe,
so the page asks with
?compat=1for an.m4awhose Kind says ALAC, and also for one whose Kind it does not know yet. The server re-decides with the Kind in hand: an AAC file comes back untouched, an ALAC file comes back converted. The one cost is Safari, which could have played the ALAC original and receives a conversion instead. - With conversion off (the default), or ffmpeg missing, nothing changes from
the table above: a refused format never enters the device queue, playback steps past it, and
the output chip says so. If a conversion fails the request answers
503 TRANSCODE_FAILEDand the listener gets the same chip.
When the player is a Cast receiver
Casting from Listen Here changes who has to decode the file: the receiver fetches the stream
itself, so the browser’s own answer no longer matters. The page does not probe a receiver
— there is nothing to ask — and instead treats these as playable on a receiver:
MP3, AAC, FLAC, WAV, Ogg Vorbis, Opus, and .m4a when Kind says it is
not ALAC. Anything else is requested with ?compat=1&sink=cast, addressed to the
hub’s LAN address (lanBase in /system/features) because a
page-relative URL would resolve against the receiver. When lanBase is null
— no qualifying adapter, or remote connections are off — casting is not offered.
Practical reading
- An all-green library for Listen Here on any device: MP3, AAC/M4A (AAC), WAV, and FLAC on anything newer than ~2017.
- Formats refused up front with “⚠ not playable here” on real devices today: WMA everywhere; AIFF off-Apple; Vorbis and Opus on pre-18.4 Safari (iPhones not updated past iOS 18.3).
- Formats that fail on the attempt instead, because the extension does not give the browser away: ALAC off-Apple when conversion is off, and the four archival formats (APE, Musepack, WavPack, DSD) always. Same outcome for the listener, one track later.
- Hearing the rest anyway is what format conversion is for: with it enabled, WMA, AIFF, Ogg Vorbis, Opus and ALAC are converted on the way out, only for a browser that said it could not play the original. See Listen Here.
- Still outside it: APE, Musepack, WavPack and DSD. Conversion does not cover them.