視訊播放--踩坑小計

螞蟻金服資料體驗技術發表於2018-06-07

作者 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(舊版本) 下自動播放:

重新整理自動播放.gif | left | 747x388

Safari (10後)不自動播放:

重新整理不自動播放.gif | left | 747x393

Chrome 瀏覽器

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

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

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

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

vued84316a856ff371e9f33681648a99d2ba.png | center | 590x270

vuedec43e2b4cda0efe595430015154e1fd2.png | center | 592x270

檢測能否自動播放?

好在無論是 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 don't 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

image.png | left | 349x199

其中:

  • 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 模擬器

載入完成:

image.png | left | 345x230

點選播放:

image.png | left | 385x350

MacOS Safari

載入完成:

image.png | left | 328x186

點選播放

image.png | left | 348x500

IOS Safari

載入完成:

image.png | left | 284x158

點選播放:

image.png | left | 292x411

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

場景四:隱藏播放控制元件

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

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

黑科技法

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

image.png | left | 432x358

微信瀏覽器

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

總結

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

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

參考

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

原文地址:github.com/ProtoTeam/b…

相關文章