2012-02-07 65 views
8

如果爲HTML5 < video>標籤提供的< source>標記都不可播放,我想顯示一個錯誤。如何使用HTML5視頻標籤捕捉NETWORK_NO_SOURCE錯誤

根據this page on the Mozilla Developer Network,似乎我必須檢查視頻元素的networkState屬性,以查看是否加載了任何源代碼,因爲每個單獨的源代碼標記在加載失敗時都會引發它自己的錯誤。

To detect that all child elements have failed to load, check the value of the media element's networkState attribute. If this is HTMLMediaElement.NETWORK_NO_SOURCE, you know that all the sources failed to load.

但是在什麼時候應該檢查networkState?如果我立即檢查調用video_tag.load(),它始終告訴我networkState是NETWORK_NO_SOURCE,即使源元素有效且視頻播放正常。因此,我假設我等待瀏覽器嘗試使用源代碼。

這裏的測試:

var state = this._video_tag.networkState;  
console.log('networkState', state); 
if(state == this._video_tag.NETWORK_NO_SOURCE) 
{ 
    throw new Error('No valid sources'); 
} 

我已經嘗試了所有非法源標籤下面的視頻元素的事件:loadstart,等待loadedmetadata,loadeddata &錯誤,結果如下(在Firefox):

  • loadstart:被叫但網絡狀態是NETWORK_LOADING
  • loadedmetadata:不叫
  • loadeddat答:不叫
  • 錯誤:不叫

不過,如果我檢查出螢火蟲的視頻標籤,該networkState是NETWORK_NO_SOURCE只是預期。

我應該使用什麼事件來控制何時檢查視頻標籤,還是有更好的方法來做到這一點?

回答

8

我用這個來檢查視頻的網絡狀態。這是如果您使用的源代碼,你可以設置的最後一個源標籤使用onerror屬性的列表,而不是從官方W3C HTML5頁面(http://dev.w3.org/html5/spec/Overview.html#the-video-element

<script> 
function failed(e) { 
    // video playback failed - show a message saying why 
    switch (e.target.error.code) { 
    case e.target.error.MEDIA_ERR_ABORTED: 
     alert('You aborted the video playback.'); 
     break; 
    case e.target.error.MEDIA_ERR_NETWORK: 
     alert('A network error caused the video download to fail part-way.'); 
     break; 
    case e.target.error.MEDIA_ERR_DECODE: 
     alert('The video playback was aborted due to a corruption problem or because the video used features your browser did not support.'); 
     break; 
    case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED: 
     alert('The video could not be loaded, either because the server or network failed or because the format is not supported.'); 
     break; 
    default: 
     alert('An unknown error occurred.'); 
     break; 
    } 
} 
</script> 
<video src="tgif.vid" autoplay controls onerror="failed(event)"></video> 
+0

在FF,e.target.error未定義兩者的視頻和源元件。 :/ – voidstate 2012-02-09 12:50:13

+2

@longilong如果您在媒體元素上使用標記而不是src =「」屬性,則此解決方案將無法工作。 – sidarcy 2013-04-09 13:29:36

8

拍攝。有關更多詳情,請參閱the bottom of section 4.8.8 on this page。從參考

報價:

If the author isn't sure if user agents will all be able to render the media resources provided, the author can listen to the error event on the last source element and trigger fallback behavior:

<script> 
function fallback(video) { 
    // replace <video> with its contents 
    while (video.hasChildNodes()) { 
    if (video.firstChild instanceof HTMLSourceElement) 
     video.removeChild(video.firstChild); 
    else 
     video.parentNode.insertBefore(video.firstChild, video); 
    } 
    video.parentNode.removeChild(video); 
} 
</script> 
<video controls autoplay> 
<source src='video.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'> 
<source src='video.ogv' type='video/ogg; codecs="theora, vorbis"' 
     onerror="fallback(parentNode)"> 
... 
</video> 

這個例子並不是完美的,因爲你像你一樣沒有得到事件對象時使用onerror屬性的視頻標籤(只,如果你有工作一個視頻標籤中的src屬性,而不是一系列標籤,然而,我相信你可以通過標籤上的networkState JS變量從視頻標籤中獲取錯誤狀態,但我還沒有測試過。這聽起來像我在這裏可能會滿足您的需求。

備註:

雖然您可以在最後一個源代碼上監聽「錯誤」事件,但我發現這是不可靠的。在preload屬性未設置爲none的情況下,我找不到在事件觸發前可靠地爲事件添加偵聽器的方法。這迫使我使用onerror屬性。

如果您確實找到一種可靠地收聽活動的方法,我想添加此註釋。根據this Chromium issue源標籤上的錯誤事件不會冒泡,這意味着您必須在該特定標籤上收聽它。

5

'error'事件不會被調用,因爲它是由內部元素觸發的,爲了使事件在元素上也被觸發,您必須使用useCapture參數設置爲true的addEventListener方法,像這樣:

video.addEventListener('error', callback, true); 

然後回調裏面,你可以檢查networkState屬性,這將是NETWORK_NO_SOURCE如果視頻無法播放的來源。

退房從MDN約的addEventListener的文檔和將useCapture參數 https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener