2016-04-03 37 views
1

我假設(可能是不正確的?),由於HTML的異步性,即頁面加載的時間安排如下:<audio>的「預加載」屬性是否會影響window.onload事件時間?

  1. ...等加載HTML DOM到
  2. 遭遇<audio>標籤
  3. 預加載被指定爲「auto」;觸發緩衝
  4. 繼續加載HTML DOM進...等
  5. window.onload事件回調
  6. 異步一段時間後:音頻資源被發現,開始緩衝,否則將返回服務器錯誤;火readystatechange事件回調

而正是我希望的是,直到音頻資源被發現preload屬性與「汽車」的值會延遲從發射或延遲的標籤對DOM處理window.onload事件並且已經開始緩衝,或者服務器錯誤被返回並且加載被取消。

我無法想象爲音頻資源預扣window.onload,但後來我看到的頁面處理在過去停止進行flash資源加載或跟蹤腳本加載。

TLDR:window.onload關於資源加載的具體時間安排 - 特別是音頻標籤?

+0

你試過審查'Timing'在'Network'標籤? ,將'

+0

我有,但是我現在很小的音頻文件裝載速度如此之快,我無法破譯 – Dexter

+0

'data URI'會將'

回答

2

window.onload事件似乎在媒體src完全加載之前調用。使用在How do you check if a HTML5 audio element is loaded?中描述的方法;和包括.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版本1 http://plnkr.co/edit/zIIDDLZeVU7NHdfAtFka?p=preview


使用XMLHttpRequest的另一種方法,onended事件的AudioContext; Promise;遞歸請求,按順序播放文件數組。見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版本2 http://plnkr.co/edit/zIIDDLZeVU7NHdfAtFka?p=preview