爲了監控移動端視頻播放的狀況,研究了一下 html5 <video>
標籤的屬性與事件觸發,及其在各系統和各個瀏覽器的兼容狀況javascript
理解清楚屬性和事件,才能更好的使用 video ,達到預期的效果,更好的檢測視頻播放的情況來作出分析和調整,這裏僅列舉了解到且大體理解的,更多相關後續補充html
<video>
標籤嵌入到HTML文檔中html5
<video src="" type="video/mp4" autoplay="autoplay" controls="" poster="" preload="none"></video>
初始化 <video>
標籤時主要設置的屬性java
src:要嵌到頁面的視頻的URL。可選;你也可使用video塊內的 <source>
元素來指定須要嵌到頁面的視頻android
autoplay:布爾屬性;指定後,視頻會立刻自動開始播放,不會停下來等着數據載入結束ios
controls:加上這個屬性,Gecko 會提供用戶控制,容許用戶控制視頻的播放,包括音量,跨幀,暫停/恢復播放web
poster:一個海報幀的URL,用於在用戶播放或者跳幀以前展現。若是屬性未指定,那麼在第一幀可用以前什麼都不會展現;以後第一幀就像海報幀同樣展現canvas
preload:該枚舉屬性旨在告訴瀏覽器做者認爲達到最佳的用戶體驗的方式是什麼。多是下列值之一:api
none:提示做者認爲用戶不須要查看該視頻,服務器也想要最小化訪問流量;換句話說就是提示瀏覽器該視頻不須要緩存跨域
metadata:提示儘管做者認爲用戶不須要查看該視頻,不過抓取元數據(好比:長度)仍是很合理的
auto:用戶須要這個視頻優先加載;換句話說就是提示:若是須要的話,能夠下載整個視頻,即便用戶並不必定會用它
空字符串:也就代指 auto 值
buffered:這個屬性能夠讀取到哪段時間範圍內的媒體被緩存了。該屬性包含了一個 TimeRanges 對象
played:一個 TimeRanges 對象,指明瞭視頻已經播放的全部範圍
loop:布爾屬性;指定後,會在視頻結尾的地方,自動返回視頻開始的地方
muted:布爾屬性,指明瞭視頻裏的音頻的默認設置。設置後,音頻會初始化爲靜音。默認值是 false ,意味着視頻播放的時候音頻也會播放
height:視頻展現區域的高度,單位是 CSS 像素
width:視頻顯示區域的寬度,單位是 CSS 像素
crossorigin:該枚舉屬性指明抓取相關圖片是否必須用到CORS(跨域資源共享)。 支持CORS的資源 可在 <canvas>
元素中被重用,而不會被污染。容許的值以下:
anonymous:跨域請求會被執行,可是不發送憑證。
use-credentials:跨域請求A cross-origin request會被執行,且憑證會被髮送。
TimeRanges 對象表示事件段,好比,視頻快進的時間段,有一個 length 屬性,表示時間段的個數,有兩個方法 start() 和 end() ,分別返回時間段開始的時間點和結束的時間點
事件交互中主要使用的屬性
currentTime:播放進行到的時間點,單位爲秒
duration:視頻總時長,單位爲秒
還有更多事件api,這裏只列舉了試過的
playing:在媒體開始播放時觸發(不管是初次播放、在暫停後恢復、或是在結束後從新開始)
ended:播放結束時觸發
pause:播放暫停時觸發
waiting:在一個待執行的操做(如回放)因等待另外一個操做(如跳躍或下載)被延遲時觸發
timeupdate:元素的 currentTime 屬性表示的時間已經改變
seeking: 在跳躍操做開始時觸發
seeked:在跳躍操做完成時觸發
error:在發生錯誤時觸發。元素的 error 屬性會包含更多信息
loadeddata: 媒體的第一幀已經加載完畢
播放:start:1(首次播放)2(重播)
播放:end:1
播放暫停:pause:1
播放停止:pause:1
快進/快退:jump:1(快進)2(快退)
錯誤:fail: 1(取回過程);2( 當下載時發生錯誤);3( 當解碼時發生錯誤);4( 不支持音頻/視頻)
播放等待: wait:1
播放時長:totaltime:秒(包含重播)
其中1,2,3,5,6,7都很好監控,對相應事件進行監聽就能夠了,這裏主要講下是怎麼監控播放停止和播放時長的
具體場景是移動端瀏覽器切換tab致使的隱藏和用戶按home鍵退出瀏覽器
html5 提供了 Page Visibility API 來支持監聽tab切換,與之對應新增了
document.hidden 屬性,它顯示頁面是否爲用戶當前觀看的頁面,值爲 ture 或 false
document.visibilityState 屬性, visible 表示頁面被展示, hidden 表示頁面未被展示, prerender 表示頁面在從新生成,用戶不可見
visibilitychange 事件,監聽頁面在 visible 與 hidden 之間的切換
visibilitychange事件的具體使用
var hidden; var visibilityChange; if (typeof document.hidden !== 'undefined') { hidden = 'hidden'; visibilityChange = 'visibilitychange'; } else if (typeof document.mozHidden !== 'undefined') { hidden = 'mozHidden'; visibilityChange = 'mozvisibilitychange'; } else if (typeof document.msHidden !== 'undefined') { hidden = 'msHidden'; visibilityChange = 'msvisibilitychange'; } else if (typeof document.webkitHidden !== 'undefined') { hidden = 'webkitHidden'; visibilityChange = 'webkitvisibilitychange'; } document.addEventListener(visibilityChange, function () { if (document[hidden]) { // do something... } }, false);
關於 visibilitychange 事件的兼容性,測試了兩部手機,華爲mt7 和 iphone6 ,兼容狀況以下
華爲mt7
qq瀏覽器:tab切換觸發,home鍵退出觸發
uc瀏覽器:tab切換觸發,home鍵退出觸發(退出後進程繼續在跑,其它瀏覽器進程被暫停)
手機百度:tab切換不觸發,home鍵退出不觸發
iphone6
uc瀏覽器:tab切換觸發,home鍵不觸發
百度瀏覽器:同上
手機百度:同上
Safari:tab切換觸發,home鍵退出觸發
因爲兼容問題,且各系統的各個瀏覽器基本在tab切換觸發,home鍵退出觸發的狀況下觸發pause事件,因此播放停止的日誌依舊打印pause,若是後面沒有繼續操做則把這個pause日誌當作播放停止
頁面刷新和瀏覽器tab被關閉的時候會觸發 window.onunload ,也能夠作爲補充場景
起初的思路是獲取到開始播放到中止播放的事件差,記下時間點使用了 currentTime 屬性,主要實如今兩方面
playing 時記下時間點startT, pause 和 ended 和 seeked 時記下時間點endT,endT - startT 即播放時長
seeked 時記下時間點startT, seeking 時記下時間點endT,endT - startT 即播放時長
這個思路在 ios 下是看似沒有問題的,可是 android 下確實不行,主要緣由是 seeking 事件的監聽沒理解到位,seeking 事件觸發點是用戶目標跳躍到的位置,好比:視頻播放在 0 秒點時,用戶點擊到了 60 秒點處,這是取到的 currentTime 就是 60 ,原本覺得會是 0 , ios 下看似沒有問題是由於它的全屏播放模式下,進度條是要拖拽的,不能直接點擊到某個點
因而,使用 timeupdate 來獲取 seeking 觸發前的時間點,就能夠獲取到相對準確的播放時長了
ios 下的qq瀏覽器和uc瀏覽器裏播放 html5 video 會啓用瀏覽器本身的播放窗口,qq瀏覽器什麼事件都監聽不到,uc瀏覽器監聽不到 seeking 和 seeked
沒有 <source>
元素且 src 元素爲空時播放會觸發 error 事件,狀態碼爲4
播放播放結束也會觸發暫停
播放結束後重播會觸發 seeking 和 seeked ,通常瀏覽器觸發一次, android 下uc瀏覽器觸發4次
ios 下uc瀏覽器和 android 下的一些瀏覽器不會觸發 seeking 和 seeked ,所以須要在 timeupdate 裏來分析猜想用戶行爲
欲先善其事必先利其器,遇到沒搞過的技術,必定要先測試一遍 api ,否則太浪費時間,學習內容來源
但願能多提寶貴建議,幫助筆者繼續優化
文章轉載自筆者我的博客 Gaoxuefeng's Blog