版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Golang實(shí)現(xiàn)RTP音視頻傳輸示例詳解目錄引言RTP數(shù)據(jù)包頭部字段Golang的相關(guān)實(shí)現(xiàn)結(jié)尾
引言
在Coding之前我們先來(lái)簡(jiǎn)單介紹一下RTP(Real-timeTransportProtocol),正如它的名字所說(shuō),用于互聯(lián)網(wǎng)的實(shí)時(shí)傳輸協(xié)議,通過(guò)IP網(wǎng)絡(luò)傳輸音頻和視頻的網(wǎng)絡(luò)協(xié)議。
由音視頻傳輸工作小組開(kāi)發(fā),1996年首次發(fā)布,并提出了以下使用設(shè)想。
簡(jiǎn)單的多播音頻會(huì)議
使用IP的多播服務(wù)進(jìn)行語(yǔ)音通信。通過(guò)某種分配機(jī)制,獲取多播組地址和端口對(duì)。一個(gè)端口用于音頻數(shù)據(jù)的,另一個(gè)用于控制(RTCP)包,地址和端口信息被分發(fā)給預(yù)期的參與者。如果需要加密,可通過(guò)特定格式進(jìn)行加密。
音視頻會(huì)議
如果在會(huì)議中同時(shí)使用音視頻媒體,那么它們是作為單獨(dú)的RTP會(huì)話(huà)傳輸。音頻,視頻兩個(gè)媒體分別使用不同的UDP端口對(duì)傳輸單獨(dú)的RTP和RTCP數(shù)組包,多播地址可能相同,可能不同。進(jìn)行這種分離的動(dòng)機(jī)是如果參與者只想接受一種媒體,可以進(jìn)行選擇。
Mixer和Translator
我們需要考慮這樣一種情況,在某個(gè)會(huì)議中,大多數(shù)人處于高速網(wǎng)絡(luò)鏈路中,而某個(gè)地方的一小部分人只能低速率連接。為了防止所有人使用低帶寬,可以在低帶寬區(qū)域放置一個(gè)RTP級(jí)的中繼器Mixer。Mixer將接收的音頻報(bào)文重新同步為發(fā)送方20ms恒定間隔,重建音頻為單一流,音頻編碼為低速帶寬的音頻,然后轉(zhuǎn)發(fā)給低速鏈路上的帶寬數(shù)據(jù)包流。
多媒體應(yīng)用程序應(yīng)該能調(diào)節(jié)傳輸速率以匹配接收者容量或適應(yīng)網(wǎng)絡(luò)擁塞??梢詫⒄{(diào)節(jié)速率的任務(wù)通過(guò)將分層編碼和分層傳輸系統(tǒng)相結(jié)合來(lái)實(shí)現(xiàn)接收器。在基于IP多播的RTP上下文中,每個(gè)RTP會(huì)話(huà)均承載在自己的多播組上。然后,接收者可以只通過(guò)加入組播組合適的子集來(lái)調(diào)整接收帶寬。
RTP數(shù)據(jù)包頭部字段
只有當(dāng)Mixer存在時(shí),才會(huì)存在CSRC標(biāo)識(shí)符列表。這些字段具有以下含義。前12個(gè)8位組在每一個(gè)包中都有。
version(V):2bits
RTP版本。
填充(P):1bit
如果設(shè)置了填充位,包中包含至少一個(gè)填充8位組,其他填充位不屬于Payload。
擴(kuò)展(X):1bit
如果設(shè)置了擴(kuò)展位則存在。
CSRC數(shù)量(CC):4bits
CSRC數(shù)量包含在固定頭中,CSRC標(biāo)識(shí)符數(shù)量。
標(biāo)記(M):1bit
標(biāo)記由配置文件定義。用于標(biāo)記數(shù)據(jù)包流中例如幀邊界之類(lèi)的重要事件。
payload類(lèi)型(PT):7bits
該字段指出RTP有效載荷格式,由應(yīng)用程序進(jìn)行解釋。接收者必須忽略無(wú)法理解的有效載荷類(lèi)型的數(shù)據(jù)包。
序列號(hào):16bits
每次RTP數(shù)據(jù)包發(fā)送時(shí)增加,可能用于接收者檢測(cè)包丟失并且恢復(fù)包序列。
時(shí)間戳:32bits
該字段反映了RTP數(shù)據(jù)包中第一個(gè)8位組的采樣時(shí)刻。
SSRC:32bits
標(biāo)識(shí)同步源,這個(gè)標(biāo)識(shí)符應(yīng)該選擇隨機(jī),在同一個(gè)RTP對(duì)話(huà)的兩個(gè)同步源應(yīng)該有不同的同步標(biāo)識(shí)。
CSRC列表:0到15項(xiàng),其中每項(xiàng)32bits
該字段表示對(duì)該payload數(shù)據(jù)做出貢獻(xiàn)所有SSRC。
Golang的相關(guān)實(shí)現(xiàn)
RTP的實(shí)現(xiàn)有一些,不過(guò)通過(guò)Go實(shí)現(xiàn)有一些好處。
這里的易于測(cè)試不僅僅是體現(xiàn)在容易書(shū)寫(xiě),能夠快速通過(guò)源碼,函數(shù)直接生成相應(yīng)測(cè)試函數(shù)。而且更重要的是能夠提供相應(yīng)的基準(zhǔn)測(cè)試,提供計(jì)時(shí),并行執(zhí)行,內(nèi)存統(tǒng)計(jì)等參數(shù)供開(kāi)發(fā)者進(jìn)行相應(yīng)調(diào)整。
語(yǔ)言層面強(qiáng)大的Web開(kāi)發(fā)能力
能夠基于語(yǔ)言層面快速的對(duì)例JSON解析,字段封裝。無(wú)需引入三方庫(kù)。
性能較為優(yōu)異
相比于Python,Ruby等解釋型語(yǔ)言快,比node,erlang等語(yǔ)言更易書(shū)寫(xiě)。如果服務(wù)中需要用并發(fā),內(nèi)置關(guān)鍵字go就可以快速起多個(gè)goroutine。
Go社區(qū)的RTP有RTP相關(guān)實(shí)現(xiàn),對(duì)應(yīng)的測(cè)試也比較全面,簡(jiǎn)單介紹一下。
package_test.go(基礎(chǔ)測(cè)試)
funcTestBasic(t*testing.T){
p:=Packet{}
iferr:=p.Unmarshal([]byte{});err==nil{
t.Fatal("Unmarshaldidnoterroronzerolengthpacket")
rawPkt:=[]byte{
0x90,0xe0,0x69,0x8f,0xd9,0xc2,0x93,0xda,0x1c,0x64,
0x27,0x82,0x00,0x01,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0x98,0x36,0xbe,0x88,0x9e,
parsedPacket:=Packet{
//固定頭部
Header:Header{
Marker:true,
Extension:true,
ExtensionProfile:1,
Extensions:[]Extension{
{0,[]byte{
0xFF,0xFF,0xFF,0xFF,
Version:2,
PayloadOffset:20,
PayloadType:96,
SequenceNumber:27023,
Timestamp:3653407706,
SSRC:476325762,
CSRC:[]uint32{},
//有效負(fù)載
Payload:rawPkt[20:],
Raw:rawPkt,
//UnmarshaltotheusedPacketshouldworkaswell.
fori:=0;ii++{
t.Run(fmt.Sprintf("Run%d",i+1),func(t*testing.T){
iferr:=p.Unmarshal(rawPkt);err!=nil{
t.Error(err)
}elseif!reflect.DeepEqual(p,parsedPacket){
t.Errorf("TestBasicunmarshal:got%#v,want%#v",p,parsedPacket)
ifparsedPacket.Header.MarshalSize()!=20{
t.Errorf("wrongcomputedheadermarshalsize")
}elseifparsedPacket.MarshalSize()!=len(rawPkt){
t.Errorf("wrongcomputedmarshalsize")
ifp.PayloadOffset!=20{
t.Errorf("wrongpayloadoffset:%d!=%d",p.PayloadOffset,20)
raw,err:=p.Marshal()
iferr!=nil{
t.Error(err)
}elseif!reflect.DeepEqual(raw,rawPkt){
t.Errorf("TestBasicmarshal:got%#v,want%#v",raw,rawPkt)
ifp.PayloadOffset!=20{
t.Errorf("wrongpayloadoffset:%d!=%d",p.PayloadOffset,20)
}
基本測(cè)試中,利用Golang自帶的Unmarshal快速將byte切片轉(zhuǎn)換為相應(yīng)結(jié)構(gòu)體。減少了相關(guān)封包,解包等代碼的工作量。在網(wǎng)絡(luò)傳輸中,也能夠在語(yǔ)言層面直接完成大端,小端編碼的轉(zhuǎn)換,減少編碼的煩惱。
h.SequenceNumber=binary.BigEndian.Uint16(rawPacket[seqNumOffset:seqNumOffset+seqNumLength])
h.Timestamp=binary.BigEndian.Uint32(rawPacket[timestampOffset:timestampOffset+timestampLength])
h.SSRC=binary.BigEndian.Uint32(rawPacket[ssrcOffset:ssrcOffset+ssrcLength])
其中關(guān)于切片的相關(guān)操作十分便捷,可以獲取數(shù)組中的某一段數(shù)據(jù),操作比較靈活,在協(xié)議數(shù)據(jù)的傳輸過(guò)程中,通過(guò)切片,獲取某段數(shù)據(jù)進(jìn)行相應(yīng)處理。
m:=copy(buf[n:],p.Payload)
p.Raw=buf[:n+m]
在實(shí)現(xiàn)完成后,Golang的子測(cè)試能夠進(jìn)行嵌套測(cè)試。對(duì)執(zhí)行特定測(cè)試用例特別有用,只有子測(cè)試完成后,父測(cè)試才會(huì)返回。
funcTestVP8PartitionHeadChecker_IsPartitionHead(t*testing.T){
checker:=amp;VP8PartitionHeadChecker{}
t.Run("SmallPacket",func(t*testing.T){
ifchecker.IsPartitionHead([]byte{0x00}){
t.Fatal("Smallpacketshouldnotbetheheadofanewpartition")
t.Run("SFlagON",func(t*testing.T){
if!checker.IsPartitionHead([]byte{0x10,0x00,0x00,0x00}){
t.Fatal("PacketwithSflagshouldbetheheadofanewpartition")
t.Run("SFlagOFF",func(t*testing.T){
ifchecker.IsPartitionHead([]byte{0x00,0x00,0x00,0x00}){
t.Fatal("PacketwithoutSflagshouldnotbetheheadofanewpartition")
}
更多的相關(guān)實(shí)現(xiàn)可以去GitHub(/pion/rtp)上看一下實(shí)現(xiàn)源碼。
結(jié)尾
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 實(shí)驗(yàn)班考試題型及答案
- 商務(wù)談判自考試題及答案
- 2025 小學(xué)三年級(jí)科學(xué)下冊(cè)保護(hù)磁鐵的正確方法課件
- 《GAT 1294-2016公安應(yīng)急物資儲(chǔ)備管理信息系統(tǒng)接口參數(shù)》專(zhuān)題研究報(bào)告
- 《GAT 1054.8-2018公安數(shù)據(jù)元限定詞(8)》專(zhuān)題研究報(bào)告
- 2026年深圳中考物理電學(xué)高分突破試卷(附答案可下載)
- 2025 小學(xué)二年級(jí)科學(xué)下冊(cè)觀(guān)察蝴蝶的產(chǎn)卵行為記錄報(bào)告總結(jié)課件
- 職高建筑類(lèi)題庫(kù)及答案
- 胚胎孵化技術(shù)介紹
- 2026年人教版道德與法治八年級(jí)上冊(cè)期末質(zhì)量檢測(cè)卷(附答案解析)
- 金雞灘礦井施工組織設(shè)計(jì)說(shuō)明書(shū)
- 喜人奇妙夜小品《越獄的夏天》劇本
- 語(yǔ)文學(xué)科建設(shè)實(shí)施方案
- 船舶設(shè)備安裝中的技術(shù)難點(diǎn)及應(yīng)對(duì)措施
- 福建省漳州市2023-2024學(xué)年高二上學(xué)期1月期末考試物理試題(解析版)
- 建筑制造施工圖設(shè)計(jì)合同模板
- 股骨粗隆骨折并發(fā)癥
- 公司外來(lái)參觀(guān)人員安全須知培訓(xùn)課件
- 農(nóng)村集貿(mào)市場(chǎng)改造項(xiàng)目實(shí)施方案
- 印刷操作指導(dǎo)書(shū)
- 廣州自來(lái)水公司招聘試題
評(píng)論
0/150
提交評(píng)論