Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Delay in playing HTML5 audio file on mobile browsers

I am making a web app, and i needed to add a short sound when a button is being clicked.

the file is in mp3 format and around 24kb in size, i didnt want to use javascript to create the element so i added it to the DOM and used CSS to hide it, also i added preload="auto" so it gets loaded with the DOM

<audio id="click" preload style="display:none;"> 
   <source src="sound/click.mp3" type="audio/mp3">
</audio>

in the javascript, i have something like:

var clickSound = $('#click')[0];

then in a function that listens to an even click on a button i have:

function(){
  clickSound.play();
}

this works fine on my computer (firefox, chrome), but on mobile after clicking the trigger button, it will wait for like 3 seconds before it plays for the first time, and will now play instantly after the first delayed play.

Update:

i noticed even if i navigate to the mp3 file on my mobile like this http://example.com/sound/click.mp3 and click on play, it still delays, seems like it had to buffer.

anyway around this problem?

Complete Example:

Here is a jsFiddle for mobile testing.

var clickSound = document.getElementById('click');
var play = document.getElementById('play');

play.addEventListener('click', function() {
      clickSound.play();
}, false);
<audio id="click" preload>
  <source src="http://scriveit.com/sound/click.mp3" type="audio/mp3">
</audio>


<input id="play" type="button" value="play sound">
like image 854
user2666633 Avatar asked Sep 29 '22 07:09

user2666633


1 Answers

One way of doing that for smaller audio files is pre-loading the file as a blob:

<button>play</button>
<audio></audio>
<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'click.mp3', true);
xhr.responseType = 'blob';
var audio = document.querySelector('audio');
xhr.onload = function () {
    audio.src = URL.createObjectURL(xhr.response);  
};
xhr.send();
document.querySelector('button').onclick = function () {
    audio.play();
};
</script>

Please note that this requires XHR2 (http://caniuse.com/#feat=xhr2) and Blob URLs (http://caniuse.com/#feat=bloburls) and that the same origin policy applies here. Moreover, you should make sure that the file is sent with some strong caching headers to prevent that the clients reloads the file with every request.

Edit: Another approach is using Data URLs (see http://jsfiddle.net/apo299od/):

<button>play</button>
<audio></audio>
<script>
var audio = document.querySelector('audio');
audio.src = 'data:audio/mp3;base64,SUQzBAAAAAA...';
document.querySelector('button').onclick = function () {
    audio.play();
};
</script>

The disadvantages here are that it is harder to maintain and that it will inflate your response size by 33%.

like image 61
Joel Avatar answered Oct 02 '22 16:10

Joel