如何在 Janus 中获取 WebRTC 的流
抓取WebRTC流量看起來相對(duì)簡(jiǎn)單,大多數(shù)情況下確實(shí)是這樣:你只需要在其中一人的機(jī)器上安裝類似tcpdump或wireshark的抓包工具,然后查看產(chǎn)生的文件,大多數(shù)情況會(huì)是.pcap或.pcapng文件。這些活動(dòng)對(duì)于診斷連接問題或其它與WebRTC相關(guān)的問題很有用:實(shí)際上,wireshark可以自動(dòng)檢測(cè)出STUN,DTLS之類的標(biāo)準(zhǔn)協(xié)議,這些是WebRTC PeerConnections所關(guān)注的。
本文關(guān)鍵是什么?
抓取WebRTC流量的唯一問題就是,媒體內(nèi)容會(huì)被加密。當(dāng)檢查了STUN連接或DTLS握手之后,這不是一個(gè)問題,但是當(dāng)你想要查看RTP或RTCP包的時(shí)候,這將會(huì)成為一個(gè)問題,它將會(huì)被加密成SRTP和SRTCP。實(shí)際上,盡管SRTP標(biāo)題沒有被加密,你可以任何形式抓取流量,但是SRTP負(fù)載不是,意味著你不能查看它的內(nèi)容。
大多數(shù)情況下你不需要查看內(nèi)容。正如期待的那樣,你依然可以查看加密RTP包的標(biāo)題,也就是最常被用到的信息。不管怎樣,對(duì)于RTCP并不能這樣說:實(shí)際上,一條RTCP信息可能實(shí)際上包含不止一個(gè)包,并且不存在一個(gè)共享的標(biāo)題。除此之外,查看RTP負(fù)載可能會(huì)有效。
這意味著抓取加密流量是可行的,但是為了診斷目的抓取無加密數(shù)據(jù)效果可能更好。不幸的是,無其它幫助下這是不可能的:實(shí)際上,WebRTC情況下瀏覽器經(jīng)常發(fā)送加密數(shù)據(jù),即使有一些允許你抓取無加密數(shù)據(jù)進(jìn)行測(cè)試,但是你還是需要依靠其它工具來獲取媒體流,才能進(jìn)行這項(xiàng)工作。
進(jìn)入Janus!
作為一個(gè)WebRTC媒體服務(wù)器,Janus確實(shí)發(fā)揮了它的效果:實(shí)際上,它存在于PeerConnection的每一條媒體路徑上。除此之外,由于它為每個(gè)PeerConnections分別建立了安全環(huán)境,它可以獲得輸入和輸出的未加密的RTP和RTCP包。
我們一年前就是這樣想的,被Firefox所激勵(lì),我們首先添加了text2pcap dump的支持,采取的方法很直接:
1.使用Admin API,開始抓取Janus處理文件的信息。
2.所有輸入輸出的RTP/RTCP包都被轉(zhuǎn)化為文本格式,保存到相關(guān)文件中。
3.抓取結(jié)束后,使用text2pcap App 將抓取文件轉(zhuǎn)化為與Wiresharak或其它工具兼容的格式。
請(qǐng)求的語法很簡(jiǎn)單:
POST /admin/sessionId/handleId {"janus" : "start_text2pcap","folder" : "<folder to save the dump to; optional, current folder if missing>","filename" : "<filename of the dump; optional, random filename if missing>","truncate" : "<number of bytes to truncate at; optional, won't truncate if 0 or missing>","transaction" : "<random alphanumeric string>","admin_secret" : "<password specified in janus.cfg, if any>" } 復(fù)制代碼如果已知了相關(guān)session和handle Id,可以輕易生成一句代碼來對(duì)handle開始抓取:
curl -X POST -H "Content-Type: application/json" -d '{"janus": "start_text2pcap", "folder": "/tmp", "filename": "my-test2pcap-dump.txt", "transaction": "123", "admin_secret": "janusoverlord"}' http://localhost:7088/admin/8412133783240844/2377476017639045 復(fù)制代碼停止抓取更簡(jiǎn)單,就像你需要一個(gè)stop_text2pcap請(qǐng)求來做這件事。
最終,你將會(huì)以類似的文本文件結(jié)束:
I 18:47:14.126004 000000 80 e0 6c 5d [..] JANUS_TEXT2PCAP_RTP [session=3740061776621518][handle=3149681776118503] O 18:47:14.128251 000000 80 e0 04 83 [..] JANUS_TEXT2PCAP_RTP [session=3740061776621518][handle=3149681776118503] I 18:47:14.136577 000000 80 6f 54 8d [..] JANUS_TEXT2PCAP_RTP [session=3740061776621518][handle=3149681776118503] O 18:47:14.136659 000000 80 6f 03 9f [..] JANUS_TEXT2PCAP_RTP [session=3740061776621518][handle=3149681776118503] 復(fù)制代碼你對(duì)此文件不能做太多:我們看到一些輸入輸出包,在某個(gè)時(shí)間被保存,還可以看到16進(jìn)制的負(fù)載值,每一行結(jié)尾有一些環(huán)境信息。你需要把它傳給其它工具,例如text2pcap,將它轉(zhuǎn)化為你可以讀懂的文件:
text2pcap -D -n -l 1 -i 17 -u 1000,2000 -t '%H:%M:%S.' /tmp/my-test2pcap-dump.txt /tmp/my-test2pcap-dump.pcapng復(fù)制代碼你可以參考說明書詳細(xì)學(xué)習(xí)應(yīng)該怎樣做和工具提供的功能,上面的一行基本可以遍歷文本文件,將每個(gè)包轉(zhuǎn)化為pcapng格式,使用不同IP和端口供兩方交流,更容易區(qū)分彼此。
但是文本序列化不是應(yīng)該效率低下么?
我很高興你問了這個(gè)問題!
那是對(duì)的:盡管上述方法簡(jiǎn)單易行,并且出色的完成了它的工作,但是耗費(fèi)了大量的CPU。這意味著,盡管看起來不錯(cuò),你不能將此方法應(yīng)用于產(chǎn)品環(huán)境中,因?yàn)檫@樣做會(huì)影響你機(jī)器的性能。
我們需要另外一種方法,在Janus中直接保存到原始pcap文件中,而不是將其轉(zhuǎn)化為文本文件,之后進(jìn)行處理。這個(gè)方法模擬了文本抓取,但是有輕微的不同之處:你可能注意到了這里不包括寫入處理:由于我們直接保存到pcap文件中,這意味著,我們一停止抓取,文件就馬上被生成,利用,使用適當(dāng)?shù)墓ぞ摺3酥?#xff0c;由于不需要文本序列化,而是直接寫入文件,這個(gè)過程變得輕量化,影響基本可忽略,并且與Janus中的媒體記錄特性很好的契合。
盡管你使用了不同的方法保存為.pcap文件,而且命名為start_pcap,而不是start_text2pcap,它的語法與另一個(gè)完全一樣:這意味著你可以提供與之前一樣的信息,并保存它,無論是否縮短。觀察前面的例子,接著,下面是請(qǐng)求的格式:
curl -X POST -H "Content-Type: application/json" -d '{"janus": "start_pcap", "folder": "/tmp", "filename": "my-pcap-dump.pcap", "transaction": "123", "admin_secret": "janusoverlord"}' http://localhost:7088/admin/8412133783240844/2377476017639045 復(fù)制代碼注意,我們只改變了請(qǐng)求名稱和目標(biāo)文件的擴(kuò)展名。其它完全一樣。
如果不想使用curl
目前為止,我們解釋了Jauns對(duì)于抓取未加密數(shù)據(jù)所提供的功能,如何使用Admin API請(qǐng)求利用這個(gè)特性。不管怎樣,你可能不想手動(dòng)做這些事,或通過命令行。幸運(yùn)的是,我準(zhǔn)備了一個(gè)虛擬接口來做這些事。
Janus報(bào)告帶來一些可供使用的網(wǎng)絡(luò)演示,包括了Admin API接口。這個(gè)接口在之前的文章中已經(jīng)詳細(xì)介紹過,特別是使用它提供的信息達(dá)到診斷問題的目的。我們不會(huì)重復(fù)這些細(xì)節(jié),但是我們會(huì)關(guān)注一點(diǎn),你應(yīng)該如何在Janus中開始或停止抓取一個(gè)特定文件。當(dāng)然了,我們假定了你之前在HTTP插件配置中開啟了Admin API后端。
如果你有Janus演示的最近的版本,打開Admin API,嘗試導(dǎo)航現(xiàn)有session,選擇一個(gè)特定的handle。你應(yīng)該在實(shí)際處理信息前看到一個(gè)叫做開啟抓取的勾選框。
點(diǎn)擊它,如下:
大多數(shù)設(shè)置應(yīng)該清晰易懂,因?yàn)楫?dāng)介紹Admin API請(qǐng)求語法時(shí),我們介紹了它們。第一個(gè)允許你選擇抓取類型,之前講到過,或者是直接保存到pcap,或者是轉(zhuǎn)化為文本文件之后處理。
接著你被要求設(shè)置保存文件的路徑:
你應(yīng)該只關(guān)心包的第一個(gè)byte,而不是全部,這將會(huì)使在保存之前縮短包變得有效。你可以使用縮短選擇:
當(dāng)抓取開始時(shí),網(wǎng)頁(yè)將會(huì)改變相關(guān)的勾選框,將其轉(zhuǎn)化為控制信息,讓你隨時(shí)可以暫停正在進(jìn)行的抓取。
當(dāng)前的抓取狀態(tài)也會(huì)顯示在handle信息中:
一旦抓取完成,不管是否需要text2pcap,使用wireshark,最終你會(huì)得到你可以使用的文件。假設(shè)使用了Wireshark,抓取界面如下所示:
正如期待,我們可以看到兩個(gè)不同的IP(10.1.1.1和10.2.2.2)在不同端口相互交流。當(dāng)Janus抓取流量時(shí),10.1.1.1:1000總是peer的地址,10.2.2.2:2000總是Janus自己的地址。
當(dāng)然,Wireshark自己并不能分辨這些UDP包的內(nèi)容是RTP和RTCP信息。這是我們需要告訴它的,將流量信息解碼為RTP。
之后,Wireshark顯示的信息會(huì)變化:
如你所見,Wireshark負(fù)責(zé)解釋RTP標(biāo)題,使我們可以觀察和分析它。對(duì)于負(fù)載也可以這樣說,它將會(huì)被解密,并且被我們看到。
Wireshark一個(gè)很少被人知道的特性,是它也支持對(duì)某些媒體編解碼器的解封裝。這意味著,如果你告訴Wireshark一個(gè)包內(nèi)含有特定編解碼器編碼的媒體信息,它將會(huì)給你一個(gè)具體的編解碼信息。VP8和H.264編解碼器處于其中,因此,如果在設(shè)置中將負(fù)載類型96和VP8穩(wěn)定關(guān)聯(lián)起來,顯示的信息將會(huì)再一次改變:
盡管這張截圖與之前的相似,還是存在一些關(guān)鍵區(qū)別:例如, 注意對(duì)于敷在類型96的所有包,協(xié)議一列如何從RTP轉(zhuǎn)化為VP8。這意味著Wireshark正在使用更高級(jí)的解碼,也可以觀察負(fù)載:在VP8情況下,這意味著獲取以VP8負(fù)載描述為前綴的實(shí)際媒體流內(nèi)容。
總結(jié)
以上是生活随笔為你收集整理的如何在 Janus 中获取 WebRTC 的流的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringAOP
- 下一篇: MYSQL 5.6安装设置中英文翻译