1

I have assumed (possibly incorrectly?), due to the asynchronous nature of HTML, that the timeline of page loading is as follows:

  1. ... etc loading html into DOM
  2. encounter <audio> tag
  3. preload is specified as "auto"; trigger buffering
  4. continue loading html into DOM... etc
  5. fire window.onload event callbacks
  6. asynchronously some time later: audio resource is found, begin buffering, or server error is returned; fire readystatechange event callbacks

Whereas what I'm hoping for is that the preload attribute with a value of "auto" will delay the window.onload event from firing or delay tag-to-DOM processing until the audio resource is found and has had begun buffering, or a server error is returned and loading is canceled.

I can't imagine withholding window.onload for an audio resource, but then I have seen page processing come to a halt for flash resource loading or tracking script loading in the past.

TLDR: What is the exact timeline of window.onload with regard to resource loading--specifically the audio tag?

Dexter
  • 731
  • 2
  • 12
  • 27

1 Answers1

2

window.onload event appears to be called before the media src is fully loaded. Using approaches described at How do you check if a HTML5 audio element is loaded? ; and including .webkitAudioDecodedByteCount

<!DOCTYPE html>
<html>   
<head>
  <script>
    window.addEventListener("load", function() {
      var media = document.querySelector("audio");
      console.log("window onload event"
                 , media.webkitAudioDecodedByteCount
                 , media.readyState)
    })

    function myOnCanPlayFunction() {
      console.log("Can play", event.target.webkitAudioDecodedByteCount
                            , event.target.seekable.start(0)
                            , event.target.seekable.end(0));
    }

    function myOnCanPlayThroughFunction() {
      console.log("Can play through", event.target.webkitAudioDecodedByteCount
                 , event.target.seekable.start(0)
                 , event.target.seekable.end(0));
    }

    function myOnLoadedData() {
      console.log("Loaded data", event.target.webkitAudioDecodedByteCount
                 , event.target.seekable.start(0)
                 , event.target.seekable.end(0));
    }
  </script>
</head>    
<body>    
  <audio oncanplay="myOnCanPlayFunction()" 
         oncanplaythrough="myOnCanPlayThroughFunction()"             
         onloadeddata="myOnLoadedData()" 
         src="/path/to/audio/file" 
         preload autoplay buffered controls></audio>
</body>   
</html>

plnkr version 1 http://plnkr.co/edit/zIIDDLZeVU7NHdfAtFka?p=preview


An alternative approach using XMLHttpRequest , onended event of AudioContext; Promise; recursion to request, play array of files in sequence. See AudioContext.decodeAudioData()

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="style.css">
  <script>
    var sources = ["/path/to/audio/src/1"
    , "/path/to/audio/src/2"];
    var src = sources.slice(0); // copy original array

    function getAudio(url) {
      return new Promise(function(resolve, reject) {
      var audioCtx = new(window.AudioContext || window.webkitAudioContext)();
      var source = audioCtx.createBufferSource();
      var request = new XMLHttpRequest();
      request.open("GET", url, true);
      request.responseType = "arraybuffer";
      request.onload = function() {
        var audioData = request.response;
        audioCtx.decodeAudioData(audioData).then(function(decodedData) {
          source.buffer = decodedData;
          source.connect(audioCtx.destination);
          console.log(source, decodedData);
          // do stuff when current audio has ended
          source.onended = function() {
            console.log("onended:", url);
            if (src.length)
              resolve(src)
            else resolve("complete")
          }
          source.start(0);
        });
      }
      request.send();
      })
    }
    var audio = (function tracks(s) {
    return getAudio(s.shift())
    .then(function(data) {
      if (Array.isArray(data) && data.length) return tracks(data)
      else return data
    })
    }(src));
    // do stuff when all `src` have been requested, played, ended
    audio.then(function(msg) {
      console.log(msg)
    })
  </script>
</head>
<body>
</body>
</html>

plnkr version 2 http://plnkr.co/edit/zIIDDLZeVU7NHdfAtFka?p=preview

Community
  • 1
  • 1
guest271314
  • 1
  • 10
  • 82
  • 156