h5直播開發之旅總結


前言

  關於直播,有很多相關技術文章,這里不多說。 作為前端,我們比較關心我們所需要的。

 

直播的大致流程:

  APP端調用攝像頭 -》 拍攝視頻 -》 實時上傳視頻 -》 服務器端獲取視頻並解碼 -》 存儲成一小段一小段視頻 -》 服務器端進行推流 -》 H5或者app端通過一個url拉取視頻流進行播放

  實際的直播和用戶播放的直播會有10秒左右或者更高的延遲,這一點對於后面開發比較重要,一定要注意這個點。

 

  H5實現直播主要是和video標簽打交道,雖然只需要拿到m3u8格式的url,通過video播放,看起來好像就是播放視頻一樣,但實際我們需要處理一些不可控的情況,這是非常麻煩的。 比如說,直播方網絡不好,直播方關閉了攝像頭,這些情況都會導致推流斷掉,在文章后面,我們詳細說這一塊。

  直播還有一個比較重要的功能,那就是評論,這里我們需要websocket來實現,其實不只是消息,還有需要通過websocket進行一些狀態通知。

  因為這里是移動端的項目,所以不支持PC端。如果要兼容PC的話,需要用flash來播放直播流。

 

直播開發之旅

  ① 狀態控制:

  目前我們先考慮直播的三種狀態: 直播前,直播中,結束。

  針對每個狀態我們肯定會有不同的顯示,這三種狀態可以是三個頁面,相互切換,或者一個頁面,控制頁面相關隱藏和顯示。 可是我們怎么知道,當前主播已經切換成某種狀態了呢? 通過輪詢嗎? 當然不是,輪詢肯定是可以實現的。 不過我們用websocket,因為我們已經提前准備了websocket,所以我們可以通過服務端的推送websocket廣播,當獲取到的直播狀態和當前狀態不同,便進行相應切換。

  但是有時候可能因為暫時的網絡原因或者其他原因,websocket的廣播消息,我們並沒有獲取到。 所以可以讓websocket間隔性的廣播直播狀態。

 

  ② 評論消息監聽:

  我們也通過websocket拉取評論消息,這里主要的問題在服務端壓力上,有可能用戶評論量很大的時候,服務器壓力過大,出現斷連的情況。 也可能是用戶網絡斷開,造成的斷連。 一方面后端通過他們的優化來提高承載力,一方面前端和后端進行配合優化。 我們每次連接websocket服務器的時候,前端會通過接口,拿到當前承載量最小的服務器地址進行連接。 websocket如果斷連了的話,是不會獲得任何消息的,所以保證功能可以使用,我們還會針對websocket進行心跳檢測(檢查是否斷開連接)。

 

  ③ 心跳 重連

  因為websocket可能會存在斷開連接的情況,而這時候是不會觸發任何事件的,所以我們不知道它是否斷開了。 那么我們設置一種消息類型,由前端發送給服務端,服務端如果返回了數據,就說明連接正常。 如果連接斷開了,我們再次去請求后端接口,拿到當前承載量最小的服務器地址,進行重連。 設置一個間隔時間比如10秒,最后一次獲取到服務器的消息后,如果10秒內沒再收到消息,就進行一次檢查,如果10秒內收到了,便重置這個時間。 之前的博客寫過比較詳細的心跳檢測:初探和實現websocket心跳重連》

 

  ④ video

  關於video,總結起來我們要解決的那些問題,或者有些不能解決的問題,歸根到底是一個問題:兼容。 兼容問題又可以分為兩種:標簽事件的兼容問題和瀏覽器表現的兼容問題。

 

  先說video的事件兼容問題,之前測試過這一塊,總之比較穩定和兼容性好點的事件如下圖片圈出來的:

  

  對,你沒看錯,目前對我來說好像就timeupdate比較靠譜,總之確實兼容性很差,這樣會導致對video的可控性變得很低。

 

  接着是瀏覽器的表現兼容問題,比如: 在微信和QQ的內置瀏覽器里,播放視頻會自動全屏,video標簽也是永遠浮在頁面最上層,你根本控制不了。 浮在最上層不只是X5瀏覽器,還有些手機只帶的瀏覽器。 視頻源出現問題的表現,播放按鈕的問題,都有不同。 這些都是脫離我們代碼本身,瀏覽器的設置,所以從代碼層面上我們是沒法解決的。 之前出現這些問題的時候,當然我也會看下相關直播的公司的頁面,看他們是怎么解決的。 比如在微信這個流量大口他們有沒有實現看起來實現不了的功能。 實際結果是,這些廠家應該是微信有合作,進行了相關定制的。 而我們本不是專門做直播的,所以沒必要投入這種成本。

 

  定制合作這個只是猜測,還不能百分百肯定,如果有誰知道,感謝告知一聲!

 

  ⑤ 評論展示

  本來我們想實現如下圖的樣式:

  

  但是由於上面提到的問題,video浮在頁面最上層,dom無法浮在video的上層。 那么我們的評論就無法展示在上圖的位置,所以無奈只有放到video下方去。 根據我們的業務需求不同,目前只有這樣,能勉強接受。

 

  ⑥ video推流監聽

  在文章最開始我們提到,推流會有一些不可控的情況,主播關閉攝像頭,推送斷流等,客戶端斷網。 這個時候在H5端的表現就是卡住,肯定會卡住。 一旦卡住之后,就算推流又重新開始了,video依然會卡在那里,不會有任何重新播放的樣子。 如果推流重新開始,用戶自己點擊控制條的暫停,再點擊播放,又可以正常播放了。 可我們不可能讓用戶一直點,因為你也不知道推流什么時候重新開始,或者什么時候不再

