API的魅力:H5讓Web頁面輕鬆控制多媒體音視頻

常見的音頻/視頻文件格式:

文件格式 所用【容器】 說明
*.oga/ *.ogv OGG 一個自由開放標準的容器格式。Ogg格式並不受軟件專利的限制,能夠設計用於高效處理流媒體和高質量數字媒體。可以納入各種自由開放源代碼的編解碼器,包含音效、視頻、文字與元數據的處理,是HTML5視頻常用的一種格式
*.avi AVI 即把視頻和音頻編碼混合在一起儲存,應該是最常見的音頻視頻容器了。支持的音視頻編碼也是最多的
*.mp4 MP4 MPEG-4編碼,是HTML5視頻常用的格式
*.wmv/ *.asf ASF 能夠用於流傳送。還能包容腳本。ASF封裝的WMV視頻還具有“數位版權保護”功能
*.mov MOV 具有較高的壓縮比率和較完美的視頻清晰度,而且還可跨平臺
*.wav WAV 一種音頻容器,常說的WAV就是指沒有壓縮的PCM編碼,其實WAV裏還包含MP3等其它ACM壓縮編碼
*.webm WebM Google基於MKV容器開發的一個免費的媒體容器格式,據說其極具效率,可以在netbook、tablet、手持裝置上順暢使用

fj

HTML5 Video&Audio API

以前包括現在,網頁中播放視頻或音頻的主要方式還是Object調用Flash插件、QuickTime插件或Windows Media插件向HTML標籤中插入視頻,相對於這種傳統方式,使用HTML5的媒體標籤的好處可是太多了

  1. 作爲瀏覽器原生支持的功能,新的audio元素和video元素無需安裝任何東西 —— 儘管有些插件安裝率很高。
  2. 可以避免插件帶來的安全問題,比如信息泄露、彈窗廣告
  3. 有些插件很難和頁面其他內容相集成
  4. 媒體元素向頁面提供了通用、集成、可腳本化控制的API。對於開發人員來說,使用新的媒體元素後,可以輕易地使用腳本來控制和播放內容。

fj

瀏覽器支持性檢測

我們當然可以通過 html5test.com 或者一些其他工具來檢測出瀏覽器是否支持 <video><audio> 標籤。
事實上,目前應該幾乎所有瀏覽器都已經“完美”支持HTML5了 —— 就連IE9也是這樣。真是件令人高興的事情。

但瀏覽器品種良多,且依賴第三方檢測並不是妥善之舉。所以檢測瀏覽器是否支持video和audio標籤最簡單的方式就是:用腳本創建,然後檢測其屬性是否存在:

var canPlay=!!(document.createElement('video').canPlayType);

這會在內存裏動態創建一個video元素(不顯示在頁面上!),然後去檢查其獨有的canPlayType()方法是否存在,其它獨有的方法/屬性也可以檢測出來。
通過 !! 運算符將結果轉爲布爾值,這樣就可以知道視頻對象是否創建成功,也就是說明瀏覽器是否支持視頻。
這段代碼你完全可以放在onload中給用戶以“恰當的”提示,但如果不是用JS渲染頁面元素(js動態渲染HTML)的話,其實我們有更好的方法:

fj

如何使用video/audio元素

接着上面的說:如果你實在瀏覽器太垃圾,檢測結果不支持,但是項目中又需要用到,可以觸發另一部分代碼去向頁面中插入傳統的媒體播放代碼。除此之外,還可以在video和audio元素中放入備選內容 —— 以防不測:比如把Flash插件播放同樣內容的代碼作爲備選內容

//如果無需兼容,給用戶簡單提示即可
<video src="xxx.mp4">
	你的瀏覽器不支持video標籤,請嘗試支持html5!
</video>
//如果要兼容插件
<video src="xxx.mp4" controls>
	<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">
		<param name="movie" value="xxx.swf" />
		<embed type="application/x-shockwave-flash" src="xxx.swf"></embed>
	</object>
</video>

(controls屬性:是否顯示自帶視頻控制控件)
瀏覽器執行這段代碼時,如果支持HTML5,那麼 <object> 標籤裏的代碼就會被忽略,反之則用object設置的classid插件編號去調用系統裏的插件 —— 這段代碼中就是Flash Player的ID,然後播放對應文件。

這裏的 <embed> 標籤是在非IE或非Window環境下被使用,這種object(-?)embed的混合寫法正是Macromedia公司所提倡的兼容寫法

fj

另一種兼容:瀏覽器兼容

上面說的是瀏覽器不支持video/audio元素時的插件兼容,但是不同瀏覽器之間也會有差異:這時就需要用到 <source> 標籤進行瀏覽器(文件格式)兼容了:

事實上,我們可用下面的js代碼來檢測瀏覽器最真實的對文件格式的支持情況

