Look Inside
HTML5 video
element, one of the most popular features in HTML5. It is now already supported by most modern browsers, and even so for IE9. However, each browser provides native browser video controls. In order to have a consistent HTML5 video controls across all browsers, we have to integrate own custom HTML5 video controls rather than using default controls.
Actually, it is not hard to have custom HTML5 video controls. In this post I’m going to show you the way to build your own custom HTML5 video controls using jQuery. Hope you will find it useful!
HTML5 Video Element Basic Markup
Before we get started, let’s recall for HTML5 video basic markup.
<video id="myVideo" controls poster="video.jpg" width="600" height="400" > <source src="video.mp4" type="video/mp4" /> <source src="video.webm" type="video/webM" /> <source src="video.ogv" type="video/ogg" /> <p>Your browser does not support the video tag.</p> </video>
It is best practice to include three video formats – MP4, WebM, and Ogg as source elements in order to have your HTML5 video works cross browsers. It is also advisable to put some text as fallback inside video
element, in case user browser doesn’t support HTML5 video. Of course, you might use Flash as fallback as well!
If you having problem to encode your video to the HTML5 formats mentioned above, try Miro Converter, it support for both Window and Mac.
Get Started with Custom HTML5 Video Controls
Luckily, HTML5 media elements (audio and video) support for media elements API, which we can access using JavaScript and use them to wire up our HTML5 video controls.
Before get started with coding, let me briefly explain about jQuery video
element targeting.
In JavaScript we use getElementById('videoID')
to target the video
element. As result, we will get a DOM object. However, this is not equivalent to jQuery $('#videoID')
targeting which will return a jQuery object, not a DOM object. That’s why we can’t directly using jQuery selector to call/use HTML5 video DOM attributes and functions before convert it to DOM object.
//return a DOM object var video = document.getElementById('videoID'); //or var video = $('#videoID').get(0); //or var video = $('#videoID')[0]; //return a jQuery object var video = $('#videoID');
Video Play/Pause Controls
OK, that’s all for introduction. Let’s start the coding right now. First, we’ll create a simple Play/Pause control over our video.
<div class="control"> <a href="#" class="btnPlay">Play/Pause</a> </div>
We can easily control video status using HTML5 video DOM functions, which are .play()
and .pause()
.
//Play/Pause control clicked $('.btnPlay').on('click', function() { if(video[0].paused) { video[0].play(); } else { video[0].pause(); } return false; };
Display Video Current Playback Time and Duration
HTML5 video also support for video playback. Hereby we are going to display video current playback time and duration.
<div class="progressTime"> Current play time: <span class="current"></span> Video duration: <span class="duration"></span> </div>
In order to get HTML5 video duration, we have to make sure the video metadata is loaded. We could easily detect it using HTML5 video loadedmetadata
event.
As for current video playback time, we can use HTML5 video timeupdate
events to keep tracks of it.
//get HTML5 video time duration video.on('loadedmetadata', function() { $('.duration').text(video[0].duration); }); //update HTML5 video current play time video.on('timeupdate', function() { $('.current').text(video[0].currentTime); });
Video Progress Bar
Since we are able to get video current playback time and video duration, why not convert these data into great looking video progress bar?
<style> .progressBar { position: relative; width: 100%; height: height:10px; backgroud-color: #000; } .timeBar { position: absolute; top: 0; left: 0; width: 0; height: 100%; background-color: #ccc; } </style> <div class="progressBar"> <div class="timeBar"></div> </div>
Below shown the formula for conversion of video duration and video current playback time into progress bar with help of JavaScript.
//get HTML5 video time duration video.on('loadedmetadata', function() { $('.duration').text(video[0].duration)); }); //update HTML5 video current play time video.on('timeupdate', function() { var currentPos = video[0].currentTime; //Get currenttime var maxduration = video[0].duration; //Get video duration var percentage = 100 * currentPos / maxduration; //in % $('.timeBar').css('width', percentage+'%'); });
Done!!? Not yet! We have to make this progress bar seekable and dragable. In this case, we have to use mousedown
, mouseup
and mousemove
listeners and bind them to progress bar. Of couse, if you want, you might replace it with slider as well!
var timeDrag = false; /* Drag status */ $('.progressBar').mousedown(function(e) { timeDrag = true; updatebar(e.pageX); }); $(document).mouseup(function(e) { if(timeDrag) { timeDrag = false; updatebar(e.pageX); } }); $(document).mousemove(function(e) { if(timeDrag) { updatebar(e.pageX); } }); //update Progress Bar control var updatebar = function(x) { var progress = $('.progressBar'); var maxduration = video[0].duration; //Video duraiton var position = x - progress.offset().left; //Click pos var percentage = 100 * position / progress.width(); //Check within range if(percentage > 100) { percentage = 100; } if(percentage < 0) { percentage = 0; } //Update progress bar and video currenttime $('.timeBar').css('width', percentage+'%'); video[0].currentTime = maxduration * percentage / 100; };
Done!
Showing Buffering Bar
Yet, we can have a buffering bar for our HTML5 video. HTML5 video progress
event will be fired when user browser loads data. It will come in handy in order to create video buffering bar. However, latest Chrome seems to have bug with progress
event. Therefore, we will replace it with JavaScript setTimeout()
function.
<style> .progressBar { position: relative; width: 100%; height: height:10px; backgroud-color: #000; } .bufferBar { position: absolute; top: 0; left: 0; width: 0; height: 100%; background-color: #ccc; } </style> <div class="progressBar"> <div class="bufferBar"></div> </div>
HTML5 video buffered
attributes will return an object of ranges which are already buffered. Hence, we will use the last value of buffered data.
//loop to get HTML5 video buffered data var startBuffer = function() { var maxduration = video[0].duration; var currentBuffer = video[0].buffered.end(0); var percentage = 100 * currentBuffer / maxduration; $('.bufferBar').css('width', percentage+'%'); if(currentBuffer < maxduration) { setTimeout(startBuffer, 500); } }; setTimeout(startBuffer, 500);
Volume Controls for Video
Now, we will include volume controls to our video as well. There are two different volume controls will be added, which are mute button control and volume bar control.
<a href="#" class="muted" >Mute/Unmute</a> <div class="volumeBar"> <div class="volume"></div> </div>
Here, we will change the video’s volume and volume bar’s width when user click on the volume bar control. And mute the video when mute control clicked. Well, you might make your volume bar dragable also!
//Mute/Unmute control clicked $('.muted').click(function() { video[0].muted = !video[0].muted; return false; }); //Volume control clicked $('.volumeBar').on('mousedown', function(e) { var position = e.pageX - volume.offset().left; var percentage = 100 * position / volume.width(); $('.volumeBar').css('width', percentage+'%'); video[0].volume = percentage / 100; });
Fast Forward, Slow Motion, and Rewind Controls
Yes, HTML5 video supports change of playback speed. We can change the video playback speed by changing the video playbackrate
attribute.
<div class="control"> <a href="#" class="ff">Fast Forward</a> <a href="#" class="rw">Rewind</a> <a href="#" class="sl">Slow Motion</a> </div>
Unfortunately, Firefox doesn’t support for playbackrate
attribute yet. But partly for Chrome (doesn’t support negative value, which is rewind). So far only Safari fully supported.
//Fast forward control $('.ff').on('click', function() { video[0].playbackrate = 3; return false; }); //Rewind control $('.rw').on('click', function() { video[0].playbackrate = -3; return false; }); //Slow motion control $('.sl').on('click', function() { video[0].playbackrate = 0.5; return false; });
What’s More in HTML5 Video?
What’s more? HTML5 video have lots more of events and attributes which can be used to control video playback. I would not cover all but useful HTML5 video events here. Still, you can check out the HTML5 video DOM attributes and events list.
HTML5 video ended
Event
– Event fired when video has ended.
HTML5 video canplay
Event
– Event fired when video can be played, but the buffering process still ongoing.
HTML5 video canplaythrough
Event
– Event fired when whole video can be played.
HTML5 video seeking
Event
– Event fired when browser seeks for a position of video.
HTML5 video waiting
Event
– Event fired when waiting for more data to play the video.
What Else?
What else? Other than main controls, you could have some extra controls over your video. In below are some extra cool controls which can be added to your video as well.
First, a fullscreen control for video.
$('.fullscreen').on('click', function() { //For Webkit video[0].webkitEnterFullscreen(); //For Firefox video[0].mozRequestFullScreen(); return false; });
Next will be light off/on control.
$('.btnLight').click(function() { if($(this).hasClass('on')) { $(this).removeClass('on'); $('body').append('<div class="overlay"></div>'); $('.overlay').css({ 'position':'absolute', 'width':100+'%', 'height':$(document).height(), 'background':'#000', 'opacity':0.9, 'top':0, 'left':0, 'z-index':999 }); $('#myVideo').css({ 'z-index':1000 }); } else { $(this).addClass('on'); $('.overlay').remove(); } return false; });
Your Turn!
It is your turn now! You could have more controls such as video expandable control, HD video control, and etc. Since the possibility is infinity with jQuery. Just to be creative. =)
If you feel lazy to create custom video controls, still you can get existing jQuery plugins for HTML5 video to do the rest for you!