html5--移動端視頻video的android兼容,去除播放控件、全屏等

android下html5的視頻播放一直是前端兼容的重災區,各類體驗差,被詬病已久。但以前的故宮穿越H5,和吳亦凡入伍H5,利用的視頻技術,貌似又給人一種新面貌。css

前段時間作某項目,剛好也是一個相似視頻全屏的,下面跟你們分享下經歷的坑和填坑的辦法。html

ios端問題其實沒什麼,基本都在android端,基本每個帶有視頻的項目都會遇到的,固然有特殊需求的產生的狀況另說了就,問題主要有幾個方面:前端

  1. 全屏處理;html5

  2. 自動播放;android

  3. 播放控制;ios

  4. 隱藏播放控件;git


video全屏的處理

這個其實不難,只需在video標籤加個webkit-playsinline屬性便可,這個屬性基本上在基於webkit內核的移動端都是沒問題的,此全屏非彼全屏,它是在瀏覽器視窗內的全屏,並非佔居整個手機的全屏,固然咱們作web端須要的就是在document的body內的視窗範圍的全屏。github

<video id="myvideo" src="test.mp4" webkit-playsinline="true"></video>

在ios下,視頻被嵌入後,媒體的元數據加載完成後,會以全屏的形式顯示出來,或者加個poster,能夠看到畫面。但在android下,多數機子是不顯示視頻畫面的,要不就是顯示一個黑色的還不是全屏的播放控件,即便及加個poster封面也不濟因而。由於poster在android兼容的並很差,不如在視頻上層加個div鋪張圖片,這個比較好的處理方式應該是:視頻上加一層div作封面,因爲android不容許視頻上層有東西,因此首先將視頻設爲的width:1px,當播放後,上層的封面remove掉,同時width:100%或者你想要的寬度。web

video的自動播放

這個的話就很少說了,相信你們跟我同樣,試圖尋找android下,頁面加載完畢就能夠自動播放,但現實是殘酷的,android下是不容許自動播放的,即便你用了video.play(),也是不行的。必須有用戶的主動觸發,好比觸摸了屏幕,有click或touch事件產生。不知之後android會不會改進,但至少目前來看是不行的。比較的好的辦法是,引導用戶觸發,滑屏或touch的行爲,而後調用video.play()播放,給用戶一個自動播放的錯覺。chrome

video播放的控制

對於video或者audio等媒體元素,有一些方法,經常使用的有play(),pause();也有一些事件,如'loadstart','canplay','canplaythrough','ended','timeupdate'.....等等。

在移動端有一些坑須要注意,不要輕易使用媒體元素的除'ended','timeupdate'之外event事件,在不一樣的機子上可能有不一樣的狀況產生,例如:
ios下監聽'canplay'和'canplaythrough'(是否已緩衝了足夠的數據能夠流暢播放),當加載時是不會觸發的,即便preload="auto"也沒用,但在pc的chrome調試器下和android下,是會在加載階段就觸發。ios須要播放後纔會觸發。
總之就是如今的視頻標準還不盡完善,有不少坑要注意,要使用前最好本身親測一遍。

關於控制的問題還想說一點就是android在播放視頻時會有個控件初始化的過程,在全屏視頻想假裝成非視頻時,是咱們很不想看到的,個人解決思路是這樣:
在咱們須要播放時提早初始化它,即須要播放的時間前先設width:1px;而後play()一下,使視頻已經播放初始化。而後再須要播放的時候再次play()時就不會產生,控件拉伸的狀況了。

「去除」android下的播放控件條

重頭戲來了,相信這個這個問題已困擾無數的前端開發人員,再搜尋這個問題的解決方法時,幾乎全部的文章都是告訴你android下,播放器的控件是去不了的。其實彷佛確實是這樣的,但你看了故宮穿越H5,和吳一凡那個H5後,會發現,在android下,也是沒有控制條的。最初看到那些H5視頻我首先並無去看他們的內容多麼新穎,傳播量多麼廣,我是第一時間測試了android下的兼容問題,發現並無出現控制條。在我研究半天未果時,在一篇技術帖中看到說:因是騰訊本身的項目,微信是騰訊本身的,他們在瀏覽器裏作了一些配置,對旗下出品的H5有所「優待」,才能確保視頻的順利「喬裝」。

