What do all the tutorials on javascript say about doing user agent sniffing? Don't do it. Detect if the browser can do what you want it to do, and act according to that. Alright, let's see, is there a way to check if a browser can play back an audio format? Yes, there is canPlayType(), great! Using it is easy:

var audio = new Audio();
if (audio.canPlayType('audio/wav')) {
    // Rejoice!
} else {
    // Try the next one
}

Haha, no, I lied. The above fragment would be 100% logical, but canPlayType() does not return a boolean. Do you know what it returns? CanPlayType returns one of three values:

  • probably
  • maybe, or
  • “” (the empty string).

Wait, what?

It returns probably? Maybe? There isn't even a yes?? According to html5doctor.com, the reason for this is:

The reason we have these odd return types is because of the general weirdness surrounding codecs. The browser can only guess at whether a certain codec is playable without actually trying to play it.

So, after coming back together from the surprise, here is an actual way of testing if the browser maybe supports a format:

var audio = new Audio();
var canPlayOgg = !!audio.canPlayType && audio.canPlayType('audio/ogg; codecs="vorbis"') != ""

First, we check if the browser supports the canPlayType method on the Audio object, then we check if that returns anything other than an empty string. Welcome to HTML5.