摘要: 直播簡介 直播最主要的特色就是實時性與互動性,這也是直播與點播之間的差異所在,它能夠實時將主播端的視頻信息以較低延遲傳輸到觀衆端,與此同時,觀衆能夠經過羣聊或者送禮物的方式與主播進行互動。 圖 1 直播主要由如下幾個環節所組成(圖 1) 1.ios
直播簡介編程
直播最主要的特色就是實時性與互動性,這也是直播與點播之間的差異所在,它能夠實時將主播端的視頻信息以較低延遲傳輸到觀衆端,與此同時,觀衆能夠經過羣聊或者送禮物的方式與主播進行互動。後端
圖 1設計模式
直播主要由如下幾個環節所組成(圖 1)緩存
1. 主播端採集安全
2. 處理:美顏、水印,基於人臉識別的動態貼紙;性能優化
3. 編碼:視頻主要是基於 H264 的編碼格式;服務器
4. 推流:使用 RTP 的實時傳輸協議,如 RTSP、RTMP、HLS;網絡
5. 網絡傳輸:使用 CDN 服務廠商的服務;多線程
6. 拉流:須要服務端處理轉碼,支持多分辨率,支持 RTP 實時傳輸協議;
7. 解碼:可使用硬件或者軟件解碼;
8. 播放。
以上主要環節絕大部分由雲服務解決。蘑菇街直播目前在前處理中加入了蘑菇街自研的基於人臉識別的動態貼紙功能。前處理和播放都是使用強大的開源庫 GPUImage。
移動端直播形態
直播形態及框架組成
目前移動端直播形態大致分爲如下幾種:全民直播、社交直播、電商直播和手遊直播。蘑菇街的直播,主要以電商爲主。下面主要介紹蘑菇街直播的組成。
圖 2
圖 2 是蘑菇街直播的大體組成,包含三大模塊,分別是媒體模塊、服務模塊和管理模塊。
1)媒體模塊
由直播和直播回放組成。直播回放的目的有兩個,一是在直播過程當中,將平臺上優質的內容沉澱下來,其次是能夠在直播較少的時間段提供直播回放,增長內容的廣度。
2)服務模塊
也稱爲業務模塊,其中包括電商、支付、聊天、禮物、運營、抽獎、安全以及統計系統;
圖 3
其中,電商系統(圖 3)是蘑菇街本身加入的一個特有的系統,主要是讓賣家在直播過程當中,能夠上架商品發放優惠券,主打商品通道,以後觀衆就能夠在觀衆端進行商品瀏覽、加購、下單、購買以及領取優惠券這些行爲。觀衆端的大小窗自由切換,爲觀衆提供了更加便捷的消費模式,能夠無縫地進行觀看和購買,這個模塊無論是從產品層面仍是技術層面都算是作的比較成功的。統計數據顯示,大部分直播間的成交場景,都來源於從直播間切換到詳情頁時所產生的下單購買行爲。
3)管理模塊
管理模塊主要用於後臺管理。
圖 4
蘑菇街的直播的頁面主要分爲主播端和觀衆端兩部分;圖 4 爲蘑菇街直播的主播端頁面的綜合展現。
圖 5
圖 5 爲主播信息頁面,頁面下面爲主推商品以及其價錢顯示。
圖 6
圖 6 頁面底部依次爲人臉識別/貼紙、電商、切換分辨率、美顏這些功能模塊。其中電商模塊主要是主播用於設置商品展現這些功能;分辨率這塊默認標清爲 960P,能夠切換爲高清(1280P)/流暢(640P)。
圖 7
圖 7 爲蘑菇街直播的觀衆端頁面綜合展現。
圖 8
如圖 8 所示,觀衆端和主播端最主要的區別是大小窗切換功能(頁面底端從左向右數第二個模塊),點開以後切換到小窗,小窗能夠任意拖動。
圖 9
電商模塊點開以後(圖 9)能夠顯示完整的商品信息(價格、名稱、規格),這裏能夠加入購物車或者當即購買;好比點擊商品信息,就能夠直接跳轉到詳情頁進行小窗模式的播放,這個時候觀衆不只能夠看到主播在介紹本身的商品,同時能夠很清晰直觀地經過圖片,還有文字的形式,去察看這個商品的一些主要的功能介紹。這也就是爲何在蘑菇街平臺上,直播的大部分下單或者成交場景,都來源於詳情頁的緣由。
直播難題及優化實踐
直播難題
蘑菇街在直播中所遇到的問題,主要爲迭代、雲服務、代碼質量、穩定性以及性能這五點。
迭代主要遇到的問題是,前期需求調研不充分,從立項到上線差很少三個星期,這個時候其實大部分同窗對直播的技術是陌生的。新需求一上線,產品就羅列了一堆須要上線的需求列表,而後按照優先級進行了排序,而後致使的問題是,直播團隊須要常常加班來解決線上的問題以及迭代新的需求。 除此以外,快速迭代致使的新老 Bug 的問題,以及接入第三方服務時所碰見的一些問題也成爲直播過程當中所碰見的一系列難題。
關於穩定性的問題,致使其存在的緣由主要有如下幾方面:內存泄露、客戶端 SDK 不穩定、硬件的兼容性問題以及複雜的多線程帶來的時序異常的問題。穩定性的問題,主要會致使觀衆沒法正常觀看直播以及主播沒法正常進行直播這兩種狀況。後續也會針對穩定性的問題,作一系列的優化措施。
圖 10
圖 10 爲性能上面存在的問題,在直播初期,剛接入雲服務時,其實並不支持硬件編解碼,這樣會致使主播手機端會很是卡頓、手機發燙這樣的狀況發生;除此以外,還會存在評論列表刷新過於頻繁,點贊、禮物和彈幕渲染以及高併發下如何打點着一系列的問題。
直播優化實踐
1. 穩定性優化
針對穩定性,蘑菇街團隊內部作了不少努力,其中包括進行 Code Review 、代碼規範、接入整個靜態分析和內存泄露的檢測工具;同時也對日誌作了必定的處理,在關鍵流程和出錯的地方,都打上 log,日誌能夠進行本地察看和發送並定向上報分析。
圖 11
關於穩定性方面的案例,如圖 11 所示是一個多層 block 嵌套的模型,是進行穩定性優化時作的代碼優化處理案例,多層 block 嵌套在大屏幕上以及在上下文參數和回調的使用方面仍是挺舒服的,可是伴隨着較差的可閱讀性,好比說筆記本電腦,只能顯示前面半部分,幾乎不可閱讀,因而可知它的閱讀性是很是差的。還會致使回調流丟失以及由於 block 嵌套致使的循環引用。後期,針對這些代碼,進行了一系列修改以後,將多層的 block 嵌套修改爲「單一職責」的方法調用,新增了代碼的可閱讀性和可維護性,同時不易形成回調流失,內存泄露等問題。
穩定性優化還包括內容泄露方面的優化,使用 instruments 進行內存泄露的檢測,在 iOS 客戶端使用 MLeaksFinder 針對直播組件進行了 Debug 下的內存泄露檢測,這樣作就能夠將內存泄露扼殺在開發階段。
圖 12
圖 13
圖 12 是 MLeaksFinder 的使用,圖 13 是它的原理。 MLeakerFinder 的原理簡單說就是當 VC 被 POP 時 ,它會在 3 s 後 ping 全部的 view,若是 ping 到了,就說明這個 view 在 3 s 內尚未釋放,說明有可能發生了泄露,雖然會有一些誤報,可是當添加一段新代碼時,他有提示,那麼這樣就能夠重新加的代碼當中找到問題,能夠用來輔助開發。
流程打點,也是穩定優化當中很是重要的一塊,流程打點裏面的定製性很是高,能夠生成一些文件或者是存儲到本地。能夠在關鍵流程上打 log,出錯、SDK 報警均可以打上 log,給 App 的生命週期打 log,VC 的生命週期打 log,這樣一來就很容易經過日誌找到線索,來解決線上碰見的問題。
2.性能優化
1)進房速度慢
圖 14
性能優化中最主要的部分,就是進房速度慢;圖 14 是串行的進房流程,這是最開始採起的一種進房方案,串性地支持一段流程,最後拉取流,這樣作會花費較長時間,由於須要每一個步驟時間的累加,時間總和確定是超過 1 s 的,這樣一來也就達不到視頻秒開的要求。
圖 15
圖 15 是針對進房速度慢的優化方案。針對能夠抽出的審檢部分,進行了預登錄;進行了同步處理和異步處理,這樣一來,節省了雲服務預登錄的 300 ms 和加入聊天室的 50 ms,以及後續獲取直播間詳情信息的 200 ms 時間,統計下來節省了近 550 ms的時間。
圖 16
圖 16 是進行優化後的結果,原來須要花費 1.3 s 進房,在優化以後只需 700 ms 就能夠進房。
2)消息
直播的的消息包括評論消息或者其餘消息,這塊常常會遇到的問題主要是觸發時機過於頻繁、缺乏消息緩存池、沒有緩存列表的高度計算。
圖 17
圖 17 是以前作的消息系統。首先由 VC 調用消息管理類發送消息接口,消息管理類持有聊天室實例進行發送,該接口異步回調給直播間 VC 去作消息內容的接收、緩存,以後進行消息的合併和轉發。這樣的處理方式應該是比較簡單清晰的,可是隨着業務的發展,直播間 VC 承擔了太多消息處理,同時伴隨着消息相關業務的耦合。由於直播相對來講就一個主播間和觀衆間,自己會集成不少功能,代碼量相對來講也會比較大,如今又將消息功能也寫進直播間內部,這樣就會致使直播間 VC 將成爲一個「上帝類」,不易開發和維護。
圖 18
圖 18 是消息優化的四個流程。
第一是消息註冊。在進入直播間時,會針對消息類型將消息註冊到消息分發管理類中,消息分發管理類內部持有 NSHashTable,弱引用註冊消息的對象。
第二是發送消息。各業務模塊單獨調用消息管理類的發送接口,消息管理類內部調用持有的實例進行消息發送,去除了直播間 VC 這個中介者。
第三是消息處理。消息管理類收到消息回調後,調用消息分發管理,而後根據第一步的消息註冊,進行消息的分發(一對多),評論列表相關的消息須要進入消息池,消息按需回調。
第四是評論列表刷新。最開始都是收到消息後當即刷新視圖,在高併發下,這樣作會致使刷新過於頻繁,嚴重時會佔用一半的 CPU 資源,使得直播間很是卡頓;優化以後的作法是,定時輪詢消息池內部的消息,存在消息時纔將消息從消息池取出,作相應的業務處理後再進行視圖刷新。
對消息進行這樣四個流程的設計,是比較清晰合理的,既減小了直播間 VC 的耦合性,同時也提高了消息的性能。
3)動畫
圖 19
性能優化方面,動畫也是很大的一塊。如圖 19 所示,動畫控件的可複用性,離屏渲染嚴重,序列幀圖片緩存都是這裏所面臨的問題。
對於點贊(彈幕),主要是會限制其點贊(彈幕)頻次上線。20次/s 即可以達到渲染直播間氣氛的行爲,直播間 100 個用戶每一個人點一下就收到 100 個,而若是同時顯示 100 個,確定會形成直播間主播端卡頓,所以,限制最高頻次就能避免這種現象的發生。
離屏渲染,能夠去除大量圓角(好比直播間列表的一些可複用性圓角),都用圖片代替,由於離屏渲染是很是影響 CPU 性能的,會形成很明顯的列表卡頓或者直播間卡頓。
對於序列幀,複用程度高的小圖片能夠進行緩存,可是對於一些禮物大動畫,圖片比較大,長時間在直播間播放會一直佔用內存,因此在使用完以後應該立馬釋放。
4)打點
圖 20
圖 20 是最初使用的打點流程,會將這些主流程的打點都附加到磁盤,從磁盤取出以後再發送數據上報給服務器,這樣作會使磁盤和網絡 IO 操做很是頻繁。
圖 21
針對這一點,作了如圖 21 的流程優化。在進行打點時,會優先將其存入內存當中,在異常狀況下才會從內存中將打點數據存儲到磁盤,而後定時去作一個打點數據發送的檢測,當數據達到闕值時再發送出去,這樣一來減小了網絡和磁盤的 IO 操做。
圖 22
圖 22 是性能打點優化的結果。原來每秒打點 50 次,須要佔用 70% 的 CPU 資源,優化之後只須要佔用 35% 的 CPU 資源。
3.直播組件化
圖 23
圖 23 是直播組件化的一些功能模塊,其中包含房間管理、消息通道、紅包、禮物、評論等功能模塊。
組件化主要是爲了解決直播間代碼耦合性高,對外提供可定製化功能模塊,自定義 UI 的功能。在選擇整體的設計方案的時候,按照需求進行了總體設計模式的選擇:
1)須要明確的接口定義和麪向接口編程,而且能夠重寫具體的實現達到自定義UI和功能的需求;
2)低耦合,可定製化功能模塊。
基於以上兩個要求,選擇了 MVP 的設計模式,MVP 能夠很好的解耦直播間的各模塊代碼,同時有良好的接口層,具體的 View 和 Presenter 實現各自的 Interface 層的邏輯,替換 View 和 Presenter 的實現就能達到可定製化UI的需求。而後直播間對各模塊 Presenter 的接口層的組合調用,也可以很好的支持功能模塊的和定製化需求。相較於比較厚重的 MVC 模式和數據雙向綁定的 MVVM,MVP 更適合蘑菇街的業務場景。
圖 24
圖 24 是一個主播信息展現組件,MVP 的組件化工做給以後的 SDK 化和平臺化帶來了極大的便利。對於直播回放的接入,則只需在回放的直播間組裝業務組件就能夠完成,操做上帶來了很大的便利。
4.SDK化
SDK 化主要目的有四點:
1.下降集團內其餘 App 的接入成本;
2.統一的接口和文檔;
3.良好的框架設計和擴展性;
4.業務功能可配置化和 UI 定製化;
圖 25
圖 25 是整個蘑菇街 SDK 化的客戶端框架圖。
底部是視頻直播 Core SDK ,包含兩個模塊,一個是直播音視頻模塊,一個是直播 IM 模塊;音視頻模塊接入蘑菇街自研的人臉識別、開源的 GPUImage、同時還接入雲服務登錄 SDK;IM 模塊包含消息分發模塊和 IM SDK 兩部分,消息分發模塊就是以前說起的將消息的一個步驟拆分紅四個步驟的組成模塊;
業務模塊就是剛纔說起的組件化,包含一些功能模塊。
圖 26
圖 26 是 Core SDK 的功能。建立視頻直播、加入視頻直播、註冊 IM 消息回調、發送 IM 消息、退出視頻直播等功能,這些都是一些基礎功能。
圖 27
圖 27 是 SDK 業務層的方面。依賴於視頻直播的 Core SDK,同時在上面會有一個本身的業務,而後進行組件化,能夠實現其餘 App 接入時的定製化功能。
5.平臺化
平臺化的工做,一方面是提供更好的業務方接入方式(與市面上常見的 SDK 相似,提供 UID );另外一方面,針對平臺內部能夠提供一個便捷精準的數據平臺,用於區分於業務端。這個事情主要由後端主導,而後客戶端配合直播相關接口的改動,由於客戶端已經作了組件化和 SDK 化兩個主要的支持業務方快速接入而且能夠定製化功能 UI 的工做。
圖 28
圖 28 是平臺化大體的結構圖,頂端是直播的來源,中間是平臺化的一些工做,包括直播 SDK 接入、直播數據存儲、直播報表以及後臺系統。底端接入了互動直播、點播以及 IM 的雲服務。
直播設備
因爲用手機進行推流播放會形成分辨率有限以及穩定性方面也會產生一些問題,因此蘑菇街採起了專業設備推流播放的方式。
圖 29
圖 29 是採用專業設備推流的大體界面,裏面支持橫豎屏兩種模式,而且能夠任意切換。
圖 30
針對專業設備推流,蘑菇街主要採起如下方案進行。視頻採集可使用電腦攝像頭或者專業的攝像設備;採集完成以後都推流給電腦(電腦上面須要裝 OBS 軟件),OBS 接收到採集的視頻流以後,經過視頻流推流,上傳到雲端進行分發;播放端則比較簡單,採用點播 SDK 就能夠完成支持。圖 30 爲完整的流程圖。
專業設備與正常直播之間的區別之一就是沒有手機端的主播端,只有攝像頭進行視頻流採集。此時,也會遇到一些問題,好比房間號的產生、羣聊的建立、業務信息的獲取;這些信息目前都是在管理後臺進行一系列的分配工做(推流地址由運營後臺點擊按鈕後調用雲服務的開啓推流頻道接口獲取);其次是在採集推流時須要經過電腦用 OBS 進行推流再進行 CDN 分發;最後是在播放時,手動設置房間狀態,直播狀態分爲三種。直播沒開始時爲訂閱狀態;直播結束了則會跳轉到直播結束頁;只有在正常情況下才能夠進入直播間進行拉流播放,房間狀態由運營後臺維護,添加了推流、斷線、重連。
https://yq.aliyun.com/articles/62961