Custom HTML5 Video Objects: Timing

In my last blog posting, I touched on defining your own implementation of an HTML5 Video. Basically all it takes is to implement the HTMLMediaElement interface on an object by defining the methods and attributes listed. It’s easy. In fact, here’s a starting skeleton I’ve whipped up:

var undef;

var MediaElement = {
  load: function() {},
  play: function() {},
  pause: function() {},

  readyState: 0,
  currentTime: 0,
  duration: 0,
  paused: 1,
  ended: 0,
  volume: 1,
  muted: 0,
  playbackRate: 1
  // These are considered to be "on" by being defined. Initialized to undefined
  autoplay: undef,
  loop: undef,
};

Those are a subset of methods and attributes and a give a good start, though there is a whole lot more functionality that may be implemented if desired. Even though we have the attributes, one important mechanism is missing. Videos update at regular intervals, which is something we’ll need to account for in our video object. This is also incredibly easy to do. According to the spec, time updates should occur every “15 to 250ms”:

var msDelay = 250;

function timerTick() {
  // Run code here

  setTimeout( timerTick, msDelay );
}

The above code will execute the “timerTick” function every 250 ms. I’ve created a timed loop using setTimeout instead of setInterval because setInterval has the unfortunate side-effects of not firing at reliable times as well as eating errors. In other words, setTimeout is used so that the program will let me know if it’s not working properly, as well as it will not be delayed by other js code that is executing on the page.

With this in place, these two code snippets can be tied together (with less than 10 extra lines of code) to create a basic video wrapper:

var undef;
var msDelay = 250;

var MediaElement = {
  load: function() {},
  play: function() {
    this.paused = 0;
    // So we can keep track of the instance
    timerTick.call( this );
  },
  pause: function() {
    this.paused = 1;
  },

  readyState: 0,
  currentTime: 0,
  duration: 0,
  paused: 1,
  ended: 0,
  volume: 1,
  muted: 0,
  playbackRate: 1,

  // These are considered to be "on" by being defined. Initialize to undefined
  autoplay: undef,
  loop: undef
};

function timerTick() {
  // The player was paused since the last time update
  if ( this.paused ) {
    return;
  }

  // So we can refer to the instance when setTimeout is run
  var self = this;

  // Run code here

  setTimeout( function() {
    timerTick.call( self );
  }, msDelay );
}

And just like that, you have a custom HTML5 “Video”. Check out a simple demo or view the source here.

Comments

Leave a Reply

Discover more from Software by Steven

Subscribe now to keep reading and get access to the full archive.

Continue reading