視頻播放--踩坑小計

視頻播放--踩坑小計

來自專欄數據體驗技術

作者 chenjsh36 螞蟻金服·數據體驗技術團隊

隨著流量時代的到來和硬體技術的提升,越來越多的網站希望能在PC端或移動端播放自己的視頻,而 <video>的兼容性的逐漸完善,使得開發者更願意使用它來實現視頻播放場景。

本篇文章主要羅列視頻播放的通用場景及各場景下踩過的坑,希望能幫助開發者在遇到需求開發時能更快地選擇合適的技術方案同時減少採坑的次數。

場景一:自動播放

autoPlay 布爾屬性;指定後,視頻會馬上自動開始播放,不會停下來等著數據載入結束。

視頻自動播放可以在頁面打開且資源載入足夠的情況下讓視頻自動播放,減少一次用戶點擊的交互,同時可以應用在動效背景、H5仿視頻通話的功能。不過由於各種原因,自動播放無論在PC端還是移動端都有不同程度的限制。

移動端

IOS

早期必須要有用戶手勢(user gesture)video標籤才可以播放; 從版本10開始修改了video的規則,蘋果放寬了inline和autoplay,策略如下(僅適用於Safari瀏覽器):

  • <video> elements will be allowed to autoplay without a user gesture if their source media contains no audio tracks.(無音頻源的 video 元素 允許自動播放)
  • <video muted> elements will also be allowed to autoplay without a user gesture.(禁音的 video 元素允許自動播放)
  • If a <video> element gains an audio track or becomes un-muted without a user gesture, playback will pause.(如果 video 元素在沒有用戶手勢下有了音頻源或者變成非禁音,會暫停播放)
  • <video autoplay> elements will only begin playing when visible on-screen such as when they are scrolled into the viewport, made visible through CSS, and inserted into the DOM.(video 元素屏幕可見才開始播放)
  • <video autoplay> elements will pause if they become non-visible, such as by being scrolled out of the viewport.(video元素不可見後停止播放)

安卓

早期同樣需要用戶手勢才可以播放; 安卓的 chrome 53 後放寬了自動播放策略,策略不同於IOS的Safari,需要同時對 video 設置 autoplaymuted(是否禁音),才允許自動播放; 安卓的 FireFox 和 UC 瀏覽器支持任何情況下的自動播放; 安卓的其他瀏覽器暫時不清楚情況;

PC端

早期是支持自動播放,但近來 Safari、Chrome陸續修改了自動播放的策略……

Safari 瀏覽器

Safari 10 後帶音頻的視頻和音頻默認禁止自動播放,更多信息可以參考這篇文章;

Chrome(舊版本) 下自動播放:

Safari (10後)不自動播放:

Chrome 瀏覽器

禁音的視頻依舊可以播放,帶聲音的視頻會根據媒體參與指數來決定能否自動播放,那什麼是媒體參與指數?官方給了解釋和相關的維度:

MEI 是一個評估用戶對於當前站點的媒體參與程度的指數,它取決於下面幾個維度:

  • 用戶在媒體上停留時間超過了 7秒以上
  • 音頻必須是展示出來,並且沒有靜音
  • 與 video 之間有過交互
  • 媒體的尺寸不小於 200x140.

看完後開發者的心裡是這樣的:

檢測能否自動播放?

好在無論是 Safari 還是 Chrome,在限制了自動播放的同時,提供了檢測視頻是否能自動播放的機制,以便於開發者在發現無法自動播放時有備選方案:

