一、基本
video標簽在兼容性上還是比較差的,如果要在頁面中使用video標簽,需要考慮三種情況,支持Ogg Theora或者VP8的(Opera、Mozilla、Chrome),支持H.264的(Safari、IE 9、Chrome),都不支持的(IE6、7、8)。但是由於H5在移動設備上展現,基本都是使用webkit內核,只需要考慮Android、IOS設備上的差異。
<video id="video" autoplay="autoplay" loop="loop" preload="auto" controls="controls" src="movie.mp4" poster="pre.jpg" width="640" height="1280"> 瀏覽器不支持,換個牛逼點的吧 </video>
video標簽含有src、poster、preload、autoplay、loop、controls、width、height等幾個屬性, 以及一個內部使用的標簽<source>。video標簽內除了可以包含<source>標簽外,還可以包含當指定的視頻都不能 播放時,返回的內容,如上面的文字。
1、src
就是媒體文件的URL,不用這個標簽也可以使用內部標簽<source>,但是個人覺得用src好看些~同樣各個瀏覽器對媒體文件的格式有要求,就支持3種格式ogg、mp4、webM,兼容性如下
格式 IE Firefox Opera Chrome Safari
Ogg No 3.5+ 10.5+ 5.0+ No
MPEG4 9.0+ No No 5.0+ 3.0+
WebM No 4.0+ 10.6+ 6.0+ No
2、poster
poster屬性用於指定一張圖片的URL,在當前視頻數據無效時顯示。視頻數據無效可能是視頻正在加載,可能是視頻地址錯誤等等。這個屬性還是蠻有用處的,特別是在網絡情況不怎么樣的時候,把視頻的第一幀圖片放在那,然后當視頻播放時就沒有違和感。
3、preload
此屬性用於定義視頻是否預加載。屬性有三個可選擇的值:none、metadata、auto。如果不使用此屬性,默認為auto。
None:不進行預加載;
Metadata:部分預加載(包括尺寸,第一幀,曲目列表,持續時間等等);
Auto:全部預加載;
4、autoplay
autoplay屬性用於設置視頻是否自動播放,出現時,表示自動播放,去掉是表示不自動播放。(這個屬性在移動設備上蠻廢的)
5、loop
loop屬性用於指定視頻是否循環播放
6、controls
如果出現該屬性,則向用戶顯示控件,控制欄須包括播放暫停控制,播放進度控制,音量控制等等。
7、width、height
寬度、高度羅
二、方法和事件
var video = document.getElementById("video");
1、屬性和方法
a、錯誤
video.error; //null:正常
video.error.code; //返回錯誤編碼 1.用戶終止 2.網絡錯誤 3.解碼錯誤 4.URL無效
b、網絡狀態
video.currentSrc; //返回當前資源的URL
video.src = value; //返回或設置當前資源的URL
video.canPlayType(type); //是否能播放某種格式的資源
video.networkState; //返回網絡狀態碼 0.此元素未初始化 1.正常但沒有使用網絡 2.正在下載數據 3.沒有找到資源
video.load(); //重新加載src指定的資源
video.buffered; //返回已緩沖區域
video.preload; //返回預加載信息 none:不預載 metadata:預載資源信息 auto:
c、播放狀態
video.currentTime = value; //當前播放的位置,賦值可改變位置
video.startTime; //一般為0,如果為流媒體或者不從0開始的資源,則不為0
video.duration; //當前資源長度 流返回無限
video.paused; //是否暫停
video.defaultPlaybackRate = value;//默認的回放速度,可以設置
video.playbackRate = value;//當前播放速度,設置后馬上改變
video.played; //返回已經播放的區域,TimeRanges
video.ended; //是否結束
video.autoPlay; //是否自動播放
video.loop; //是否循環播放
video.play(); //播放
video.pause(); //暫停
d、視頻控制
video.controls;//是否有默認控制條
video.volume = value; //音量
video.muted = value; //靜音
2、事件
video.addEventListener("XXX" , function(){ //..... })
XXX是事件類型
loadstart //客戶端開始請求數據
progress //客戶端正在請求數據
suspend//延遲下載
abort //客戶端主動終止下載(不是因為錯誤引起)
loadstart //客戶端開始請求數據
error //請求數據時遇到錯誤
stalled //網速失速
play //play()和autoplay開始播放時觸發
pause//pause()觸發
loadedmetadata //成功獲取資源長度
waiting//等待數據,並非錯誤
playing//開始回放
canplay//可以播放,但中途可能因為加載而暫停
canplaythrough//可以播放,歌曲全部加載完畢
seeking //尋找中
seeked//尋找完畢
timeupdate //播放時間改變
ended//播放結束
ratechange//播放速率改變
durationchange //資源長度改變
volumechange //音量改變
三、開發中遇到的坑
1、mp4文件在瀏覽器中只能播放音頻部分,視頻部分不顯示
這是開發時最開始遇到的問題,因為視頻是用單反錄的,經過濾鏡、剪輯等處理導出AVI格式,然后通過格式工廠轉成mp4,但是在瀏覽器中硬是沒有視頻顯示只有音頻的聲音。最后確定是視頻轉換是編碼的問題,格式工廠在轉換時可以選擇一些編碼格式,包括MPEG2、MPEG4、AVC、WMV2等等。選擇AVC就好了,當時也是醉了
2、mp4文件在蘋果設備的瀏覽器上不能播放,android上是好的
播放按鈕上一個大大的斜杠,表示不能播放,當時心中淚崩啊。經過問題查找,是因為http協議中沒有rang請求頭,具體跟IOS的播放器如何使用http協議進行mp4解析有關。最方便快捷的解決辦法就是使用nginx存放mp4文件。
http頭的Range、Content-Range表示http斷點續傳
Range
用於請求頭中,指定第一個字節的位置和最后一個字節的位置,一般格式:
Range:(unit=first byte pos)-[last byte pos]
Content-Range
用於響應頭,指定整個實體中的一部分的插入位置,他也指示了整個實體的長度。在服務器向客戶返回一個部分響應,它必須描述響應覆蓋的范圍和整個實體長度。一般格式:
Content-Range: bytes (unit first byte pos) - [last byte pos]/[entity legth]
請求下載整個文件:
- GET /test.rar HTTP/1.1
- Connection: close
- Host: 116.1.219.219
- Range: bytes=0-801 //一般請求下載整個文件是bytes=0- 或不用這個頭
一般正常回應
- HTTP/1.1 200 OK
- Content-Length: 801
- Content-Type: application/octet-stream
- Content-Range: bytes 0-800/801 //801:文件總大小
3、IOS設備自動播放不生效,必須要手動調用play()方法
autoplay真的是個蠻沒有什么作用的屬性,IOS中不能自動播放,需要JS調用play()方法,解決辦法就是
<script> if ("wView" in window) { //用於蘋果設備自動播放 window.wView.allowsInlineMediaPlayback = "YES"; window.wView.mediaPlaybackRequiresUserAction = "NO"; } </script>
在html文件head標簽中加入上述JS代碼
4、在部分android設備上無法播放
無法播放是指autoplay這個鬼沒有用,同時調用play()方法同樣然並卵,這個問題我也不清楚解決的原因是什么,在網上抄的代碼
具體情況是,在播放時需要判斷用戶的手機類型,IOS和Android設備分開處理
var isiOS = !! navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
然后IOS設備直接使用autoplay這個屬性或者調用play()方法,android這邊需要在video之上加一張圖片,通過點擊圖片然后播放,100ms之后設置視頻時間為1S,然后再次播放,就OK了
$(video).css({ display: "block" }); $(".androidBegin").show(); $(".androidBegin").bind("touchstart", function(a) { video.play(); setTimeout(function() { video.currentTime = 1; video.play(); }, 100) $(".androidBegin").hide(); $(video).unbind("touchstart"); })
如果不加入點擊事件,直接調用點擊事件內的播放代碼,那么該視頻就直接結束了,感覺好奇葩,然后就是連續播放多個視頻,只需要第一個使用上述代碼進行觸發就行,之后的視頻直接調用play()方法即可,如有大神遇到類似的問題,有更好的辦法,請指教下,謝謝!