天天看點

蘑菇街直播架構

直播簡介

直播最主要的特點就是實時性與互動性,這也是直播與點播之間的差别所在,它可以實時将主播端的視訊資訊以較低延遲傳輸到觀衆端,與此同時,觀衆可以通過群聊或者送禮物的方式與主播進行互動。

蘑菇街直播架構

圖 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 分發;最後是在播放時,手動設定房間狀态,直播狀态分為三種。直播沒開始時為訂閱狀态;直播結束了則會跳轉到直播結束頁;隻有在正常狀況下才可以進入直播間進行拉流播放,房間狀态由營運背景維護,添加了推流、斷線、重連。