簡介
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作爲父容器:
- <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>
注意,我們使用元素的class屬性來代替ID屬性是爲了方便在一個頁面上使用多個播放器。
打包成jQuery插件
創建好控制按鈕後我們需要配合多媒體元素的API來實現視頻控制的目的,正如前面提到的一樣我們將我們的播放器打包成jQuery插件,這樣可以很好的實現複用,代碼如下:
- $.fn.gVideo = function(options) {
- // build main options before element iteration
- var defaults = {
- theme: 'simpledark',
- childtheme: ''
- };
- var options = $.extend(defaults, options);
- // iterate and reformat each matched element
- return this.each(function() {
- var $gVideo = $(this);
- //create html structure
- //main wrapper
- var $video_wrap = $('<div></div>').addClass('ghinda-video-player').addClass(options.theme).addClass(options.childtheme);
- //controls wraper
- 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>');
- $gVideo.wrap($video_wrap);
- $gVideo.after($video_controls);
- //get newly created elements
- var $video_container = $gVideo.parent('.ghinda-video-player');
- var $video_controls = $('.ghinda-video-controls', $video_container);
- var $ghinda_play_btn = $('.ghinda-video-play', $video_container);
- var $ghinda_video_seek = $('.ghinda-video-seek', $video_container);
- var $ghinda_video_timer = $('.ghinda-video-timer', $video_container);
- var $ghinda_volume = $('.ghinda-volume-slider', $video_container);
- var $ghinda_volume_btn = $('.ghinda-volume-button', $video_container);
- $video_controls.hide(); // keep the controls hidden
- var gPlay = function() {
- if($gVideo.attr('paused') == false) {
- $gVideo[0].pause();
- } else {
- $gVideo[0].play();
- }
- };
- $ghinda_play_btn.click(gPlay);
- $gVideo.click(gPlay);
- $gVideo.bind('play', function() {
- $ghinda_play_btn.addClass('ghinda-paused-button');
- });
- $gVideo.bind('pause', function() {
- $ghinda_play_btn.removeClass('ghinda-paused-button');
- });
- $gVideo.bind('ended', function() {
- $ghinda_play_btn.removeClass('ghinda-paused-button');
- });
爲了創建進度條的拖動塊,我們使用了jQuery UI的Slider組件:
- var createSeek = function() {
- if($gVideo.attr('readyState')) {
- var video_duration = $gVideo.attr('duration');
- $ghinda_video_seek.slider({
- value: 0,
- step: 0.01,
- orientation: "horizontal",
- range: "min",
- max: video_duration,
- animate: true,
- slide: function(){
- seeksliding = true;
- },
- stop:function(e,ui){
- seeksliding = false;
- $gVideo.attr("currentTime",ui.value);
- }
- });
- $video_controls.show();
- } else {
- setTimeout(createSeek, 150);
- }
- };
- createSeek();
- var gTimeFormat=function(seconds){
- var m=Math.floor(seconds/60)<10?"0"+Math.floor(seconds/60):Math.floor(seconds/60);
- var s=Math.floor(seconds-(m*60))<10?"0"+Math.floor(seconds-(m*60)):Math.floor(seconds-(m*60));
- return m+":"+s;
- };
- var seekUpdate = function() {
- var currenttime = $gVideo.attr('currentTime');
- if(!seeksliding) $ghinda_video_seek.slider('value', currenttime);
- $ghinda_video_timer.text(gTimeFormat(currenttime));
- };
- $gVideo.bind('timeupdate', seekUpdate);
至於音量控制控件我們還是利用jQuery UI的Slider組件然後利用自定義函數實現靜音和取消靜音的功能:
- $ghinda_volume.slider({
- value: 1,
- orientation: "vertical",
- range: "min",
- max: 1,
- step: 0.05,
- animate: true,
- slide:function(e,ui){
- $gVideo.attr('muted',false);
- video_volume = ui.value;
- $gVideo.attr('volume',ui.value);
- }
- });
- var muteVolume = function() {
- if($gVideo.attr('muted')==true) {
- $gVideo.attr('muted', false);
- $ghinda_volume.slider('value', video_volume);
- $ghinda_volume_btn.removeClass('ghinda-volume-mute');
- } else {
- $gVideo.attr('muted', true);
- $ghinda_volume.slider('value', '0');
- $ghinda_volume_btn.addClass('ghinda-volume-mute');
- };
- };
- $ghinda_volume_btn.click(muteVolume);
好了,我們的插件功能已經全部完成了,調用方法:
- $('video').gVideo();
外觀和體驗
好的,現在到了比較有意思的部分,也就是播放器的外觀和體驗了。當插件功能已經完成後利用一點CSS就可以很容易地自定義樣式了,我們將全部使用CSS3來實現。
首先,我們給播放器主容器加一些樣式:
- .ghinda-video-player {
- float: left;
- padding: 10px;
- border: 5px solid #61625d;
- -moz-border-radius: 5px; /* FF1+ */
- -ms-border-radius: 5px; /* IE future proofing */
- -webkit-border-radius: 5px; /* Saf3+, Chrome */
- border-radius: 5px; /* Opera 10.5, IE 9 */
- background: #000000;
- background-image: -moz-linear-gradient(top, #313131, #000000); /* FF3.6 */
- background-image: -webkit-gradient(linear,left top,left bottombottom,color-stop(0, #313131),color-stop(1, #000000)); /* Saf4+, Chrome */
- box-shadow: inset 0 15px 35px #535353;
- }
- .ghinda-video-play {
- display: block;
- width: 22px;
- height: 22px;
- margin-right: 15px;
- background: url(../images/play-icon.png) no-repeat;
- opacity: 0.7;
- -moz-transition: all 0.2s ease-in-out; /* Firefox */
- -ms-transition: all 0.2s ease-in-out; /* IE future proofing */
- -o-transition: all 0.2s ease-in-out; /* Opera */
- -webkit-transition: all 0.2s ease-in-out; /* Safari and Chrome */
- transition: all 0.2s ease-in-out;
- }
- .ghinda-paused-button {
- background: url(../images/pause-icon.png) no-repeat;
- }
- .ghinda-video-play:hover {
- opacity: 1;
- }
現在輪到滑動塊了,我們進度條和音量控制的滑動塊的實現都是利用了jQuery UI的Slider組件,這個組件它本身自帶了樣式,定義在jQuery UI對應的css文件中,但是爲了使滑動塊和播放器其他控件外觀保持一致我們全部重寫了它的樣式:
- .ghinda-video-seek .ui-slider-handle {
- width: 15px;
- height: 15px;
- border: 1px solid #333;
- top: -4px;
- -moz-border-radius:10px;
- -ms-border-radius:10px;
- -webkit-border-radius:10px;
- border-radius:10px;
- background: #e6e6e6;
- background-image: -moz-linear-gradient(top, #e6e6e6, #d5d5d5);
- background-image: -webkit-gradient(linear,left top,left bottombottom,color-stop(0, #e6e6e6),color-stop(1, #d5d5d5));
- box-shadow: inset 0 -3px 3px #d5d5d5;
- }
- .ghinda-video-seek .ui-slider-handle.ui-state-hover {
- background: #fff;
- }
- .ghinda-video-seek .ui-slider-range {
- -moz-border-radius:15px;
- -ms-border-radius:15px;
- -webkit-border-radius:15px;
- border-radius:15px;
- background: #4cbae8;
- background-image: -moz-linear-gradient(top, #4cbae8, #39a2ce);
- background-image: -webkit-gradient(linear,left top,left bottombottom,color-stop(0, #4cbae8),color-stop(1, #39a2ce));
- box-shadow: inset 0 -3px 3px #39a2ce;
- }
- .ghinda-volume-box {
- height: 30px;
- -moz-transition: all 0.1s ease-in-out; /* Firefox */
- -ms-transition: all 0.1s ease-in-out; /* IE future proofing */
- -o-transition: all 0.2s ease-in-out; /* Opera */
- -webkit-transition: all 0.1s ease-in-out; /* Safari and Chrome */
- transition: all 0.1s ease-in-out;
- }
- .ghinda-volume-box:hover {
- height: 135px;
- padding-top: 5px;
- }
- .ghinda-volume-slider {
- visibility: hidden;
- opacity: 0;
- -moz-transition: all 0.1s ease-in-out; /* Firefox */
- -ms-transition: all 0.1s ease-in-out; /* IE future proofing */
- -o-transition: all 0.1s ease-in-out; /* Opera */
- -webkit-transition: all 0.1s ease-in-out; /* Safari and Chrome */
- transition: all 0.1s ease-in-out;
- }
- .ghinda-volume-box:hover .ghinda-volume-slider {
- position: relative;
- visibility: visible;
- opacity: 1;
- }
自定義皮膚
可能您已經注意到,我們在編寫插件的時候已經定義了一些默認選項,它們是theme和childtheme,可以在調用插件的時候根據需要方便的應用自定義皮膚。
這裏解釋下theme就是所有控件的一整套樣式定義,childtheme就是在theme基礎上重寫某些樣式,我們在調用插件的時候可以同時指定這兩個選項或者其中的一個:
- $('video').gVideo({
- childtheme:'smalldark'
- });
總結
利用HTML5 video,JavaScript和CSS3打造自定義的視頻播放器真的非常容易,t實現工具條功能用JavaScrip,外觀和體驗交給CSS3,我們得到了一個功能強大並且易於定製的解決方案!
enjoy!