html5中video在安卓與ios實際應用中遇到的問題及解決


原文: https://juejin.cn/post/6844903683105226759

 

昨天公司指派給我了一個任務,是關於視頻播放后展示頁面的單頁應用,具體需求如下:

1)用戶在進入頁面后視頻開始自動播放,期間不得操作;

2)視頻播放完成后順滑切換到主體頁。

看起來是不是特別簡單粗暴,乍一看好像也是就是不到一小時的工作量,卻讓我足足熬到了深夜兩點鍾,說起來都是淚~~。這期間遇到了不少問題,我都會在下面一一列舉(以下所說的瀏覽器均為移動端瀏覽器,不再一一標注)。

一、video的默認顯示

在我開發完基本代碼之后,push到githook上在手機上展示時,遇到了第一個問題: 眾所周知,html中video的autoplay在移動端瀏覽器上基本失效(其一,移動端要有用戶交互才能觸發事件,如click、touch;其二,ios協議蜂窩數據下不得開啟音視頻的自動播放),所以我在加載后取巧的加了一個懸浮播放圖標,引導用戶點擊開始業務流程。

但可能因為內核不同,在微信瀏覽器/safari/chrome上默認展示的poster各有不同,chrome應用了默認行為截取了視頻第一幀作為顯示,微信瀏覽器和safari卻顯示空白,效果就是孤零零的播放圖放在一張白紙上。解決方案是:通過canvas截取視頻第一幀作為默認顯示的圖片:

    var cut = function() {
        let canvas = document.createElement("canvas");//創建畫布
        canvas.width = video.videoWidth * scale;
        canvas.height = video.videoHeight * scale;//設定寬高比
        canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);//將視頻此刻幀數畫入畫布
        let img = document.createElement("img");
        img.src = canvas.toDataURL("image/png");
        Dom.appendChild(img);//寫入到Dom
    };
    video.addEventListener('loadeddata',cut);//在視頻幀數已加載時執行截取

二、video控制欄的隱藏

html文檔里寫有,如果controls屬性不出現,則默認不顯示,但其實在實際應用中,瀏覽器一般都是調用默認播放器進行播放,再加上雙端差異,實際展示效果更是精彩紛呈。說到這里,要寫一下目前各個瀏覽器的內核情況:

微信瀏覽器

  • 安卓

微信6.1版本以上的android用戶,都是使用的QQ瀏覽器的X5內核。 5.4-6.1之間的版本,若用戶安裝了QQ瀏覽器就是使用的X5內核,若用戶未安裝瀏覽器,使用的是系統內核。

  • IOS

Webkit。

大部分手機瀏覽器

Webkit。(UC的U3內核和X5內核一樣,是基於webkit修改的內核)。

由上可知,在移動端開發遇到的百分之九十的問題,都是系統和機型問題。

我們回到問題本身,在使用htmlvideo標簽時,我們會發現,點擊播放之后首先會進入播放器占用整個屏幕,之后開始播放,再次點擊視頻會出現控制欄。

好,捋一捋思路。第一步,要解決脫離屏幕的播放問題。

<video  poster="img/test.jpg" webkit-playsinline="true" playsinline>
    <source src="img/movie.mp4" type="video/mp4">
    <source src="img/movie.ogg" type="video/ogg">
    您的瀏覽器不支持該視頻格式。
</video> 

webkit-playsinline playsinline:這個屬性作用是讓視頻播放時局域播放(不全屏,在原有位置上播放),不脫離文檔流 。但這個屬性需要嵌入網頁的APP比如WeChat中UIwebview 的allowsInlineMediaPlayback = YES webview.allowsInlineMediaPlayback = YES,才能生效。換句話說,安卓不支持,而IOS的wechat卻支持,因為APP不支持playsinline,所以安卓是默認全屏播放的。

第二步,隱藏掉控制欄。

<video x5-video-player-type="h5"   id="video">
    <source src="img/movie.mp4" type="video/mp4">
    <source src="img/movie.ogg" type="video/ogg">
    您的瀏覽器不支持該視頻格式。
</video> 

x5-video-player-type='h5' 啟用同層H5播放器,學名叫沉浸式播放。播放的時候除去了control和微信的導航欄,只留下"X"和"<"兩鍵。