是斷網狀態。 通過點擊控制條的暫停,再點擊播放便可以播放的規律,我們可以自己檢查當前的狀態,再用JS控制video暫停,再播放。

 

var video = document.getElementById('video');
video.pause(); video.play();

  

  如何檢查當前是卡住的狀態呢?這里就用到我開始說的比較可靠的timeupdate事件。一旦用戶是播放狀態,監聽timeupdate,通過對比currentTime輪詢着來檢查當前是否卡住。

 

復制代碼
var checkTime = null;
var checkLastTime = null;
var check = setInterval(function(){
    if(checkTime != null){
        if(video.paused){
            //如果是暫停狀態
        }
        if(checkTime == checkLastTime || (checkTime== 0 && checkLastTime==0)){
            if(!video.paused){//如果是暫停狀態,就忽略
                showTip('主播離開一會兒'); //提示一下用戶
                video.pause();
                video.src = video.src;//重置src,否則ios不會再次播放
                video.play();
            }
            
        }
    }
    checkLastTime = checkTime;
}, 10000);

video.addEventListener('timeupdate', function(e){
    //每次play()都會觸發一次timeupdate,所以需要加個條件判斷
    if(checkTime != checkLastTime) hideShowTip();//隱藏上面 主播 離開的提示
    checkTime = e.target.currentTime;
});
復制代碼

  

  但是這樣仍然會有一些問題,比如當前檢測到視頻卡住了,JS控制重新播放,而當前還是沒有獲取到推流的話。 瀏覽器會先loading獲取視頻,最后會失敗顯示下圖的信息。 我們的檢查會輪詢執行,所以下面的情況會一直循環,直到視頻正常播放。

 

 

  這樣確實有點影響體驗,但是目前無解。

  如果用戶不是全屏播放,頁面下方會有提示用戶等待。

  如果是全屏那么就看不到提示,不過用戶這個時候可能會關閉全屏,返回到頁面上,這樣仍然可以看到提示。

  

結語:

  以上就是我所遇到的h5直播開發里,比較核心的地方。 開發過程中有很多地方,感覺受到了充滿“惡意”限制,需要用一些比較特別的方法去處理或者妥協。 這一點對於下游的我們也是無可奈何,過程中,還是很有樂趣的,雖然最終效果並不是很好,但從指縫中,爭取到的結果,很可貴。

 

http://www.cnblogs.com/1wen/p/5973468.html

 


免責聲明!

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



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