1 Video介紹
引用我翻譯文檔《在HTML5頁面中嵌入音頻和視頻》中的介紹文字:“當今,在網頁上嵌入視頻且所有用戶不管使用任何浏覽器或者操作系統都能看到的唯一可靠方法是使用Flash。這需要Adobe Flash插件,並且結合<object>和<embed>標簽。
大多數用戶已經安裝了Flash插件(事實上,大概95%的上網用戶都裝有Flash的某個版本),但HTML 5的支持者正在推動一個開放的,不需要任何插件的視頻標准。這就是HTML 5的新標簽<video>帶來的構想,他提供了一個嵌入視頻(以及與其交互)而不需要類似Flash的私有插件的方法。
不幸的是,視頻並非那麼簡單。不僅僅是浏覽器需要理解<video>標簽,而且需要一個必要的編碼譯碼器來播放視頻。明顯的解決方法只能是HTML 5規范的締造者們選擇一個視頻編碼譯碼器,並且讓每一個浏覽器制造商執行。
總之,這就是所推薦的打算。同時,這也是引起混亂的導火索。對於各種各樣編碼譯碼器的爭論就已經很煩雜了,但更悲劇的事情是,浏覽器制造商們還不能就此達成統一。蘋果不願意使用提議的Ogg Theora編碼譯碼器,但Opera和Mozilla也不願意支付由於他們的浏覽器裝載H.264編碼譯碼器而造成的許可費用。Google同時支持兩者,微軟面對爭論,遠遠的置身事外,因為他現在根本沒有計劃去支持HTML 5的視頻元素。
面對浏覽器制造商的僵持局面,HTML 5善意的獨裁者Ian Hickson甩了甩他的手並說到去他媽的。所以HTML 5規范中沒有特別指名或規定的視頻編碼解碼器。”好吧,引用到這兒。
如今的情況是,微軟終於陷進去了,但很悲劇的是,在IE 9中只支持H.264。同時,Googe終於在I/O大會上發布了開源的視頻封裝格式webM和視頻編碼格式VP8。Opera、Mozilla、Chrome宣布將完全支持VP8,IE宣布部分支持(需要裝一個插件,但如果我沒記錯的話,HTML5的一個願景就是脫離浏覽器插件,微軟真是讓人覺得悲劇)。
蘋果決定不支持VP8,喬布斯認為VP8在質量或效率方面不如H.264,不能滿足其產品的要求。另外最新消息表明VP8還有可能牽扯到專利的問題(如果真的侵犯專利的話,Opera和Firefox估計馬上會無視VP8的)。
說了這麼多,其實說到底就是,現在如果要在頁面中使用<video>標簽,需要考慮三種情況,支持Ogg Theora或者VP8(如果這玩意兒沒出事的話)的(Opera、Mozilla、Chrome),支持H.264的(Safari、IE 9、Chrome),都不支持的(IE6、7、8)。
好吧,現在讓我們從技術層面來認識HTML 5的視頻,包括<video>標簽的使用,視頻對象可以用到的媒介屬性和方法,以及媒介事件。
2 Video標簽的使用
Video標簽含有src、poster、preload、autoplay、loop、controls、width、height等幾個屬性,以及一個內部使用的標簽<source>。
Video標簽內除了可以包含<source>標簽外,還可以包含當指定的視頻都不能播放時,返回的內容。
2.1 src屬性和poster屬性
你能想象src屬性是用來干啥的。跟<img>標簽的一樣,這個屬性用於指定視頻的地址。
而poster屬性用於指定一張圖片,在當前視頻數據無效時顯示(預覽圖)。視頻數據無效可能是視頻正在加載,可能是視頻地址錯誤等等。
2.2 preload屬性
這個屬性也能通過名字了解用處,此屬性用於定義視頻是否預加載。屬性有三個可選擇的值:none、metadata、auto。如果不使用此屬性,默認為auto。
None:不進行預加載。使用此屬性值,可能是頁面制作者認為用戶不期望此視頻,或者減少HTTP請求。
Metadata:部分預加載。使用此屬性值,代表頁面制作者認為用戶不期望此視頻,但為用戶提供一些元數據(包括尺寸,第一幀,曲目列表,持續時間等等)。
Auto:全部預加載。
2.3 autoplay屬性
又是一個看名字知道用處的屬性。Autoplay屬性用於設置視頻是否自動播放,是一個布爾屬性。當出現時,表示自動播放,去掉是表示不自動播放。
注意,HTML中布爾屬性的值不是true和false。正確的用法是,在標簽中使用此屬性表示true,此時屬性要麼沒有值,要麼其值恆等於他的名字(此處,自動播放為<video autoplay />或者<video autoplay=”autoplay” />);而在標簽中不使用此屬性表示false(此處不進行自動播放為<video />)。
2.4 loop屬性
一目了然,loop屬性用於指定視頻是否循環播放,同樣是一個布爾屬性。
2.5 controls屬性
Controls屬性用於向浏覽器指明頁面制作者沒有使用腳本生成播放控制器,需要浏覽器啟用本身的播放控制欄。
控制欄須包括播放暫停控制,播放進度控制,音量控制等等。
每個浏覽器默認的播放控制欄在界面上不一樣。由於我浏覽器的詭異問題,Firefox和Safari的Video不正常,所以這兩個只能在網上找截圖了。
2.6 width屬性和height屬性
屬於標簽的通用屬性了,這個不用多說。
2.7 source標簽
Source標簽用於給媒體(因為audio標簽同樣可以包含此標簽,所以這兒用媒體,而不是視頻)指定多個可選擇的(浏覽器最終只能選一個)文件地址,且只能在媒體標簽沒有使用src屬性時使用。
浏覽器按source標簽的順序檢測標簽指定的視頻是否能夠播放(可能是視頻格式不支持,視頻不存在等等),如果不能播放,換下一個。此方法多用於兼容不同的浏覽器。Source標簽本身不代表任何含義,不能單獨出現。
此標簽包含src、type、media三個屬性。
src屬性:用於指定媒體的地址,和video標簽的一樣。
Type屬性:用於說明src屬性指定媒體的類型,幫助浏覽器在獲取媒體前判斷是否支持此類別的媒體格式。具體的屬性值,請參見W3C的文檔。
Media屬性:用於說明媒體在何種媒介中使用,不設置時默認值為all,表示支持所有媒介。你想到<style>標簽的media屬性了麼?一樣一樣一樣的。
2.8 一個完整的例子
這段代碼在頁面中定義了一個視頻,此視頻的預覽圖為poster的屬性值,顯示浏覽器的默認媒體控制欄,預加載視頻的元數據,循環播放,寬度為900像素,高度為240像素。
第一選擇視頻地址為第一個source標簽的src屬性值,視頻類別為Ogg視頻,視頻編碼譯碼器為Theora,音頻編碼譯碼器為Vorbis,播放媒介為顯示器;第二選擇視頻地址不再累述。
如果你還要兼容IE的話,可以在最後一個source標簽後再加上Flash播放器的標簽集,或者使用一點JavaScript代碼。具體可以查看這篇文章。
3 媒介屬性
媒介屬性包括error、currentsrc、networkState、preload、buffered、readyState、seeking、currentTime、startTime、duration、paused、defaultPlaybackRate、playbackRate、played、seekable、ended、autoplay、loop、controls、volume、muted等,可以用於返回或改變媒介的狀態。
注意:以下使用到的“media”統一代表一個視頻元素。如下圖所示:
3.1 error屬性
只讀屬性。使用media.error返回一個MediaError對象表明當前的錯誤狀態,如果沒有出錯,返回null。
使用media.error.code返回媒介的錯誤狀態,共有4個可能值。
MEDIA_ERR_ABORTED(數字值為1):媒體資源獲取異常;
MEDIA_ERR_NETWORK(數字值為2):網絡錯誤;
MEDIA_ERR_DECODE(數字值為3):媒體解碼錯誤;
MEDIA_ERR_SRC_NOT_SUPPORTED(數字值為4):視頻格式被不支持。
3.2 currentSrc屬性
只讀屬性。使用media.currentSrc返回該媒介標簽的src屬性值。
3.3 networkState屬性
只讀屬性。使用media.networkState返回媒介的網絡狀態,共有4個可能值。
NETWORK_EMPTY(數字值為0):尚未初始化;
NETWORK_IDLE(數字值為1):加載完成,網絡空閒;
NETWORK_LOADING(數字值為2):視頻加載中;
NETWORK_NO_SOURCE(數字值為3):加載失敗。
3.4 preload屬性
可讀寫屬性。使用media.preload返回媒介標簽的preload屬性值,或者對其進行賦值,改變媒介標簽的preload屬性值。
3.5 buffered屬性
只讀屬性。使用media.buffered返回一個TimeRanges對象,確認浏覽器已緩存媒介文件。
3.6 readyState屬性
只讀屬性。使用media.readyState返回媒介當前播放位置的就緒狀態,共有5個可能值。
HAVE_NOTHING(數字值為0):當前播放位置無有效媒介資源;
HAVE_METADATA(數字值為1):加載中,媒介資源確認存在,但當前位置沒有能夠加載到有效媒介數據進行播放;
HAVE_CURRENT_DATA(數字值為2):已獲取到當前播放數據,但沒有足夠的數據進行播放;
HAVE_FUTURE_DATA(數字值為3):已獲取到後續播放數據,可以進行播放;
HAVE_ENOUGH_DATA(數字值為4):可以進行播放,且浏覽器確認媒體數據以某一種速度進行加載,可以保證有足夠的後續數據進行播放,而不會使浏覽器的播放進度趕上加載數據的末端。
3.7 seeking、seekable屬性
均為只讀屬性。
使用media.seeking返回一個布爾值,表明浏覽器是否正在請求數據,ture表示浏覽器正在請求數據,false表示浏覽器已停止請求。
使用media.seekable發揮一個TimeRanges對象,表明可以對當前媒介資源進行請求。
3.8 currentTime、startTime、duration屬性
三者的值均為時間,單位為秒,currentTime為可讀寫屬性,其余兩個均為只讀屬性。
使用media.currentTime返回當前媒介的播放位置,或者對其賦值,改變媒介的播放位置。
對於使用media.currentTime的時候,如果返回的時間超出了浏覽器的請求能力,將拋出一個INDEX_SIZE_ERR異常;如果沒有選中的媒體資源,將拋出一個INVALID_STATE_ERR異常。
使用media.startTime返回媒介文件播放的開始時間,通常為0。
使用media.duration返回媒介文件總的播放時長。
3.9 played、paused、ended屬性
三者均為只讀屬性。
使用media. played返回一個TimeRanges對象,標明浏覽器已播放的媒介資源范圍。
使用media.paused返回一個布爾值,表明媒介是否暫停播放,ture表示媒介暫停播放,false表示媒介正在播放。
使用media.ended返回一個布爾值,表明媒介是否已結束,ture表示媒介已經播放完畢,false表示還未播放完畢。
3.10 defaultPlaybackRate、playbackRate屬性
兩者均為可讀寫屬性。
使用media.defaultPlaybackRate返回媒介默認的播放速率,或對其賦值,改變媒介的默認播放速率。
使用media.playbackRate返回當前的媒介播放速率,或對其賦值,改變當前的媒介播放速率。
3.11 autoplay、loop屬性
兩者均為可讀寫屬性。
使用media.autoplay返回一個布爾值,表明當前媒介是否設置了自動播放,ture表示當前媒介為自動播放,false表示非自動播放,或對其賦值,設置是否自動播放。
使用media.loop返回一個布爾值,表明當前媒介是否設置了循環播放,ture表示當前媒介設置了循環播放,false表示沒有設置循環播放,或對其賦值,設置是否循環播放。
3.12 controls、volume、muted屬性
三者均為可讀寫屬性。
使用media.controls返回一個布爾值,表明當前媒介是否使用了浏覽器默認的播放控制欄,ture表示加載了,false表示沒有加載,或對其賦值,設置是否使用浏覽器默認的播放控制欄。
使用media.volume返回當前媒介的音量值,或對其賦值,改變媒介的播放音量,范圍為0到1,0相當於靜音,1為最大音量。
使用media.muted返回一個布爾值,表明當前媒介播放是否開啟靜音,ture表示沒有開啟靜音,false表示靜音,或對其賦值,設置播放是否靜音。
4 媒介方法
4.1 play()、pause()、load()方法
使用media.play()播放視頻,並會將media.paused的值強行設為false。
使用media.pause()暫停視頻,並會將media.paused的值強行設為ture。
使用media.load()重新載入視頻,並會將media.playbackRate的值強行設為media.defaultPlaybackRate的值,且強行將media.error的值設為null。
4.2 canPlayType(type)方法
使用canPlayType(type)方法測試浏覽器是否支持特定的媒介類型。其中,type參數和1.1.7節中介紹的type屬性是相同的。
方法返回3個可能值(均為浏覽器判斷的結果)。
空字符串:浏覽器不支持此種媒體類型;
maybe:浏覽器可能支持此種媒體類型;
probably:浏覽器確定支持此種媒體類型。
5 媒介事件
媒介事件可以作用於各種媒介元素,如視頻、音頻、圖片等,主要包括loadstart、progress、suspend、abort、error、emptied、stalled、play、pause、loadedmetadata、loadeddata、waiting、playing、canplay、canplaythrough、seeking、seeked、timeupdate、ended、ratechange、durationchange、volumechange等事件。
5.1 事件處理方式
一般有兩種方式處理事件。
一種是監聽的方式:addEventListener(“事件名”,處理函數,處理方式)。例如,如果需要在浏覽器對媒介進行播放時執行begin_playing函數,那麼可以這樣,media. addEventListener(“play”, begin_playing,false)。
另一種是直接賦值的方式:on時間名=處理函數,這是我們相對用的較多的方法,也就是“當XXX事件觸發時”。例如,要進行和上面相同的處理,可以這樣media.onplay= begin_playing。
5.2 事件介紹
loadstart事件:浏覽器開始請求媒介;
progress事件:浏覽器正在獲取媒介;
suspend事件:浏覽器非主動獲取媒介數據,但沒有加載完整個媒介資源;
abort事件:浏覽器在完全加載前中止獲取媒介數據;
error事件:獲取媒介數據出錯;
emptied事件:媒介元素的網絡狀態突然變為未初始化;
stalled事件:浏覽器獲取媒介數據異常;
play事件:即將開始播放
pause事件:暫停播放
loadedmetadata事件:浏覽器獲取完媒介資源的時長和尺寸
loadeddata事件:已加載當前播放位置的媒介數據;
waiting事件:播放由於下一幀無效(例如未加載)而已停止(但浏覽器確認下一幀會馬上有效);
playing事件:已經開始播放
canplay事件:浏覽器能夠開始媒介播放,但估計以當前速率播放不能直接將媒介播放完(播放期間需要緩沖);
canplaythrough事件:浏覽器估計以當前速率直接播放可以直接播放完整個媒介資源(期間不需要緩沖);
seeking事件:浏覽器正在請求數據(seeking屬性值為true);
seeked事件:浏覽器停止請求數據(seeking屬性值為false);
timeupdate事件:當前播放位置(currentTime屬性)改變;
ended事件:播放由於媒介結束而停止;
ratechange事件:默認播放速率(defaultPlaybackRate屬性)改變或播放速率(playbackRate屬性)改變;
durationchange事件:媒介時長(duration屬性)改變;
volumechange事件:音量(volume屬性)改變或靜音(muted屬性)。
6 Video完結
W3C網站上有一個關於HTML 5視頻的舉例,很好的說明了所有前面介紹的標簽的使用,屬性和方法以及事件的應用,非常直觀。隨便還可以通過這個頁面查看浏覽器對HTML 5視頻各個方面的支持情況。
文檔的第一章,關於HTML 5視頻的相關知識背景和技術規范就差不多介紹完了,整章的內容不是文字就是代碼,有圖也幾乎是代碼截圖。後續還會有第二章、第三章……HTML 5引入了很多強大的新內容,我們有很多東西需要去學習。學習的過程相當枯燥,寫文檔也是如此,希望有同學能按順序看到這兒,感謝你的耐心閱讀。期待HTML 5能早日普及,給互聯網帶來新鮮血液。