在前面几篇文章中介绍了HTML5的特点和需要掌握的基础知识,下面我们开始真正的体验一下HTML5的优势,我们开始制作一个漂亮的视频播放器吧先别急,在开始制作之前先了解一下视频文件的基本知识。
一、视频的格式
目前比较主流和使用比较的的视频格式主要有:avi、rmvb、wmv、mpeg4、ogg、webm。这些视频都是由视频、音频、编码格式三部分组成的。在HTML5中,根据浏览器的不同,目前拥有多套不同的编码器:
H.264(个人不看好):这个编码器是苹果系统包括苹果手机中的编码 器,拥有专利的视频编码器。在编码及传输过程中的任何部分都可能需要收取专利费。因此Safari(苹果的浏览器)和Intenet Explorer支持该编码器,但是在开源已经成为大势的当下,还在浏览器中收取专利费,个人实在是不看好啊。
Theora:这是一个不受专利限制的编码格式,并且对所有等级的编码、传输以及回放免费的视频编码器。Chrome、Firefox以及Opera支持该编码器。
VP8:该视频编码器与Theora相似,但是其拥有者是Google公司,Google公司已经开源,因此不需要专利费。Chrome、Firefox以及Opera支持该编码器。
AAC:音频编码器,与H.264相同,该音频编码器拥有专利限制,Safari、Chrome和Internet Explorer支持该音频编码器。
MP3:也是一个专利技术,Safari、Chrome和Internet Explorer支持该音频编码器。
PCM:存储由模拟数字转换器编码的完整数据,在音频CD上存储数据的一种格式。是以中国无损编码器,它的文件大小一般是AAC和MP3文件的几倍,Safari、Firefox和Internet Explorer支持该音频编码器。
Vorbis:文件扩展名为.ogg,有时候也被称为Ogg Vorbis,该音频编码器不受专利保护,因此版权免费。支持的浏览器包括Chrome、Firefox和Opera.
主流浏览器和设备支持的视频和音频
浏览器 |
容器 |
视频 |
音频 |
Apple ios |
MP4 |
H.264 |
ACC、MP3、PCM |
Apple Safari |
MP4 |
H.264 |
|
Google Android(pre v.3) |
-- |
-- |
-- |
Google Chrome |
MP4、OGG、WebM |
Theora、VP8 |
ACC、MP3、Vorbis |
Microsoft Internet Explorer |
MP4 |
H.264 |
ACC、MP3 |
Mozilla Firefox |
OGG、WebM |
Theora、VP8 |
PCM、Vorbis |
Opera |
OGG、WebM |
Theora、VP8 |
PCM、Vorbis |
二、HTML5中的<vido>属性
在html5中可以使用<audio>或者<video>标签播放html5媒体,使用方式如下:
00001. <video src="move.mp4"></video>
video标签中有很多属性,例如controls属性可以控制是否有控制台。
00001. <video src="move.mp4" controls="controls">
00002. 浏览器不支持HTML5的视频播放功能
00003. </video>
从上面的视频格式中我们可以看到不同的浏览器支持不同的视频格式,这样我们可以采用<source>标签指定多种格式的视频,默认情况下浏览器会自动启动下载文件来确定其类型。
00001. <video width="400" controls="controls">
00002. <source src="move.mp4" type="video/mp4" />
00003. <source src="move.ogg" type="video/ogg" />
00004. </video>
三、制作视频播放器
index.html
00001. <!DOCTYPE html>
00002. <html>
00003. <head>
00004. <title>Demo 1 | Custom HTML5 Video Controls with jQuery</title>
00005. <link rel="stylesheet" href="../vendorstyle.css" />
00006. <link rel="stylesheet" href="style.css" />
00007. <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
00008. <!--[if lt IE 9]>
00009. <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
00010. <![endif]-->
00011. <script src="../vendorscript.js"></script>
00012. <script src="video.js"></script>
00013. <!--[if lt IE 9]>
00014. <script>
00015. $(document).ready(function() {
00016. $('.control').hide();
00017. $('.loading').fadeOut(500);
00018. $('.caption').fadeOut(500);
00019. });
00020. </script>
00021. <![endif]-->
00022. <link rel="shortcut icon" href="http://www.inwebson.com/wp-content/themes/inwebson/favicon.ico" />
00023. </head>
00024.
00025. <body>
00026. <!-- Header -->
00027. <header>
00028. <h1>Custom HTML5 Video Controls with jQuery</h1>
00029. <div id="backlinks">
00030. <a href="http://www.inwebson.com/custom-html5-video-controls-with-jquery-and-css/">BACK TO ARTICLE »</a>
00031. <a href="http://www.inwebson.com">Visit inWebson.com »</a>
00032. </div>
00033. <div class="clearfix"></div>
00034. </header>
00035.
00036. <!-- Content -->
00037. <section id="wrapper">
00038.
00039. <!-- Title -->
00040. <h2>Demo 1</h2>
00041. <h3>Custom HTML5 Video Controls</h3>
00042.
00043. <div class="videoContainer">
00044.
00045. <video id="myVideo" controls preload="auto" poster="poster.jpg" width="600" height="350" >
00046. <source src="http://demo.inwebson.com/html5-video/iceage4.mp4" type="video/mp4" />
00047. <source src="http://demo.inwebson.com/html5-video/iceage4.webm" type="video/webM" />
00048. <source src="http://demo.inwebson.com/html5-video/iceage4.ogv" type="video/ogg" />
00049. <p>Your browser does not support the video tag.</p>
00050. </video>
00051. <div class="caption">This is HTML5 video with custom controls</div>
00052. <div class="control">
00053.
00054. <div class="topControl">
00055. <div class="progress">
00056. <span class="bufferBar"></span>
00057. <span class="timeBar"></span>
00058. </div>
00059. <div class="time">
00060. <span class="current"></span> /
00061. <span class="duration"></span>
00062. </div>
00063. </div>
00064.
00065. <div class="btmControl">
00066. <div class="btnPlay btn" title="Play/Pause video"></div>
00067. <div class="btnStop btn" title="Stop video"></div>
00068. <div class="spdText btn">Speed: </div>
00069. <div class="btnx1 btn text selected" title="Normal speed">x1</div>
00070. <div class="btnx3 btn text" title="Fast forward x3">x3</div>
00071. <div class="btnFS btn" title="Switch to full screen"></div>
00072. <div class="btnLight lighton btn" title="Turn on/off light"></div>
00073. <div class="volume" title="Set volume">
00074. <span class="volumeBar"></span>
00075. </div>
00076. <div class="sound sound2 btn" title="Mute/Unmute sound"></div>
00077. </div>
00078.
00079. </div>
00080. <div class="loading"></div>
00081. </div>
00082.
00083. <!-- Navigation -->
00084. <nav id="navigation">
00085. <ul>
00086. <li class="currentbtn"><a href="#" title="Demo 1">DEMO 1</a></li>
00087. <li><a href="../demo2/" title="Demo 2">DEMO 2</a></li>
00088. </ul>
00089. <div class="clearfix"></div>
00090. </nav>
00091. </section>
00092.
00093. <!-- Footer -->
00094. <footer>
00095. <span>© 2011 <a href="http://www.inwebson.com">inWebson.com</a>. Design by <a href="http://www.inwebson.com/contactus">Kenny Ooi</a>. Powered by <a href="http://www.inwebson.com/html5/">HTML5</a> and <a href="http://www.inwebson.com/jquery/">jQuery</a>.</span>
00096. </footer>
00097. </body>
00098. </html>
style.css
00001. /* video container */
00002. .videoContainer{
00003. width:600px;
00004. height:350px;
00005. position:relative;
00006. overflow:hidden;
00007. background:#000;
00008. color:#ccc;
00009. }
00010.
00011. /* video caption css */
00012. .caption{
00013. display:none;
00014. position:absolute;
00015. top:0;
00016. left:0;
00017. width:100%;
00018. padding:10px;
00019. color:#ccc;
00020. font-size:20px;
00021. font-weight:bold;
00022. box-sizing: border-box;
00023. -ms-box-sizing: border-box;
00024. -webkit-box-sizing: border-box;
00025. -moz-box-sizing: border-box;
00026. background: #1F1F1F; /* fallback */
00027. background:-moz-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00028. background:-webkit-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00029. background:-o-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00030. }
00031.
00032. /*** VIDEO CONTROLS CSS ***/
00033. /* control holder */
00034. .control{
00035. background:#333;
00036. color:#ccc;
00037. position:absolute;
00038. bottom:0;
00039. left:0;
00040. width:100%;
00041. z-index:5;
00042. display:none;
00043. }
00044. /* control top part */
00045. .topControl{
00046. height:11px;
00047. border-bottom:1px solid #404040;
00048. padding:1px 5px;
00049. background:#1F1F1F; /* fallback */
00050. background:-moz-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00051. background:-webkit-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00052. background:-o-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00053. }
00054. /* control bottom part */
00055. .btmControl{
00056. clear:both;
00057. background: #1F1F1F; /* fallback */
00058. background:-moz-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00059. background:-webkit-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00060. background:-o-linear-gradient(top,#242424 50%,#1F1F1F 50%,#171717 100%);
00061. }
00062. .control div.btn {
00063. float:left;
00064. width:34px;
00065. height:30px;
00066. padding:0 5px;
00067. border-right:1px solid #404040;
00068. cursor:pointer;
00069. }
00070. .control div.text{
00071. font-size:12px;
00072. font-weight:bold;
00073. line-height:30px;
00074. text-align:center;
00075. font-family:verdana;
00076. width:20px;
00077. border:none;
00078. color:#777;
00079. }
00080. .control div.btnPlay{
00081. background:url(control.png) no-repeat 0 0;
00082. border-left:1px solid #404040;
00083. }
00084. .control div.paused{
00085. background:url(control.png) no-repeat 0 -30px;
00086. }
00087. .control div.btnStop{
00088. background:url(control.png) no-repeat 0 -60px;
00089. }
00090. .control div.spdText{
00091. border:none;
00092. font-size:14px;
00093. line-height:30px;
00094. font-style:italic;
00095. }
00096. .control div.selected{
00097. font-size:15px;
00098. color:#ccc;
00099. }
00100. .control div.sound{
00101. background:url(control.png) no-repeat -88px -30px;
00102. border:none;
00103. float:right;
00104. }
00105. .control div.sound2{
00106. background:url(control.png) no-repeat -88px -60px !important;
00107. }
00108. .control div.muted{
00109. background:url(control.png) no-repeat -88px 0 !important;
00110. }
00111. .control div.btnFS{
00112. background:url(control.png) no-repeat -44px 0;
00113. float:right;
00114. }
00115. .control div.btnLight{
00116. background:url(control.png) no-repeat -44px -60px;
00117. border-left:1px solid #404040;
00118. float:right;
00119. }
00120. .control div.lighton{
00121. background:url(control.png) no-repeat -44px -30px !important;
00122. }
00123.
00124. /* PROGRESS BAR CSS */
00125. /* Progress bar */
00126. .progress {
00127. width:85%;
00128. height:10px;
00129. position:relative;
00130. float:left;
00131. cursor:pointer;
00132. background: #444; /* fallback */
00133. background:-moz-linear-gradient(top,#666,#333);
00134. background:-webkit-linear-gradient(top,#666,#333);
00135. background:-o-linear-gradient(top,#666,#333);
00136. box-shadow:0 2px 3px #333 inset;
00137. -moz-box-shadow:0 2px 3px #333 inset;
00138. -webkit-box-shadow:0 2px 3px #333 inset;
00139. border-radius:10px;
00140. -moz-border-radius:10px;
00141. -webkit-border-radius:10px;
00142. }
00143. .progress span {
00144. height:100%;
00145. position:absolute;
00146. top:0;
00147. left:0;
00148. display:block;
00149. border-radius:10px;
00150. -moz-border-radius:10px;
00151. -webkit-border-radius:10px;
00152. }
00153. .timeBar{
00154. z-index:10;
00155. width:0;
00156. background: #3FB7FC; /* fallback */
00157. background:-moz-linear-gradient(top,#A0DCFF 50%,#3FB7FC 50%,#16A9FF 100%);
00158. background:-webkit-linear-gradient(top,#A0DCFF 50%,#3FB7FC 50%,#16A9FF 100%);
00159. background:-o-linear-gradient(top,#A0DCFF 50%,#3FB7FC 50%,#16A9FF 100%);
00160. box-shadow:0 0 1px #fff;
00161. -moz-box-shadow:0 0 1px #fff;
00162. -webkit-box-shadow:0 0 1px #fff;
00163. }
00164. .bufferBar{
00165. z-index:5;
00166. width:0;
00167. background: #777;
00168. background:-moz-linear-gradient(top,#999,#666);
00169. background:-webkit-linear-gradient(top,#999,#666);
00170. background:-o-linear-gradient(top,#999,#666);
00171. box-shadow:2px 0 5px #333;
00172. -moz-box-shadow:2px 0 5px #333;
00173. -webkit-box-shadow:2px 0 5px #333;
00174. }
00175. /* time and duration */
00176. .time{
00177. width:15%;
00178. float:right;
00179. text-align:center;
00180. font-size:11px;
00181. line-height:12px;
00182. }
00183.
00184. /* VOLUME BAR CSS */
00185. /* volume bar */
00186. .volume{
00187. position:relative;
00188. cursor:pointer;
00189. width:70px;
00190. height:10px;
00191. float:right;
00192. margin-top:10px;
00193. margin-right:10px;
00194. }
00195. .volumeBar{
00196. display:block;
00197. height:100%;
00198. position:absolute;
00199. top:0;
00200. left:0;
00201. background-color:#eee;
00202. z-index:10;
00203. }
00204.
00205. /* OTHERS CSS */
00206. /* video screen cover */
00207. .loading, #init{
00208. position:absolute;
00209. top:0;
00210. left:0;
00211. width:100%;
00212. height:100%;
00213. background:url(loading.gif) no-repeat 50% 50%;
00214. z-index:2;
00215. display:none;
00216. }
00217. #init{
00218. background:url(bigplay.png) no-repeat 50% 50% !important;
00219. cursor:pointer;
00220. }
video.js
00001. $(document).ready(function(){
00002. //INITIALIZE
00003. var video = $('#myVideo');
00004.
00005. //remove default control when JS loaded
00006. video[0].removeAttribute("controls");
00007. $('.control').show().css({'bottom':-45});
00008. $('.loading').fadeIn(500);
00009. $('.caption').fadeIn(500);
00010.
00011. //before everything get started
00012. video.on('loadedmetadata', function() {
00013. $('.caption').animate({'top':-45},300);
00014.
00015. //set video properties
00016. $('.current').text(timeFormat(0));
00017. $('.duration').text(timeFormat(video[0].duration));
00018. updateVolume(0, 0.7);
00019.
00020. //start to get video buffering data
00021. setTimeout(startBuffer, 150);
00022.
00023. //bind video events
00024. $('.videoContainer')
00025. .append('<div id="init"></div>')
00026. .hover(function() {
00027. $('.control').stop().animate({'bottom':0}, 500);
00028. $('.caption').stop().animate({'top':0}, 500);
00029. }, function() {
00030. if(!volumeDrag && !timeDrag){
00031. $('.control').stop().animate({'bottom':-45}, 500);
00032. $('.caption').stop().animate({'top':-45}, 500);
00033. }
00034. })
00035. .on('click', function() {
00036. $('#init').remove();
00037. $('.btnPlay').addClass('paused');
00038. $(this).unbind('click');
00039. video[0].play();
00040. });
00041. $('#init').fadeIn(200);
00042. });
00043.
00044. //display video buffering bar
00045. var startBuffer = function() {
00046. var currentBuffer = video[0].buffered.end(0);
00047. var maxduration = video[0].duration;
00048. var perc = 100 * currentBuffer / maxduration;
00049. $('.bufferBar').css('width',perc+'%');
00050.
00051. if(currentBuffer < maxduration) {
00052. setTimeout(startBuffer, 500);
00053. }
00054. };
00055.
00056. //display current video play time
00057. video.on('timeupdate', function() {
00058. var currentPos = video[0].currentTime;
00059. var maxduration = video[0].duration;
00060. var perc = 100 * currentPos / maxduration;
00061. $('.timeBar').css('width',perc+'%');
00062. $('.current').text(timeFormat(currentPos));
00063. });
00064.
00065. //CONTROLS EVENTS
00066. //video screen and play button clicked
00067. video.on('click', function() { playpause(); } );
00068. $('.btnPlay').on('click', function() { playpause(); } );
00069. var playpause = function() {
00070. if(video[0].paused || video[0].ended) {
00071. $('.btnPlay').addClass('paused');
00072. video[0].play();
00073. }
00074. else {
00075. $('.btnPlay').removeClass('paused');
00076. video[0].pause();
00077. }
00078. };
00079.
00080. //speed text clicked
00081. $('.btnx1').on('click', function() { fastfowrd(this, 1); });
00082. $('.btnx3').on('click', function() { fastfowrd(this, 3); });
00083. var fastfowrd = function(obj, spd) {
00084. $('.text').removeClass('selected');
00085. $(obj).addClass('selected');
00086. video[0].playbackRate = spd;
00087. video[0].play();
00088. };
00089.
00090. //stop button clicked
00091. $('.btnStop').on('click', function() {
00092. $('.btnPlay').removeClass('paused');
00093. updatebar($('.progress').offset().left);
00094. video[0].pause();
00095. });
00096.
00097. //fullscreen button clicked
00098. $('.btnFS').on('click', function() {
00099. if($.isFunction(video[0].webkitEnterFullscreen)) {
00100. video[0].webkitEnterFullscreen();
00101. }
00102. else if ($.isFunction(video[0].mozRequestFullScreen)) {
00103. video[0].mozRequestFullScreen();
00104. }
00105. else {
00106. alert('Your browsers doesn\'t support fullscreen');
00107. }
00108. });
00109.
00110. //light bulb button clicked
00111. $('.btnLight').click(function() {
00112. $(this).toggleClass('lighton');
00113.
00114. //if lightoff, create an overlay
00115. if(!$(this).hasClass('lighton')) {
00116. $('body').append('<div class="overlay"></div>');
00117. $('.overlay').css({
00118. 'position':'absolute',
00119. 'width':100+'%',
00120. 'height':$(document).height(),
00121. 'background':'#000',
00122. 'opacity':0.9,
00123. 'top':0,
00124. 'left':0,
00125. 'z-index':999
00126. });
00127. $('.videoContainer').css({
00128. 'z-index':1000
00129. });
00130. }
00131. //if lighton, remove overlay
00132. else {
00133. $('.overlay').remove();
00134. }
00135. });
00136.
00137. //sound button clicked
00138. $('.sound').click(function() {
00139. video[0].muted = !video[0].muted;
00140. $(this).toggleClass('muted');
00141. if(video[0].muted) {
00142. $('.volumeBar').css('width',0);
00143. }
00144. else{
00145. $('.volumeBar').css('width', video[0].volume*100+'%');
00146. }
00147. });
00148.
00149. //VIDEO EVENTS
00150. //video canplay event
00151. video.on('canplay', function() {
00152. $('.loading').fadeOut(100);
00153. });
00154.
00155. //video canplaythrough event
00156. //solve Chrome cache issue
00157. var completeloaded = false;
00158. video.on('canplaythrough', function() {
00159. completeloaded = true;
00160. });
00161.
00162. //video ended event
00163. video.on('ended', function() {
00164. $('.btnPlay').removeClass('paused');
00165. video[0].pause();
00166. });
00167.
00168. //video seeking event
00169. video.on('seeking', function() {
00170. //if video fully loaded, ignore loading screen
00171. if(!completeloaded) {
00172. $('.loading').fadeIn(200);
00173. }
00174. });
00175.
00176. //video seeked event
00177. video.on('seeked', function() { });
00178.
00179. //video waiting for more data event
00180. video.on('waiting', function() {
00181. $('.loading').fadeIn(200);
00182. });
00183.
00184. //VIDEO PROGRESS BAR
00185. //when video timebar clicked
00186. var timeDrag = false; /* check for drag event */
00187. $('.progress').on('mousedown', function(e) {
00188. timeDrag = true;
00189. updatebar(e.pageX);
00190. });
00191. $(document).on('mouseup', function(e) {
00192. if(timeDrag) {
00193. timeDrag = false;
00194. updatebar(e.pageX);
00195. }
00196. });
00197. $(document).on('mousemove', function(e) {
00198. if(timeDrag) {
00199. updatebar(e.pageX);
00200. }
00201. });
00202. var updatebar = function(x) {
00203. var progress = $('.progress');
00204.
00205. //calculate drag position
00206. //and update video currenttime
00207. //as well as progress bar
00208. var maxduration = video[0].duration;
00209. var position = x - progress.offset().left;
00210. var percentage = 100 * position / progress.width();
00211. if(percentage > 100) {
00212. percentage = 100;
00213. }
00214. if(percentage < 0) {
00215. percentage = 0;
00216. }
00217. $('.timeBar').css('width',percentage+'%');
00218. video[0].currentTime = maxduration * percentage / 100;
00219. };
00220.
00221. //VOLUME BAR
00222. //volume bar event
00223. var volumeDrag = false;
00224. $('.volume').on('mousedown', function(e) {
00225. volumeDrag = true;
00226. video[0].muted = false;
00227. $('.sound').removeClass('muted');
00228. updateVolume(e.pageX);
00229. });
00230. $(document).on('mouseup', function(e) {
00231. if(volumeDrag) {
00232. volumeDrag = false;
00233. updateVolume(e.pageX);
00234. }
00235. });
00236. $(document).on('mousemove', function(e) {
00237. if(volumeDrag) {
00238. updateVolume(e.pageX);
00239. }
00240. });
00241. var updateVolume = function(x, vol) {
00242. var volume = $('.volume');
00243. var percentage;
00244. //if only volume have specificed
00245. //then direct update volume
00246. if(vol) {
00247. percentage = vol * 100;
00248. }
00249. else {
00250. var position = x - volume.offset().left;
00251. percentage = 100 * position / volume.width();
00252. }
00253.
00254. if(percentage > 100) {
00255. percentage = 100;
00256. }
00257. if(percentage < 0) {
00258. percentage = 0;
00259. }
00260.
00261. //update volume bar and video volume
00262. $('.volumeBar').css('width',percentage+'%');
00263. video[0].volume = percentage / 100;
00264.
00265. //change sound icon based on volume
00266. if(video[0].volume == 0){
00267. $('.sound').removeClass('sound2').addClass('muted');
00268. }
00269. else if(video[0].volume > 0.5){
00270. $('.sound').removeClass('muted').addClass('sound2');
00271. }
00272. else{
00273. $('.sound').removeClass('muted').removeClass('sound2');
00274. }
00275.
00276. };
00277.
00278. //Time format converter - 00:00
00279. var timeFormat = function(seconds){
00280. var m = Math.floor(seconds/60)<10 ? "0"+Math.floor(seconds/60) : Math.floor(seconds/60);
00281. var s = Math.floor(seconds-(m*60))<10 ? "0"+Math.floor(seconds-(m*60)) : Math.floor(seconds-(m*60));
00282. return m+":"+s;
00283. };
00284. });
运行效果: