視頻播放--踩坑小計

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

隨着流量時代的到來和硬件技術的提高,愈來愈多的網站但願能在PC端或移動端播放本身的視頻,而 <video>的兼容性的逐漸完善,使得開發者更願意使用它來實現視頻播放場景。html

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

場景一:自動播放

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

視頻自動播放能夠在頁面打開且資源加載足夠的狀況下讓視頻自動播放,減小一次用戶點擊的交互,同時能夠應用在動效背景、H5仿視頻通話的功能。不過因爲各類緣由,自動播放不管在PC端仍是移動端都有不一樣程度的限制。android

移動端

IOS

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

  • <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 瀏覽器支持任何狀況下的自動播放; 安卓的其餘瀏覽器暫時不清楚狀況;git

PC端

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

Safari 瀏覽器

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

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

相關文章
相關標籤/搜索