iOS has some pretty decent support for HTML5 audio and video in the Safari browser. For the new 3voor12 site we’re currently investigating how can we use HTML5 video/audio to support the new site on touch devices, such as iOS. Apple’s development site has a nice section on preparing your media content for iOS. However, some of the sections are pretty terse, while they might have big implications on your site.
So, we did some research ourselves, and we like to share it with you here. Note that we tested on both iOS 3, 4 and 5. Any differences are marked in the text.
Autoplay problems
The autoplay property is disabled on iOS, as is the preload property. The reasoning behind this is that users might have a prepaid plan, and pay a large sum for their data transfer on media items. This sounds a bit weird, because no such restriction exists on large images, and AFAIK native apps don’t have this restriction.
A problem with this restriction is that the Javascript play() and load() methods only work on user events, such as a click. Normally this isn’t a problem, but it can be quite tricky when you want to do other things before playing the video. Imagine doing a call to some kind of web service using Ajax and on the callback play the media file. This doesn’t work because the ‘play’ didn’t originate from an user action.
However there’s a hack: when you do a synchronous Ajax call instead of asynchronous (which is the default when using a library such as jQuery) iOS does play the video after the callback. There are two drawbacks to this hack: sync calls don’t work cross-domain (for example using JSONP or CORS) and the browser is ‘frozen’ when the call is active. If your call doesn’t return your webapp is broken, Safari freezes and the user can only exit to home (closing the tab doesn’t work because the browser thread is locked).
The video element on iPhone and iPod Touch
There’s a distinction between using the <video> element on the iPad and the iPhone/iPod. On the iPhone a video always plays full-screen, while on the iPad it’s an element on the page and you can use it on your site like any other HTML element.
Audio in the background
Audio played in an <audio> element keeps on playing, even if the user goes to another app using the home button (provided the app doesn’t play audio itself). Video always stops whenever the user exits Safari. When the user returns to Safari different things happen on iOS 4 and iOS5: on iOS4 the audio keeps on playing, on iOS5 the audio fades out and the user has to press the play button in the web app again.
Playlists
For the new site we want to create auto-playing ‘playlists’ consisting of multiple files. Video and audio can be on one playlist, so for example after a video ends an audio file can start.
The restrictions mentioned above make this tricky on iOS Safari. Automatically playing the ‘next’ video after a media item ended (using the ended event listener on the element) works, apart from iOS 3 where apparently the ‘ended’ event doesn’t trigger.
However, if you’re switching from an audio to a video element the original ‘click’ doesn’t come from the original element and the next item doesn’t start.
There’s a hack: it’s actually possible to put an audio file in a <video> element and vice versa. This provides one hack to counter the autoplay problem on playlists (by playing all audio in a video element). However, it doesn’t allow you to play ‘video’ in the background, which means that on the iPhone the video element always takes over Safari and you can’t play audio and read the website at the same time.
More references
Miller Medeiros has written two in-depth articles pointing out more quirks on HTML5 video/audio on iOS:
oktober 24th, 2011 at 16:23
Another hack for the autoplay could be to send the ajax request after you start playing the video. Whether that is after the play call or on a loading/playing callback.
oktober 24th, 2011 at 16:25
@bashgrep: nice solution indeed, however in our case the call actually returns the URL we need to play. I suppose you can’t play a video if you don’t know the URL yet
april 14th, 2012 at 04:13
It should be noted that the JavaScript .play() method actually does work once the sound has been triggered at least once via user interaction before.
But still, the element is pretty useless for anything serious on Mobile Safari, especially because it has a huge, unpredictable lag when .play()d or .pause()d which makes it impossible to use for any kind of sound effect.
april 6th, 2013 at 12:48
I like the valuable info you provide to your articles. I’ll bookmark your blog and test once more here regularly. I am rather certain I’ll be informed many new stuff proper here! Best of luck for the following!