如何使用HTML5视频标记捕获NETWORK_NO_SOURCE错误

voi*_*ate 8 javascript html5-video

如果没有为HTML5 <video>标签提供的<source>标签可播放,我想显示错误.

根据Mozilla开发者网络上的这个页面,似乎我必须检查视频元素的networkState属性以查看是否加载了任何源,因为每个单独的源标记在加载失败时都会抛出自己的错误.

要检测所有子元素都无法加载,请检查media元素的networkState属性的值.如果这是HTMLMediaElement.NETWORK_NO_SOURCE,您知道所有源都无法加载.

但是我应该在什么时候检查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' );
}
Run Code Online (Sandbox Code Playgroud)

我已尝试使用无效源标记的所有以下视频元素事件:loadstart,loadedmetadata,loadeddata&error以及以下结果(在Firefox中):

  • loadstart:已调用但networkState为NETWORK_LOADING
  • loadedmetadata:未调用
  • loadeddata:没有调用
  • 错误:未调用

但是,如果我在Firebug中查看视频标记,则networkState就像预期的那样是NETWORK_NO_SOURCE.

我应该使用什么事件来控制何时检查视频标签,或者有​​更好的方法来执行此操作?

lon*_*ngi 8

我用这个来检查视频的网络状态.这取自官方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>
Run Code Online (Sandbox Code Playgroud)

  • @longilong如果您使用<source>标签而不是媒体元素上的src =""属性,则此解决方案无效. (4认同)

rad*_*101 8

如果您使用的是源标记,则可以在列表中的最后一个源标记上设置onerror属性.有关详细信息,请参阅本页4.8.8节的底部.

引用该引用:

如果作者不确定用户代理是否都能够呈现所提供的媒体资源,则作者可以侦听最后一个源元素上的错误事件并触发回退行为:

<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>
Run Code Online (Sandbox Code Playgroud)

这个例子并不完美,因为你没有像在视频标签上使用onerror属性那样获得事件对象(只有在视频标签中有src属性而不是在一系列标签中才有效.) ,我相信你可以使用该标签上的networkState JS变量从视频标签中检索错误状态.虽然我没有测试过.所以这取决于你.听起来我在这里可能是满足您的需求.

笔记:

虽然您可以在最后一个源标记上侦听"错误"事件,但我发现这是不可靠的.如果preload属性未设置为none,我找不到在事件触发之前可靠地为事件添加侦听器的方法.这迫使我使用onerror属性.

如果你确实找到了一种可靠地监听事件的方法,我想添加这个音符.根据这个Chromium问题,源标记上的错误事件不会冒泡,这意味着您必须在该特定标记上侦听它.


Tib*_*org 8

不会调用'error'事件,因为它是由内部元素触发的,并且为了使事件也在元素上触发,您必须使用addEventListener方法并将useCapture参数设置为true,如下所示:

video.addEventListener('error', callback, true);
Run Code Online (Sandbox Code Playgroud)

然后在回调内部,您可以检查networkState属性,如果视频无法播放源,则该属性将为NETWORK_NO_SOURCE.

查看MDN关于addEventListener和useCapture参数的文档 https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener