iOS audio autoplay HTML5

Let me start this with a warning: If you’re making a website and you think autoplaying audio in the background is a great idea, you’re wrong. Very, very wrong.

Autoplaying audio, especially hidden autoplaying audio, is a terrible idea. Users hate it. It’s even more a terrible idea if you’re aiming your website at iPhone users, because most of them are on a data plan and they don’t want to pay large amounts of money to visit your site. It’s an awful thing to do and you should never do it.

That said, here’s how you do it.

Some html first

First, of course, you’ll need to add the audio tag in your html.

This is a fairly standard audio tag. Simple stuff, really.

A sprinkle of Javascript

Next, the javascript. I was expecting this to be much, much more difficult than it was. Apple even say it themselves, in the Safari documentation, that it’s not possible to have autoplaying audio on iOS. They clearly missed something then:

window.onload = function() { var audioEl = document.getElementById("audioTag"); audioEl.load(); audioEl.play(); };

Simple, right? In fact, so simple that I’d expect it to stop working at any moment. Right now, though, it does work, for iOS4 on iPhone and whatever it is the iPad runs.

So now you have autoplaying audio, but you’ve still got those pesky controls onscreen. Easily fixed. A little bit of CSS will fix that for you.

Some CSS for flavour

This, again, is so simple that even I could do it. Simply hide the div that contains the audio tag with css, like so:

#hideme {display: none;}

And that’s it! Now your audio will hide and autoplay for every iOS user who visits your site.

And here’s one I made earlier

Want to just see it in action? Here’s the code.

Let me reinforce, though: if you do this without warning, nobody will visit your site and your dog will run away. The only reason I’ve done this is because we need it for the Flax Engine (and we will, of course, warn our users). Unless you’ve got a similar excuse, just don’t do this.

Thanks to @gabrielvisser and @jearle for sacrificing their iPhones to ruthless testing.

Related Posts

First here is my code:

(function(a,n){ window.onload = function() { var b = document.body, userAgent = navigator.userAgent || navigator.vendor || window.opera, playSound = function(file) { var mediaAudio = new Audio(file); mediaAudio.play(); }; if(b.id == 'fail' || b.id == 'success') { if ((/android/gi.test(userAgent) && !window.MSStream)) { var vm = document.createElement("video"), type; vm.autoPlay = false; vm.controls = true; vm.preload = 'auto'; vm.loop = false; vm.muted = true; vm.style.position = 'absolute'; vm.style.top = '-9999%'; vm.style.left = '-9999%'; vm.style.zIndex = '-1'; vm.id = 'video'; if(b.id == 'fail') type = a; else type = n; for(key in type) { if(/video/gi.test(key) && vm.canPlayType(key) == 'probably') { vm.type = key; vm.src = type[key]; b.appendChild(vm); setTimeout(function(){ vm.muted = false; vm.play(); },100); return; } } } else { var au = new Audio(),type; if(b.id == 'fail') type = a; else type = n; for(key in type) { if(/audio/gi.test(key) && au.canPlayType(key) == "probably") { playSound(type[key]); return; } } } } } }({ 'audio/mpeg':'./sfx/not_ok.mp3', 'audio/wav':'./sfx/not_ok.wav', 'audio/ogg':'./sfx/not_ok.ogg', 'video/mp4; codecs=avc1.42E01E,mp4a.40.2':'./sfx/not_ok.mp4', }, { 'audio/mpeg':'./sfx/ok.mp3', 'audio/wav':'./sfx/ok.wav', 'audio/ogg':'./sfx/ok.ogg', 'video/mp4; codecs=avc1.42E01E,mp4a.40.2':'./sfx/ok.mp4', }));

I'm trying to play background sound on all devices on one special page. That page play fail or success sound.

All works great on desktop browsers but when I try to play on mobile, I not get results. In that code you see above, I add one hack where I on android platform generate hidden video and trying to autoplay but not have success.

Is there a way how I can trigger play for video or audio automaticaly?

Is there a way to emulate some click event on body to automaticaly play sound on click event or some other solution?

This article provides:

  • a basic guide to creating a cross-browser HTML5 audio player with all the associated attributes, properties, and events explained
  • a guide to custom controls created using the Media API

The code below is an example of a basic audio implementation using HTML5:

<audio controls> <source src="audiofile.mp3" type="audio/mpeg"> <source src="audiofile.ogg" type="audio/ogg"> <p>Your browser does not support HTML5 audio, but you can still <a href="audiofile.mp3">download the musica>.p> audio>

Note: You can also use an MP4 file instead of MP3. MP4 files typically contain AAC encoded audio. You can use type="audio/mp4". (Currently, browsers that support mp3 also support mp4 audio).

  • Here we define an
  • We do this using the element, which takes the attributes src and type.
    • src contains the path to the audio file to be loaded (relative or absolute).
    • type is used to inform the browser of the file type. If omitted, most browsers will attempt to guess this from the file extension.
  • If the
  • The controls attribute on the

Now we've looked at a basic example, let's now explore the different aspects of HTML5 audio in more detail.

We can specify a number of attributes with the audio tag to further determine the way audio is initialized.

autoplay

Specifying autoplay will cause the audio to start playing as soon as possible and without any user interaction — in short, the audio will autoplay.

<audio autoplay> ... audio>

Note: This value is often ignored on mobile platforms, and its use is not recommended unless really necessary. Auto-playing audio (and video) is usually really annoying. Plus browsers have policies that will block autoplay entirely in many situations. See the Autoplay guide for media and Web Audio APIs for details.

loop

The loop attribute will ensure that upon getting to the end of the audio clip, the audio clip will loop back to the beginning and start playing again.

<audio loop> ... audio>

muted

If you want the audio to start muted (no volume), add the muted attribute.

<audio muted> ... audio>

Note: This value is often ignored on mobile platforms.

preload

The preload attribute allows you to specify a preference for how the browser preloads the audio, in other words, which part of the file it downloads when the

preload can take 3 different values:

  1. none: Don't download anything before the play button is pressed.
  2. metadata: Download the audio metadata; this is usually the best option, as it allows you to access and display information such as audio length, and allow the browser to work out which audio file it should use.
  3. auto: Download the whole audio file as soon as possible. This is generally not a good option unless you can guarantee your users will have a fast network connection.

Note: This value is often ignored on mobile platforms.

<audio preload="auto"> ... audio>

controls

We specify the controls attribute when we require the browser to provide us with its default playback controls.

<audio controls> ... audio>

src

As mentioned above, you can use the element to specify one or more source audio files. Alternatively, you can include the src attribute directly on the

<audio src="audiofile.mp3"> ... audio>

type

As mentioned above, to be sure that the browser knows what type of file is being specified, it's good practice to specify a type attribute alongside the src attribute. The type attribute specifies the MIME type or Internet Media Type of the file.

<audio src="audiofile.mp3" type="audio/mpeg"> ... audio>

In addition to being able to specify various attributes in HTML, the

Given the following HTML:

<audio id="my-audio" src="audiofile.mp3"> ... audio>

You can grab the

var myAudio = document.getElementById('my-audio');

Alternatively, you can create a new element. Here's an example of creating an

var myAudio = document.createElement('audio'); if (myAudio.canPlayType('audio/mpeg')) { myAudio.setAttribute('src','audiofile.mp3'); } if (myAudio.canPlayType('audio/ogg')) { myAudio.setAttribute('src','audiofile.ogg'); } alert('play'); myAudio.play(); alert('stop'); myAudio.pause(); alert('play from 5 seconds in'); myAudio.currentTime = 5; myAudio.play();

Let's explore the available properties and methods in more detail.

play

The play() method is used to tell the audio to play. It takes no parameters.

pause

The pause() method is used to tell the audio to pause. It takes no parameters.

Note: There is no stop method — to implement a stop function, you'd have to pause the media then set the currentTime property value to 0.

canPlayType

The canPlayType() method asks the browser whether a certain audio file type is supported. It takes the mime type of the type to check as a parameter.

if (myAudio.canPlayType('audio/mpeg')) { }

canPlayType() returns one of three values:

  1. probably
  2. maybe
  3. "" (an empty string)

In practice, we usually check if the result is true or false. Non-empty strings are true.

Note: A very early spec specified that the browser should return no instead of an empty string, but thankfully the number of people using older browsers that implement this version of the spec are few and far between.

currentTime

The currentTime property gets or sets the current time the audio should play at. This is useful in many ways, for example since play() does not take a parameter we need to set the point to play from separately if we don't want it to be 0.

The value of currentTime is a number which represents the time in seconds.

if (myAudio.currentTime > 5) { myAudio.currentTime = 3; }

volume

The volume property allows us to set the audio volume, as a number between 0 and 1.

The JavaScript media API allows you to create your own custom player. Let's take a look at a very minimal example. We can combine HTML and JavaScript to create a very simple player with a play and a pause button. First, we'll set up the audio in the HTML, without the controls attribute, since we are creating our own controls:

<audio id="my-audio"> <source src="audiofile.mp3" type="audio/mpeg"> <source src="audiofile.ogg" type="audio/ogg"> <p>Download<a href="audiofile.mp3">audiofile.mp3a>p> audio> <button id="play">playbutton> <button id="pause">pausebutton>

Next, we attach some functionality to the player using JavaScript:

window.onload = function(){ var myAudio = document.getElementById('my-audio'); var play = document.getElementById('play'); var pause = document.getElementById('pause'); play.onclick = playAudio; pause.onclick = pauseAudio; function playAudio() { myAudio.play(); } function pauseAudio() { myAudio.pause(); } }

Above we have shown how you can create a very simple audio player, but what if we want to show progress, buffering and only activate the buttons when the media is ready to play? Fortunately, there are a number of events we can use to let our player know exactly what is happening.

First, let's take a look at the media loading process in order:

The loadstart event tells us that load process has started and the browser is connecting to the media.

myAudio.addEventListener("loadstart", function() { });

If you just want to know as soon as the duration of your media is established, this is the event for you. This can be useful because the initial value for duration is NaN (Not a Number), which you probably don't want to display to your users.

myAudio.addEventListener("durationchange", function() { });

Metadata can consist of more than just duration — if you want to wait for all the metadata to download before doing something, you can detect the loadedmetadata event.

myAudio.addEventListener("loadedmetadata", function() { });

The loadeddata event is fired when the first bit of media arrives. The playhead is in position but not quite ready to play.

myAudio.addEventListener("loadeddata", function() { });

The progress event indicates that the download of media is still in progress. It is good practice to display some kind of 'loader' at this point.

myAudio.addEventListener("progress", function() { });

canplay is a useful event to detect should you want to determine whether the media is ready to play. You could, for example, disable custom controls until this event occurs.

myAudio.addEventListener("canplay", function() { });

canplaythrough is similar to canplay but it lets you know that the media is ready to be played all the way through (that is to say that the file has completely downloaded, or it is estimated that it will download in time so that buffering stops do not occur).

myAudio.addEventListener("canplaythrough", function() { });

To recap, the order of the media loading events are:

loadstart > durationchange > loadedmetadata > loadeddata > progress > canplay > canplaythrough

We also have a few events available that will fire when there is some kind of interruption to the media loading process.

suspend

Media data is no longer being fetched even though the file has not been entirely downloaded.

abort

Media data download has been aborted but not due to an error.

error

An error is encountered while media data is being download.

emptied

The media buffer has been emptied, possibly due to an error or because the load() method was invoked to reload it.

stalled

Media data is unexpectedly no longer available.

