欧美,精品,综合,亚洲,好吊妞视频免新费观看,免费观看三级吃奶,一级a片女人自慰免费看

您當(dāng)前的位置是:  首頁(yè) > 資訊 > 文章精選 >
 首頁(yè) > 資訊 > 文章精選 >

下一代音視頻實(shí)時(shí)傳輸 SDK 的架構(gòu)設(shè)計(jì)

2019-12-12 11:09:20   作者:   來(lái)源:CTI論壇   評(píng)論:0  點(diǎn)擊:


  在 12 月 6 日的 ArchSummit 北京站,聲網(wǎng) Agora SDK 資深架構(gòu)師章真分享了 Agora SDK 的架構(gòu)設(shè)計(jì)。以下為演講實(shí)錄。
  我是來(lái)自聲網(wǎng)的SDK資深架構(gòu)師,負(fù)責(zé)整個(gè)前端API。聲網(wǎng)在全球部署了軟件定義的實(shí)時(shí)網(wǎng) SD-RTN?,它為開發(fā)者提供了實(shí)時(shí)音視頻專用網(wǎng)絡(luò)服務(wù)。之前有一位演講人說(shuō) API 很重要。確實(shí)是這樣的。
  我會(huì)從這 4 個(gè)方面簡(jiǎn)要介紹一下我們的架構(gòu)經(jīng)驗(yàn):
  1. RTC 場(chǎng)景現(xiàn)在面臨的問題和挑戰(zhàn);
  2. 重點(diǎn)介紹一下架構(gòu)和API的設(shè)計(jì)和思想;
  3. 如何對(duì)架構(gòu)上進(jìn)行重構(gòu)或代碼改進(jìn),從而更好地控制媒體和網(wǎng)絡(luò);
  4. 為了 SDK 的低延遲、高性能、高并發(fā),我們做了哪些探索。
  考慮到大家對(duì) RTC 領(lǐng)域不是太了解,我先簡(jiǎn)單介紹一下。其實(shí)它是一個(gè)很傳統(tǒng)的實(shí)時(shí)音視頻場(chǎng)景,現(xiàn)在最主流的技術(shù)是由谷歌提供 WebRTC,利用它,你可以通過(guò)瀏覽器與另一個(gè)人進(jìn)行實(shí)時(shí)音視頻的通話。聲網(wǎng)也參考了一些 WebRTC 的設(shè)計(jì),從最開始的一對(duì)一通話,然后到一對(duì)一多通話,到現(xiàn)在一個(gè)頻道可以支持上百萬(wàn)的用戶,其中也有很多技術(shù)挑戰(zhàn)。
  問題與挑戰(zhàn)
  首先,從場(chǎng)景角度講,我們會(huì)遇到的問題和挑戰(zhàn)有哪些呢?
  • 傳統(tǒng)的 RTC 場(chǎng)景:現(xiàn)在我們可以看到很多場(chǎng)景,例如說(shuō) 4K 高清視頻,如果傳統(tǒng)的SDK不做改善的話,傳輸一個(gè) 4K 視頻,對(duì)它的內(nèi)存、CPU等各方面都會(huì)帶來(lái)極大的挑戰(zhàn)。
  • 娛樂社交和在線教育:現(xiàn)在不光需要打開 Web 瀏覽器、攝像頭,還需要打開本地的播放器,傳輸本地播放器的內(nèi)容。
  • 云游戲加速:現(xiàn)在很多廠商還在開發(fā)云游戲,游戲運(yùn)行于服務(wù)端,數(shù)據(jù)以音視頻、指令等形式傳輸至手機(jī),手機(jī)僅僅負(fù)責(zé)渲染,其中最大的挑戰(zhàn)就是延時(shí),如果從服務(wù)端到手機(jī)的傳輸延時(shí)超過(guò) 200ms 的話,游戲體驗(yàn)會(huì)變得很差,這就需要一個(gè)類似于聲網(wǎng)的實(shí)時(shí)碼流加速傳輸網(wǎng)絡(luò)。
  • SIP/PSTN:SIP傳統(tǒng)的網(wǎng)絡(luò)電話,在全球有大量的業(yè)務(wù)需求,通過(guò)網(wǎng)絡(luò)的流量來(lái)達(dá)到整個(gè) RTC 的效果。
  • WebRTC 加速:如果在中國(guó)和美國(guó)之前通過(guò)公網(wǎng) P2P 溝通,卻缺少一個(gè)底層網(wǎng)絡(luò)網(wǎng)和SDK的介入的話,其實(shí)是很難工作的。一個(gè)沒有任何 QoS(服務(wù)質(zhì)量)保障的連接,通話會(huì)很糟。
  這些都是我們?cè)?RTC 領(lǐng)域會(huì)遇到的場(chǎng)景,而 WebRTC 一類的開源引擎是遠(yuǎn)不能達(dá)到我們對(duì)場(chǎng)景的技術(shù)要求的,需要一個(gè)具備網(wǎng)絡(luò)傳輸、音視頻編解碼等能力的 SDK 來(lái)實(shí)現(xiàn)。
  面對(duì)這樣的場(chǎng)景需求,SDK 需要具備哪些特性呢?
  首先是合理的架構(gòu)設(shè)計(jì),它有兩個(gè)特點(diǎn):第一點(diǎn)是媒體和網(wǎng)絡(luò)是獨(dú)立控制的。因?yàn)樵陬愃?PSTN、云游戲加速傳輸?shù)膱?chǎng)景中,它的媒體數(shù)據(jù)是由自己處理的,僅需要我們提供網(wǎng)絡(luò)傳輸加速的能力。但像 4K 音視頻的實(shí)時(shí)傳輸,從采集、編碼、渲染到傳輸,都需要 SDK 來(lái)完成。所以對(duì)于不同場(chǎng)景,SDK 就需要提供不同層次和不同模塊的接口。
  第二是面向?qū)ο蟮?API 設(shè)計(jì)。關(guān)于 WebRTC 有個(gè)小故事,P2P 連接的協(xié)商過(guò)程是通過(guò) SDP 協(xié)議做的,而整個(gè)能力協(xié)商的過(guò)程通過(guò)交換 offer 和 answer 就可以快速握手。最初這種設(shè)計(jì)認(rèn)為協(xié)商過(guò)于復(fù)雜,一般的工程師搞不懂,所以并沒有開放接口讓開發(fā)者控制SDP相關(guān)內(nèi)容。微軟在進(jìn)入 RTC 領(lǐng)域后,基于 WebRTC 貢獻(xiàn)了 ORTC 項(xiàng)目,它 API 設(shè)計(jì)則是面向?qū)ο蟮摹K麄冊(cè)?jīng)有過(guò)這樣一個(gè)看法,如果可以開放更多面向底層、面向?qū)ο蟮?API,開發(fā)者可以根據(jù)自己的場(chǎng)景需要來(lái)搭建。這也是面向?qū)ο?API 設(shè)計(jì)的重要性。
  現(xiàn)在很多提供 API 的公司都強(qiáng)調(diào)一點(diǎn),叫做易用性,十幾行代碼就可以讓你實(shí)現(xiàn)某個(gè)功能。因?yàn)橐郧伴_發(fā)者的能力普遍還沒有那么強(qiáng),也不清楚 RTC 場(chǎng)景是怎樣的,所以我們通過(guò)這種簡(jiǎn)單的方式,讓任何一個(gè)小白開發(fā)者都可以輕松做出一個(gè) App。隨著這些年的發(fā)展,場(chǎng)景變得越來(lái)越復(fù)雜,開發(fā)者的能力也越來(lái)越強(qiáng),我們完全可以提供面向?qū)ο蟮?API,讓開發(fā)者自己通過(guò)它們構(gòu)建自己想要的場(chǎng)景。
  除了合理的架構(gòu)設(shè)計(jì),還要支持豐富的媒體傳輸能力,具備低延時(shí)、高性能、高并發(fā)的特性等。這些我稍后會(huì)詳細(xì)分析。
  架構(gòu)與API設(shè)計(jì)
  先說(shuō)一下傳輸 SDK 的分層。如上圖,SDK 的分層最底下是網(wǎng)絡(luò)層。最早之前的一些網(wǎng)絡(luò)傳輸都是基于 TCP 的,TCP 和 UDP 之間的區(qū)別,我就不說(shuō)了,但是對(duì)于媒體的實(shí)時(shí)傳輸來(lái)講,在有網(wǎng)絡(luò)丟包時(shí),TCP 的延時(shí)會(huì)非常大,完全不能滿足實(shí)時(shí)互動(dòng)的要求,所以最核心的是說(shuō)媒體其實(shí)是不需要,就是在網(wǎng)絡(luò)上丟包的情況下,TCP現(xiàn)在幾乎所有的媒體實(shí)時(shí)傳輸都是基于 UDP 實(shí)現(xiàn)的,包括比較新的 QUIC 協(xié)議,底層也是基于 UDP的。
  Transport(UDP)上面是擁塞控制與網(wǎng)絡(luò)連接控制,這是 RTC 領(lǐng)域最重要的一個(gè)技術(shù)環(huán)節(jié)和算法模塊。目的是要在比較復(fù)雜錯(cuò)綜的網(wǎng)絡(luò)環(huán)境下,實(shí)現(xiàn)更靈活的網(wǎng)絡(luò)控制。
  然后是 Media stream 層,它類似于一個(gè) RTP 的協(xié)議,更多是面向媒體流,這一層有時(shí)間戳和一些標(biāo)準(zhǔn)的協(xié)議。
  再上面就是 Media Engine。Media Engine有兩層,一層是編解碼器,一層是輸出編碼后的數(shù)據(jù),比如 VP8、VP9,也包括一些傳統(tǒng)的編碼碼率。
  再往上是 Frame YUV/PCM。WebRTC 一般只能傳YUV和PCM的數(shù)據(jù)。這里講一個(gè)小的故事,很多中國(guó)的開發(fā)者會(huì)把 WebRTC 當(dāng)成一個(gè) SDK 用,其實(shí) WebRTC 根本算不上是一個(gè) SDK,它僅僅是一個(gè) Media Engine。Media Engine 和 SDK 最主要的差別是什么呢?Media Engine僅僅是提供了一個(gè)功能,比如說(shuō)像谷歌自己也有 RTC 的功能,它僅僅是把 WebRTC 的代碼當(dāng)成一個(gè)功能模塊來(lái)使用,Chromium 才是一個(gè)真正的 SDK。
  說(shuō)完網(wǎng)絡(luò)與對(duì)象的簡(jiǎn)單分層,我們來(lái)一起看一下對(duì)象的建模。
  我們?nèi)シ治鲆粋(gè)業(yè)務(wù)場(chǎng)景,或者是去設(shè)計(jì)一個(gè) API,最重要是要了解你控制的對(duì)象是什么。首先,我們一般的輸入源有攝像頭、屏幕共享、錄音設(shè)備,以及文件或客戶自定義數(shù)據(jù),對(duì)于這些對(duì)象,我們通過(guò) Audio Source 和 Video Source 作為管理,既可以管理 YUV/PCM 這種原始采集數(shù)據(jù),也可以管理類似 H264/VP8 這種編碼后數(shù)據(jù)。這些數(shù)據(jù)源可以產(chǎn)生媒體流,對(duì)于媒體流對(duì)象,我們用 Video Track 或者 Audio Track 來(lái)管理,對(duì)于本地發(fā)布流和遠(yuǎn)端訂閱的流,用 local 和 remote 作為區(qū)分。而最重要的模塊自然就是網(wǎng)絡(luò),我們抽象為一個(gè)叫 RTC Connection 的對(duì)象,負(fù)責(zé)網(wǎng)絡(luò)連接到我們的 SD-RTN? 上。每一個(gè) Connection 都有且只有一個(gè) local user 負(fù)責(zé)媒體流的發(fā)布和訂閱。除此以外,video 和 audio 的處理模塊也都對(duì)象化處理,如 video filter、audio filter、audio device manager 等。把媒體流發(fā)布到這個(gè) Connection 上,你可以進(jìn)行遠(yuǎn)端的通話了。
  在這里我們可以看到面向?qū)ο?API 的一些優(yōu)點(diǎn)。你可以在其中創(chuàng)建多個(gè)對(duì)象,對(duì)應(yīng)這個(gè)圖來(lái)講就是可以創(chuàng)建多個(gè) Local Video Track,能同時(shí)有幾個(gè)或幾千個(gè) RTC Connection,可以同時(shí)與多人建立連接,或者創(chuàng)建更多頻道。
  從我們的理解來(lái)講,API 的設(shè)計(jì)還有一個(gè)非常重要的地方。很多初級(jí)開發(fā)者都會(huì)覺得 API 僅僅是把 SDK 的功能體現(xiàn)給使用者。而在我們看來(lái),好的 API 設(shè)計(jì)“能自己講故事”。當(dāng)別人看過(guò)你 30%的 API 之后,就能知道你整個(gè)架構(gòu)和設(shè)計(jì)理念是什么,它能成為架構(gòu)師與開發(fā)者對(duì)話的一個(gè)渠道。如果發(fā)送編碼數(shù)據(jù)和發(fā)送原始數(shù)據(jù) 是完全兩套API的style,就會(huì)給開發(fā)者帶來(lái)困惑。所以在 API 的設(shè)計(jì)之中,架構(gòu)要做的不僅僅是展現(xiàn)功能,還將你的API 設(shè)計(jì)理念通過(guò) API 傳達(dá)給使用者。
  舉一個(gè)例子。我們?cè)趺磳?shí)現(xiàn)與遠(yuǎn)端用戶的通話。首先你要?jiǎng)?chuàng)建一個(gè) Connection,你作為一個(gè) Local User 想要發(fā)布流就需要一個(gè) Local Track,這時(shí)候你需要調(diào)用 Publish Track 把 Local Track 發(fā)送到 Connection 上,這樣遠(yuǎn)端的用戶就能看到你了。同樣的,你也可以去訂閱遠(yuǎn)端用戶(Remote Users)的流,他的 Remote Track 會(huì)通過(guò) Connection 發(fā)送到 Local Users 這一端。這就是一個(gè)完整的“故事”。在聽完這個(gè)“故事”之后,如果有一天你想傳輸你的攝像頭數(shù)據(jù),對(duì)你來(lái)講,它仍然是一個(gè) Track,只是 Source 不同了。只有會(huì)講“故事”的 API,才能讓用戶理解如何去靈活使用。
  另外,還有很重要的一點(diǎn),就是不要?jiǎng)?chuàng)造新的名詞,應(yīng)該符合全球定義的標(biāo)準(zhǔn)。我們?cè)诙x API 的時(shí)候,就會(huì)大量地翻閱一些國(guó)際標(biāo)準(zhǔn),比如 W3C 的,這些都是符合開發(fā)者認(rèn)知體系的。
  媒體和網(wǎng)絡(luò)控制
  接下來(lái),我們講講架構(gòu)設(shè)計(jì)里面的一些具體實(shí)現(xiàn)。
  我不知道大家是否聽過(guò) SOLID 法則。在講它之前,我們要講講為什么說(shuō) WebRTC 只是一個(gè)功能模塊。當(dāng)你去玩一些開源項(xiàng)目,谷歌提供的能力也好,WebRTC 的開源代碼也罷,你可能會(huì)發(fā)現(xiàn)它的適用場(chǎng)景非常單一,它只是適合 P2P 或者跟一些服務(wù)器打交道。
  作為一個(gè) SDK,要講功能開放給開發(fā)者,就必須要實(shí)現(xiàn)一個(gè) Pipeline。從最簡(jiǎn)單的 Pipeline 來(lái)講,有 5 個(gè) SOLID 法則:
  • 單一責(zé)任法則。假如你有一個(gè) 100 人的團(tuán)隊(duì),每個(gè)團(tuán)隊(duì)都有自己的任務(wù),有做降噪的,有做視頻編碼的,好的架構(gòu)是讓這些人只需要專注于自身的功能模塊的實(shí)現(xiàn),代碼如何寫,算法如何改進(jìn),而不需要去考慮其它模塊中的業(yè)務(wù)。
  • 開閉法則。當(dāng)你需要開發(fā)一個(gè)新功能的時(shí)候,不需要去修改之前的代碼,這是好的架構(gòu)。
  • 模塊可替換。作為一個(gè)好的 SDK 架構(gòu),SDK 中的任何接口和模塊都是可以被無(wú)縫替換的。
  • 接口隔離。用戶可以清楚找到控制對(duì)象或者接口,而不需要理解很多不感興趣的接口。
  最后,依賴反轉(zhuǎn)是特別重要的一點(diǎn)。任何API 都需要面向接口編程,這樣一來(lái),用戶就不需要去理解模塊內(nèi)部是如何實(shí)現(xiàn)的,只需要看接口就行了。
  我們的 Pipeline 如上圖所示。綠色的是接收端,中間通過(guò) Agora SD-RTN?進(jìn)行傳輸。我們會(huì)將一些算法、引擎等用 Pipeline 的方式進(jìn)行組織; SOLID 法則,我們面向各種場(chǎng)景的應(yīng)用,代碼會(huì)變得越來(lái)越快、越來(lái)越方便,算法專家也不用去了解其他模塊,只專注于手上的工作。
  舉個(gè)例子,我們有一個(gè)叫做 Media Player Kit 的組件,它支持本地媒體播放和多流互動(dòng)(詳見我們此前的文章),如上圖是它的架構(gòu)。Media Player 可以支持本地媒體播放,也可以將本地視頻流發(fā)送到遠(yuǎn)端。如果你還記得“API需要講統(tǒng)一的故事“,就能想象到,Media Player 是一個(gè)媒體數(shù)據(jù)源,可以提供 video track 和 audio track,如果將這些 track 加上 renderer,就可以本地播放,如果把這個(gè) track 發(fā)布到 RTC Connection 就可以和遠(yuǎn)端用戶共享了。
  Pipeline 就像一個(gè)管道一樣,一般來(lái)說(shuō) Pipeline 都是單向的,從管道的入口到出口,但其實(shí)Pipeline 里最核心的一些控制是通過(guò)負(fù)向反饋來(lái)做的,這也是控制理論經(jīng)典的話題。
  在 RTC 領(lǐng)域里,有一個(gè)很核心的 Pipeline 叫“帶寬估計(jì)”,它可以實(shí)時(shí)監(jiān)控當(dāng)前網(wǎng)絡(luò)是否有擁塞,當(dāng)發(fā)現(xiàn)有擁塞的之后,會(huì)立即反饋預(yù)估的帶寬值到 Video Quality Controller 模塊,動(dòng)態(tài)調(diào)整碼流、幀率,以保證音視頻流的實(shí)時(shí)體驗(yàn)。如上圖所示,Video Quality Controller模塊同時(shí)還會(huì)監(jiān)聽 CPU 狀態(tài),因?yàn)榈投耸謾C(jī),遇到較高幀率、分辨率的視頻會(huì)容易遇到 CPU 的性能瓶頸,從而出現(xiàn)卡頓。Video Quality Controller 模塊會(huì)基于收到的帶寬估計(jì)和 CPU 狀態(tài)信息來(lái)動(dòng)態(tài)改變編碼碼率,比如你現(xiàn)在發(fā)送的是 2M 的碼流,但是遇到了網(wǎng)絡(luò)擁塞,那么就會(huì)降低一些畫質(zhì),改為發(fā)送 1M 的碼流,能保證通話是流暢的。
  在架構(gòu)中,策略層和功能層是要嚴(yán)格區(qū)分的。從上圖來(lái)講,實(shí)線的部分就是數(shù)據(jù)通道,它提供了視頻的采集、編碼、傳輸功能,而下方的模塊則是策略層,負(fù)責(zé)根據(jù)網(wǎng)絡(luò)及設(shè)備情況來(lái)反饋給功能模塊,調(diào)整其中的碼率、幀率這樣的參數(shù)。
  低延時(shí)、高性能、高并發(fā)
  除此弱網(wǎng)對(duì)抗的算法等常規(guī)方法以外,我們還可以在開發(fā)工具層面來(lái)進(jìn)一步優(yōu)化網(wǎng)絡(luò)延時(shí)。就好像萊特兄弟造飛機(jī)一樣。他們做的最重要的一項(xiàng)設(shè)計(jì)就是風(fēng)洞。這飛機(jī)真正試飛前就可以進(jìn)行充分的測(cè)試。我們也一樣,在此方面也花費(fèi)了很多精力。我們做了配套的性能調(diào)查工具、系統(tǒng)工具,比如perf性能瓶頸的查找,熱點(diǎn)代碼的定位等,以此來(lái)做到 SDK 的白盒化。我們通過(guò)這些工具來(lái)不斷優(yōu)化SDK 的各項(xiàng)指標(biāo),包括延時(shí)、弱網(wǎng)對(duì)抗、內(nèi)存優(yōu)化、CPU 優(yōu)化等。
  以分段延時(shí)為例,如果以光的速度來(lái)計(jì)算,從中國(guó)到美國(guó)直線傳輸大概需要 30ms。我們聲網(wǎng)在全球的平均延時(shí)可以達(dá)到 76ms。下圖是一個(gè)傳輸?shù)姆侄窝訒r(shí)示意圖。我們通過(guò)工具來(lái)對(duì)每段延時(shí)生成清晰的報(bào)表。這些監(jiān)測(cè)數(shù)據(jù)讓我們能有針對(duì)性地優(yōu)化不同的模塊。
 
  同時(shí),我們還要對(duì)弱網(wǎng)對(duì)抗算法進(jìn)行不斷的驗(yàn)證和優(yōu)化。我們會(huì)模擬丟包、模擬延遲,我們?cè)谒惴ㄉ蠒?huì)關(guān)注碼率跟蹤速度、帶寬預(yù)估準(zhǔn)確度。如下圖所示,紅線是我們的預(yù)估值,黑線是驗(yàn)證的數(shù)值,兩者越接近,說(shuō)明碼率控制得越好。
  在高性能方面,我們提出了內(nèi)存池和線程池的概念。
  我們需要根據(jù)系統(tǒng)內(nèi)存情況,自動(dòng)調(diào)整內(nèi)存池的大小,不同大小的空閑隊(duì)列需要自動(dòng)進(jìn)行負(fù)載均衡,同時(shí)要有效地減少 malloc/free 調(diào)用次數(shù)、頁(yè)錯(cuò)誤數(shù)量。確保 SDK 在低內(nèi)存環(huán)境中的可用性。
  在某些服務(wù)器推流的場(chǎng)景下,高并發(fā)可以極大的降低用戶的服務(wù)器使用成本。如果每一路通話或者推流都需要一個(gè)進(jìn)程實(shí)例的話,在并發(fā)情況下,CPU 會(huì)消耗在線程切換上。在我們的 SDK 中,我們可以通過(guò)線程的方式多開實(shí)例,可以極大地降低線程梳理,從而提高并發(fā)量。我們也進(jìn)行了一些測(cè)試,業(yè)界其他產(chǎn)品在相同機(jī)器環(huán)境下,并發(fā)路只有 600 路,而我們聲網(wǎng)的最大并發(fā)數(shù)可以到達(dá) 3400 路。
  在我們的SDK中,線程是通過(guò)統(tǒng)一的線程池管理的,這種做法既讓研發(fā)功能模塊中,降低并發(fā)編程模型的復(fù)雜度,有可以讓我們的線程數(shù)目受控,比如如果模塊或者功能團(tuán)隊(duì)需要新的線程,需要提出申請(qǐng),SDK通過(guò)注入的方式,將線程給予模塊使用。這對(duì)于 SDK 的性能改善會(huì)很有幫助。來(lái)源:聲網(wǎng) Agora
【免責(zé)聲明】本文僅代表作者本人觀點(diǎn),與CTI論壇無(wú)關(guān)。CTI論壇對(duì)文中陳述、觀點(diǎn)判斷保持中立,不對(duì)所包含內(nèi)容的準(zhǔn)確性、可靠性或完整性提供任何明示或暗示的保證。請(qǐng)讀者僅作參考,并請(qǐng)自行承擔(dān)全部責(zé)任。

專題

CTI論壇會(huì)員企業(yè)