document.createElement('video').canPlayType("video/ogg");
document.createElement('video').canPlayType("video/mp4");
document.createElement('video').canPlayType("video/webm");
document.createElement('video').canPlayType("video/webm; codecs='vp8.0,vorbis'");

如果返回probably,表示最有可能支持;如果返回maybe,表示也許支持;如果返回空字符串,則表示不支持。
用腳本方式兼容不同格式只是其中一種方法,而source標籤的方式及其爲大衆所接受:

<video controls>
	<source src="xxx.mp4" />
	<source src="xxx.ogv" />
	<source src="xxx.webm" />
</video>

這樣瀏覽器會自行去檢測支持的格式,並讀取播放,不支持的則自動忽略。

用的時候,可以把上面幾段HTML-video代碼合併一下即可。(若是“音頻”,將video換成audio,src裏面的路徑也換成mp3之類的格式就行啦)

fj

JavaScript對屬性的控制

其實video/audio中HTML5控制的屬性中常用的就那麼幾個:src、controls、loop(循環播放)、preload(預加載,和autoplay衝突)、height、width、poster(封面)、muted(是否輸出視頻聲音)。
我們還是來說下視頻中JavaScript的作用:
比如音量值volumn、播放總時長duration、是否結束播放ended、暫停paused、當前播放時間currentTime等,這些都是可以在對應事件中獲取並賦值的!

這裏就要說說video/audio元素的主要事件:

  • onloadstart:瀏覽器開始查找音視頻
  • ondurationchange:音視頻時長已修改
  • onloadedmetadate:已加載音視頻元數據時;比如設置當前播放時間點爲15s處:dom.onloadedmetadata=function(){dom.currentTime=15;}
  • onloadeddata:瀏覽器已加載當前幀時
  • onprogress:瀏覽器正在下載音視頻
  • oncanplay:瀏覽器正在播放音視頻
  • onpause:音視頻已暫停
  • onplay:音視頻已開始或不再暫停
  • ontimeupdate:當前播放位置已更改
  • onvolumechange:音量已修改

在實際項目中我們一般採用addEventListener監聽的方式觸發:


比如筆者最近做的仿小米官網視頻播放列表中,就對這些事件有使用:

//videoContent: 視頻元素
//videoTimes: 當前/總時間(通過selectAll獲取的數組)
//videoProgress: 進度條元素(通過selectAll獲取的數組)

//監聽視頻加載完畢執行事件
videoContent.addEventListener('canplay',()=>{
	videoTimes[1].innerHTML=formatTime(videoContent.duration);   //formatTime:自定義時間處理函數
})
//監聽視頻播放事件執行事件
videoContent.addEventListener('play',()=>{
	videoPlay.className="...";
	timer-setInterval(playing(),1000);
})
//監聽視頻暫停事件執行事件
videoContent.addEventListener('pause',()=>{
	videoPlay.className="...";
	clearInterval(timer);
})
function playing(){   //正在播放中
	let scale=videoContent.currentTime / videoContent.duration;
	let scaleSuc=videoContent.buffered.end(0) / videoContent.duration;
	videoTimes[0].innerHTML=formatTime(videoContent.currentTime);
	//進度條All獲取的三個元素要分別設置當前位置、加載位置、進度條上小球位置
	videoProgress[0].style.width=scale*100+'%';
	videoProgress[1].style.width=scaleSuc*100+'%';
	videoProgress[2].style.left=scale*100+'%';
}

如何通過按鈕對視頻進行控制呢:

//videoPlay: 播放/暫停按鈕元素
videoPlay.addEventListener('click',()=>{
	if(videoContent.paused){
		videoContent.play();
	}else{
		videoContent.pause();
	}
})
`videoContent.buffered.end(0)` 爲【緩存節點時間】,是video控件自帶,實時監聽,其值永遠大於等於【當前時間currentTime】。常用來渲染“加載進度”

fj

常見的小應用

相信還在刷網課的各位已經對學校網站及其不耐煩了吧。和一些國外視頻網站一樣,通常在列表中採用了鼠標懸停播放視頻的效果,讓當前用戶能夠“一直停留在此網頁上”。
其實這就是利用了在通用事件onmouseover和onmouseout中控制視頻的播放和暫停:

<video id="xxx" onmouseover="this.play()" onmouseout="this.pause()">
	<source src="xxx.mp4" />
	<source src="xxx.ogv" />
</video>

其實,若是“無限視頻列表”,我們完全可以用【事件代理】來提高性能。


相關參考:

  • https://developer.mozilla.org/zh-CN/HTML/Element/video
  • https://blog.csdn.net/ffffffff8/article/details/78030610
  • https://blog.csdn.net/qq_43624878/article/details/102694623
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章