h5直播開發之旅總結

前言

  關於直播,有不少相關技術文章,這裏很少說。 做爲前端,咱們比較關心咱們所須要的。html

 

直播的大體流程:前端

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

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

 

  H5實現直播主要是和video標籤打交道,雖然只須要拿到m3u8格式的url,經過video播放,看起來好像就是播放視頻同樣,但實際咱們須要處理一些不可控的狀況,這是很是麻煩的。 好比說,直播方網絡很差,直播方關閉了攝像頭,這些狀況都會致使推流斷掉,在文章後面,咱們詳細說這一塊。後端

  直播還有一個比較重要的功能,那就是評論,這裏咱們須要websocket來實現,其實不僅是消息,還有須要經過websocket進行一些狀態通知。瀏覽器

  由於這裏是移動端的項目,因此不支持PC端。若是要兼容PC的話,須要用flash來播放直播流。服務器

 

直播開發之旅

  ① 狀態控制:

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

  針對每一個狀態咱們確定會有不一樣的顯示,這三種狀態能夠是三個頁面,相互切換,或者一個頁面,控制頁面相關隱藏和顯示。 但是咱們怎麼知道,當前主播已經切換成某種狀態了呢? 經過輪詢嗎? 固然不是,輪詢確定是能夠實現的。 不過咱們用websocket,由於咱們已經提早準備了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

相關文章
相關標籤/搜索