h5直播


直播開發之旅

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

  針對每個狀態我們肯定會有不同的顯示,這三種狀態可以是三個頁面,相互切換,或者一個頁面,控制頁面相關隱藏和顯示。 可是我們怎么知道,當前主播已經切換成某種狀態了呢? 通過輪詢嗎? 當然不是,輪詢肯定是可以實現的。 不過我們用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直播開發里,比較核心的地方。 開發過程中有很多地方,感覺受到了充滿“惡意”限制,需要用一些比較特別的方法去處理或者妥協。 這一點對於下游的我們也是無可奈何,過程中,還是很有樂趣的,雖然最終效果並不是很好,但從指縫中,爭取到的結果,很可貴。

 

 


轉自【B5教程網】:http://www.bcty365.com/content-142-5245-1.html


免責聲明!

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



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