Как поймать ошибки NETWORK_NO_SOURCE с помощью видео тега HTML5 - PullRequest
8 голосов
/ 07 февраля 2012

Если ни один из тегов

, предоставленных для тега HTML5, не воспроизводится, я хочу отобразить ошибку.

В соответствии с этой страницей в Mozilla Developer Network кажется, что мне нужно проверить свойство networkState элемента video, чтобы увидеть, загружены ли какие-либо источники, поскольку каждый отдельный тег источника генерирует свою собственную ошибку, когда он не удается загрузить.

Чтобы определить, что все дочерние элементы не удалось загрузить, проверьте значение атрибута 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' );
}

Я перепробовал все следующие события видеоэлемента с недопустимыми тегами источника: loadstart, Загруженные метаданные, загруженные данные и ошибка со следующими результатами (в Firefox):

  • loadstart: вызвано, но networkState - NETWORK_LOADING
  • загруженные метаданные: не называются
  • загруженные данные: не называются
  • ошибка: не вызывается

Однако, если я проверю видео тег в Firebug, networkState будет NETWORK_NO_SOURCE, как и ожидалось.

Какое событие я должен использовать, чтобы контролировать, когда проверять тег видео, или есть ли лучший способ сделать это?

Ответы [ 3 ]

8 голосов
/ 05 сентября 2013

Если вы используете теги источника, вы можете вместо этого установить атрибут 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>

Этот пример не идеален, потому что выне получайте объект события, как вы, когда атрибут onerror находится в теге video (это работает только в том случае, если у вас есть атрибут src в теге video вместо ряда тегов. Однако я полагаю, что вы можете получитьсостояние ошибки из видео-тега с переменной JS networkState для этого тега. Я не проверял это, хотя, так что это зависит от вас. Кажется, что то, что у меня здесь есть, может быть удовлетворительным для ваших нужд.

Примечания:

Хотя вместо этого вы можете прослушивать событие «ошибка» в последнем теге источника, я обнаружил, что это ненадежно. В случаях, когда предварительная загрузка вtribute не установлен в none, я не смог найти способ надежного добавления прослушивателя для события до его запуска.Это заставило меня использовать атрибут onerror.

Если вы найдете способ надежно прослушать событие, я хотел добавить эту заметку.В соответствии с этой проблемой Chromium событие ошибки в исходном теге НЕ всплывает, что означает, что вы должны прослушивать его для этого конкретного тега.

8 голосов
/ 06 августа 2015

Событие 'error' не вызывается, потому что оно вызывается элементами внутри, и чтобы событие было вызвано также на элементе, вы должны использовать метод addEventListener с параметром useCapture, установленным в true, например, так:

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

И затем внутри обратного вызова вы можете проверить свойство networkState, которое будет NETWORK_NO_SOURCE, если видео не может воспроизводить источники.

Посмотрите документы из MDN о addEventListener и параметре useCapture. https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

8 голосов
/ 07 февраля 2012

Я использовал это, чтобы проверить состояние сети видео.это взято с официальной страницы 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...