Search code examples
javascripthtmlhtml5-audio

js / html5 audio: Why is canplaythrough not fired on iOS safari?


i use the code below to preload an array of audio files (after user interacts with a button starting the process). After all audio files fired "canplaythrough" the code proceeds:

var loaded = 0;
function loadedAudio() {
    // this will be called every time an audio file is loaded
    // we keep track of the loaded files vs the requested files
    loaded++;
    console.log(loaded + " audio files loaded!");
    if (loaded == audioFiles.length){
      // all have loaded
      main();
    }
}

function preloadsounds()
{
  $("#loader").show();
  console.log(level.config);
  audioFiles = level.config.soundfiles;

  // we start preloading all the audio files with html audio
  for (var i in audioFiles) {
      preloadAudio(audioFiles[i]);
  }

}

function preloadAudio(url)
{
  console.log("trying to preload "+ url);
  var audio = new Audio();
  // once this file loads, it will call loadedAudio()
  // the file will be kept by the browser as cache
  audio.addEventListener('canplaythrough', loadedAudio, false);

  audio.addEventListener('error', function failed(e)
  {
    console.log("COULD NOT LOAD AUDIO");
    $("#NETWORKERROR").show();
  });
  audio.src = url;
}

works great on Android (Chrome and Firefox) but not a single canplaythrough event is fired on iOs Safari (tested live on 5s and emulated X both 11.x). All files are served from the same Origin. I also don't get any Error messages in my log.

What am I missing?

( the basis for the code above i go from: https://stackoverflow.com/a/31351186/2602592 )


Solution

  • Try calling the load() method after setting the src.

    function preloadAudio(url)
    {
      console.log("trying to preload "+ url);
      var audio = new Audio();
      // once this file loads, it will call loadedAudio()
      // the file will be kept by the browser as cache
      audio.addEventListener('canplaythrough', loadedAudio, false);
    
      audio.addEventListener('error', function failed(e)
      {
        console.log("COULD NOT LOAD AUDIO");
        $("#NETWORKERROR").show();
      });
      audio.src = url;
    
      audio.load();  // add this line
    }