上面的說法我並無真正覈實過,但好像是這麼回事,很是有幸我作的那個視頻項目也是騰訊的,實際上是有機會能夠向他們證明一下以上說法的,但即便是這樣的,也只有騰訊的項目有這樣的解決辦法,對於廣大的開發者來講彷佛並太不公平,我試圖找到一種解決去除播放控件的解決方案,下面是我花了不少心思找到的一種解決辦法,看似很簡單也不那麼高大尚,但確實解決了問題,跟你們分享:

我這裏只看android的狀況,ios基本沒什麼問題,就忽略啦。
測試機android版本:5.1
首先咱們將那個H5視頻地址嵌入本身的頁面,你會發現確實播放器出現了。以下

圖片描述

怎麼辦呢,不是騰訊本身的項目就沒辦法了嘛?再我搜了N多資料未果後,發現了一個細節,控制條始終是最下方的,可不可讓視頻的尺寸放大些,將控制條頂到瀏覽窗口外面,就看不到了嘛,因而我將視頻寬高放大到120%-----控件條神奇的‘消失’了(實際上是頂到視窗外面了),驚喜萬分啊。

具體思路和實現以下:
html中將video標籤外包一層,

<div class="videobox">
        <video id="mainvideo" webkit-playsinline="true" src="http://7xvl2z.com1.z0.glb.clouddn.com/nigg2.mp4"></video>
    </div>

初始樣式表以下:

html,body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  -webkit-user-select: none; 
  user-select: none;
  overflow: hidden;
}

.videobox {
  width: 100%;
  height: 100%;
  position: absolute;
  left: 0;
  top: 0;
  overflow: hidden;
}

video {width: 1px;display: blcok;}

/*
注:html,body裏的overflow:hidden,很是重要,不能省。
由於微信android的播放器是脫離DOM結構的,也不會響應click、touch等事件。
若是視頻尺寸大了,會產生滾動條,必須在html和body加overflow:hidden,
在videobox加沒用的。
*/

當視頻要播放時改變video的寬度(高度會等比縮放,即便自定義高度也是沒用的,會被忽略)

var video = document.querySelector('#mainvideo');
  var videobox = document.querySelector('.videobox');

  //播放時改變外層包裹的寬度,使video寬度增長,
  //相應高度也增長了,播放器控件被擠下去,配合overflow:hidden
  //控件看不見也觸摸不到了
  var setVideoStyle = function (){
    videobox.style.width = '120%';
    videobox.style.left = '-10%';
    video.style.width = '100%';
  }

固然上面這樣寫參雜了一些需求邏輯,也能夠直接樣式表就width:120%,或者更大;這個根據本身的須要來,但基本思路就是將播放器控件頂出視窗以外,達到一種‘去除’、‘消失’的效果。連‘小窗’字樣也被頂出去了,用過android或測試過的同窗都知道點了小窗後會怎樣....(原版的即便去掉了播放器,但小窗字樣還在,不能算徹底的隱藏播放控件吧)

相應產生的一些問題的解決辦法:

1,視頻被放大了,畫面會被截掉一部分怎麼辦?

這個能夠在視頻輸出的時候兩邊和下邊留一些留白,即留白能夠沒用畫面黑色底,但又屬於視頻尺寸的一部分,放視頻放大後,將主體畫面置滿視窗,被擠到外面都是留白的便可。

2,視頻播放完畢後會中間自動出現播放控件按鈕

若是確實不想在播放完是出現一個按鈕,哪怕只有零點幾秒,就把視頻remove掉,可使用timeupdate監聽視頻播放,用video.duration-video.currentTime的差值判斷是否快要結束了,在結束前零點幾秒提早remove掉。

3,要是否是全屏視頻怎麼搞?

能夠,思路是同樣的,將視頻控件頂出外層的包裹層,利用overflow:hidden。只是全屏的外層包裹是body而已。

