Summary: Back in 2012, I wrote that HTML5 audio is broken on iOS. Now as we enter 2017, it turns out things are still horribly broken. It is currently impossible to build a music player web app that works on iOS.
Last week I published a big update to Chavah Messianic Jewish radio. It’s an HTML5 music player in the vein of Pandora (users can thumb up songs, influencing what gets played) for the Messianic Jewish faith.
And thanks to the magic of the web and HTML5 audio, it works flawlessly on PCs, Macs, and Linux. Sweet!
What about mobile? Well, yeah. Umm. Apple’s mobile implementation of HTML5 audio is still busted.
After releasing the new version last week, my users reported things still busted on iOS devices:
Well, I did have a look. And what I found is that iOS still cripples web apps that use HTML5 audio.
I was hoping that the new (July 2016) relaxed web media restrictions in iOS 10+ would un-cripple HTML5 audio in iOS.
I was disappointed to find it’s still broken. It’s currently impossible to write a working audio player using modern web technologies.
Here are the working things:
- You can play MP3 audio* ** *** ****
* Only after user interaction
** Only while the page is active and in the fore
*** Only while the phone screen is on
**** There’s no way to keep the screen from turning off, so your audio will stop after the first song.
So yes, you can play audio (10 asterisks here). Or more precisely, you can play a single audio track, but not much more.
Here are the busted things:
- Minor: Audio doesn’t play until user interaction.
- Major, blocking: Audio can’t play the next track when the phone screen is off.
Details on each of these below:
Audio doesn’t play until user interaction
This is the most minor of the busted things. But it’s an artificial restriction by Apple, likely for user experience and battery life reasons.
None of the other operating systems, mobile or desktop, do this. So we have to have special handling for iOS to require the user to interact with the UI before playing.
As for battery life, 3d content, muted <video>, gifs, ads and more don’t require interaction before start. Why hurt real web apps and real users by singling out audio apps?
Audio can’t play next track in background
Common user scenario: they go to my web app, hit play, and the music starts streaming in. Now they switch over to Twitter. When the current song ends, the music just stops. No new track is played.
But in practice, this kills real web apps on iOS. Music playing apps need to know when the song is finished in order to play the next song. So, we call
Audio can’t play the next track when the phone screen is off.
The most common scenario for my app: user goes to my web app, the app starts playing music. Then, the user leaves her phone alone; perhaps she’s in the car driving while listening to the music.
Upon further investigation, I tried to find out if it’s possible to prevent the screen from sleeping.
For a native iOS app, you can set application.idleTimerDisabled = YES. Super simple.
But for a web app? Nope, there’s no supported way to tell iOS, “Hey, keep the screen on, the user is in the middle of listening to music so don’t disrupt them.”
Some dated information on StackOverflow suggests looping a silent audio or video may prevent sleep. I built a little test app to try this out, and it appears to no longer work on iOS 10.
Additional answers on StackOverflow suggest pseudo page navigation every few seconds to prevent phone sleep/lock. I tried this as well, and it likewise appears to no longer work on iOS 10. The phone still sleeps even with page navigation going on.
Bottom line: there appears to be no way for a web app to prevent an iPhone from sleeping/locking.
Apple Webkit team action items
Here’s what we web developers need to make audio web apps a first class citizen on iOS:
It’s not enough to let the audio finish and then suspend JS; this breaks the user experience and causes audio web apps to stop working.
This would solve the other problems.
Alternately, don’t sleep/lock the phone if an active web app is playing audio. While this alternate solution doesn’t fix all the problems, it would address the most blocking use case for using audio web apps unattended.