开发者

HTML5 video error handling

I need to tell, whether video cannot be played ("x" sign is shown in browser).

This code does't works. "onerror" event will never be fired under Firefox

var v = document.getElementsByTagName("video")[0];
    if ( v != undefined )
        v.onerror = function(e) {
            if ( v.networkState == v.NETWORK开发者_StackOverflow中文版_NO_SOURCE )
            {
                // handle error
            }
        }

What's wrong here ?


"onerror" is not a valid event type for <video>

Use "error" instead.

document.getElementsByTagName('video')[0].addEventListener('error', function(event) { ... }, true);

For a complete list of events for <video> go here: https://developer.mozilla.org/En/Using_audio_and_video_in_Firefox


From Firefox 4 onwards, the 'error' event is dispatched on the <source> element.

And you should add an error handler on the only/last 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

You can create an error handling directive (or just use 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>

Where the error handling directive's link function should do (copied from ng-error):

element.on('error', function(event) {
    scope.$apply(function() {
        fn(scope, {$event:event});
    });
});


It's good to know that Chrome and Firefox have different onerror callbacks. The error must therefore be mapped. Mozilla uses error.originalTarget.

Here is a sample on how to do it with pure 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);
});

The above example maps an incoming error event into a MediaError which can be used to display an error playback message.


To catch error event, you should use video.addEventListener():

var video = document.createElement('video');
var onError = function() { // your handler};
video.addEventListener('error', onError, true);
...
// remove listener eventually
video.removeEventListener('error', onError, true);

Note that the 3rd parameter of addEventListener (on capture) should be set to true. Error event is typically fired from descendants of video element ( tags).

Anyway, relying on video tag to fire an error event is not the best strategy to detect if video has played. This event is not fired on some android and iOS devices.

The most reliable method, I can think of, is to listen to timeupdate and ended events. If video was playing, you'll get at least 3 timeupdate events. In the case of error, ended will be triggered more reliably than error.


Try adding the event listener to the tag instead - I think the onerror attribute ("error" event) works on the source tag now, not the video tag.


Pug example

video(src= encodeURI(item.urlVideo), type='video/mp4'  onerror="myFunction('param',this)")
script(src='/javascripts/onerror.js')

function myFunction(param, me) { 
    console.log(me);
    me.poster = './images/placeholder.jpg'; }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