HTML5+CSS3+JQuery打造自定義視頻播放器

 簡介

HTML5的<video>標籤已經被目前大多數主流瀏覽器所支持,包括還未正式發佈的IE9也聲明將支持<video>標籤,利用瀏覽器原生特性嵌入視頻有很多好處,所以很多開發者想盡快用上,但是真正使用前還有些問題要考慮,尤其是 Opera/Firefox 和IE/Safari瀏覽器所支持的視頻編碼不同的問題,Google幾個月前發佈的開源視頻編碼VP8有望能解決這一問題,另外Google還發布了開放網絡媒體項目WebM,旨在幫助開發者爲開放網絡製作出世界級媒體格式,Opera, Firefox, Chrome和IE9都將支持VP8,而且Flash Player也將可以播放VP8,這就意味着我們很快就可以只製作一個版本的視頻然後在所有主流瀏覽器上播放了。另外一個主要的問題就是如何構建自定義的HTML5<video>播放器,這是目前Flash Player的優勢所在,利用Flash的IDE所提供的接口可以很方便的構建一個個性化的視頻播放器,那HTML5的<video>標籤要怎樣才能實現呢?這個問題就是本文所要解決的!我們將開發一個HTML5<video>視頻播放器的jQuery插件,並且可以很方便的進行自定義,將分爲以下幾個部分:
1.視頻控制工具條
2.視頻控制按鈕
3.打包成jQuery插件
4.外觀和體驗
5.自定義皮膚


視頻控制工具條
做爲一個專業的web開發人員,我們創建一個視頻播放器時一定希望它的外觀在各個瀏覽器中看起來一致(consistent),但是通過下面的圖可以看到目前各個瀏覽器提供的視頻控制工具條外觀各不相同:

那就沒辦法了,我們得自己從頭來創建這個控制工具條,利用HTML和CSS再加上一些圖片實現起來並不算很難,另外通過HTML5多媒體元素提供的API我們可以很方便將創建的任何按鈕與播放/暫停等事件進行綁定。

視頻控制按鈕
基本的視頻控制工具條要包含一個播放/暫停按鈕,一個進度條,一個計時器和一個音量控制按鈕,我們將這些按鈕放在<video>元素下面,並用一個div作爲父容器:

XML/HTML Code複製內容到剪貼板
  1. <div class="ghinda-video-controls">  
  2.         <a class="ghinda-video-play" title="Play/Pause"></a>  
  3.         <div class="ghinda-video-seek"></div>  
  4.         <div class="ghinda-video-timer">00:00</div>  
  5.         <div class="ghinda-volume-box">  
  6.                 <div class="ghinda-volume-slider"></div>  
  7.                 <a class="ghinda-volume-button" title="Mute/Unmute"></a>  
  8.         </div>  
  9. </div>  
複製代碼

注意,我們使用元素的class屬性來代替ID屬性是爲了方便在一個頁面上使用多個播放器。

打包成jQuery插件
創建好控制按鈕後我們需要配合多媒體元素的API來實現視頻控制的目的,正如前面提到的一樣我們將我們的播放器打包成jQuery插件,這樣可以很好的實現複用,代碼如下:

