語音即時通信總結

一、 

要回答這個問題,從最基本的數據傳輸開始說。將數據從一個麥克風開始傳輸到另一個客戶端上,並且進行播放來說,它的流程是怎樣的呢?

對於客戶端A來說,它首先會將數據投遞到一個SendPacket當中,也就是直流傳輸,然後會把數據解析成每一個幀,然後將每一個幀的數據解析成IoArgs,最終通過服務器將數據傳遞到B客戶端中,B客戶端接收到數據的時候,會反向解析出幀,然後解析成SendPacket,最後實現對整個音頻的播放。

爲什麼需要兩個連接相互輔助進行命令識別並傳輸音頻。首先從A客戶端發送數據到B客戶端是一個音頻數據流,而音頻數據流在服務器上傳輸的時候使用的是橋接模式。這也就說明了在服務器端,其實不是將一個packet數據傳輸到另一個packet。如果需要用packet進行傳輸,這意味着我們需要對客戶端的數據進行反向解析,解析之後需要進行存儲,存儲之後再進行另一個連接的調度,而整個過程是比較漫長的,從而會導致整個傳輸流程的延遲增加,因此導致了整個音頻的不夠順暢,所以,在服務器端實現的是從IoArgs傳輸到IoArgs。

因此也就明白了爲什麼需要另一個連接來實現命令傳輸了,因爲直流傳輸的整個橋接流,一旦進行了橋接模式,也就是把數據從一個IoArgs傳輸到另一個IoArgs,此時數據沒有傳輸到上層,也就是不可能得到packet。一旦無法得到packet,也就是無法傳輸到業務數據層。業務數據層的數據是可以進行解析的,並且可以進行識別的,而對於IoArgs而言,是一個原始數據層,它的數據無法進行一個準確的識別,導致了之前的音頻傳輸流無法進行命令識別,所以需要另外連接來輔助進行命令識別。

 

二、交互流程

首先,A客戶端會建立好兩個連接.

對於B客戶端來說,也是建立兩個連接。

對於橋接連接:首先在服務端肯定有兩個連接,分別連接着兩個客戶端。這兩個客戶端連接之後的數據,從A客戶端發送過去的數據到達服務器後,首先會被接收成IoArgs,然後會把這個IoArgs直接傳輸給另一個客戶端,整個過程是一個可逆向的,可以循環進行交互的。A客戶端將數據傳輸到服務器,服務器將數據傳輸給B客戶端。同時,B客戶端將數據傳輸給服務器,也可以再反向轉發給A客戶端,這就是橋接模式的核心原理。

對於命令連接來說,我們的服務端也有一個對應的命令連接,從A客戶端先把數據投遞到服務器的時候,服務器會對整個數據進行反向解析,解析到packet,而對於B連接也是一樣,此時,具有兩個隊列的packet,此時可以對兩個隊列的數據進行識別。識別是在服務端完成的,整個過程是由服務端進行控制,遵循的是我們的命令結構,對命令進行解析,並且進行識別,比如說生成房間,或者通知某個客戶端進行聊天,這個過程中涉及到是否把A客戶端的信息同步給B客戶端,這個過程也是由服務器端決定的,具體的流程由服務器端的業務進行判斷。

所以,整個紅色框的部分,就是服務器端的部分,這就是兩個連接連接之後的整個傳輸流程。

 

三、Opus數據規則

一個客戶端通過麥克風不斷地產生數據,而這個數據我們稱之爲PCM數據流,也就是最原始的數據,這部分數據一旦被緩衝區存滿之後,會不斷地進行覆蓋,而我們需要的就是從整個緩衝區中讀取一部分數據出來。

此時,我們已經從緩衝區讀取了10個字節,那要如何將數據填充到Opus壓縮數據中呢?

我們會對數據進行Opus編碼,而編碼之後的數據可能只有6個字節,此時把它寫到另一個buffer當中,而這個buffer寫的時候從第三個座標開始寫,依次往後推,我們寫6個座標長度,這就代表了壓縮之後的數據。而壓縮之後的數據,在傳輸之前會先對這部分數據進行提取,此時提取到的數據是6個字節,所以會在前面的兩個字節當中寫入我們的長度信息,也就是0、6。那麼整個的長度就是2個字節再加上6個字節,最終是8個字節長度。網絡傳輸的時候,會把8個字節長度進行發送。發送到B客戶端的時候,B客戶端開始進行讀取,此時,他會先讀取長度,而讀取長度,它有一個長度限制,它會先讀2個字節,讀取到2個字節後,也就是06,在客戶端會進行short讀取,讀取之後會拿到長度信息,也就是6,那麼它直到後面的Opus編碼部分的長度,也就是6個字節,然後它會在之後面的長度當中讀取6個字節出來,讀取到新的buffer當中,那這是在新連接當中。當整個數據讀取出來後,會對整個數據進行Opus節碼,節碼之後會對整個數據進行還原。

然後再對整個10個字節長度的數據進行播放。

這就是整個傳輸數據的流程。

 

爲什麼要對正Opus編碼之後的數據提取長度呢?

其實是因爲Opus的基本規則。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章