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:
Here are our demo and downloadable package:
Live Demo
[sociallocker]
download in package
[/sociallocker]
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
01 |
< div class = "video_player" > |
02 |
< video controls = "controls" poster = "media/poster.jpg" style = "width:800px;" > |
03 |
< source src = "media/video.ogg" type = "video/ogg" /> |
04 |
< source src = "media/video.mp4" type = "video/mp4" /> |
05 |
< source src = "media/video.webm" type = "video/webm" /> |
06 |
</ video > |
07 |
< div class = "custom_controls" > |
08 |
< a class = "play" title = "Play" ></ a > |
09 |
< a class = "pause" title = "Pause" ></ a > |
10 |
< div class = "time_slider" ></ div > |
11 |
< div class = "timer" >00:00</ div > |
12 |
< div class = "volume" > |
13 |
< div class = "volume_slider" ></ div > |
14 |
< a class = "mute" title = "Mute" ></ a > |
15 |
< a class = "unmute" title = "Unmute" ></ a > |
16 |
</ div > |
17 |
</ div > |
18 |
</ div > |
19 |
< script > |
20 |
$(function() { |
21 |
$('.video_player').myPlayer(); |
22 |
}); |
23 |
</ 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
001 |
/* jquery */ |
002 |
.ui-slider-handle { |
003 |
display : block ; |
004 |
margin-left : -9px ; |
005 |
position : absolute ; |
006 |
z-index : 2 ; |
007 |
} |
008 |
.ui-slider-range { |
009 |
bottom : 0 ; |
010 |
display : block ; |
011 |
height : 100% ; |
012 |
left : 0 ; |
013 |
position : absolute ; |
014 |
width : 100% ; |
015 |
z-index : 1 ; |
016 |
} |
017 |
/* player */ |
018 |
.video_player { |
019 |
background-color : #E8E8E8 ; |
020 |
border : 1px solid #888 ; |
021 |
float : left ; |
022 |
padding : 10px ; |
023 |
border-radius: 10px ; |
024 |
-moz-border-radius: 10px ; |
025 |
-webkit-border-radius: 10px ; |
026 |
} |
027 |
/* controls */ |
028 |
.video_player .custom_controls { |
029 |
clear : both ; |
030 |
height : 30px ; |
031 |
padding-top : 8px ; |
032 |
position : relative ; |
033 |
width : 100% ; |
034 |
} |
035 |
.play, .pause, .volume, .time_slider, .timer { |
036 |
float : left ; |
037 |
} |
038 |
.play, .pause, .mute, .unmute { |
039 |
cursor : pointer ; |
040 |
} |
041 |
.play, .pause { |
042 |
display : block ; |
043 |
height : 24px ; |
044 |
margin-left : 5px ; |
045 |
margin-right : 15px ; |
046 |
opacity: 0.8 ; |
047 |
width : 33px ; |
048 |
transition: all 0.2 s ease-in-out; |
049 |
-moz-transition: all 0.2 s ease-in-out; |
050 |
-webkit-transition: all 0.2 s ease-in-out; |
051 |
-o-transition: all 0.2 s ease-in-out; |
052 |
} |
053 |
.play { |
054 |
background : url (../images/play.png) no-repeat ; |
055 |
} |
056 |
.pause { |
057 |
background : url (../images/pause.png) no-repeat ; |
058 |
display : none ; |
059 |
} |
060 |
.play:hover, . pause :hover { |
061 |
opacity: 1 ; |
062 |
} |
063 |
.time_slider { |
064 |
border : 1px solid #5f5f5f ; |
065 |
height : 10px ; |
066 |
margin-top : 5px ; |
067 |
position : relative ; |
068 |
width : 630px ; |
069 |
border-radius: 5px ; |
070 |
-moz-border-radius: 5px ; |
071 |
-webkit-border-radius: 5px ; |
072 |
background : #777777 ; |
073 |
background-image : -moz-linear-gradient( top , #777777 , #9d9d9d ); |
074 |
background-image : -webkit-gradient(linear, left top , left bottom ,color-stop( 0 , #777777 ),color-stop( 1 , #9d9d9d )); |
075 |
} |
076 |
.time_slider .ui-slider-handle { |
077 |
background : url (../images/handler.png) no-repeat ; |
078 |
cursor : pointer ; |
079 |
height : 16px ; |
080 |
opacity: 0.8 ; |
081 |
top : -2px ; |
082 |
width : 16px ; |
083 |
} |
084 |
.time_slider .ui-slider-handle.ui-state-hover { |
085 |
opacity: 1 ; |
086 |
} |
087 |
.time_slider .ui-slider-range { |
088 |
border-radius: 5px ; |
089 |
-moz-border-radius: 5px ; |
090 |
-webkit-border-radius: 5px ; |
091 |
background : #e9742e ; |
092 |
background-image : -moz-linear-gradient( top , #e9742e , #c14901 ); |
093 |
background-image : -webkit-gradient(linear, left top , left bottom ,color-stop( 0 , #e9742e ),color-stop( 1 , #c14901 )); |
094 |
} |
095 |
.timer { |
096 |
color : #000 ; |
097 |
font-size : 12px ; |
098 |
margin-left : 10px ; |
099 |
margin-top : 3px ; |
100 |
} |
101 |
.volume { |
102 |
bottom : 0 ; |
103 |
color : #FFFFFF ; |
104 |
height : 35px ; |
105 |
overflow : hidden ; |
106 |
padding : 5px 10px 0 ; |
107 |
position : absolute ; |
108 |
right : 0 ; |
109 |
width : 33px ; |
110 |
} |
111 |
. volume :hover { |
112 |
background : url (../images/volume.png) no-repeat scroll 8px 0 transparent ; |
113 |
height : 161px ; |
114 |
} |
115 |
.volume_slider { |
116 |
height : 105px ; |
117 |
left : -1px ; |
118 |
opacity: 0 ; |
119 |
position : relative ; |
120 |
width : 33px ; |
121 |
} |
122 |
. volume :hover .volume_slider { |
123 |
opacity: 1 ; |
124 |
} |
125 |
.volume_slider .ui-slider-handle { |
126 |
background : url (../images/handler.png) no-repeat ; |
127 |
height : 15px ; |
128 |
left : 9px ; |
129 |
margin-bottom : -15px ; |
130 |
margin-left : 0 ; |
131 |
opacity: 0.8 ; |
132 |
width : 14px ; |
133 |
} |
134 |
.volume_slider .ui-slider-handle.ui-state-hover { |
135 |
opacity: 1 ; |
136 |
} |
137 |
.mute, .unmute { |
138 |
bottom : 7px ; |
139 |
display : block ; |
140 |
height : 23px ; |
141 |
opacity: 0.8 ; |
142 |
position : absolute ; |
143 |
text-indent : -999px ; |
144 |
width : 33px ; |
145 |
} |
146 |
.mute:hover, .unmute:hover { |
147 |
opacity: 1 ; |
148 |
} |
149 |
.mute { |
150 |
background : url (../images/vol_full.png) no-repeat ; |
151 |
} |
152 |
.unmute { |
153 |
background : url (../images/vol_mute.png) no-repeat ; |
154 |
display : none ; |
155 |
} |
Step 3. JS
js/script.js
001 |
function rectime(secs) { |
002 |
var hr = Math.floor(secs / 3600); |
003 |
var min = Math.floor((secs - (hr * 3600))/60); |
004 |
var sec = Math.floor(secs - (hr * 3600) - (min * 60)); |
005 |
if (hr < 10) {hr = '0' + hr; } |
006 |
if (min < 10) {min = '0' + min;} |
007 |
if (sec < 10) {sec = '0' + sec;} |
008 |
if (hr) {hr = '00' ;} |
009 |
return hr + ':' + min + ':' + sec; |
010 |
} |
011 |
( function ($) { |
012 |
$.fn.myPlayer = function () { |
013 |
return this .each( function () { |
014 |
// variables |
015 |
var $oMain = $( this ); |
016 |
var $oVideo = $( 'video' , $oMain); |
017 |
var $oPlay = $( '.play' , $oMain); |
018 |
var $oPause = $( '.pause' , $oMain); |
019 |
var $oTimeSlider = $( '.time_slider' , $oMain); |
020 |
var $oTimer = $( '.timer' , $oMain); |
021 |
var $oVolSlider = $( '.volume_slider' , $oMain); |
022 |
var $oMute = $( '.mute' , $oMain); |
023 |
var $oUnmute = $( '.unmute' , $oMain); |
024 |
var bTimeSlide = false ; |
025 |
var iVolume = 1; |
026 |
// functions section |
027 |
var prepareTimeSlider = function () { |
028 |
if (! $oVideo[0].readyState) { |
029 |
setTimeout(prepareTimeSlider, 1000); |
030 |
} else { |
031 |
$oTimeSlider.slider({ |
032 |
value: 0, |
033 |
step: 0.01, |
034 |
orientation: 'horizontal' , |
035 |
range: 'min' , |
036 |
max: $oVideo[0].duration, |
037 |
animate: true , |
038 |
slide: function () { |
039 |
bTimeSlide = true ; |
040 |
}, |
041 |
stop: function (e, ui) { |
042 |
bTimeSlide = false ; |
043 |
$oVideo[0].currentTime = ui.value; |
044 |
} |
045 |
}); |
046 |
}; |
047 |
}; |
048 |
// events section |
049 |
$oPlay.click( function () { |
050 |
$oVideo[0].play(); |
051 |
$oPlay.hide(); |
052 |
$oPause.css( 'display' , 'block' ); |
053 |
}); |
054 |
$oPause.click( function () { |
055 |
$oVideo[0].pause(); |
056 |
$oPause.hide(); |
057 |
$oPlay.css( 'display' , 'block' ); |
058 |
}); |
059 |
$oMute.click( function () { |
060 |
$oVideo[0].muted = true ; |
061 |
$oVolSlider.slider( 'value' , '0' ); |
062 |
$oMute.hide(); |
063 |
$oUnmute.css( 'display' , 'block' ); |
064 |
}); |
065 |
$oUnmute.click( function () { |
066 |
$oVideo[0].muted = false ; |
067 |
$oVolSlider.slider( 'value' , iVolume); |
068 |
$oUnmute.hide(); |
069 |
$oMute.css( 'display' , 'block' ); |
070 |
}); |
071 |
// bind extra inner events |
072 |
$oVideo.bind( 'ended' , function () { |
073 |
$oVideo[0].pause(); |
074 |
$oPause.hide(); |
075 |
$oPlay.css( 'display' , 'block' ); |
076 |
}); |
077 |
$oVideo.bind( 'timeupdate' , function () { |
078 |
var iNow = $oVideo[0].currentTime; |
079 |
$oTimer.text(rectime(iNow)); |
080 |
if (! bTimeSlide) |
081 |
$oTimeSlider.slider( 'value' , iNow); |
082 |
}); |
083 |
// rest initialization |
084 |
$oVolSlider.slider({ |
085 |
value: 1, |
086 |
orientation: 'vertical' , |
087 |
range: 'min' , |
088 |
max: 1, |
089 |
step: 0.02, |
090 |
animate: true , |
091 |
slide: function (e, ui) { |
092 |
$oVideo[0].muted = false ; |
093 |
iVolume = ui.value; |
094 |
$oVideo[0].volume = ui.value; |
095 |
} |
096 |
}); |
097 |
prepareTimeSlider(); |
098 |
$oVideo.removeAttr( 'controls' ); |
099 |
}); |
100 |
}; |
101 |
})(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:
Live Demo
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!