HTML5 Video player jQuery plugin

HTML5 Video player jQuery plugin

13 138750
HTML5 Video player jQuery plugin

HTML5 Video player jQuery plugin

As you know – HTML5 <video> element is already supported by most of browsers (by modern browsers). Its initialization is very easy. During today’s investigation I have understood few things: that each browser supports only few of video formats, and each browser has own native video controls (and all of them are different). But fortunately, html5 can give us all necessary possibilities to make own interface to control our video element. Today I will show you process of building own html5 player (quite crossbrowser), more, it will be new jquery plugin.

Final result of our player:

HTML5 Video player

Here are our demo and downloadable package:

Live Demo


download in package


Ok, download the source files and lets start coding !

Step 1. HTML Markup

This is markup of our result slideshow page. Here it is:


<div class="video_player">
    <video controls="controls" poster="media/poster.jpg" style="width:800px;">
        <source src="media/video.ogg" type="video/ogg" />
        <source src="media/video.mp4" type="video/mp4" />
        <source src="media/video.webm" type="video/webm" />
    <div class="custom_controls">
        <a class="play" title="Play"></a>
        <a class="pause" title="Pause"></a>
        <div class="time_slider"></div>
        <div class="timer">00:00</div>
        <div class="volume">
            <div class="volume_slider"></div>
            <a class="mute" title="Mute"></a>
            <a class="unmute" title="Unmute"></a>
    $(function() {

You can see here and our Video element, and the custom controls set. Plus – jquery plugin initialization. As you can see – I have to provide 3 file formats (ogg, mp4 and webm) to cover all browsers (FF, IE, Chrome, Safari and possible Opera too). As video converter software, I can recommend Miro Video Converter ( as example.

Step 2. CSS

Here are all stylesheets


/* jquery */
.ui-slider-handle {
    display: block;
    margin-left: -9px;
    position: absolute;
    z-index: 2;
.ui-slider-range {
    bottom: 0;
    display: block;
    height: 100%;
    left: 0;
    position: absolute;
    width: 100%;
    z-index: 1;
/* player */
.video_player {
    background-color: #E8E8E8;
    border: 1px solid #888;
    float: left;
    padding: 10px;
    border-radius: 10px;
    -moz-border-radius: 10px;
    -webkit-border-radius: 10px;
/* controls */
.video_player .custom_controls {
    clear: both;
    height: 30px;
    padding-top: 8px;
    position: relative;
    width: 100%;
.play, .pause, .volume, .time_slider, .timer {
    float: left;
.play, .pause, .mute, .unmute {
    cursor: pointer;
.play, .pause {
    display: block;
    height: 24px;
    margin-left: 5px;
    margin-right: 15px;
    opacity: 0.8;
    width: 33px;
    transition: all 0.2s ease-in-out;
    -moz-transition: all 0.2s ease-in-out;
    -webkit-transition: all 0.2s ease-in-out;
    -o-transition: all 0.2s ease-in-out;
.play {
    background: url(../images/play.png) no-repeat;
.pause {
    background: url(../images/pause.png) no-repeat;
    display: none;
.play:hover, .pause:hover {
    opacity: 1;
.time_slider {
    border: 1px solid #5f5f5f;
    height: 10px;
    margin-top: 5px;
    position: relative;
    width: 630px;
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    background: #777777;
    background-image: -moz-linear-gradient(top, #777777, #9d9d9d);
    background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #777777),color-stop(1, #9d9d9d));
.time_slider .ui-slider-handle {
    background: url(../images/handler.png) no-repeat;
    cursor: pointer;
    height: 16px;
    opacity: 0.8;
    top: -2px;
    width: 16px;
.time_slider .ui-slider-handle.ui-state-hover {
    opacity: 1;
.time_slider .ui-slider-range {
    border-radius: 5px;
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    background: #e9742e;
    background-image: -moz-linear-gradient(top, #e9742e, #c14901);
    background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #e9742e),color-stop(1, #c14901));
.timer {
    color: #000;
    font-size: 12px;
    margin-left: 10px;
    margin-top: 3px;
.volume {
    bottom: 0;
    color: #FFFFFF;
    height: 35px;
    overflow: hidden;
    padding: 5px 10px 0;
    position: absolute;
    right: 0;
    width: 33px;
.volume:hover {
    background: url(../images/volume.png) no-repeat scroll 8px 0 transparent;
    height: 161px;
.volume_slider {
    height: 105px;
    left: -1px;
    opacity: 0;
    position: relative;
    width: 33px;
.volume:hover .volume_slider {
    opacity: 1;
.volume_slider .ui-slider-handle {
    background: url(../images/handler.png) no-repeat;
    height: 15px;
    left: 9px;
    margin-bottom: -15px;
    margin-left: 0;
    opacity: 0.8;
    width: 14px;
.volume_slider .ui-slider-handle.ui-state-hover {
    opacity: 1;
.mute, .unmute {
    bottom: 7px;
    display: block;
    height: 23px;
    opacity: 0.8;
    position: absolute;
    text-indent: -999px;
    width: 33px;
.mute:hover, .unmute:hover {
    opacity: 1;
.mute {
    background: url(../images/vol_full.png) no-repeat;
.unmute {
    background: url(../images/vol_mute.png) no-repeat;
    display: none;

Step 3. JS


function rectime(secs) {
    var hr = Math.floor(secs / 3600);
    var min = Math.floor((secs - (hr * 3600))/60);
    var sec = Math.floor(secs - (hr * 3600) - (min * 60));
    if (hr < 10) {hr = '0' + hr; }
    if (min < 10) {min = '0' + min;}
    if (sec < 10) {sec = '0' + sec;}
    if (hr) {hr = '00';}
    return hr + ':' + min + ':' + sec;
(function($) {
    $.fn.myPlayer = function() {
        return this.each(function() {
            // variables
            var $oMain = $(this);
            var $oVideo = $('video', $oMain);
            var $oPlay = $('.play', $oMain);
            var $oPause = $('.pause', $oMain);
            var $oTimeSlider = $('.time_slider', $oMain);
            var $oTimer = $('.timer', $oMain);
            var $oVolSlider = $('.volume_slider', $oMain);
            var $oMute = $('.mute', $oMain);
            var $oUnmute = $('.unmute', $oMain);
            var bTimeSlide = false;
            var iVolume = 1;
            // functions section
            var prepareTimeSlider = function() {
                if (! $oVideo[0].readyState) {
                    setTimeout(prepareTimeSlider, 1000);
                } else {
                        value: 0,
                        step: 0.01,
                        orientation: 'horizontal',
                        range: 'min',
                        max: $oVideo[0].duration,
                        animate: true,
                        slide: function() {
                            bTimeSlide = true;
                        stop:function(e, ui) {
                            bTimeSlide = false;
                            $oVideo[0].currentTime = ui.value;
            // events section
            $ () {
                $oPause.css('display', 'block');
            $ () {
                $oPlay.css('display', 'block');
            $ () {
                $oVideo[0].muted = true;
                $oVolSlider.slider('value', '0');
                $oUnmute.css('display', 'block');
            $ () {
                $oVideo[0].muted = false;
                $oVolSlider.slider('value', iVolume);
                $oMute.css('display', 'block');
            // bind extra inner events
            $oVideo.bind('ended', function() {
                $oPlay.css('display', 'block');
            $oVideo.bind('timeupdate', function() {
                var iNow = $oVideo[0].currentTime;
                if (! bTimeSlide)
                    $oTimeSlider.slider('value', iNow);
            // rest initialization
                value: 1,
                orientation: 'vertical',
                range: 'min',
                max: 1,
                step: 0.02,
                animate: true,
                slide: function(e, ui) {
                    $oVideo[0].muted = false;
                    iVolume = ui.value;
                    $oVideo[0].volume = ui.value;

As you see – this is simple jQuery plugin. In the beginning – I have prepared all necessary controls and variables. Then – I have binded ‘onclick’ events to our controls, plus several inner events of video player (like ‘ended’ and ‘timeupdate’). After, I have implemented two jQueryUI sliders (time slider and volume slider). At the end – I have removed default controls: $oVideo.removeAttr(‘controls’); Generally – thats all.

Step 4. Images

For our html5 video player I have used next images:

play icon
pause icon
volume full icon
volume mute icon
volume icon
handler icon

Live Demo


Hope that today’s html5 tutorial was great. We have made another one nice html5 example. I will be glad to see your thanks and comments. Good luck!



  1. Wow, the game has changed with the announcement that Adobe is no longer supporting development for FLASH for mobile devices or TV…it is focusing on youtube html5 and Adobe AIR apps instead….the news got around the game development community quickly. I think the market penetration of mobile devices like the iPad, iPhone, and iTouch from Apple being a merket leader who doesn’t support FLASH made a true impression on developers whose clients pages were losing views by this audience. Comsider Apple’s leadership history introducing CD ROM’s fiirst in computers, dropping the beige look of computers, introucing the iMAc, iTunes, Quicktime, and Jobs support of Blu Ray at Disney helped set standards in many industries…

  2. Hey! This is once again a great tutorial as usual.
    Thanks a lot Andrew for your outstanding job here.

    But this time, I do have some issue with the video controls and the global aspect in Chome browser, here are the details:
    First, the custom controler with the nice buttons does not seem to work in any browser i have tested (Safari 5.1.7, Chrome 19 and Firefox 13.0). I have noticed that you’ve had in the package html file this notation:

    google.load(“jquery”, “1.7.1”);
    google.load(“jqueryui”, “1.8.16”);

    This, if i understand, should be the google/jQuery default controls (so these controls works fine anywhere). Do they actually take over the custom controllers?

    Second, i’m a bit confuse with this statement in the scrip.js file “At the end – I have removed default controls: $oVideo.removeAttr(‘controls’);” since in my case, the custom and the default controls showed in every browser. Is my problem with the controls is related with this line of code?

    Third, the layout is quite different in Chrome as the height of the video window is about twice taller than it should be. I have probably screwed up here, can you tell me where in the code i have missed or what should i add to it in order to fix Chrome behavior? I have tried naively to fix the height in the CSS but it just hided the bottom…

    You can take a look at the web page (I’ve have code commented the custom controls to hide them)
    You’ll also see one of your template slightly transformed and integrated all over my web site (Thanks again, links are still there as you can see).

    Hope you will be able to help me with this!

    • Hello Dominic my friend,
      As the first –
      google.load(“jquery”, “1.7.1?);
      google.load(“jqueryui”, “1.8.16?);
      this is not custom google controls. This is free google’s service to obtain jQuery libraries (of different version). So, this script doesn’t link custom controls at all, it loads jQuery library version 1.7.1 and jQuery UI version 1.8.16.
      I can recommend you to check your image: VanHoutte_still.jpg
      or, you can also define height of video player too. Please pay attention to our Video element. It has only Width value, you can try to add Height as well.
      My regards.

    • There is the one of params:
      Boolean : (Default: false) : Sets the initial state of the full screen mode.

  3. Caro colega, obrigado pelas informações que dispõem em seu site, fiz teste no IE e não funcionou. O player não aparece totalmente, os botões perdem a funcionalidade e o leiaute fica comprometido. Porem no google crome funcionou perfeitamente.
    Minha duvida é se existe a possibilidade de torna-lo útil em todos os navegadores? Pois se não for possível o sistema perde o objetivo.

    Dear Colleague, Thank you for the information you have on your site, I test in IE and it did not work. The player does not appear completely, the buttons lose functionality and layout is compromised. However google chrome worked perfectly.
    My doubt is whether it is possible to make it useful in all browsers? For if this is not possible the system loses the point. Sorry for my English is very poor.

    • Hi Sergio,
      Yes, indeed, it doesn’t work for IE, but it works in all other browsers. Anyway, nothing (I mean – styles) is distorted in IE (v10)

  4. Great tutorial. I have been looking for a simple html5 player.

    Tried to setup for fullscreen but never got it to work, but still learning html5 so that most likely the issue:)

    Also like to make the player “responsive” for smaller screens. You have any plans to do this in a tutorial or perhaps know of easy fix for this video player?

    Many thanks,


    • Hi Woody,
      In the beginning, I think that you should understand what is ‘responsive’ and what we usually need to do to make something responsive. Basically, we don’t need to define any certain sizes (in pixels) for page elements. Thus, you need just re-size our player to make it responsive. For instance, you can specify the size in percentage.

  5. Hi,
    Thx for tutorial.
    I want to set a ‘fullscreen’ button in .js file for player. But I have no idea how can I solve this issue?
    Please help me,

    • Hi Cavey85,
      First – you need to add this button (HTML+CSS), then you can use the following JS to bind the fullscreen function:
      $(‘.fscr’).click(function () {
      if ($oVideo.get(0).requestFullscreen) {
      } else if ($oVideo.get(0).msRequestFullscreen) {
      } else if ($oVideo.get(0).mozRequestFullScreen) {
      } else if ($oVideo.get(0).webkitRequestFullscreen) {

  6. If I try to load and play the video not from the controls, I get an exception in Jquery : cannot call methods on slider prior to initialization; attempted to call method ‘value’. I looked inside and saw that the event who causes it is: timeupdate.
    any idea what to do?

Leave a Reply