XML/HTML Code複製內容到剪貼板
  1. $.fn.gVideo = function(options) {  
  2.         // build main options before element iteration  
  3.         var defaults = {  
  4.                 theme: 'simpledark',  
  5.                 childtheme: ''  
  6.         };  
  7.         var options = $.extend(defaults, options);  
  8.         // iterate and reformat each matched element  
  9.         return this.each(function() {  
  10.                 var $gVideo = $(this);  
  11.                   
  12.                 //create html structure  
  13.                 //main wrapper  
  14.                 var $video_wrap = $('<div></div>').addClass('ghinda-video-player').addClass(options.theme).addClass(options.childtheme);  
  15.                 //controls wraper  
  16.                 var $video_controls = $('<div class="ghinda-video-controls"><a class="ghinda-video-play" title="Play/Pause"></a><div class="ghinda-video-seek"></div><div class="ghinda-video-timer">00:00</div><div class="ghinda-volume-box"><div class="ghinda-volume-slider"></div><a class="ghinda-volume-button" title="Mute/Unmute"></a></div></div>');                                                  
  17.                 $gVideo.wrap($video_wrap);  
  18.                 $gVideo.after($video_controls);  
這裏先假設您瞭解jQuery並知道如何創建一個jQuery插件,因爲這個不在本文的討論範圍之內,在上面這段腳本中我們使用jQuery動態創建視頻控制工具條的元素,接下來爲了綁定事件我們需要獲取對應的元素:
 
JavaScript Code複製內容到剪貼板
  1. //get newly created elements  
  2. var $video_container = $gVideo.parent('.ghinda-video-player');  
  3. var $video_controls = $('.ghinda-video-controls', $video_container);  
  4. var $ghinda_play_btn = $('.ghinda-video-play', $video_container);  
  5. var $ghinda_video_seek = $('.ghinda-video-seek', $video_container);  
  6. var $ghinda_video_timer = $('.ghinda-video-timer', $video_container);  
  7. var $ghinda_volume = $('.ghinda-volume-slider', $video_container);  
  8. var $ghinda_volume_btn = $('.ghinda-volume-button', $video_container);  
  9.   
  10. $video_controls.hide(); // keep the controls hidden  
這裏我們通過className方式獲取,先讓工具條隱藏直到所有資源加載完成,現在來實現播放/暫停按鈕:
 
JavaScript Code複製內容到剪貼板
  1. var gPlay = function() {  
  2.         if($gVideo.attr('paused') == false) {  
  3.                 $gVideo[0].pause();                                          
  4.         } else {                                          
  5.                 $gVideo[0].play();                                  
  6.         }  
  7. };  
  8.   
  9. $ghinda_play_btn.click(gPlay);  
  10. $gVideo.click(gPlay);  
  11.   
  12. $gVideo.bind('play'function() {  
  13.         $ghinda_play_btn.addClass('ghinda-paused-button');  
  14. });  
  15.   
  16. $gVideo.bind('pause'function() {  
  17.         $ghinda_play_btn.removeClass('ghinda-paused-button');  
  18. });  
  19.   
  20. $gVideo.bind('ended'function() {  
  21.         $ghinda_play_btn.removeClass('ghinda-paused-button');  
  22. });  
大多數瀏覽器在右鍵點擊視頻時會提供一個獨立的菜單,它也提供了視頻控制功能,如果用戶通過這個右鍵菜單控制視頻那就會跟我們的自定義控件衝突,所以爲了避免這一點我們需要綁定視頻播放器自身的“播放”,“暫停”和“結束”事件,在事件處理函數中處理播放/暫停按鈕,控制按鈕的樣式。

爲了創建進度條的拖動塊,我們使用了jQuery UI的Slider組件:

JavaScript Code複製內容到剪貼板
  1. var createSeek = function() {  
  2.         if($gVideo.attr('readyState')) {  
  3.                 var video_duration = $gVideo.attr('duration');  
  4.                 $ghinda_video_seek.slider({  
  5.                         value: 0,  
  6.                         step: 0.01,  
  7.                         orientation: "horizontal",  
  8.                         range: "min",  
  9.                         max: video_duration,  
  10.                         animate: true,                                          
  11.                         slide: function(){                                                          
  12.                                 seeksliding = true;  
  13.                         },  
  14.                         stop:function(e,ui){  
  15.                                 seeksliding = false;                                                  
  16.                                 $gVideo.attr("currentTime",ui.value);  
  17.                         }  
  18.                 });  
  19.                 $video_controls.show();                                          
  20.         } else {  
  21.                 setTimeout(createSeek, 150);  
  22.         }  
  23. };  
  24.   
  25. createSeek();  
正如你所看到的,這裏我們寫了一個遞歸函數,通過循環比較video的readyState屬性來判斷視頻是否已經準備好,否則我們就不能獲得視頻的時長也無法創建滑動塊,當視頻準備好後我們初始化滑動塊並顯示控制工具條,下一步我們通過綁定video元素的timeupdate事件實現計時器功能:
 
JavaScript Code複製內容到剪貼板
  1. var gTimeFormat=function(seconds){  
  2.         var m=Math.floor(seconds/60)<10?"0"+Math.floor(seconds/60):Math.floor(seconds/60);  
  3.         var s=Math.floor(seconds-(m*60))<10?"0"+Math.floor(seconds-(m*60)):Math.floor(seconds-(m*60));  
  4.         return m+":"+s;  
  5. };  
  6.   
  7. var seekUpdate = function() {  
  8.         var currenttime = $gVideo.attr('currentTime');  
  9.         if(!seeksliding) $ghinda_video_seek.slider('value', currenttime);  
  10.         $ghinda_video_timer.text(gTimeFormat(currenttime));                                                          
  11. };  
  12.   
  13. $gVideo.bind('timeupdate', seekUpdate);  
這裏我們用seekUpdate函數獲取video的currentTime屬性值然後調用gTimeFormat函數進行格式化後得到當前播放的時間點。

至於音量控制控件我們還是利用jQuery UI的Slider組件然後利用自定義函數實現靜音和取消靜音的功能:

JavaScript Code複製內容到剪貼板
  1. $ghinda_volume.slider({  
  2.         value: 1,  
  3.         orientation: "vertical",  
  4.         range: "min",  
  5.         max: 1,  
  6.         step: 0.05,  
  7.         animate: true,  
  8.         slide:function(e,ui){  
  9.                 $gVideo.attr('muted',false);  
  10.                 video_volume = ui.value;  
  11.                 $gVideo.attr('volume',ui.value);  
  12.         }  
  13. });  
  14.   
  15. var muteVolume = function() {  
  16.         if($gVideo.attr('muted')==true) {  
  17.                 $gVideo.attr('muted'false);  
  18.                 $ghinda_volume.slider('value', video_volume);  
  19.                   
  20.                 $ghinda_volume_btn.removeClass('ghinda-volume-mute');                                          
  21.         } else {  
  22.                 $gVideo.attr('muted'true);  
  23.                 $ghinda_volume.slider('value''0');  
  24.                   
  25.                 $ghinda_volume_btn.addClass('ghinda-volume-mute');  
  26.         };  
  27. };  
  28.   
  29. $ghinda_volume_btn.click(muteVolume);  
最後當我們自己的自定義視頻控制工具條構造完成後需要移除<video>標籤的controls屬性,這樣瀏覽器默認的工具條就被去掉了。

好了,我們的插件功能已經全部完成了,調用方法:

JavaScript Code複製內容到剪貼板
  1. $('video').gVideo();  
這會將我們的插件應用到頁面上每一個video元素上。


外觀和體驗
好的,現在到了比較有意思的部分,也就是播放器的外觀和體驗了。當插件功能已經完成後利用一點CSS就可以很容易地自定義樣式了,我們將全部使用CSS3來實現。
首先,我們給播放器主容器加一些樣式:

CSS Code複製內容到剪貼板
  1. .ghinda-video-player {  
  2.         floatleft;  
  3.         padding10px;  
  4.         border5px solid #61625d;  
  5.                   
  6.         -moz-border-radius: 5px/* FF1+ */  
  7.         -ms-border-radius: 5px/* IE future proofing */  
  8.         -webkit-border-radius: 5px/* Saf3+, Chrome */  
  9.         border-radius: 5px/* Opera 10.5, IE 9 */  
  10.           
  11.         background#000000;  
  12.         background-image: -moz-linear-gradient(top#313131#000000); /* FF3.6 */  
  13.         background-image: -webkit-gradient(linear,left top,left bottombottom,color-stop(0, #313131),color-stop(1, #000000)); /* Saf4+, Chrome */  
  14.           
  15.         box-shadow: inset 0 15px 35px #535353;  
  16. }  
下一步,我們設置視頻控制工具條左邊浮動使它們水平對齊,利用CSS3的opacity和transitions我們給播放/暫停和靜音/取消靜音按鈕添加了非常不錯的懸浮效果:
 
CSS Code複製內容到剪貼板
  1. .ghinda-video-play {  
  2.         displayblock;  
  3.         width22px;  
  4.         height22px;  
  5.         margin-right15px;  
  6.         backgroundurl(../images/play-icon.png) no-repeat;          
  7.           
  8.         opacity: 0.7;  
  9.           
  10.         -moz-transition: all 0.2s ease-in-out; /* Firefox */  
  11.         -ms-transition: all 0.2s ease-in-out; /* IE future proofing */  
  12.         -o-transition: all 0.2s ease-in-out;  /* Opera */  
  13.         -webkit-transition: all 0.2s ease-in-out; /* Safari and Chrome */  
  14.         transition: all 0.2s ease-in-out;   
  15. }  
  16.   
  17. .ghinda-paused-button {  
  18.         backgroundurl(../images/pause-icon.png) no-repeat;  
  19. }  
  20.   
  21. .ghinda-video-play:hover {          
  22.         opacity: 1;  
  23. }  
如果您仔細看了前面那段根據視頻播放狀態(Playing/Paused)添加和移除播放/暫停按鈕樣式的JavaScript代碼,就會明白爲什麼.ghinda-paused-button爲什麼要重寫.ghinda-video-play的背景屬性了。

現在輪到滑動塊了,我們進度條和音量控制的滑動塊的實現都是利用了jQuery UI的Slider組件,這個組件它本身自帶了樣式,定義在jQuery UI對應的css文件中,但是爲了使滑動塊和播放器其他控件外觀保持一致我們全部重寫了它的樣式:

CSS Code複製內容到剪貼板
  1. .ghinda-video-seek .ui-slider-handle {  
  2.         width15px;  
  3.         height15px;  
  4.         border1px solid #333;  
  5.         top: -4px;  
  6.   
  7.         -moz-border-radius:10px;  
  8.         -ms-border-radius:10px;  
  9.         -webkit-border-radius:10px;  
  10.         border-radius:10px;          
  11.           
  12.         background#e6e6e6;  
  13.         background-image: -moz-linear-gradient(top#e6e6e6#d5d5d5);  
  14.         background-image: -webkit-gradient(linear,left top,left bottombottom,color-stop(0, #e6e6e6),color-stop(1, #d5d5d5));  
  15.           
  16.         box-shadow: inset 0 -3px 3px #d5d5d5;          
  17. }  
  18.   
  19. .ghinda-video-seek .ui-slider-handle.ui-state-hover {  
  20.         background#fff;  
  21. }  
  22.   
  23. .ghinda-video-seek .ui-slider-range {  
  24.         -moz-border-radius:15px;  
  25.         -ms-border-radius:15px;  
  26.         -webkit-border-radius:15px;  
  27.         border-radius:15px;  
  28.           
  29.         background#4cbae8;  
  30.         background-image: -moz-linear-gradient(top#4cbae8#39a2ce);  
  31.         background-image: -webkit-gradient(linear,left top,left bottombottom,color-stop(0, #4cbae8),color-stop(1, #39a2ce));  
  32.           
  33.         box-shadow: inset 0 -3px 3px #39a2ce;  
  34. }  
這時候音量控制的滑動塊一直顯示在音量按鈕旁邊,我們需要將它改成默認隱藏,當鼠標懸浮在音量按鈕上再動態顯示出來,使用transitions來實現這個效果會是個不錯的的選擇:
 
CSS Code複製內容到剪貼板
  1. .ghinda-volume-box {          
  2.         height30px;  
  3.           
  4.         -moz-transition: all 0.1s ease-in-out; /* Firefox */  
  5.         -ms-transition: all 0.1s ease-in-out; /* IE future proofing */  
  6.         -o-transition: all 0.2s ease-in-out;  /* Opera */  
  7.         -webkit-transition: all 0.1s ease-in-out; /* Safari and Chrome */  
  8.         transition: all 0.1s ease-in-out;   
  9. }  
  10.   
  11. .ghinda-volume-box:hover {          
  12.         height135px;  
  13.         padding-top5px;  
  14. }  
  15.   
  16. .ghinda-volume-slider {          
  17.         visibilityhidden;  
  18.         opacity: 0;  
  19.           
  20.         -moz-transition: all 0.1s ease-in-out; /* Firefox */  
  21.         -ms-transition: all 0.1s ease-in-out;  /* IE future proofing */  
  22.         -o-transition: all 0.1s ease-in-out;  /* Opera */  
  23.         -webkit-transition: all 0.1s ease-in-out; /* Safari and Chrome */  
  24.         transition: all 0.1s ease-in-out;   
  25. }  
  26.   
  27. .ghinda-volume-box:hover .ghinda-volume-slider {  
  28.         positionrelative;  
  29.         visibilityvisible;  
  30.         opacity: 1;  
  31. }  
利用一些基礎的CSS屬性以及CSS3提供的新屬性我們打造了一個全新的播放器外觀,它看起來是這個樣子:


自定義皮膚
可能您已經注意到,我們在編寫插件的時候已經定義了一些默認選項,它們是theme和childtheme,可以在調用插件的時候根據需要方便的應用自定義皮膚。
這裏解釋下theme就是所有控件的一整套樣式定義,childtheme就是在theme基礎上重寫某些樣式,我們在調用插件的時候可以同時指定這兩個選項或者其中的一個:

JavaScript Code複製內容到剪貼板
  1. $('video').gVideo({  
  2.            childtheme:'smalldark'  
  3. });  
我們寫了一個示例的皮膚smalldark,它只重寫了部分的樣式,顯示效果是這樣的:


總結
利用HTML5 video,JavaScript和CSS3打造自定義的視頻播放器真的非常容易,t實現工具條功能用JavaScrip,外觀和體驗交給CSS3,我們得到了一個功能強大並且易於定製的解決方案!
enjoy!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章