Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The canplay/canplaythrough events for an HTML5 video are not called on Firefox. Why?

I'm building a jQuery plugin for managing HTML5 videos. I'm trying to capture the canplay and canplaythrough events. In Chrome, the event is fired without problem. In Firefox, sometime it's triggered, sometime it's not.

I'm simplifying my code a little here:

$('#my_video').on('canplay canplaythrough', function(){
    console.log('canplay event fired');
});

I also tried with the native javascript .addEventListener() and it's not working.

Any idea why the event is not called on Firefox and how to fix that?

NOTE: Please do not tell me to use one of the already available plugins like jplayer and video-js, I know that they exist and work well, but I have to build an in-house solution.

like image 773
Gabriel Avatar asked Apr 19 '12 20:04

Gabriel


3 Answers

The problem is that your video element has triggered the canplaythrough event before you registered the event handler.

As you pointed out in your own answer, you can put your scripts in the <head>, but this is bad for your page performance.

A better way to fix your problem is to check the readystate attribute and execute your function manually in that case:

var $video = $('video'),
    videoElement = $video[0];

$video.on('canplaythrough', callback);

// If the video is in the cache of the browser,
// the 'canplaythrough' event might have been triggered
// before we registered the event handler.
if (videoElement.readyState > 3) {
  callback();
}
like image 190
Pierre Spring Avatar answered Nov 11 '22 21:11

Pierre Spring


The most likely reason you're seeing this probably has to do with timing issues. You stated in your accepted answer that putting jQuery into the head rather than the footer solves the problem. This tells me that the issue is DOM parsing and script execution order. The most likely culprit is that the "canplay" and "canplaythrough" events were being fired before jquery and your page script were parsed and the event handlers added - but only sometimes, depending on network traffic and load times. By putting the script in the head, you forced your event binding to occur before the DOM elements were created, thereby ensuring that you didn't miss any events.

As an aside, the performance benefits of putting script elements at the bottom of the page are debatable. If you really want to tweak page performance, use something like LABjs to manage parallel script loading.

like image 11
Clayton Gulick Avatar answered Nov 11 '22 21:11

Clayton Gulick


In my case, this was determined by the preload attribute specified for the element. I did not have it specified at all, so different browsers were choosing to do different things.

Once I specified preload="auto", the on("canplay") event handler worked fine/as expected.

like image 8
RCNeil Avatar answered Nov 11 '22 21:11

RCNeil