語音數據直流擴展

一、數據傳輸流程

如果想發送數據,先把數據放到Packet中,然後把數據寫入到IoArgs中再進行發送。在這個過程中,packet對應的是一個有限大小的inputstream,會把數據讀取一部分到buffer中,這個過程是由channel來完成的,也就是從packet到buffer之間的channel來完成的。通過不停地循環buffer,將數據全部填充到Frame當中,再把Frame發送給IoArgs,最終實現數據的發送流程。

對於整個發送流程來說,就是從SendPacket將數據填充到多個Frame當中,再把數據從Frame填充到IoArgs當中,最中通過socket傳遞到另一個客戶端。另外一個客戶端首先接收的地方也是一個IoArgs,然後再反向把它解析爲幀Frame,然後再把Frame解析爲ReceivePacket,這就是數據發送的整個過程。

 

二、語音數據傳輸

1、

如果將上面的流程應用到語音傳輸上會怎樣?首先要確定一點,語音數據是一個非常大的數據,它會隨着時間的迭代不斷地產生數據,只要不關閉麥克風、不關閉語音數據的讀取,理論來說,它是一個無限大的,所有input stream是一個非常多數據的。上面的input stream是一個固定大小的,也就是說可能會使用語音流的一部分來封裝成一個SendPacket,當有第二部分數據來的的時候,會把第二部分數據也封裝成一個SendPacket發送,依次類推。因此,會產生很多的SendPacket,並且添加到隊列當中,再進行Frame的發送,這部分沒有問題。從數據發送方面來說,沒太大問題,因爲都是把數據全部都發送出去了,但是有一個問題,語音要的是即時性,說了一句話之後,另一個客戶端需要即時收到數據並即時播放該數據。如果採用上述的模式,則意味着如果SendPakcet緩衝區太大的話,可能錄了2s的數據,再把這2s的數據打包再發送,接收方在收到數據的時候其實是2s播放一段2s播放一段,是可能有延遲的,並且延遲是非常高的,這是不允許的。

解決辦法是,將整個input stream封裝成一個packet。但是,之前的Packet都是固定大小的,但是語音消息是沒有大小的,隨着時間的遞增,它會不斷增加,所以,迫切需要一個新的類型。

2、

 

在新的封裝類型中,同樣有一個input stream,代表了整個封裝數據,然後會把整個流封裝起來,放到一個DirectPacket當中。DirectPacket包括了輸入input stream和輸出output stream,對這個的更改本質上反向還影響了對Frame的更改,因爲直流它的包長度是變化的,它會產生非常多的幀,這些非常多的幀長度都是不一樣的,這就涉及到了對幀的調整。

 

3、

對於這個不斷變化的流,首次讀取可能讀取到了10個字節,首先發送的幀包含了前面10個字節,當把前面10個字節讀取完後,發現它還有4個字節,那麼就會把這4個字節發送。當我們把這4個字節發送完後,再來讀取,此時可能讀取到0。當網絡發送速度大於生產速度的時候就有可能讀取到0,此時應該去等待,等待數據繼續去填充,然後再把後面填充的數據封裝成一個幀再去發送,這樣一個過程纔是OK的。在Frame這邊,只要讀取到0的時候,就認爲沒有後續的東西了。那麼你要保證的是,只要數據不爲0,那麼一定要返回一個不爲0的數據給我,或者大於0的size給了,此時,你做一些循環的數據填充,與我無關,這是你自己的職責。

 

三、類名及作用

StreamDirectReceivePacket :直流接收packet

StreamDirectSendPacket : 直流發送packet

 

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