HTML 5 Video - Part 3: Media Events

We have already looked at how to build a HTML 5 player and how to add your own controls. This week, we will be looking at how you can do even more clever things using media events.

Media events are special functions that get fired automatically when certain events happen, for example, when the video is paused or when the video volume is changed. The benefit of this is that you do not need to write all of the logic in the button click event which would trigger one of these. Also, if you are using the player's built in controls, you wouldn't have button click events anyway, so this is an alternative place for logic.

There are dozens of potential events and countless complex things that you can do with them. This tutorial will only pick a few to add some basic functionality to get you started. You can read about all of the available events here.

As usual, all of the code from this tutorial will be available as a tag ('Part3') in the Github repository.

Revisiting Play/Pause

Last week, we programmed a play/pause button like so:

 var playing = false;
 $('#play').click(function(e){
     e.preventDefault();
     if (!playing) {
         player.play();
         $(this).html('Pause');
         playing = true;
     } else {
         player.pause();
         $(this).html('Play');
         playing = false;
     }
 });

As you can see, apart from playing and pausing the video, it also changes the text of the button and updates a variable to hold the playing state of the player. We can greatly simplify this using triggered events.

First, let's get rid of the variable that we do not need. The player has its own attribute that tells us if it is playing or not: player.paused.

 $('#play').click(function(e){
     e.preventDefault();
     if (player.paused) {
         player.play();
         $(this).html('Pause');
     } else {
         player.pause();
         $(this).html('Play');
     }
 });

Now we will remove the html modifiers to leave a much simpler function:

 $('#play').click(function(e){
     e.preventDefault();
     if (player.paused) {
         player.play();
     } else {
         player.pause();
     }
 });

So how will we change the button text?

There are two events we can use: play, which is triggered when a video starts playing and pause, which is triggered when a video is paused. Let's start with play:

player.onplay = function() {
    $('#play').html('Pause');
}

There are several ways of attaching listeners to the player. I have chosen this way for the tutorial. The rule of thumb is to add 'on' to the start of the event name and then assign it a function with your code.

As you can see in this case, the play button text is changed to 'Pause' each time the video is played. The benefit of this is that if I had other controls that triggered playback, then this code would still be triggered and I wouldn't have to keep implementing in each case.

Now the pause one is equally easy:

player.onpause = function() {
    $('#play').html('Play');
}

Exactly the same principals as before. So if you run all this code now, the play/pause buttons should appear to behave exactly the same as it did last week.

Loading Meta Data

One useful thing that I want to display, is the length of the video and how much has played.

To start, I have put some HTML to hold this information:

<p>Time: <span id="time">0:00</span>/<span id="duration">0:00</span></p>

There are 2 events that are useful for this. The first, is loadedmetadata. As you can tell from the name, this is fired after information about the video is loaded. Note: this is done after the load event and so this information is not available if you tried to get it onload.

player.onloadedmetadata = function() {
    $('#duration').html(player.duration);
}

Same as before: prepend the event with 'on' and I am just modifying the html in the function. The player.duration, as you would expect, has the total length of the video. This is in the format "seconds.milliseconds" - so you may want to format this time yourself to be more human readable.

Now we will use timeupdate (run each time the time changes) to update the HTML with currentTime:

player.ontimeupdate = function() {
    $('#time').html(player.currentTime);
}

Hopefully, you are getting it. The basics are very simple and once you have done one event you can work out how to do the rest.

Just one more example then.

Showing Volume

Pretty much the same as the example above. I have HTML to hold the current volume:

<p>Volume: <span id="volume"></span></p>

I populate this in loadmetadata to get the volume at that moment:

player.onloadedmetadata = function() {
    $('#duration').html(player.duration);
    $('#volume').html(player.volume);
}

And then I update it when I change the volume:

player.onvolumechange = function() {
    if (player.muted) {
       $('#volume').html(0);
    } else {
       $('#volume').html(player.volume);
    }
}

The only complex part here is the player's handling of muting. When the player is muted, the volume is not changed to 0 - it is just an attribute that is changed to either true or false. This is good because when you unmute, it will be the same volume as before. But it does mean that when I display the volume, I need to have a special case to show that it is muted.

Summary

What we have seen are some very basic and easy ways to use events to extend the functionality of your player. There are loads more events out there (again, the full list is here) that can all be used with the same template as above.

I think next week will be the final tutorial. We will bring back the player's built in controls and learn what CSS rules can be applied to it to make it fit your website better.


© 2012-2017