Wednesday, April 18, 2012

The state of HTML5 audio in Mobile Safari on iOS

Yesterday I did an extensive web search and found out that the current browser support for the HTML5 audio element is very poor. Other bloggers agree on this, as you can read in a rather amusing post (that contains some strong language, also in the almost 100 comments). The poor audio support especially affects HTML5 game developers, who cannot preload sound files or play background music in their games. It is even rumoured that this is on purpose, so that 'real games' can only be played on e.g. mobile devices (phones or tablets) when they are developed as 'native' apps and hence must be downloaded from a device-specific app store (and paid for!).

Anyway, in the remainder of this post I am going to share with you two severe limitations of HTML5 audio in Mobile Safari on iOS, Apple's browser for the iPhone and iPad. While I was adding sounds to an iPad compatible hangman game for my daughter (that I have referred to before) I discovered the following restrictions:

  • You cannot preload sound files or cache them in the HTML5 application cache.
  • You cannot play audio automatically, i.e. without the user clicking on some element. Technically speaking, the audio must be played in the same call stack as a click event.

The first limitation makes the HTML5 audio support in Mobile Safari almost useless for the moment. If you cannot preload sounds, and they are instead fetched from the network with every play, there is a big chance that there will be a delay before playing them. This guarantees a bad user experience.

Also, I have not been able to store sound (MP3) files in the HTML5 application cache. Maybe they are cached by Mobile Safari (the opinions on this vary) but they certainly are not played. Hence there is no way I can combine an offline game experience with playing audio, which is a pity.

As far as I have been able to discover there are no current workarounds for this. If you know of any, please let me know by leaving a comment! By the way, I have been testing in Mobile Safari on iOS 5.0.1 on an iPad 2.

I will conclude with the explanation that Apple gives for disabling preloads on sound files (quote from the Safari Developer Library):

In Safari on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and autoplay are disabled. No data is loaded until the user initiates it. This means the JavaScript play() and load() methods are also inactive until the user initiates playback, unless the play() or load() method is triggered by user action. In other words, a user-initiated Play button works, but an onLoad="play()" event does not.

My suggestion to Apple: Why not ask the user for permission to (pre)load audio like has been done with the Geolocation feature?

3 comments:

  1. There's a Web Audio API in IOS 6 https://developer.apple.com/technologies/ios6/

    ReplyDelete
  2. Not a total loss. It turns out that, if you declare your audio object in a tag, and call play() on that object in the click handler for the first click, so long as you preserve that object, you can subsequently continue manipulating the audio object by loading alternate audio files and calling play() without any issues. You just need that first click, the first call to play(), and the single original audio object. If you do something like var aud=new Audio(), it will not work.

    ReplyDelete
  3. Another AnonymousMarch 24, 2013 at 2:23 PM

    Anonymous, your comment saved me endless nights of trial and error... thank you son much! You rock :)

    ReplyDelete