1. 程式人生 > >視訊video標籤在移動端的播放總結

視訊video標籤在移動端的播放總結

昨天新上線了一個關於騰訊18週年嘉年華的html5,這個html5是有5段不同的視訊組成,中間使用各種手勢進行串聯,歡迎大家訪問。

img

眾所周知,在移動端的視訊和音訊都是需要使用者手動點選開啟的,而使用autoplay或在js裡寫play()是沒有任何作用的。還有幾個常見的問題這裡也提示一下:

  1. iOS不支援preload屬性,android可能會支援,沒太細測試。使用者只有在點選的時候才會去載入視訊;

  2. iOS不支援autoplay屬性,需手動點選開啟,使用setTimeout延遲開啟也不行;

  3. canplaythrough表示可是流暢播放了,但是在android下是沒有卵用的; 有的android下是播放完成後才會觸發。

  4. playing表示開始播放了,android下無效;

  5. canplay認為是視訊元素沒有問題,可以執行,沒有更多含義了,基本用不上,android下一樣;

  6. iOS和android都支援ended事件,但不能在ended事件裡啟動一段音訊或視訊,因此不能使用ended進行視訊的迴圈播放;

  7. 有的iOS版本下,會彈出一個全屏播放器來播放視訊,iPad則支援內聯播放。有人說新增webkit-playsinline屬性即可支援內聯播放,不過我這兒並沒有什麼卵用。全屏播放後,會造成操作很不流暢,必須關閉視訊的全屏效果,才能進行下一步的操作;

  8. 在網路不太好,或視訊比較大的情況下,在點選和正式播放的空隙內會有一段等待視訊載入的時間;有時候也會出現只有音訊而沒有畫面的情況。

針對這些問題,有的是系統級的問題(比如調起全屏的播放器,迴圈播放視訊等),我們無法修改;其他的,我們都儘量地通過程式來實現。

1. 如何獲取視訊的載入進度,讓視訊載入完成後才讓使用者進入?

不能,沒有任何的辦法來判斷視訊的載入進度,而且在iOS中,只有視訊在播放的時候,才臨時去載入視訊。因此,即使在video標籤中寫了preload屬性也是不管用的。使用canplaythrough事件也是沒法檢測的,雖然video標籤在載入的時候會觸發canplaythrough方法,但播放時依然會有卡頓的現象,而且某些android還不支援次屬性。

2. 播放視訊時只有聲音沒有影象

有部分原因是視訊的編碼不正確,在mp4格式的視訊中,只支援h.264的視訊。我的專案中也遇到了這種情況,但不是視訊編碼的問題。我在自己的網路下測試時,沒有這樣的問題,但是在外部環境測試時就會出現黑屏、有聲音沒影象的情況。那麼應該就是視訊有點大了,然後我就把視訊壓縮了一下,結果還是會有這樣的情況出現。

經過同事的指點,我在使用者點選和視訊正式播放之前新增一個loading效果,當視訊正式播放的時候就取消loading。如下:

    function video_loading( $video ){
        $('.video_loading').show();

        var timer = setInterval(function(){
            var currentTime = $video[0].currentTime; // 檢測當前的播放時間

            if( currentTime>0 ){
                $('.video_loading').hide();
                clearInterval( timer );
            }
        }, 100)
    }

完美解決黑屏和有聲音沒影象的問題。

3. 在每段視訊的結尾都有向上滑、點選的操作

我們是無法在視訊上直接進行滑動和點選等操作的,只能是在視訊播放結束時,新增一個透明遮罩,讓使用者在遮罩上進行操作。

    /**
        視訊的播放時間改變時進行的操作
        videoid video標籤的id
        cur 當前播放時間,可以傳入ended引數
        func 回撥函式
    */
    videoUpdate : function(videoid, cur, func){
        var myVideo = document.getElementById(videoid);

        if( myVideo ){
            if( typeof cur =='number' ){
                myVideo.addEventListener('timeupdate', function(){
                    if( this.currentTime>=cur ){
                        func();
                        myVideo.removeEventListener('timeupdate', function(){

                        }, false);
                    }
                }, false);
            }else{
                myVideo.addEventListener(cur, function(){
                    func();
                }, false);
            }
        }
    }

使用方法:

    // 第一屏的視訊進行到4秒時,顯示透明圖層以提供使用者操作
    tool.videoUpdate( 'video1', 4, function(){
        $('.s1 .overlay').show();
    });

    // 第一屏的視訊結束時,顯示向下滑動提示按鈕
    tool.videoUpdate( 'video1', 'ended', function(){
        $('.s1 .tip').show();
    });

總結

這是第一次做移動端的視訊播放html5,在很多地方還有不足的地方,歡迎大家提出意見和建議。