Much has been written about the woeful state of HTML5 audio support. It is what it is, so I won’t bother retreading over the same points in this article. Rather, I’m going to focus on the issues a developer may encounter on a per platform basis, and the potential solutions for them.
|Browser Version||Total Market Share|
|Microsoft Internet Explorer 8.0||26.92%|
|Microsoft Internet Explorer 9.0||17.00%|
|Microsoft Internet Explorer 6.0||6.17%|
|Microsoft Internet Explorer 7.0||3.43%|
|Browser Version||Total Market Share|
|Android Browser 4.0||18.96%|
|Opera Mini 4.2||4.52%|
|Opera Mini 4.1||2.11%|
The tables above summarize the web browser market share today (courtesy of NetMarketShare). Internet Explorer is still the leading desktop web browser followed by Chrome and Firefox. In the mobile market, Safari (unsurprisingly) dominates the market on account of the strong iOS brand followed by Android. Therefore, that’s the order that we’ll be covering the browsers.
IE 8 and below lack HTML5 canvas and audio support so expect to fallback to DOM manipulation for visuals and Flash for audio. Using SoundManager 2 will save you a lot of the headache in trying to support HTML5 audio in the older IE browsers.
IE 9 is a whole different ball game. HTML5 canvas and audio work perfectly. Expect the IE 9 adoption rate to sky rocket when Microsoft sunsets the Win XP OS.
Kudos to Microsoft for getting it right (finally).
Chrome version 18 and higher supports HTML5 audio and canvas. However, HTML5 audio will only function correctly if the web server supports partial downloading (ranged requests). Symptoms of this issue are:
- Unable to replay sound
- Unable to control playback position
- Sound plays once then stops, but the ‘ended’ event is not fired
The easiest way to resolve this is to enable ranged requests on the web server. Please note that Google App Engine does not support ranged requests, but it is possible to work around the issue by implementing a file serving servlet which supports ranged request. The Balus C Code website contains an article describing one possible servlet implementation.
Another way to circumvent this issue is to avoid using the built-in loop functionality and to use the load() function to “rewind” and play sounds again. This will resolve the problem but increases the load on the web server. Every time load is called on an audio instance, the web browser will fetch the audio data from the web server.
Another alternative is to use the Web Audio API. The major drawback is that the Web Audio API is currently supported exclusively by Chrome and only in versions 18 or higher. The major advantage is that the Web Audio API addresses all of HTML5 audio shortcomings by providing volume and pan controls, and real-time filtering.
As Safari and Chrome are both Webkit based browsers, both share similar advantages and drawbacks. Like Chrome, Safari supports HTML5 canvas and HTML5 audio, however Safari does not support the Google Web Audio API.
Unfortunately, Safari has similar drawbacks to Chrome – it doesn’t like audio served from a web server lacking partial download (ranged requests) support. The symptoms on Safari are different. They are:
- Small/short sounds play just fine
- Long sounds don’t play at all and throw an error that the sound file format is corrupted.
The easiest way to address this issue is to enable partial downloading on the web server. Please refer to the Chrome section for possible ways of remedying this situation
Firefox 3.6 and higher support HTML5 canvas and audio. However, Firefox 3.6′s audio support is buggy – short sounds do not play but medium length sounds (or longer) play just fine. If you’re looking for more advanced audio control, the Mozilla foundation is currently implementing its own version of the Web Audio API called the Audio Data API.
iOS mobile platform (Safari mobile)
Safari Mobile has all the strengths and weaknesses of its desktop brethren but introduces a new limitation – all HTML5 audio must be triggered through a user interaction. There are two major drawbacks caused by the limitation.
Finally, the Flash audio fallback trick will not work on the iOS because the iOS does not support Flash.
There are really only two options on the iOS – either (1) disable all sounds and continue serving the app through the web browser, or (2) keep all the sounds and publish the HTML5 app as a native app via appMobi, PhoneGap, or Appcelerator. For game development, my recommendation is appMobi because of its canvas acceleration feature.
Android (built-in browser)
Oh, Android… if only your OS platform wasn’t as splintered. The numerous Android versions out there make it hard to give a definitive answer on HTML5 audio support. For an idea of how many existing variants of the Android OS out there, watch the below on ‘Scaling Mobile with YUI’. At the 22 minute marker, the speaker shows a slide containing a non-exhaustive list of Android OS versions in the market.
These are the platform’s general audio characteristics:
- Android 2.x seems to support HTML5 audio but it will not play the sounds. Fortunately, the application continues to function normally – all audio function calls return appropriate results and load/cache events fire properly.
- ICS (Android 4.x) supports HTML5 audio and it will play sounds. However, playback is limited to only one sound at a time with the latest played sounds superceding all previous sound playback.
I did not test out Android 3.x HTML5 audio capability.
Fortunately, Android does support Flash integration so it is possible to fall back to Flash audio. With that said, Flash is an optional Google app so not all Android phones will have it installed. Unfortunately, I don’t have any statistics on the mobile Flash market penetration. Regardless, this approach is not recommended as Adobe has dropped mobile Flash support (yes, I’m still somewhat bitter about this), so expect it to go away sometime in the near future
The best approach to ensure proper audio support to go native and publish the HTML5 app via appMobi, PhoneGap, or Appcelerator. For game development, my recommendation is appMobi because of its plan to add accelerated canvas support for the Android. The feature is currently in the Beta stage.
The road to HTML5 audio is rife with pain. My recommendation is to save yourself a heap of trouble and use SoundManager 2 for the audio layer. For the mobile platforms, things are less clearcut. Consider going native and publishing the HTML5 app as a native app using an HTML5 native app platform such as appMobi, PhoneGap, or Appcelerator. For game development, the best HTML5 native app platform today is appMobi.
Happy bug hunting!
UPDATE: Jun 21, 2012
CocoonJS is a promising alternative to appMobi. Unlike AppMobi, it does not require any additional library integration. In addition, it already has canvas acceleration support for the Android. With that said, the platform is still pretty early in development.
Thank you everyone for bringing this to my attention.