相關鏈接:
- H5 video 的使用
- H5 video 全屏播放
? video點播與直播
?H5 video
目前所有瀏覽器都支持的視頻格式是MP4格式,所以mp4應當是點播web視頻的首選格式。而在直播視頻上,H5 video只在移動端原生支持HLS
流的直播視頻(Mac safari video標簽也支持, PC Chrome不支持),其他直播流(如FLV
)就需要Flash
插件的支持。
? video與206狀態碼
video播放mp4時,發的依然是get請求,但http返回206狀態碼, 即
partial Content
。有關206狀態碼的相關內容,可以參考下文- Http協議206狀態碼
? 終止視頻下載
video.pause()
可以暫停視頻播放,但并不能停止視頻資源的繼續加載,媒體元素會繼續加載知道被垃圾回收機制回收。要在暫停播放后立即停止,可使用以下方法
video.pause()
video.src=''
video.removeAttribute('src');復制代碼
? 防止iOS上默認全屏播放
ios10及以后的版本,可以通過給video標簽加playsinline屬性防止iOS默認全屏播放,ios9之前加
webkit-playsinline
屬性,如果要兼容,則把兩個屬性都加上。通過客戶端添加配置
UIwebview: webview.allowsInlineMediaPlayback = YES
,不過還是要求在video元素上加playsinline屬性參考:
- HTML5 inline video on iPhone vs iPad/Browser
- allowsInlineMediaPlayback
? 自動播放及播放控制
在移動端,有些瀏覽器支持添加autoplay屬性后自動播放,有些設置 autoplay 和 muted屬性也能自動播放,比如IOS 10+、Chrome。
如果想控制什么時候播放,且并不是用戶觸發的(如沒有設置controls),那就設置muted屬性,然后調用video.play()方法,隔300ms左右有后,再通過video.muted = false打開聲音。
vide.muted = true;
video.play()
setTimeout(function () {video.muted = false
}, 300)復制代碼
iOS9及之前的版本要求有用戶交互才能播放,即手動點擊播放按鈕或者有用戶觸發的click、touchend、鍵盤等事件,然后調用video.play() 方法播放。在iOS9之前,iOS Native可以通過UIWebView的mediaPlaybackRequiresUserAction屬性來控制是否需要用戶交互。
使用element.click()觸發的click事件是否可以被人為是用戶行為?不能
瀏覽器是如何知道是否是用戶觸發的事件?Event對象的只讀屬性isTrusted
<div id="test-ele">這個元素監聽事件</div>
<script>const testEle = document.querySelector('#test-ele');testEle.addEventlistener('click', function (evt) {// 用戶觸發為true,script或EventTarget.dispatchEvent() 觸發為falseconsole.log(evt.isTrusted);}, false);testEle.click() // 這個觸發,evt.isTrusted = false
</script>復制代碼
有關iOS 10對safari video的放松策略可以參考: New <video> Policies for iOS
? video.play() 的Promise對象(可用于捕獲視頻播放錯誤)
在Chrome上,如果沒有設置video.muted屬性,在非用戶行為下,直接使用video.play() 播放,會收到 Uncaught (in promise) DOMException 的報錯,視頻也沒有播放。在iOS下面,可能不會有任何報錯,視頻也沒播放,這樣就無法定位問題。
video.play() 會返回一個Promise對象,如果播放失敗,可以通過返回的Promise catch到相關錯誤信息。
const pro = video.play();
if (pro) { // iOS9及以下版本不會返回Promise對象,做下兼容處理pro.catch(err=>{ console.log(err) });
}復制代碼
? TimeRanges 對象
在開始獲取played屬性的時候,以為會返回一個已經播放的時長,實際上返回的是TimeRanges對象,而且看到TimeRanges的length一直不變,當時一臉摸不著頭腦,不知道有什么用。后來在做進度控制,需要知道視頻已緩沖多少時,才弄明白。
video DOM對象有三個屬性會返回TimeRanges對象,分別為
video.played/ video.buffered/ video.seekable
視頻開始時只有一個播放時間段,如果不進行跳躍觀看,就一直只有一個時間段,即
TimeRanges.length
值為1;如果進行了跳躍觀看(如從2分鐘,突然跳進到15分鐘的位置),而跳躍內容并沒有緩沖完畢,則會出現兩個時間段,這時TimeRanges的length為2。所以TimeRanges個數會隨著跳躍觀看未緩沖完成的內容而增加,隨著緩沖的完成而減少,最少為1個,即從開頭到結尾。------------------------------------------------------
|=============| |===========| |
------------------------------------------------------
0? ? ? ? ?5? ? ? ? ? ? ? ? 15 19? ? 21
TimeRanges對象有一個length屬性和
start()
、play()
兩個方法:TimeRanges: length: 1 // 代表當前播放視頻存在的播放段 play(index) // 獲取指定播放段的播放(緩沖)開始時間,index從0開始取,以秒計 end(index) // 獲取指定播放段的播放(緩沖)結束時間
要獲取第一段的開始時間,使用
TimeRanges.start(0)
,結束時間為TimeRanges.end(0)
,第二段TimeRanges.start(1)
,以此類推參考:
- Media buffering, seeking, and time ranges: developer.mozilla.org/en-US/docs/…
- Time?Ranges: developer.mozilla.org/en-US/docs/…
? video的寬高
video視區的高寬根據視頻源有不同的固定比例,但并不會出現因video標簽或其容器的高寬設置比例與視頻源比例不一致而出現拉伸、變形,會自動根據設置的高寬中較小的值按照自身的比例進行縮放,不足的會兩邊補白居中。
如視頻的原始尺寸為640 * 360
設置video高400、寬800,高度的增長跟寬度的增長不成比例,寬度會比視寬度寬,則video會左右補白,視區居中。