HTML5 Video player jQuery plugin

Date: 22nd Feb 2012 Author: admin 5 Comments
Posted in: HTML/CSS, HTML5, jQuery |Tags: , , ,

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:

index.html

<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" />
    </video>
    <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>
        </div>
    </div>
</div>
<script>
    $(function() {
        $('.video_player').myPlayer();
    });
</script>

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 (http://www.mirovideoconverter.com/) as example.

Step 2. CSS

Here are all stylesheets

css/player.css

/* 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

js/script.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 {
                    $oTimeSlider.slider({
                        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
            $oPlay.click(function () {
                $oVideo[0].play();
                $oPlay.hide();
                $oPause.css('display', 'block');
            });
            $oPause.click(function () {
                $oVideo[0].pause();
                $oPause.hide();
                $oPlay.css('display', 'block');
            });
            $oMute.click(function () {
                $oVideo[0].muted = true;
                $oVolSlider.slider('value', '0');
                $oMute.hide();
                $oUnmute.css('display', 'block');
            });
            $oUnmute.click(function () {
                $oVideo[0].muted = false;
                $oVolSlider.slider('value', iVolume);
                $oUnmute.hide();
                $oMute.css('display', 'block');
            });

            // bind extra inner events
            $oVideo.bind('ended', function() {
                $oVideo[0].pause();
                $oPause.hide();
                $oPlay.css('display', 'block');
            });
            $oVideo.bind('timeupdate', function() {
                var iNow = $oVideo[0].currentTime;
                $oTimer.text(rectime(iNow));
                if (! bTimeSlide)
                    $oTimeSlider.slider('value', iNow);
            });

            // rest initialization
            $oVolSlider.slider({
                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;
                }
            });
            prepareTimeSlider();
            $oVideo.removeAttr('controls');
        });
    };
})(jQuery);

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
download in package

Conclusion

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!

Enjoyed this Post?

    Tweet
   
   

Stay connected with us:

If you enjoyed this article, feel free to share our tutorial with your friends.

5 Comments

    • farook's Gravatar
    • 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…

    • Dominic Brown's Gravatar
    • Dominic BrownMay 29, 2012 7:08 pm

      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) http://dominicbrown.ca/dbVideos.html
      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!

    • criss's Gravatar

Leave a Reply

Your email address will not be published. Required fields are marked *

*

CAPTCHA Image
Refresh Image

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>