一般來說,這種已經足夠‘沉浸’了,但項目對定制化要求比較高,要求這種也不要出現。我苦思冥想,查了好多文檔,方法卻都大同小異。直到最后靈光一閃,放棄了通過屬性或方法來限制的思路,決定用視覺遮擋來實現效果:

將video的控制欄擠出可視區域,不就相當於隱藏了控制欄嘛。

/*這是CSS*/
html,body,.main{
   width: 100%;
   height: 100%;
   overflow: hidden;//隱藏
   background: #FFF;
   box-sizing:border-box;
}
.videobox{
   z-index: 12;
   position: fixed;
   left: 0;
   top: 0;
   width: 100%;
   height: 100%;
}
#video{
    position: absolute;
    top: -2%;
    width: 100%;
    height: 110%;
}

<!--這是HTML-->

<div class="videobox" ontouchmove="return false;">
    <video  poster="img/test.jpg" webkit-playsinline="true" playsinline x5-video-player-type="h5"  x-webkit-airplay="true" id="video">
        <source src="img/movie.mp4" type="video/mp4">
        <source src="img/movie.ogg" type="video/ogg">
        您的瀏覽器不支持該視頻格式。
    </video> 
</div>

這樣就實現了播放時不得操作的需求。

三、IOS當視頻被打開在safari瀏覽器時播放白屏。

這就牽扯到兩個個問題,我們分開來說。

video標簽對視頻格式以及編碼的支持

  • MPEG4 = 帶有H.264視頻編碼和AAC音頻編碼的MPEG4文件

  • WebM = 帶有VP8視頻編碼和Vorbis音頻編碼的 WebM文件

  • Ogg = 帶有Theora視頻編碼和Vorbis音頻編碼的Ogg文件

如上所示,只有h264編碼的MP4視頻(MPEG-LA公司)、VP8編碼的webm格式的視頻(Google公司)和Theora編碼的ogg格式的視頻(iTouch開發)可以支持html5的<video>標簽。

那么在實際代碼上我們應該這么布置:

<video  poster="img/test.jpg" webkit-playsinline="true" playsinline x5-video-player-type="h5"  x-webkit-airplay="true" id="video">
    <source src="img/movie.mp4" type="video/mp4">
    <source src="img/movie.ogg" type="video/ogg">
    您的瀏覽器不支持該視頻格式。
</video> 

首先會判斷是否支持MP4,如否,判斷是否支持OGG,如否,展示文字。這也是我最后選擇的解決方式,簡單粗暴可以早睡覺 :)。

備注:網上有文章說,用格式工廠將mp4編碼轉成H264即可,但我實際應用中發現H264在safari和chrome中竟然無法打開,具體原因究竟是我編碼錯誤還是與文檔沖突,暫未知曉。

iOS上播放視頻,http協議中應用rang請求頭

視頻格式MP4是正確的,但是你的后台沒有對ios的視頻播放器做適配。如果想要在iOS上播放視頻,那么必須在http協議中應用rang請求頭。
對於有的朋友還對ios播放器http的range標記不是很懂。我再講解下。

視頻文件總長度是123456789
range是播放器要求的區間也就是客戶端發送請求的時候http會帶有這個標記,這個區間的值在http.headers.range中獲取,一般是bytes=0-1這樣的。

我們需要做的處理是返回文件的指定區間(如上面的例子,我們就應該返回0到1的字符),並添加
Content
-Range:btyes 0-1、Accept-Ranges:bytes、'Content-Length: 123456789''Content-Type: video/mp4'到http.headers中

具體效果因為時間關系並沒有親自測試,有興趣的朋友可以研究一下。

四、關於其他屬性的補充

  • 讓你的視頻充滿屏幕。
#video{
    object-fit: fill;
}
  • 把當前的視頻投放到其他支持此技術的設備上。
<video x-webkit-airplay="true"></video>
  • 在視頻結束時執行事件。
 $("#video").get(0).addEventListener("ended", function() {
        
    }, false);
  • 微信瀏覽器下實現自動播放。
document.addEventListener("WeixinJSBridgeReady", function() {
    video.play()
}, false)

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM