Subscribe by Email

In today’s multimedia web it’s becoming an ever increasing part of web design to include videos. Customizing the video player is one of the first things web designers think about when implementing these elements, as often the default player does not match the website, or merely for consistency across browsers and devices. In this tutorial we’re going to be going through exactly how to do that.

The Media Element API

The media element API is a simple API that allows you to manipulate videos with simple Javascript commands. For example, normally when using the HTML5 video tags we type something like this:

We have set controls in the video tag so this particular video will have controls (play, pause, etc). This is all well and good but sometimes we want to control the video with another (custom) player, or maybe we just want a link that makes the video play. To do this we use the Media Elements API. For example, lets say we have something like this:

<a href="#" class="play">Click me to play the video!</a>

Using the Media Elements API with jQuery we can write something as simple as this to make the video play:

$('#our-video')[0].play();

We’re using [0] here so we target a specific element (in the same way that document.getElementById() works!)

Easy, huh? Well it’s also possible to control a variety of video aspects with the media elements API, and you can create some pretty interesting things.

Functions

There are a bunch of features as part of the media elements API which can be used to control a video or how it is displayed. Here’s a bunch of things which become useful when creating a custom player:

Using these simple functions and a few other tricks we’re going to combine all this to make a custom video player which you can change with just CSS.

Lets Get Started

First of all lets accustom ourselves with the HTML5 video tag. To create a new video element we just use the video tag. It’s best to use multiple video types since not all videos are supported by all browsers. Using just .webm and .mp4 will cover mostly every video type though. Miro provides a simple method to convert files to .webm.

The CSS

CSS is what we’re going to use to style the video. This opens up a lot of possibilities since CSS is very easy to use, and changing the style of your video, therefore, becomes very easy. For this particular video style this is the CSS I’m going to be using, so go ahead and put it in your CSS file:

jQuery

The easiest and most succinct way to go about doing this is to use jQuery and design our code as a plugin. Don’t forget to include the jQuery file! As with all jQuery plugins, make a new Javascript file and paste in the following:

I’ve added a few customizable options (when you run this plugin you’ll be able to change the options to whatever you want). These include the width of the player for styling purposes (by default 0.95 or95%) and the video class (in case you need to change it because of clashes). All of our code is going to go inside the return this.each(function() { }); brackets.

Now the first thing we want to do is check that the video meta data is ready to run. In some cases this will take a moment to load, so if we don’t check this we’ll end up loading the video player without any data (that wouldn’t work!). We’re also going to set some basic variables, the purpose of which will become more apparent later on.

Next lets start defining some functions. The first function we’re going to define is for buffering, so the user can see what sections of the video is buffered. The second is for time setting, so the time will increase correctly. The timing function is going to be run every time the current time is updated. I’ve commented in the code so you can see exactly what is happening.

Next the play button! We’re going to add and remove CSS classes to make the play change to a pause button when clicked. We’ll also set a variable to check if the video is playing, which we will use later in the code:

One of the most complicated parts of this code is the progress slider. First off we need to check when the user clicks on the progress bar and then set a variable telling us that’s what’s happening. Then when the user moves the mouse we’ll be able to adjust it so it slides appropriately. We’re going to use the same process for the volume slider, so I’ve included it here too, as well as an animation function for the volume icon, as well as a way to check if the user is hovering over the volume icon using the jQuery hover() function.

Next we have to do the actual mouse moving event. There are a bunch of things that depend on mouse move so the function is quite long. For instance, if the user is dragging the mouse while holding the progress bar, the progress bar should slide. Similarly, so should the volume bar. On top of that, if the user is moving the mouse and the video is already playing, the player should disappear so it isn’t a distraction to the actual video. I’ve included the entire function below, commented so you can see what’s going on. I’ve also included a function that fixes a few problems with the play and pause button, so the correct icon is always displaying.

Next is a little function that checks if the user is clicking their mouse down onto the volume icon, and if so, whether to mute the video or not. We use our stored volume so we can set the volume to the previous volume should the user unmute the video.

Next, a quick little function that resets everything when the user lets go of the mouse button:

// If the user lets go of the mouse, clicking is false for both volume and progress.
// Also the video will begin playing if it was playing before the drag process began.
// We're also running the bufferLength function
$('body, html').bind('mouseup', function(e) {
$mclicking = false;
$vclicking = false;
$draggingProgress = false;
if($playing == true) {
$spc.play();
}
bufferLength();
});

Finally we’re going to add a button that allows us to enable fullscreen mode. If the browser doesn’t support fullscreen the button will not be displayed, otherwise we just request it for every browser until one works.

Fullscreen is not supported by every browser. In the below example the fullscreen icon will not appear if the browser doesn’t support it.

And that’s it! Now it’s pretty simple to add more features to your video player via jQuery, or just change the general style of it with CSS. These features are widely supported in most browsers with the exception of fullscreen, but that will change with time. Thanks for reading and have a good day!

I have a complicated implementation of MediaElements.js I was hoping to get some feedback on.

I’m building a media heavy web app which will utilize both audio and video.

The app will have a persistent audio player in a bar at the top of the page. What I’d like to be able to do is dynamically control play, pause, etc for both the audio player and the videos so that when one is started all others stop.

E.G. User is listening to music streaming in bar. User plays a video on the site. This triggers audio in bar to pause playing.

I’d love any feedback or to even discuss contracting you for this job if you’d find it stimulating.

wow. thank you. really awesome :) I have implemented this script sucessfully to my project and everything works fine except that the video begins stuttering after a couple of minutes because they are to many buffer regions created. …

i don’t know why but if I drag the progress button to a new position the buffer buffers correct at the right point but the old buffer region also stays there.

do you know how to fix this?
i’m trying this since many hours but no success :/

i mean this region here:

var bufferLength = function() {

// The buffered regions of the video
var buffered = $spc.buffered;

// Rest all buffered regions everytime this function is run #### does not work and old regions are present the whole time.
$that.find(‘[class^=buffered]‘).remove();

This was the biggest issue I faced when coding it. You can fix this (sort of) by only showing the last loaded buffer area, rather than all buffered regions (I think you can do this by removing the while loop), but I felt that this wasn’t accurate enough and decided to show all buffered regions for this version of the code. The buffer regions do join up so unless you’re loading a lot of sections of the video separately you should only have 1 or 2 buffer areas.

After hours of Trying i finally got it. My problem with stuttering video is solved and now i have one buffer bar which has dynamic width to current buffer progress.

But the problem is the buffered.lenght Range. On Safari it is no problem to get latest range and bind it to the progress. same method doesn’t work an Chrome, Firefox and Opera. Here is my current code. Fell free to add it to yours. Maybe you find a way that this will work on all Browser. We all know that this is possible because Flowplayer and many others also has multiregional Buffering.

hi.your controls is good.but i want to autoplay the video when page is loaded.i added autoplay to video tag but it is not working.
i actually want to pause the video,when i click some other element in the page.

Hey there,
I am so thankfull for this tut. Torrow I’ll go try out Yeah! At the moment I am working an a wp theme so it would be interesting how to hook up the custom Player with it. Do you have any idea?
Regards

1. How do I do, so that the volume is horizontal instead of vertical?
2. The ttime is not displayed correctly
3. How do I add another zero to the time, so it will be displayed like this: 01:00 instead of: 1:00?