轉自IMWeb社群,作者:Terrance,原文連結
一、直播知識小科普
- 一個典型的直播流程:錄製->編碼->網路傳輸(推流->伺服器處理->CDN分發)->解碼->播放
- IPB:一種常用的視訊壓縮方案,用I幀表示關鍵幀,B幀表示前向差別幀,P幀表示雙向差別幀
- GOP (Group of Pictures):GOP 越長(I幀之間的間隔越大),B 幀所佔比例越高,編碼的率失真效能越高。雖然B幀壓縮率高,但解碼時CPU壓力會更大。
- 音視訊直播質量好壞的主要指標:內容延時、卡頓(流暢度)、首幀時長
- 音視訊直播需要克服的主要問題:網路環境、多人連麥、主輔路、瀏覽器相容性、CDN支援等
- MSE(Media Source Extensions):W3C 標準API,解決 HTML5 的流問題(HTML5 原生僅支援播放 mp4/webm 非流格式,不支援 FLV),允許JavaScript動態構建
<video>
和<audio>
的媒體流。可以用MediaSource.isTypeSupported() 判斷是否支援某種MINE型別。在ios Safari中不支援。
- 檔案格式/封裝格式/容器格式:一種承載視訊的格式,比如flv、avi、mpg、vob、mov、mp4等。而視訊是用什麼方式進行編解碼的,則與Codec相關。舉個栗子,MP4格式根據編解碼的不同,又分為nMP4、fMP4。nMP4是由巢狀的Boxes 組成,fMP4格式則是由一系列的片段組成,因此只有後者不需要載入整個檔案進行播放。
- Codec:多媒體數字訊號編碼解碼器,能夠對音視訊進行壓縮(CO)與解壓縮( DEC ) 。CODEC技術能有效減少數字儲存佔用的空間,在計算機系統中,使用硬體完成CODEC可以節省CPU的資源,提高系統的執行效率。
- 常用視訊編碼:MPEG、H264、RealVideo、WMV、QuickTime。。。
- 常用音訊編碼:PCM、WAV、OGG、APE、AAC、MP3、Vorbis、Opus。。。
二、現有方案比較
RTMP協議
- 基於TCP
- adobe壟斷,國內支援度高
- 瀏覽器端依賴Flash進行播放
- 2~5秒的延遲
RTP協議
- Real-time Transport Protocol,IETF於1996提出的一個標準
- 基於UDP
- 實時性強
- 用於視訊監控、視訊會議、IP電話
- CDN廠商、瀏覽器不支援
HLS 協議
- Http Live Streaming,蘋果提出的基於HTTP的流媒體傳輸協議
- HTML5直接支援(video),適合APP直播,PC斷只有Safari、Edge支援
- 必須是H264+AAC編碼
- 因為傳輸的是切割後的音視訊片段,導致內容延時較大
flv.js
- Bilibli開源,解析flv資料,通過MSE封裝成fMP4餵給video標籤
- 編碼為H264+AAC
- 使用HTTP的流式IO(fetch或stream)或WebSocket協議流式的傳輸媒體內容
- 2~5秒的延遲,首幀比RTMP更快
WebRTC協議
1、Google力推,已成為W3C標準
2、現代瀏覽器支援趨勢,X5也支援(微信、QQ)
3、基於UDP,低延遲,弱網抗性強,比flv.js更有優勢
方案 | CPU佔用 | 幀率 | 位元速率 | 延時 | 首幀 |
---|---|---|---|---|---|
flv.js | 0.4 | 30 | 700kbit/s | 1.5s | 2s |
WebRTC | 1.9 | 30 | 700kbit/s | 0.7s | 1.5s |
4、支援Web上行能力
5、編碼為H264+OPUS
6、提供NAT穿透技術(ICE)
實際情況下,當使用者數量很大時,對推流裝置的效能要求很高,複雜的許可權管理也難以實現,採用P2P的架構基本不可行。對於個別使用者提供上行流、海量使用者只進行拉流的場景,騰訊課堂實現了一種P2S的解決方案。進一步學習可閱讀jaychen的系列文章《WebRTC直播技術》。
三、小程式+直播
技術方案
- 基於RTMP,官方說底層使用HTTP/2的一種內部傳輸機制,但又說是基於UDP的,這就搞不懂了。。。
- live-pusher 和 live-player 沒有限制第三方雲服務
- 可直接使用騰訊雲視訊直播能力,只需配置好推流url、播放url即可
推流url:
播放url:
下面是我根據官網教程搭建的一個音視訊小程式,搭建過程簡單,同一個區域網下直播體驗也很流暢(讀者也可直接搜尋騰訊視訊雲小程式進行體驗):
前端核心程式碼還是相當簡潔的:
live-pusher元件:設定好url推流地址(僅支援 flv, rtmp 格式)等引數即可,使用bindstatechange獲取播放狀態變化
<view id='video-box'> <live-pusher id="pusher" mode="RTC" url="{{pusher.push_url}}" autopush='true' bindstatechange="onPush"> </live-pusher> </view> 複製程式碼
live-player元件:設定後src音視訊地址(僅支援 flv, rtmp 格式)等引數即可,使用bindstatechange獲取播放狀態變化
<view id='video-box'> <live-player wx:for="{{player}}" id="player_{{index}}" mode="RTC" object-fit="fillCrop" src="{{item.playUrl}}" autoplay='true' bindstatechange="onPlay"> </live-player> </view> 複製程式碼
能否和WebRTC同時使用?
對於騰訊課堂的應用場景,老師上課推流採用的是RTMP協議,考慮到WebRTC目前只能用於PC端拉流,那麼在移動端能否讓使用者可以直接通過小程式來觀看直播課呢?我覺得在技術層面可行的,接入小程式直播對於擴大平臺影響力、社交圈分享、提高收費轉化都會產生很大的幫助。難點在於複雜的許可權控制、多路音視訊流、多人連麥等問題,比如許可權控制只能單獨放到房間控制邏輯中完成,而音視訊流本身缺乏這種校驗;主輔路的切換還需要新增單獨的信令控制,同時在小程式中加入相應的判斷邏輯。