哦了,終於能夠搞一個全屏視頻假裝的東西了。





2017-03-21補
隨着時間的變遷,設備和技術的更新,本着不坑害同胞的心,負責任更新下仍是有必要的
我們仍是從上面的4個要點來講ios和android吧

  1. 全屏處理;

  2. 自動播放;

  3. 播放控制;

  4. 隱藏播放控件;

補充--全屏處理

ios加playsinline屬性,以前只帶webkit前綴的在ios10之後,會弔起系統自帶播放器,兩個屬性都加上基本ios端均可以保證內斂到瀏覽器webview裏面了。若是仍有個別版本的ios會弔起播放器,還能夠引用一個庫iphone-inline-video(具體用法很簡單看它github,這裏不介紹了,只需加js一句話,css加點),
github地址是https://github.com/bfred-it/i...,加上playsinline webkit-playsinline這兩個屬性和這個庫基本能夠保證ios端沒有問題了(不過親測,只加這兩個屬性不引入庫好像也是ok的,至今沒有在ios端微信沒有出現問題,若是你要兼容uc或者qq的瀏覽器建議帶上這個庫),
最後介紹個新的x5-video-player-type="h5"屬性,騰訊x5內核系的android微信和手Q內置瀏覽器用的瀏覽器webview的內核,使用這個屬性在微信中視頻會有不一樣的表現,會呈現全屏狀態,貌似播放控件剝去了,至少加了這個屬性後視頻上層能夠有其餘dom元素出現了(非騰訊白名單機制的一種處理措施),

<video id="mainvideo" src="test.mp4" playsinline webkit-playsinline></video>

補充--自動播放

android始終不能自動播放,很少說。值得一提的是經測如今ios10後版本的safari和微信都不讓視頻自動播放了(順帶音頻也不能自動播放了),但微信提供了一個事件WeixinJSBridgeReady,在微信嵌入webview全局的這個事件觸發後,視頻仍能夠自動播放,這個應該是如今在ios端微信的視頻自動播放的比較靠譜的方式,其餘如手q或者其餘瀏覽器,建議就引導用戶出發觸屏的行爲操做出發比較好。

//也能夠在這個事件觸發後播放一次而後暫停(這樣之後視頻會處於加載狀態,爲後面的流暢播放作準備)
document.addEventListener("WeixinJSBridgeReady", function (){ 
    video.play();
    video.pause();
}, false)

補充--播放控制

關於控制,這裏僅補充一點吧,就是當第一次播放視頻的時候ios端,若是網絡慢,視頻從開始播到能展示畫面會有短暫的黑屏(處理視頻源數據的時間),爲了不這個黑屏,能夠在視頻上加個div浮層(能夠一個假的視頻第一幀),而後用timeupdate方法監聽,視屏播放及有畫面的時候再移除浮層

video.addEventListener('timeupdate',function (){
    //當視頻的currentTime大於0.1時表示黑屏時間已過,已有視頻畫面,能夠移除浮層(.pagestart的div元素)
    if ( !video.isPlayed && this.currentTime>0.1 ){
        $('.pagestart').fadeOut(500);
        video.isPlayed = !0;
    }
})

補充--隱藏播放控件

聽說騰訊的android團隊的x5內核團隊放開了視頻播放的限制,視頻不必定調用它們那個備受詬病的視頻播放器了,x5-video-player-type="h5"屬性這個屬性好像就有點那個意思,雖然體驗仍是有點...(導航欄也會清理)但至少播放器控件沒有了,上層能夠浮div或者其餘元素了,這個仍是值得一提。
還有一點值得說的是,帶播放器控件的隱藏,

<div class="videobox" ontouchmove="return false;">
    <video id="mainvideo" src="test.mp4" x5-video-player-type="h5" playsinline webkit-playsinline></video>
</div>

好比這個videobox在android下隱藏,只用display:none貌似仍是不行的,但加個z-index:-1,設置成-1就能夠達到隱藏播放器控件的目的了。這個經測可用且好用,能夠一試。

好了就先補充能想到要說的這麼多吧,但願對你們有幫助

相關文章
相關標籤/搜索