- 直播平台軟體開發的全流程探索
- 近年來,直播興起,QQ音樂也接入了直播能力,支援演唱會的直播和主播、明星直播,根據互動方式的不同,我們可以分為互動直播和推流直播,本人有幸參與了直播從無到有的過程;對直播這一塊有了一個比較清晰的認識,本文主要對web部分的直播流程進行介紹;
直播現狀

上圖列出的app都有涉足直播行業,可以看出目前的直播有多火;
我們按照整個視訊内容的流動過程,将整個直播過程劃分為三個階段,生成階段、傳輸階段、呈現階段
下面将對這些階段進行一一介紹;
生成階段
生成階段包括對音視訊的采集和處理;
音視訊的采集,采集階段主要是對原始視訊内容進行采集即直播内容的來源,根據應用場景的差别,我們可以分為五大類
内容分發後就來到使用者播放階段,怎樣把一段視訊更好的呈現給使用者
呈現階段
- 電視内的直播主要是采集已有的視訊源 比如電視劇 綜藝節目等都是預先錄制好的;
- 演唱會直播主要是通過錄影機和麥克風分别錄制演唱會的畫面和音頻
- 端遊直播,比如平常我們看到英雄聯盟、吃雞等遊戲的直播, 主要是主播通過攝像頭、話筒錄制主播的直播畫面 以及OBS等錄屏軟體錄制遊戲界面并合成直播畫面
- 戶外直播,目前戶外直播也比較流行,類似于真人秀的模式,主播主要依賴手機自帶攝像頭和話筒來錄制内容
- 手遊直播,比如最近很火的王者榮耀,大仙、嗨氏等主播就是手遊直播,android端主要是通過模拟器來錄制,ios可以通過itools蘋果錄屏大師錄制視訊然後同步到obs上
直播平台軟體開發的全流程探索 - 音視訊處理
DIY視訊處理
直播平台軟體開發的全流程探索 對于采集到的視訊内容,需要做一些後期處理,主要包括兩個方面
(1)對于錄制好的視訊畫面可能達不到主播滿意,還有一些主播想要加一些特效,需要對内容做美顔、磨皮、濾鏡、加特效等處理,這個處理過程涉及到複雜的運算,運用到人臉識别、視訊合成等方面的技術;
(2)有一些視訊有版權方面的限制,需要加注水印,可以在這個環節處理,後面的轉碼階段處理也可以
DIY音頻處理
(1)原始聲音可能比較雜,需要做降噪處理
(2)有一些直播場景,主播有一些混音、變音的處理,聲音特效也是在這個環節處理;
編碼處理
編碼處理實際就是視訊壓縮處理的過程
我們先來做個計算
直播平台軟體開發的全流程探索 一段6s720p的原始視訊,不做任何處理大小為474M,在10M帶寬下大概需要6分鐘時間傳輸,這對于直播來說顯然是不能忍受的;目前視訊一般采用H.264标準編碼,經過這個标準處理後大小可以直降到1M以下,傳輸時間可以降到800ms以下;
我們先來看下H.264協定,H.264标準基于MPEG格式進行封裝,我們先來看MPEG的格式,将畫面(即幀)分為I、P、B三種。 I是内部編碼幀,P是前向預測幀,B是雙向内插幀。 簡單地講,I幀是一個完整的畫面,而P幀和B幀記錄的是相對于I幀的變化。 沒有I幀,P幀和B幀就無法解碼,我們隻需要保留關鍵的I幀,其他幀做一些關聯資訊的記錄。
直播平台軟體開發的全流程探索 壓縮的過程就是去除備援資訊的過程,主要包括兩個方面的壓縮:
幀内壓縮 1、人的視覺系統對某些細節不敏感,視覺備援;
幀間壓縮 1、圖像相鄰像素之間有較強的相關性,空間備援; 2、視訊序列的相鄰圖像之間内容相似,時間備援。
舉個栗子
直播平台軟體開發的全流程探索 比如一段滑雪的視訊,連續的幀其實大部分内容都是相同的,滑雪的同學是向前位移的,但實際上是雪景在向後位移,P 幀通過參考幀(I 或其他 P 幀)就可以進行編碼了,編碼之後的大小非常小,壓縮比非常高。
另外音頻内容也需要經過壓縮,目前主要采用acc的編碼方式;
整個生成階段的流程如下
直播平台軟體開發的全流程探索 傳輸階段
傳輸階段主要是是視訊從采集端到使用者端的過程
-
推流
推流即我們平常說的上行,我們錄制好的視訊需要先推流到伺服器,目前推流協定大部分采用的rtmp協定,rtmp全稱是Real Time Messaging Protocol實時消息傳輸協定,具有以下幾個特點
(1)Abode私有協定,隻要浏覽器支援flashplayer的機器都支援rtmp協定 pc上基本都支援
(2)長連結,不用重複握手 延遲可以控制在2s内,這個在直播過程中控制延時很關鍵
(3)CDN 支援良好,主流的 CDN 廠商都支援
-
轉碼
目前騰訊雲提供的幾種轉碼格式 直播流推送到伺服器後 為了保證各個端的使用者都能觀看 基本能滿足所有的觀看場景 移動端native用的rtmp流 pc端 用的flv流 移動端H5用的hls流
-
分發
分發即我們平常說的下行,主要是服務端推流給使用者,這一塊主要需要運維同學關注在複雜的網絡環境怎樣更快速的讓使用者看到高品質的直播, 這一塊涉及到傳輸品質監控、品質優化、鑒黃等部分的工作,網上也有很多這方面的專項文章,本文不做展開。
-
播放協定
目前移動端H5直播主要采用HLS協定播放,HLS最初是蘋果公司針對iPhone、iPod、iTouch和iPad等移動裝置而開發的流. 後續android3.0以上也支援,下表可以看出移動端基本都支援;
#EXTM3U m3u檔案頭,必須放在第一行
#EXT-X-ALLOW-CACHE 設定是否允許cache,目前是不允許
#EXT-X-MEDIA-SEQUENCE 接下來請求的第一個TS分片的序号,
#EXT-X-TARGETDURATION 每個分片TS的最大的時長,目前為9s,
#EXTINF 分片TS的資訊,如時長等**
HLS的請求流程是:
1 播放器發起一個http請求,拿取m3u8的配置資訊。
2 服務端傳回一個m3u8的播放清單,清單的資訊如上圖。這裡的分片長度和清單數量反應了時延長度,比如清單長度為5,分片時長為9s,則整個時延為45s;
3 播放終端解析m3u8的播放清單,依照順序擷取ts資料流,播放完畢的時候拉取下一個。
(1)移動端播放問題-僞全屏
我們有很多場景下視訊是全屏播放的且有互動部分的資訊需要展示,如果是系統的全屏 整個播放界面不可控,這裡需要用僞全屏,即css樣式來設定視訊大小,鋪滿全屏達到全屏效果,
- H5播放的過程中 也遇到了很多問題
這裡僞全屏需要注意的是ios上面需要設定内嵌播放,不然會被系統接管 ,在video标簽上加上對應的屬性即可,ios9以下設定是無效的,目前無解,ios9-ios10 webkit-playsinline ,ios10以上playsinline,需要所在的webview環境支援這種形式 ios微信 手Q 音樂app内均支援webviewallowsInlineMediaPlayback=YES即可;android端 用戶端 手Q 微信 都是基于x5核心的 支援内嵌播放,但是在qq浏覽器會接管直播 這裡如果要改成内嵌的 需要找浏覽器的同學加下白名單 如下圖效果 正常效果是右圖,QQ浏覽器中會如左圖效果
(2)自适應全屏
由于視訊大小不一,在螢幕高寬度固定的情況下,讓視訊自适應螢幕很關鍵;
具體步驟
1、計算視訊的高寬度
2、視訊高寬比和螢幕高寬比做比較
3、值偏大 以螢幕寬度為基準,進行等比縮放,值偏小,以螢幕高度為基準進行等比縮放;
舉個例子
1、如下圖左
2、螢幕是93169(寬/高) ,視訊大小252192,252/192>93/169 ,以螢幕寬度為基準 則縮放比為252/93 如圖2,
3、然後将視訊居中存放到容器中,如圖三;
(3)播放協定自适應終端
目前直播流協定用的HLS,ios端均支援,android端不同的機型、不同的系統版本、不同的webview環境支援HLS協定不盡相同,對于不支援的再做降級處理,可以通過canPlayType來看支援程度,該方法會傳回三個值
"probably" - 浏覽器最可能支援該音頻/視訊類型
"maybe" - 浏覽器也許支援該音頻/視訊類型
"-" (空字元串)浏覽器不支援該音頻/視訊類型
function chooseWay(){
var h5Able = {'probably': 1, 'maybe': 1};
var videoDom = document.createElement("video");
if( videoDom.canPlayType && ( videoDom.canPlayType("application/vnd.apple.mpegURL" ) in h5Able )){
$('#js_video').attr('src','http://3260.liveplay.myqcloud.com/live/3260_17c84703049011e791eae435c87f075e.m3u8');
console.log("支援HLS");
}else{
console.log("不支援HLS");
};
}
(4)播放是否在繼續
判斷直播狀态即直播是否在進行也是一個比較麻煩的事,由于android上對canplay canplaythrough playing事件支援程度不一樣,觸發時機也不盡相同,我們可以用一些hack技術,比如根據timeupdate進度的實時變化來判斷是否有在播放
$('#js_video').on('timeupdate',function(){
playtimeupdate = new Date().getTime();
});
setInterval(function(){//檢測有沒有在播放
if( lastplaytimeupdate && lastplaytimeupdate == playtimeupdate ){
console.log("異常");
}else{
lastplaytimeupdate = playtimeupdate;
}
},3000)
(5)pc調用系統全屏 自定義ui遇到的坑
全屏時預設系統會有一個ui,如果想自定義ui 需要想辦法把video自帶的影子節點隐藏或者蓋住,
在調用全屏時
浏覽器會為全屏的節點加上z-index ,是一個無限大的值,如果我們直接對video全屏 會将video和影子節點的層級設到無限高,即使設定了自定義ui的z-index 也會導緻點選失效,需要在video和自定義ui節點的 父節點上做全屏;
自研sdk
目前音樂也推出了自研視訊sdk,輕量、相容性好,歡迎使用
H5部分 點播功能已經全量,支援後退/快進/進度拖動/全屏,直播正在接入中
pc部分 點播功能已經灰階,在H5基礎上新增/音量控制/自定義全屏ui/清晰度切換,直播正在接入中
demo頁
y.qq.com/m/demo/demo…
H5基于zepto 引用
y.gtimg.cn/music/qmv/q…
pc基于jquery 引用
var params = {
title: "QMV播放清單",
container: ".js_videoplayer",
source:["x00248tvbgv","t0024928s1j","g00133xte6r"],
quality:true,
autoplay:false,
mode:0,// 0 順序 1 随機 當清單數量大于2時有效
useConnectionPlay: false,
};
var qmv = new QMV(params);
參考資料
HLS介紹
https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS
幀内壓縮和幀間壓縮差別
https://www.zhihu.com/question/20237091
H5視訊直播掃盲
http://km.oa.com/group/19674/articles/show/266140?kmref=search&from_page=1&no=1
移動端HTML5 video 标簽深入實踐