We also have another set of events that are useful for reacting to the state of the media playback.

The timeupdate event is triggered every time the currentTime property changes. In practice, this occurs every 250 milliseconds. This event can be used to trigger the displaying of playback progress.

myAudio.addEventListener("timeupdate", function() { });

The playing event is initiated when playback is ready to start after having being paused due to lack of media data.

The waiting event is triggered when playback has stopped due to lack of media data, although it is expected to resume once data becomes available.

The play event is initiated after the play() method is returned or when the autoplay attribute has caused playback to begin. This is when the state of the media switches from paused to playing.

The pause event is triggered after the pause() method is returned. This is when the states switch from playing to paused.

The ended event is initiated when the end of the media is reached.

myAudio.addEventListener("ended", function() { });

The volumechange event signifies that the volume has changed; that includes being muted.

Consider this snippet of HTML:

<audio id="my-audio"> <source src="http://jPlayer.org/audio/mp3/Miaow-07-Bubble.mp3" type="audio/mpeg"> <source src="http://jPlayer.org/audio/ogg/Miaow-07-Bubble.ogg" type="audio/ogg"> <a href="audiofile.mp3">audiofile.mp3a> audio> <div id="controls"> <span id="loading">loadingspan> <button id="play" style="display:none">playbutton> <button id="pause" style="display:none" >pausebutton> div> <div id="progress"> <div id="bar">div> div>

Styled like so:

#controls { width: 80px; float: left; } #progress { margin-left: 80px; border: 1px solid black; } #bar { height: 20px; background-color: green; width: 0; }

Now let's wire this thing up with JavaScript:

window.onload = function(){ var myAudio = document.getElementById('my-audio'); var play = document.getElementById('play'); var pause = document.getElementById('pause'); var loading = document.getElementById('loading'); var bar = document.getElementById('bar'); function displayControls() { loading.style.display = "none"; play.style.display = "block"; } if (myAudio.paused) { displayControls(); } else { myAudio.addEventListener('canplay', function() { displayControls(); }); } play.addEventListener('click', function() { myAudio.play(); play.style.display = "none"; pause.style.display = "block"; }); pause.addEventListener('click', function() { myAudio.pause(); pause.style.display = "none"; play.style.display = "block"; }); myAudio.addEventListener('timeupdate', function() { bar.style.width = parseInt(((myAudio.currentTime / myAudio.duration) * 100), 10) + "%"; }); }

You should end up with something like this:

iOS audio autoplay HTML5

This is a good start, but it would be nice to be able to navigate the audio using the progress bar. Fortunately this isn't too difficult to implement.

First of all, we apply a quick update to the progress bar CSS to display the hand pointer on hover:

#progress { margin-left: 80px; border: 1px solid black; cursor: pointer; }

Then we add the code that detects the click and moves the 'playhead' to the correct position:

var progress = document.getElementById('progress'); progress.addEventListener('click', function(e) { var clickPosition = (e.pageX - this.offsetLeft) / this.offsetWidth; var clickTime = clickPosition * myAudio.duration; myAudio.currentTime = clickTime; });

Ok, we're getting there, but there is another piece of useful information we can display: the amount of audio has been buffered or downloaded in advance.

There are a couple of properties we haven't looked at yet, buffered and seekable.

buffered

This property lets us know which parts of the audio has been buffered (downloaded in advance). It returns something called a TimeRanges object.

myBufferedTimeRanges = myAudio.buffered;

seekable

The seekable property informs you of whether you can jump directly to that part of the media without further buffering.

mySeekableTimeRanges = myAudio.seekable;

Buffering events

There are also a couple of events related to buffering:

seeking

The seeking event is fired when media is being sought.

seeked

seeked occurs when the seeking attribute changes to false.

Note: You can read more on Buffering, Seeking and Time Ranges elsewhere.

The following tables list basic audio support across desktop and mobile browsers, and what audio codecs are supported.