var promise = document.querySelector(video).play();if (promise !== undefined) { promise.catch(error => { // Auto-play was prevented // Show a UI element to let the user manually start playback }).then(() => { // Auto-play started });}

思考

為什麼早期禁止視頻自動播放?

because it can be disruptive, data-hungry and many users dont like it. (因為它是破壞性的、需要大量流量同時很多用戶不喜歡它)

為什麼又允許自動播放?

  • 有些開發者使用其他方式如 canvas、gif 等來實現視頻自動播放的效果,但是性能上、流量消耗上都遠不如視頻播放;
  • 現在流量便宜了、手機硬體越來越好了;
  • 用戶可以通過設置來禁止自動播放(開啟省流量模式等);

為什麼 IOS 下微信和釘釘可以自動播放帶聲音的視頻?

確實發現在微信經常能看到自動播放的H5,但是作者自己寫的設置了 autoplay、playsInline 的視頻播放樣例,在微信上依舊無法自動播放,而在釘釘上卻可以自動播放

系統-瀏覽器帶聲音不帶聲音IOS 釘釘支持支持IOS Safari禁止自動播放IOS 微信禁止禁止

通過查詢資料,IOS WebAPP 開發都是基於 IOS 提供的瀏覽器內核進行開發的,所以在 WebAPP 的 webview 中可以修改自動播放的表現,釘釘明顯是支持自動播放,微信則是禁止自動播放,但是提供了內置事件來支持自動播放:

微信下通過 WeixinJSBridgeReady 事件進行自動播放:

document.addEventListener( WeixinJSBridgeReady, function() { video.play(); }, false);

場景二:全屏處理

在移動端瀏覽器, video 在用戶點擊播放或者通過API video.play() 觸發播放時,會強制以全屏置頂的形式進行播放,設計的初衷可能是因為全屏能提供更好的用戶體驗,但有時候開發者希望能自己控制是否全屏從而實現其他需求。

playsinline 取消全屏

如果想實現不全屏播放,只需在video標籤加個 playsinline 屬性即可,這個屬性在基於webkit內核的移動端瀏覽器基本沒問題,實在不行就再加個 webkit-playsinline

<video src={videoUrl} webkit-playsinline="true" playsinline="true" />

那麼對於其他內核的瀏覽器要怎麼處理呢?這個時候要了解下目前市場上存在的瀏覽器有哪些。

playsinline 兼容性

首先要知道全球目前四個瀏覽器內核:

  • 微軟IE的Trident
  • 網景最初研發後賣給Mozilla基金會並演化成火狐的Gecko
  • KDE的開源內核Webkit
  • Opera的Presto

其中:

  • Trident在移動端主要為WP7系統內置瀏覽器
  • Presto在所有聯網設備上都使用,移動終端上主要為 Opera Mobile、OperaMini、歐朋瀏覽器以及歐朋HD Beta版
  • Webkit內核的適用範圍則較為廣泛,Android原生瀏覽器、蘋果的Safari、谷歌的Chrome(Android4.0使用)都是基於Webkit開源內核開發的。

而國內常見的PC瀏覽器如UC瀏覽器、QQ瀏覽器、百度手機瀏覽器、360安全瀏覽器、谷歌瀏覽器、搜狗手機瀏覽器、獵豹瀏覽器以及移動端的UC、QQ、百度等手機瀏覽器都是根據Webkit修改過來的內核,本質上我們可以認為市場上移動端用戶使用的基本上都是webkit內核或者基於 webkit 內核做修改的瀏覽器,所以 playsinline 的兼容性非常好!

場景三:播放控制

video 元素有提供多個行為事件供開發者控制視頻播放,兼容性比較好的有 onendedontimeupdate、onplay、onplaying等,有些事件在不同瀏覽器不同設備上的的表現情況並不一致,

例如:ios 下監聽canplay(是否已緩衝了足夠的數據可以流暢播放),當載入時是不會觸發的,即使preload="auto"也沒用,但在 pc 的 Chrome 調試器下,是會在載入階段就觸發。ios 需要播放後才會觸發。

Chrome 模擬器

載入完成:

點擊播放:

MacOS Safari

載入完成:

點擊播放

IOS Safari

載入完成:

點擊播放:

部分事件在不同系統、設備、瀏覽器下顯示的特性不一致,使用的時候需謹慎。

場景四:隱藏播放控制項

controls 加上這個屬性,Gecko 會提供用戶控制,允許用戶控制視頻的播放,包括音量,跨幀,暫停/恢復播放。

controls 屬性規定瀏覽器應該為視頻提供播放控制項,反之則隱藏播放控制項,那麼開發者可以自定義自己的播放控制項。隱藏播放控制項在 PC 端和 IOS 移動端兼容性良好,而在安卓移動端並不支持隱藏控制項,不過還是可以通過一些方法來實現。

黑科技法

比較黑科技的方法是放大視頻,把控制項條移到視野之外,從而達到隱藏的效果!其實就是讓視頻元素比父容器還大,這樣底部的控制條就會在父容器外面,然後父容器設置為:overflow:hidden 實現隱藏播放控制項的方法! 缺點是視頻會被放大,需要提前留好空白供放大用。

微信瀏覽器

騰訊的android團隊的x5內核團隊放開了視頻播放的限制,視頻不一定調用它們那個備受詬病的視頻播放器了,利用x5-video-player-type="h5"屬性隱藏控制項元素,同時視頻不再置頂,允許其他元素浮動在頂層

總結

了解了視頻播放的通用場景及常見的坑後,我們只要針對不同的場景提供對應的兜底方案就能增強用戶體驗效果。例如移動端自動播放的H5 頁面,可以通過引導用戶進行點擊或者滑動來間接觸發視頻播放是最保守的做法,no bug!更好的方案是默認自動播放並捕捉禁止播放的情況,再引導用戶進行交互實現視頻播放。

使用 video 進行視頻播放早期因為涉及到性能消耗大、流量消耗多以及處於用戶體驗等的考慮,在移動端被限制得很嚴重,但是隨著手機性能的提升、流量時代的到來、更強地場景需求,逐步放寬了限制,而PC端則逐漸從「寬鬆世代」走向「緊縮世代」,兩者都有出於讓用戶有更好地體驗的目的而不斷更新自己的策略,未來也許會走向一統,開發者就可以從底層兼容適配中釋放出來,從而有更多地精力來做更上層的工作。

參考

  • auto-play-policy-changes-for-macos
  • Chrome auto-play
  • auto-play-is-bad-for-users
  • 為什麼很少有瀏覽器採用Gecko內核?
  • 瀏覽器內核

對我們團隊感興趣的可以關注專欄,關注github或者發送簡歷至tao.qit####alibaba-inc.com.replace(####, @),歡迎有志之士加入~

原文地址:github.com/ProtoTeam/bl


推薦閱讀:

橫行的前端(上)
CSS 在relative absolute定位布局裡通過-margin定位技巧
熟練使用這幾款仿站工具, 推廣事半功倍
React 應用設計之道 - curry 化妙用
每日一個前端特效(誤)-滾動錨點動畫

TAG:前端開發 | HTML5 |