2

I am creating an audio element in JavaScript and then appending it to my document. I am controlling it through JavaScript as well. It works fine in Firefox, Chrome, and Opera but not on IE and Safari. In those two browsers, the readyState of the audio element never changes from 0 nor do any associated events fire. Here is my basic program:

var init = function() {
    var audioElement = createAudioElement();        
    audioElement.addEventListener('canplay', function() {
        audioElement.play();
        trace(audioElement.readyState);
    }, false);
    document.body.appendChild(audioElement);
    //audioElement.play();  
}

var createAudioElement = function() {
    var m4a = 'song.m4a';
    var ogg = 'song.ogg';

    var m4aSrc = document.createElement('source');
        m4aSrc.setAttribute('src', m4a);
        m4aSrc.setAttribute('type', 'audio/mp4');
    var oggSrc = document.createElement('source');
        oggSrc.setAttribute('src', ogg);
        oggSrc.setAttribute('type', 'audio/ogg');
    var audioEle = document.createElement('audio');
        audioEle.setAttribute('preload', 'preload');
        audioEle.appendChild(m4aSrc);
        audioEle.appendChild(oggSrc);

    return audioEle;
}
Marty
  • 2,104
  • 2
  • 23
  • 42
  • Maybe because ie < 10 does not support audio element? – karaxuna Jul 18 '13 at 09:59
  • possible duplicate of [Create audio element dynamically with createElement instead of getElementById](http://stackoverflow.com/questions/10966408/create-audio-element-dynamically-with-createelement-instead-of-getelementbyid) – Paul Sweatte Oct 10 '13 at 02:27

1 Answers1

1

I know this is a bit late, but still; I managed to play audio on all those browsers (except IE < 9) without appending to DOM. You can create audios with something like this:

var audios = {};
audios['audioIDorName'] = new Audio('pathToYourAudio');   // create audio element
audios['audioIDorName'].load();                           // force load it
audios['audioIDorName'].addEventListener('canplaythrough', audioLoaded, false); // add event for when audio is fully loaded

Then you create audioLoaded() function which checks when all your audios are loaded (if you for instance added more than one in a loop or one after another.

var audiosLoaded = 0
function audioLoaded(){ 
    audiosLoaded++;
    console.log("Loaded "+this.src);
    // here you can check if certain number of audios loaded and/or remove eventListener for canplaythrough
    audios['audioIDorName'].removeEventListener('canplaythrough', audioLoaded, false);       
}

Then you manipulate audios with these functions:

audios['yourAudioIDorName'].pause();
audios['yourAudioIDorName'].currentTime = 0; // pause() and currentTime = 0 imitate stop() behaviour which doesn't exist ...
audios['yourAudioIDorName'].play();

This worked for me.

You can also try appending your audio element to an existing element if you insist on appending to DOM. See more details here.

Unfortunately there are still many other issues with html5 audio considering cross-browser usage. Codecs are just one thing; using ogg+mp3 is probably necessary. Flash fallback is not-so-neat solution that is used by libraries/APIs such as SoundManager and Howler.js. There is soundJS as well which may be the best thing to try. See my SO question as well.

Community
  • 1
  • 1
trainoasis
  • 6,419
  • 12
  • 51
  • 82
  • SoundJS is a good solution that solves many problems for you, but I may be biased as I work on it. You can also look at the code in the [github repo](https://github.com/CreateJS/SoundJS/) for an example of how to create and playback dynamic html audio tags. – OJay May 07 '14 at 15:33