Enter HTML 5 <audio>
One of the most exciting and long-awaited features in HTML 5 the <audio> element, enabling native audio playback within the browser. We can take advantage of this for browsers that support it — such as Safari 4, Firefox 3.5 and Chrome 3 — while falling back on Flash or other plugins for other browsers.
According to spec
Currently, the HTML 5 spec defines five attributes for the <audio> element:
src— a valid URL specifying the content sourceautobuffer— a boolean specifying whether the file is to be buffered in advanceautoplay— a boolean specifying whether the file should play as soon as it canloop— a boolean specifying whether the file should be repeatedly played.controls— a boolean specifying whether the browser should display its default media controls
Note that these are the same attributes defined for the <video> element.
Examples
Let’s take a couple of these attributes and create a simple example that will play an audio file:
<audio src="elvis.ogg" controls autobuffer></audio>
(This example will work for Firefox 3.5 and Chrome 3. You’ll need to replace the Ogg file with an MP3 to get it working in Safari 4.)
Of course, the spec is not finalised, and there isn’t yet a consensus on which codecs to support. This table details the codecs supported by today’s browsers:
| Browser | Ogg Vorbis | MP3 | WAV | FireFox 3.5 | ✓ | ✓ |
|---|---|---|---|
| Safari 4 | ✓ | ✓ | |
| Chrome 3 (beta) | ✓ | ✓ | |
| Opera 10 (beta) | ✓ |
To create our own controls, we can use the API methods defined by the spec:
play()— plays the audiopause()— pauses the audiocanPlayType()— interrogates the browser to establish whether the given mime type can be playedbuffered()— attribute that specifies the start and end time of the buffered part of the file
Note that Opera 10 does not support the <audio> HTML element, but it does support the Audio() API in a basic and unique manner: from the above list, it only supports the play() method.
Safari 4, Firefox 3.5, and Chrome 3 beta support both <audio> and Audio(). Internet Explorer 8 has no native audio support whatsoever.
Use the Source
The best way to coerce browsers into playing audio (or video, for that matter) is to use the <source> element. The browser will try to load the first audio source, and if it fails or isn’t supported, it will move on to the next audio source. In addition, we can embed a Flash player if all else fails:
<audio controls autobuffer>
<source src="elvis.ogg" />
<source src="elvis.mp3" />
<!-- now include flash fall back -->
</audio>
One caveat, though: you need to be careful about the order of the <source> elements. Because of a bug in Firefox, if you list the MP3 first (which Firefox doesn’t support), it will silently fail and refuse to render that particular <audio> element. The trick is to list the Ogg Vorbis file first and the other formats after. Webkit (Safari and Chrome) handle unsupported formats just fine.
Opera is another kettle of fish altogether, which we’ll need to solve using JavaScript.
Cross-Browser Implementation
When we created jPlayer, an audio player plugin for jQuery, we were attempting to address some of the limitations of the current crop of Flash-based audio players. Many relied on Flash to implement the player’s graphical interface, effectively isolating the player from the rest of the web design process.
The original jPlayer relied on Flash to play the actual audio while allowing the look and feel to be styled via HTML and CSS. With growing support for HTML 5 in modern browsers, we were inspired to break our Flash dependency and use native audio when it was supported.
The most significant issue is the cross-browser implementation, where lack of a common supported audio format among browsers causes complications. If developers want to take full advantage of all browsers that support HTML 5 audio, they’ll need to create both MP3 and Ogg (and in Opera’s case, WAV) versions of the audio file they want to stream!
Our job was made more difficult by the lack of available information:
- Firefox 3.5 — quite a detailed document
- Safari 4 — technically complete, but lacks explanations and examples
- Opera 10 — only a short note
- Chrome 3 — a wiki
Since the HTML 5 standard is still a work in progress, several aspects of the <audio> element vary from browser to browser. For example, there seems to be no way to determine the load progress of an audio file. Although Safari 4 can determine how much of an audio file has downloaded, Firefox 3.5 does not yet implement the buffered DOM attribute. (It is, however, included as part of the Firefox’s documentation, so we presume it will be implemented.)
Firefox 3.5 does appear to enable “seeking” of the file, allowing you to start the download from any point in the media. Other browsers, such as Safari 4, grab the file from the beginning and only allow seeking within the part already downloaded (or wait until the particular part being seeked to has been downloaded).
Although these inconsistencies aren’t showstoppers, in order to compete effectively with plugin-based solutions, we believe any HTML 5 audio implementation should be consistent across all browsers and match current implementations feature for feature.
JavaScript solutions
If we intend to take advantage of each browser’s audio capabilities, we need to create different solutions for different browsers. We could use browser sniffing, but considering the rapidly changing landscape, it’s better to check what capabilities a particular browser supports and adapt accordingly.
To demonstrate this “feature sniffing”, we’ve created a rough and ready HTML 5 audio checker.
Using JavaScript, you can check for audio tag support:
// returns a boolean
var audioTagSupport = !!(document.createElement('audio').canPlayType);
or check for the Audio() object:
try {
// The 'src' parameter is mandatory in Opera 10, so have used an empty string "".
// Otherwise, an exception is thrown.
myAudioObj = new Audio("");
audioObjSupport = !!(myAudioObj.canPlayType);
basicAudioSupport = !!(!audioObjSupport ? myAudioObj.play : false);
} catch (e) {
audioObjSupport = false;
basicAudioSupport = false;
}
or check file type compatibility:
// Need to check the canPlayType first or an exception
// will be thrown for those browsers that don't support it
if (myAudio.canPlayType) {
// Currently canPlayType(type) returns: "no", "maybe" or "probably"
canPlayOgg = ("no" != myAudio.canPlayType("audio/ogg")) && ("" != myAudio.canPlayType("audio/ogg"));
canPlayMp3 = ("no" != myAudio.canPlayType("audio/mpeg")) && ("" != myAudio.canPlayType("audio/mpeg"));
}
Note that to change the src attribute of an audio object or element, you’ll need to recreate the object or element with the new value for its src attribute.
So, to create a solution that takes full advantage of HTML 5 audio, you’ll typically need to:
- check for HTML 5 audio support, and if not present, fall back on Flash,
- check the level of HTML 5 audio support and adapt your code accordingly for each browser, and
- check what file types are supported and link to appropriate formats of the files.
The Road Ahead
Although HTML 5 audio is a relatively immature part of the standard, if recent trends continue and users upgrade to the latest versions of Safari and Firefox, browser support will likely rise above the 25% mark in the very near future. This is a significant chunk of the browser market that will no longer need to rely on Adobe’s Flash, Microsoft’s Silverlight, or any other browser plugin for audio support.
And when you consider that mobile and other lower-spec devices — like Apple’s iPod and iPhone (Safari), Nintendo’s Wii (Opera), and Google Android-powered devices (Chrome) — are choosing to support HTML 5 audio rather than Flash, you begin to paint a picture of how important native audio support will soon become.