H5 Video踩坑記錄

lq782655835發表於2019-01-23

臨時接手一個即將上線的公司專案,純H5活動頁,內容不多,但對還原度和各機型相容性(尤其是Android機型)有極高要求。涉及的問題很多,這裡重點說下在H5中Video的一系列坑。插個技術選型問題,不復雜的活動頁建議使用jquery技術棧,而不是使用vue和reactjs等。後者的優點在於元件系統,可複用度高,適合大型專案。活動頁一般UI改動頻繁,動效多,適合jquery外掛生態,新增也方便。筆者半道接替該vue專案,中間要加一些新特性,還得看看有沒有對應的vue輪子,十分麻煩。

效果請戳:H5 Video(在移動端模式檢視)

1.基本video屬性設定

  1. poster:視訊未播放前的代替圖片,如果未設定該屬性,預設使用視訊第一幀(但小部分機型相容性不好)。建議新增

  2. muted: 靜音. 建議新增

  3. webkit-playsinline/playsinline: 視訊播放時局域播放,不脫離文件流 。基本保證iphone手機在H5頁面內播放。個別不支援可以引入第三方庫iphone-inline-video建議新增

  4. x5-video-player-type="h5"/x5-playsinline: 啟用同層H5播放器,保證anroid手機在H5頁面內播放,但在各android機型下表現不一。建議新增

<video
    ref="video"
    :poster="startSource"
    muted
    x-webkit-airplay="allow"
    x5-video-player-type="h5" x5-playsinline
    webkit-playsinline playsinline>
    <source :src="videoSource" type="video/mp4" />
</video>
複製程式碼

2.自動播放

先說結論:如果需要微信/網易雲音樂/微博/QQ/瀏覽器等各平臺完美自動播放,不行。正確的解決方案:讓視覺設計引導使用者點選螢幕,進行播放視訊。或者如果產品能接受,只要使用者接觸螢幕就開始播放(監聽touchstart事件)。錯誤方式:video標籤autoplayjs執行video.playload完成後執行play()

只在微信端傳播。微信瀏覽器是經過特殊處理的,可以通過回撥WeixinJSBridgeReady解決,適用於iPhone和anroid。注意自動播放的視訊要無音軌或者手動muted。見示例程式碼:

<!-- 必須加在微信api資源 --> 
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>

let that = this
if (window.WeixinJSBridge) {
    WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
        video.play()
    }, false);
} else {
    document.addEventListener("WeixinJSBridgeReady", function () {
        WeixinJSBridge.invoke('getNetworkType', {}, function (e) {
            video.play()
        });
    }, false);
}
複製程式碼

3.視訊開始短暫黑屏

部分android機型點選播放視訊時,會出現短暫1~2s的黑屏。該問題出現可能是還沒請求完成可順利播放的視訊。

解決方案:在視訊上疊加一個div,把它的背景圖換成首幀圖。監聽timeupdate事件,有視訊播放時移除該div。

<div @click="play">
      <video
        ref="video"
        :class="{'playing': playing}"
        :poster="startSource"
        x-webkit-airplay="allow"
        x5-video-player-type="h5"
        x5-playsinline
        webkit-playsinline playsinline>
        <source :src="videoSource" type="video/mp4" />
      </video>
      <div :class="['cover-start']" v-if="!playing"></div>
    </div>
複製程式碼
this.videoNode.addEventListener('timeupdate', () => {
    // 當視訊的currentTime大於0.1時表示黑屏時間已過,已有視訊畫面,可以移除浮層
    if (this.videoNode.currentTime > 0.1 && !this.playing) {
        this.playing = true
    }
}, false)
複製程式碼

4.部分Android機跳到x5 player播放視訊

有些android在微信或瀏覽器,播放視訊會跳到x5 player播放器中。這種video位於頁面最頂層,無法被遮蓋,說不定播完會推送騰訊視訊資訊,而且不會自動關掉。

解決方案:利用timeupdate事件,當視訊快要結束時,手動remove掉整個視訊。

this.videoNode.addEventListener('timeupdate', () => {
    // 相容Android X5在瀏覽器行為.時間為視訊時長
    if (this.videoNode.currentTime > 56.9) {
        this.isShowVideo = false
    }
}, false)
複製程式碼

5.視訊canplay的坑

換了引導使用者的視訊方案後,前面有個loading頁面。產品希望視訊載入好後,loading消失並視訊可點選。但是ios下canplay和canplaythrough事件都不會執行回撥。ios是點選播放後才會去載入視訊流。android下會執行canplay事件回撥,但視訊流也是邊下邊播。所以無法準確獲得視訊可載入時間點

總結:H5現在視訊標準不完善,除了timeupdateended事件外,其他事件慎用。

6.safari可以縮放視訊

通常情況在meta的viewport中設定user-scalable=no即可。但是IOS 10以後的safari中,apple為了提高Safari中網站的輔助功能,即使網站在視口中設定該屬性,使用者也可以手動縮放。

解決方案:

// IOS10 Safari不識別meta,故需要js hack
document.documentElement.addEventListener('touchstart', function (event) {
if (event.touches && event.touches.length > 1) {
    event.preventDefault()
}
}, false)
複製程式碼

相關文章