HTML5 Video

前段時間從新學習了一下html5的video部分,之前只是停留在標籤的使用上,這一次決定深刻了解相關的API,並運用這些API打造一個簡單的視頻播放器。所謂「打造本身的」,就是要本身重寫video標籤的控制欄部分,實現包括播放、暫停、進度和音量控制、全屏等功能,並自定義控制欄的樣式。這是我本身的視頻播放器的演示地址(請用chrome打開):javascript

http://animademo.sinaapp.com/html5_video/ (^-^:鼠標中鍵點擊連接,在新標籤頁中打開)php

這是該播放器的代碼地址,也能夠下載下來後查看:
https://github.com/animabear/html5_video_playercss

下面我將逐步講解打造本身的html5視頻播放器的過程:html

1、自定義控制欄涉及到的主要API

一、video播放相關APIhtml5

只讀屬性:
video.duration:整個媒體文件的播放時長,單位s
video.paused :若是媒體文件被暫停,則返回true;若是還沒開始播放,默認返回true
video.ended :若是媒體文件播放完畢,則返回truejava

可寫屬性:
video.currentTime:以s爲單位返回從開始播放到如今所用的時間。在播放過程當中,設置currentTime來進行搜索,並定位到媒體文件的特定位置
video.volume :在0.0到1.0之間設置音頻音量的相對值,或者查詢當前音量相對值
video.muted :檢測當前是否爲靜音,是則爲true;爲文件設置靜音或消除靜音css3

控制函數:
video.play() :播放視頻文件
video.pause() :暫停處於播放狀態的視頻文件
video.canPlayType() :測試video元素是否支持給定MIME類型的文件git

監聽事件:
ontimeupdate :當video.currentTime發生改變時觸發該事件github

二、全屏控制API
說明:這裏只給出webkit的全屏API,本代碼沒有作兼容性處理,主要應用了webkit的一些高級API和chrome的僞元素,因此前面請你們用chrome打開演示地址。web

video.webkitRequestFullScreen():全屏顯示
document.webkitCancelFullScreen():退出全屏
document.webkitIsFullScreen:若是當前處於全屏狀態,則返回true,不然返回false
document.addEventListener('webkitfullscreenchange', handler):當在全屏和非全屏狀態切換時,觸發該事件

三、本地文件讀取API
說明:個人這個視頻播放器支持從本地添加視頻文件播放,支持的格式在webkit瀏覽器支持的html5視頻播放標準範圍內。本地文件讀取API是html5的新標準。

window.URL.createObjectURL(file):file爲文件對象,該函數返回指向文件的對象URL,經過該URL能夠訪問文件。

 
1 video.src = window.URL.createObjectURL(file);

2、視頻播放器控制欄的樣式實現

爲了圖方便,佈局上我使用 pure 來幫忙,一個很簡潔的css框架,其實也沒用到它多少。至於那些控制按鈕,藉助css3的@font-face,我使用icon-font來實現。

icon-font其實就是所謂的圖標字體,將設計好的svg格式圖片導入相關平臺,生成字體文件或者base64的編碼字符串,而後在頁面中引用這些自定義的字體文件或者插入base64編碼字符串。

這裏給你們推薦一個不錯的平臺,IcoMoon,藉助該平臺的IcoMoon App,能夠方面的完成上述操做。並且該平臺還提供了很多優秀的字體庫,我使用的就是現有的。對於不怎麼會作設計又不想花時間找圖片的童鞋來講,這是個不錯的選擇。其實icon-font主要仍是用來減少請求文件大小的。

3、video元素的初始化工做

video元素的html結構:

 
1 <video id="player" width="600" height="450">您的瀏覽器不支持HTML5 2     <source src="./videos/echo-hereweare.mp4"></source>  <!-- 提供默認的播放視頻 -->
3 </video>

video元素的js初始化:

 

1 var $player = $('#player'); 2 var player = $player[0];  //方便使用dom原生的api

 

4、控制欄上各個控制器的功能實現

一、播放、暫停和中止
html:

 
1 <span id="play" class="icon icon-play"></span>
2 <span id="stop" class="icon icon-stop"></span>

javascript:

 
 1 $play
 2     .on('click', function() {
 3         if (player.paused) {
 4             player.play(); //播放
 5             $(this).removeClass('icon-play').addClass('icon-pause');
 6         } else {
 7             player.pause(); //暫停
 8             $(this).removeClass('icon-pause').addClass('icon-play');
 9         }
10     });
11 
12 $stop
13     .on('click', function() {
14         player.currentTime = 0; //中止播放
15         $innerBar.css('width', 0 + 'px');
16     });

二、播放進度控制條和播放時間顯示
1)播放進度控制條:
這一部分要實現兩個功能,一個是點擊控制條上的某一點,視頻能跳轉到對應的時間點;另外一個是點擊後控制條要有相應的顯示(反饋),代表當前位置。
html:

 

1 <div id="progressBar" class="controlBar">
2     <div id="innerBar" class="controlInner"></div>
3 </div>

 

javascript:

 
 1 $progressBar
 2     .on('click', function(e) {
 3         var w = $(this).width(),
 4             x = e.offsetX;
 5         window.per = (x / w).toFixed(3); //全局變量
 6 
 7         var duration = player.duration;
 8         player.currentTime = (duration * window.per).toFixed(0);
 9 
10         $innerBar.css('width', x + 'px'); //反饋
11     });

進度控制條的實現部分,要用到一個很關鍵的屬性:e.offsetX,在firefox裏無此屬性,但有一個相似的e.layerX,具體能夠查閱MDN。e.offsetX表示鼠標指針的位置相對於觸發事件的對象的X座標,知道了這個值和進度條的寬度,就能夠計算出當前點擊位置的百分比了,而後就能夠根據百分比來從新設置video的currentTime,實現進度控制。

注意:這裏之因此要引入一個全局變量window.per來記錄當前播放的進度百分比,是由於在切換到全屏後,控制條的長度會變長,退出全屏後,控制條的長度又會變短,因此對應的內層進度條(用於顯示進度的)的長度也要隨之變化,在以後講實現全屏/非全屏切換時會具體說明。此外,由於在播放過程當中這個百分比是變化的,因此也要不斷更新window.per這個全局變量:
javascript:

 
 1 $player
 2     .on('timeupdate', function() {
 3         // ... (表示省略的代碼)
 4         var w = $progressBar.width();
 5         if (player.duration) {
 6             var per = (player.currentTime / player.duration).toFixed(3);
 7             window.per = per;
 8         } else {
 9             per = 0;
10         }
11         $innerBar.css('width', (w * per).toFixed(0) + 'px');
12         // ...
13     });
 

 

 

2)播放時間顯示
這個就比較簡單了,主要是一個時間換算,仍是利用上面的timeupdate事件
html:

<span id="timer">0:00</span> 

javascript:

 
 1 $player
 2     .on('timeupdate', function() {
 3         //秒數轉換
 4         var time = player.currentTime.toFixed(1),
 5             minutes = Math.floor((time / 60) % 60),
 6             seconds = Math.floor(time % 60);
 7 
 8         if (seconds < 10) {
 9             seconds = '0' + seconds;
10         }
11         $timer.text(minutes + ':' + seconds);
12 
13         // ... (更新控制條部分)
14 
15         if (player.ended) { //播放完畢
16             $play.removeClass('icon-pause').addClass('icon-play'); 
17         }
18     });
 

 

 

注意:播放完畢後,記得將播放按鈕的圖標重置爲播放狀態

三、音量控制
1)靜音與取消靜音
html:

<span id="volume" class="icon icon-volume"></span> 

javascript:

 
 1 $volume
 2     .on('click', function() {
 3         if (player.muted) {
 4             player.muted = false;
 5             $(this).removeClass('icon-volume-mute').addClass('icon-volume');
 6             $volumeInner.css('width', 100 + '%'); //音量控制條回滿血
 7         } else {
 8             player.muted = true;
 9             $(this).removeClass('icon-volume').addClass('icon-volume-mute');
10             $volumeInner.css('width', 0);
11         }
12     });
 

 

 

2)音量控制條
音量控制條和播放進度控制條實際上是同樣的,惟一不一樣的是這裏咱們改變的是video.volume的值。
html:

<div id="volume-control" class="controlBar"> <div id="volume-inner" class="controlInner"></div> </div> 

