Обработка ошибок видео HTML5
Мне нужно сказать, нельзя ли воспроизводить видео (знак "x" отображается в браузере).
Этот код не работает. Событие "onerror" никогда не будет запущено в Firefox
var v = document.getElementsByTagName("video")[0];
if ( v != undefined )
v.onerror = function(e) {
if ( v.networkState == v.NETWORK_NO_SOURCE )
{
// handle error
}
}
Что здесь не так?
Ответы
Ответ 1
"onerror" не является допустимым типом события для <video>
Вместо этого используйте "error".
document.getElementsByTagName('video')[0].addEventListener('error', function(event) { ... }, true);
Полный список событий для <video>
можно найти здесь: https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox
Ответ 2
Начиная с Firefox 4, событие 'error' отправлено в элементе <source>
.
И вы должны добавить обработчик ошибок в единственный/последний источник:
HTML
<video id="vid" controls>
<source src="dynamicsearch.mp4" type="video/mp4"></source>
<source src="otherdynamicsearch.avi" type="video/avi"></source>
</video>
JS
var v = document.querySelector('video#vid');
var sources = v.querySelectorAll('source');
if (sources.length !== 0) {
var lastSource = sources[sources.length-1];
lastSource.addEventListener('error', function() {
alert('uh oh');
});
}
JQuery
$('video source').last().on('error', function() {
alert('uh oh');
});
AngularJS
Вы можете создать директиву обработки ошибок (или просто использовать ng-error):
<video id="vid" controls>
<source src="dynamicsearch.mp4" type="video/mp4"></source>
<source src="otherdynamicsearch.avi" type="video/avi" ng-error="handleError()"></source>
</video>
Если должна выполняться функция директивы обработки ошибок link
(скопирована из ng-error):
element.on('error', function(event) {
scope.$apply(function() {
fn(scope, {$event:event});
});
});
Ответ 3
Чтобы уловить событие ошибки, вы должны использовать video.addEventListner()
:
var video = document.createElement('video');
var onError = function() { // your handler};
video.addEventListener('error', onError, true);
...
// remove listener eventually
video.removeEventListener('error', onError, true);
Обратите внимание, что третий параметр addEventListener
(при захвате) должен быть установлен в true. Событие с ошибкой обычно запускается из descendatns видеоэлемента (тегов).
В любом случае, полагаясь на тег видео, чтобы запустить событие error
, это не лучшая стратегия для обнаружения воспроизведения видео. Это событие не запускается на некоторых устройствах android и iOS.
Самый надежный метод, о котором я могу думать, - слушать события timeupdate
и ended
. Если видео воспроизводилось, вы получите как минимум 3 раза времени. В случае ошибки ended
будет срабатывать более надежно, чем error
.
Ответ 4
Попробуйте добавить прослушиватель событий в тег вместо этого - я думаю, что атрибут onerror (событие "ошибка" ) теперь работает с исходным тегом, а не с тегом видео.
Ответ 5
Хорошо знать, что Chrome и Firefox имеют разные обратные вызовы onerror
. Поэтому ошибка должна отображаться. Mozilla использует error.originalTarget.
Вот пример того, как это сделать с помощью чистого JavaScript:
const file = 'https://samples.ffmpeg.org/MPEG-4/MPEGSolution_jurassic.mp4';
window.fetch(file, {mode: 'no-cors'})
.then((response) => response.blob())
.then((blob) => {
const url = window.URL.createObjectURL(blob);
const video = document.createElement('video');
video.addEventListener('error', (event) => {
let error = event;
// Chrome v60
if (event.path && event.path[0]) {
error = event.path[0].error;
}
// Firefox v55
if (event.originalTarget) {
error = error.originalTarget.error;
}
// Here comes the error message
alert(`Video error: ${error.message}`);
window.URL.revokeObjectURL(url);
}, true);
video.src = url;
document.body.appendChild(video);
});