How to preload a sound in Javascript?

JavascriptAudioPreload

Javascript Problem Overview


I can preload images easily thanks to the onload function. But it doesn't work with audio. Browsers like Chrome, Safari, Firefox, etc. don't support the onload functions in the audio tag.

How do I preload a sound in Javascript without using JS libraries and without using or creating HTML tags?

Javascript Solutions


Solution 1 - Javascript

Your problem is that Audio objects don't support the 'load' event.

Instead, there's an event called 'canplaythrough' that doesn't mean it's fully loaded, but enough of it is loaded that at the current download rate, it will finish by the time the track has had enough time to play through.

So instead of

audio.onload = isAppLoaded;

try

audio.oncanplaythrough = isAppLoaded;

Or better yet.. ;)

audio.addEventListener('canplaythrough', isAppLoaded, false);

Solution 2 - Javascript

I tried the accepted answer by tylermwashburn and it didn't work in Chrome. So I moved on and created this and it benefits from jQuery. It also sniffs for ogg and mp3 support. The default is ogg because some experts say a 192KBS ogg file is as good as a 320KBS MP3, so you save 40% on your required audio downloads. However mp3 is required for IE9:

// Audio preloader

$(window).ready(function(){
  var audio_preload = 0;
  function launchApp(launch){
    audio_preload++;
    if ( audio_preload == 3 || launch == 1) {  // set 3 to # of your files
      start();  // set this function to your start function
    }
  }
  var support = {};
  function audioSupport() {
    var a = document.createElement('audio');
    var ogg = !!(a.canPlayType && a.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, ''));
    if (ogg) return 'ogg';
    var mp3 = !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
    if (mp3) return 'mp3';
    else return 0;
  }
  support.audio = audioSupport();
  function loadAudio(url, vol){
    var audio = new Audio();
    audio.src = url;
    audio.preload = "auto";
    audio.volume = vol;
    $(audio).on("loadeddata", launchApp);  // jQuery checking
    return audio;
  }
  if (support.audio === 'ogg') {
    var snd1 = loadAudio("sounds/sound1.ogg", 1);  // ie) the 1 is 100% volume
    var snd2 = loadAudio("sounds/sound2.ogg", 0.3);  // ie) the 0.3 is 30%
    var snd3 = loadAudio("sounds/sound3.ogg", 0.05);
        // add more sounds here
  } else if (support.audio === 'mp3') {	
    var snd1 = loadAudio("sounds/sound1.mp3", 1);
    var snd2 = loadAudio("sounds/sound2.mp3", 0.3);
    var snd3 = loadAudio("sounds/sound3.mp3", 0.05);
        // add more sounds here
  } else {
    launchApp(1);  // launch app without audio
  }

// this is your first function you want to start after audio is preloaded:
  function start(){
     if (support.audio) snd1.play();  // this is how you play sounds
  }

});

Furthermore: Here is an mp3 to ogg converter: http://audio.online-convert.com/convert-to-ogg Or you can use VLC Media player to convert. Check your mp3 bitrate by right-clicking on the mp3 file (in Windows) and going to the file details. Try to reduce by 40% when selecting your new bitrate for your new 'ogg' file. The converter may throw an error, so keep increasing the size until is accepted. Of course test sounds for satisfactory quality. Also (and this applied to me) if you are using VLC Media player to test your audio tracks make sure you set the volume at 100% or below or otherwise you'll hear audio degradation and might mistakenly think it is the result of compression.

Solution 3 - Javascript

Depending on your target browsers, setting the [prelaod][1] attribute on the audio tag may be sufficient.

[1]: http://www.w3.org/TR/2011/WD-html5-20110113/video.html#attr-media-preload "WC3 HTML5 Specification"

Solution 4 - Javascript

//Tested on Chrome, FF, IE6

function LoadSound(filename) {
    var xmlhttp;
    if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    } else { // code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            document.getElementById("load-sound").innerHTML = '<embed src="' + filename + '" controller="1" autoplay="0" autostart="0" />';
        }
    }
    xmlhttp.open("GET", filename, true);
    xmlhttp.send();
}

Reference > - http://sharkysoft.com/tutorials/jsa/content/048.html > - https://stackoverflow.com/questions/2762865/jquery-how-do-you-preload-sound > - http://jsarchive.8m.com/Main/audio.html

Solution 5 - Javascript

Remy came up with a solution for iOS that utilizes the sprite concept:

http://remysharp.com/2010/12/23/audio-sprites/

Not sure it directly addresses the preload, but has the advantage that you only need to load one audio file (which is also a drawback, I suppose).

Solution 6 - Javascript

Did you try making an ajax request for the file? You wouldn't show/use it until it was all the way loaded.

E.g. https://stackoverflow.com/questions/2762865/jquery-how-do-you-preload-sound/2763101#2763101 (you wouldn't have to use jQuery).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionManuel Ignacio L&#243;pez QuinteroView Question on Stackoverflow
Solution 1 - JavascriptMcKaylaView Answer on Stackoverflow
Solution 2 - JavascriptJonathan TongeView Answer on Stackoverflow
Solution 3 - JavascriptDamien WilsonView Answer on Stackoverflow
Solution 4 - JavascriptLuca FilosofiView Answer on Stackoverflow
Solution 5 - JavascriptDA.View Answer on Stackoverflow
Solution 6 - Javascripttwo7s_clashView Answer on Stackoverflow