安卓和IOS對於html5中的video兼容一直是大問題,各類不同,體驗還不好。這段時間作一個html的video播放的時候,要求全屏展現,真是各類問題。下面就就記一下這個項目中遇到的一下手機兼容問題和對應的處理方法。查資料的過程當中,發現針對於video的兼容問題仍是比較多個,會羅列視頻播放的通用場景和各個場景下踩過的坑,但願在需求開發的時候,可以針對合適的場景,選擇合適的技術方案。有相關的補充,歡迎你們進行補充。php
src
視頻的地址poster
容許用戶控制視頻的播放,包括音量,跨幀,暫停/恢復播放。controls
屬性規定視頻下載時顯示的圖像,或者在用戶點擊播放按鈕前顯示的圖像preload
在頁面加載後載入視頻webkit-playsinline
&& playsinline
視頻播放時局域播放,不脫離文檔流 。可是這個屬性比較特別, 須要嵌入網頁的APP好比WeChat中UIwebview 的allowsInlineMediaPlayback = YES webview.allowsInlineMediaPlayback = YES,才能生效。換句話說,若是APP不設置,你頁面中加了這標籤也無效,這也就是爲何安卓手機WeChat 播放視頻老是全屏,由於APP不支持playsinline,而ISO的WeChat卻支持。x-webkit-airplay
這個屬性應該是使此視頻支持ios的AirPlay功能。使用AirPlay能夠直接從使用iOS的設備上的不一樣位置播放視頻、音樂還有照片文件,也就是說經過AirPlay功能能夠實現影音文件的無線播放,固然前提是播放的終端設備也要支持相應的功能x5-video-player-type
啓用同層H5播放器,就是在視頻全屏的時候,div能夠呈如今視頻層上,也是WeChat安卓版特有的屬性。同層播放別名也叫作沉浸式播放,播放的時候看似全屏,可是已經除去了control和微信的導航欄,只留下"X"和"<"兩鍵。目前的同層播放器只在Android(包括微信)上生效,暫時不支持iOS。至於爲何同層播放只對安卓開放,是由於安卓不能像ISO同樣局域播放,默認的全屏會使得一些界面操做被阻攔,若是是全屏H5還好,可是作直播的話,諸如彈幕那樣的功能就沒法實現了,因此這時候同層播放的概念就解決了這個問題。不過在測試的過程當中發現,不一樣版本的IOS和安卓效果略有不一樣 安卓效果圖-如圖所示x5-video-orientation
聲明播放器支持的方向,可選值landscape 橫屏, portraint豎屏。默認值portraint。不管是直播仍是全屏H5通常都是豎屏播放,可是這個屬性須要x5-video-player-type開啓H5模式x5-video-player-fullscreen
全屏設置。它又兩個屬性值,ture和false,true支持全屏播放,false不支持全屏播放。其實,IOS 微信瀏覽器是Chrome的內核,相關的屬性都支持,也是爲何X5同層播放不支持的緣由。安卓微信瀏覽器是X5內核,一些屬性標籤好比playsinline就不支持,因此始終全屏。早期的安卓和IOS都須要用戶手勢才能自動播放,後期逐漸放寬的自動播放的策略,逐漸開始支持自動播放,固然在不一樣的安卓微信手機和對應的瀏覽器上,展現略有差別,這個沒有徹底清楚因此機型展現狀況。css
PC端的瀏覽器具體狀況有所差異,這個沒有進行深刻研究,你們有采坑歡迎進行補充。html
真正的作法是,檢測當前的瀏覽器是否能支持自動播放,示例代碼:前端
var promise = document.querySelector('video').play(); if (promise !== undefined) { promise.then(() => { // video can play }).catch(err => { // video cannot play }) }
document.addEventListener('WeixinJSBridgeReady', function () { music.play() }, false)
這個其實並不難,安卓和IOS,在微信環境下打開,默認應該都是全屏(不是視頻佔據整個手機的全屏,而是佔用body內的視窗範圍以內)html5
安卓全屏效果,沒有頂部的導航欄,只有」>「 和 」...「,[效果以下]:
android
IOS會直接打開全屏模式。效果以下:
ios
IOS的非全屏展現。對安卓無影響 IOS效果圖-如圖所示:
es6
可是有的時候不想全屏展現,只須要加上webkit-playsinline
&& playsinline
便可,視頻播放不脫離文檔流,進行局部播放。安卓狀況下有'...', 若是安裝過QQ瀏覽器會能進行小窗播放,懸浮在頁面的最上面,這個現象符合條件都有,可是不能去掉。這個仍是解決不了的,不過通常這樣操做的用戶仍是在少數。web
video 元素有提供多個行爲事件供開發者控制視頻播放,兼容性比較好的有 onended 、 ontimeupdate、onplay、onplaying等,有些事件在不一樣瀏覽器不一樣設備上的的表現狀況並不一致,不一樣的系統,設備,瀏覽器顯示的特性仍是很不同的,仍是看業務場景須要兼容到什麼樣,儘可能不要大量處理這些事件,否則用戶去瀏覽的時候,兼容問題較多。canvas
我處理的基本是,安卓和IOS進入全屏,退出全屏,暫停和中止這4個事件,其中進入全屏,退出全屏須要針對安卓和IOS作不一樣的處理。
安卓監聽進入全屏的事件:
jsvideo.addEventListener("x5videoenterfullscreen", () => { console.log("進入全屏通知"); }) jsvideo.addEventListener("x5videoexitfullscreen", () => { console.log("退出全屏通知"); })
IOS監聽進入全屏的事件:
jsvideo.addEventListener("webkitbeginfullscreen", () => { console.log("進入全屏通知"); }) jsvideo.addEventListener("webkitendfullscreen", () => { console.log("退出全屏通知"); })
監聽暫停事件
jsvideo.addEventListener('pause', () => { console.log('暫停了') })
監聽中止事件
jsvideo.addEventListener('ended', () => {
console.log('中止了22')
})
重頭戲來了,相信這個這個問題已困擾無數的前端開發人員,再搜尋這個問題的解決方法時,幾乎全部的文章都是告訴你android下,播放器的控件是去不了的。其實彷佛確實是這樣的,但後邊在的android下,也是沒有控制條的。最初看到那些H5視頻我首先並無去看他們的內容多麼新穎,傳播量多麼廣,我是第一時間測試了android下的兼容問題,發現並無出現控制條。在我研究半天未果時,在一篇技術帖中看到說:因是騰訊本身的項目,微信是騰訊本身的,他們在瀏覽器裏作了一些配置,對旗下出品的H5有所「優待」,才能確保視頻的順利「喬裝」。
上面的說法我並無真正覈實過,不過可使用css進行操做,我實現的方式是在video外層套一個div,height設置爲100%而且設置overflow:hidden,video大於100%,就能把控制條頂到視窗外。這算是視覺的隱藏(驚喜萬分~),這個時候對於video可能會形成放大,視頻要留有必定的安全區,防止遮擋主體內容。對於用戶體驗來講,長視頻沒有控制欄仍是挺不合適的,固然這個只是一個思路,具體的狀況仍是看產品的形式適合哪一種。
現象描述:設置poster在不一樣設備上表現不一樣,瀏覽器沒問題,可是微信瀏覽器和IOS就是死活顯示空白,展現效果就是:孤零零的一個播放按鈕展現在白紙上同樣
解決方案:
var cut = function() { // 1. 建立畫布 let canvas = document.createElement("canvas"); canvas.width = video.videoWidth * scale; // 2. 設定寬高比 canvas.height = video.videoHeight * scale; // 3. 將視頻此刻幀數畫入畫布 canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height); let img = document.createElement("img"); img.src = canvas.toDataURL("image/png"); // 4. 寫入到Dom Dom.appendChild(img); }; video.addEventListener('loadeddata',cut);//在視頻幀數已加載時執行截取
現象描述:第一次播放視頻ok,可是在IOS12.*如下的機型,再次播放視頻會出現黑屏的現象。檢查代碼發現,video使用了v-show
,關閉以後,對應的方法執行,可是隻有聲音沒有圖像,爲啥???
解決方案:
webkit-playsinline
&& playsinline
,能保證再次進入不黑屏,可是IOS自動全屏的失效。思考:可是爲啥這樣子??不太符合邏輯的呢,仔細又看了代碼,發現外邊有v-show(代碼如:代碼1所示),猜想多是這樣引發的,第二次使用的時候,難道IOS12.*如下的手機自己有兼容問題,所以,沒有使用v-show處理,只用css處理了。,這樣能保證IOS打開視頻全屏,再次打開也不黑屏。根本緣由仍是有待深究的。
代碼片1: <div class="video-fullscreen-mask'" v-show="!isShowVideoCover"> <video id='js-video' controls :class="{'width-auto': babyInfo.isNewModel,'height-auto': !babyInfo.isNewModel}" :poster="babyInfo.videoCover" webkit-playsinline="true" playsinline="true" x5-video-player-type="h5" x5-video-player-fullscreen="true" x5-video-orientation="portraint" > <source :src="babyInfo.videoUrl"></source> </video> </div> ---- 分割線 ----- 代碼片2: <div class="default-video" :class="{'video-fullscreen-mask':!isShowVideoCover}"> <video id='js-video' controls :class="{'width-auto': babyInfo.isNewModel,'height-auto': !babyInfo.isNewModel}" :poster="babyInfo.videoCover" :src="babyInfo.videoUrl" v-if="!userInfo.isApp" x5-video-player-type="h5" x5-video-player-fullscreen="true" x5-video-orientation="portraint" ></video> </div>
若是你沒有付費的話 從理論來講 廣告是不可避免的 可是能夠經過一些方法繞過廣告:
簡單粗暴解決方案:
let isiOS = !!navigator.userAgent.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) let videoContext = document.getElementById('video'); videoContext.addEventListener('ended', () => { if (!isiOS) { videoContext.play(); setTimeout(() => { videoContext.pause(); }, 100) } }
總結上面的問題,發現正是的場景下不一樣設備的手機兼容狀況仍是真的不同的,咱們針對特定的狀況考慮一個合適的兜底方案便可,儘可能使用最保險的作法,畢竟上線儘可能保證沒有bug纔是極好的。
當使用video進行視頻播放,相對於早期來講,如今手機的性能愈來愈好,流量時代也要迎來5G,會愈來愈放寬限制,如今表現雖然不太同樣,可是將來仍是會走向統一的。
視頻播放--踩坑小計