javascript:

 
1 $volumeControl
2     .on('click', function(e) {
3         var w = $(this).width(),
4             x = e.offsetX;
5         window.vol = (x / w).toFixed(1); //全局變量
6 
7         player.volume = window.vol;
8         $volumeInner.css('width', x + 'px');
9     });
 

 

 

這裏設置全局變量的理由同上。

四、文件上傳按鈕
這裏要作兩件事,一件是上傳文件並生成對象URL,另外一件是在上傳前判斷瀏覽器是否能播放該格式的文件。因爲瀏覽器支持的播放格式比較少,比較常見的就是mp4了,算是一個嘗試性功能吧。
html:

<span id="upload" class="icon icon-upload"></span> <!-- ... 省略代碼 --> <input type="file" id="file"> 

css:

#file { visibility: hidden; } 

javascript:

 
 1 $upload
 2     .on('click', function() {
 3         $file.trigger('click');
 4     });
 5 
 6 $file
 7     .on('change', function(e) {
 8         var file = e.target.files[0],
 9             canPlayType = player.canPlayType(file.type); //判斷是否支持該格式
10 
11         if (canPlayType === 'maybe' || canPlayType === 'probably') {
12             src = window.URL.createObjectURL(file);
13             player.src = src;
14             $play.removeClass('icon-pause').addClass('icon-play'); //新打開的視頻處於paused狀態
15             player.onload = function() {
16                 window.URL.revokeObjectURL(src);
17             };
18         } else {
19             alert("瀏覽器不支持您選擇的文件格式");
20         }
21     });
 

注意:這裏爲了徹底自由定義上傳按鈕的樣式,用了一個小技巧,就是經過點擊自定義的上傳按鈕來觸發真正的提交按鈕(input[type='file'])的點擊事件,而後在css中隱藏真正的提交按鈕便可。關於文件讀取的API,能夠去MDN上詳細學習一下。

五、全屏/非全屏的切換及相關控制
在全屏和非全屏之間切換,利用webkit的API很容易實現
html:

<span id="expand" class="icon icon-expand"></span> 

javascript:

 
 1 $expand
 2     .on('click', function() {
 3         if (!document.webkitIsFullScreen) {
 4             player.webkitRequestFullScreen(); //全屏
 5             $(this).removeClass('icon-expand').addClass('icon-contract');
 6         } else {
 7             document.webkitCancelFullScreen();
 8             $(this).removeClass('icon-contract').addClass('icon-expand');
 9         }
10     });

如今有兩個比較關鍵的問題,一是如何在全屏時隱藏video標籤默認的控制欄並顯示本身的控制欄;二是播放進度控制條和音量控制條顯示狀態的調整,這個在前面已經提到過了。

1)如何在全屏時隱藏video標籤默認的控制欄
關於這個問題,我剛開始用中文搜了很久,都沒有找到相關內容,因此我嘗試着在google裏用"how to hide video controls in html5",結果出來的第三條就是我想要的,不得不感慨有些資源只能經過英語才能搜到。

這篇文章很清楚得描述了這個問題,基本的原理要利用瀏覽器特有的僞元素,其中還提到了shadow dom這個概念,挺好的一篇文章,我就不贅述了:
Hiding Native HTML5 Video Controls in Full-Screen Mode

2)在全屏/非全屏切換時更改控制進度條(內層進度條)的寬度
javascript:

 
 1 $(document)
 2     .on('webkitfullscreenchange', function(e) {
 3         var w = $progressBar.width(),
 4             w1 = $volumeControl.width();
 5         if (window.per) {
 6             $innerBar.css('width', (window.per * w).toFixed(0) + 'px');
 7         }
 8         if (window.vol) {
 9             $volumeInner.css('width', (window.vol * w1).toFixed(0) + 'px')
10         }
11     });
 

這裏前面定義的兩個全局變量就派上用場了。


所有的代碼能夠在github上下載,其實寫的是一個很簡單的demo,主要目的仍是想深刻學習一下html5的video,畢竟不能只停留在一個標籤的使用上。最後推薦一篇文章,是「打造」本身的HTML5音樂播放器,別人作的那個纔是真的牛,很值得學習:
http://www.feelcss.com/html5-music-player-design.html

相關文章
相關標籤/搜索