RTP在流媒體傳輸中是廣為應用的一種協定,包括大家熟知的GB28181協定以及很多視訊會議的應用,都是采用RTP。常用的RTSP協定實際上也是在RTP基礎上實作的。RTP并不複雜,本質上可以了解為RAW資料加上一些頭,封裝以後進行UDP傳輸。封包結構是這樣的:
1 | 2 | 3 | |||||||||||||||||||||||||
1 | 2 | 3 | 4 | 5 | 6 | 7 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
V | P | X | CC(4bit) | M | PT(7bit) | Sequence Number(16bit) | |||||||||||||||||||||
timestamp(32bit) | |||||||||||||||||||||||||||
SSRC辨別符(32bit) | |||||||||||||||||||||||||||
CSRC辨別符(n個32bit) … | |||||||||||||||||||||||||||
… | |||||||||||||||||||||||||||
playload |
每個字段具體的含義可查閱相關資料。RTP傳輸的時候,并不保證資料包按序号傳送,即使下層網絡提供可靠性傳送,也不能保證資料包的順序到達,包含在RTP中的序列号就是供接收方重新對資料包排序之用。與RTP對應的,還有RTCP是控制協定。正常情況下,RTP和RTCP是使用配套的兩個端口,RTP都是使用偶數端口,例如,要給目标位址的30010端口發送RTP資料,則30011端口會發送RTCP資料。
使用FFMPEG可以進行RTP的推流測試,接收端可以用VLC,也可以用FFPLAY。以下指令行使用内置攝像頭采集實時視訊,h.264編碼,幀率25fps,GOP為25,低延時,以RTP推送到本機的30010端口,并生成一個sdp檔案用于播放使用:
ffmpeg -f dshow -i video="Integrated Camera" -b:v 500k -r 25 -g 25 -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f rtp rtp://127.0.0.1:30010 > v.sdp
攝像頭的名字每個電腦不一定相同,可以用ffmpeg指令檢視,也可以在電腦屬性裡面看裝置名稱。如果要播放,可以把生成的這個sdp檔案拷貝下來,用VLC打開播放。但是注意生成的檔案第一行有SDP這幾個字母,要把這行删掉,不然VLC播放出錯。用ffplay也可以播放,指令行如下:
ffplay -protocol_whitelist "file,udp,rtp" -i v.sdp
類似地,也可以采集麥克風資料,推送AAC音頻,指令行如下:
ffmpeg -f dshow -i audio="Microphone Array (Realtek High " -acodec aac -ar 32000 -b:a 128k -f rtp rtp://127.0.0.1:30012 > a.sdp
麥克風的名字同樣自己去查。
以上的指令行推流,都是用的RTP裸流,也有一些場景是要求對資料采用PS或TS進行封裝以後再推送的。此外,視訊音頻也可以在一個指令行進行推送,,播放方式類似:
ffmpeg -fflags +genpts -f dshow -i video="Integrated Camera":audio="Microphone Array (Realtek High " -an -s 720x576 -b:v 500k -r 25 -g 25 -bufsize 2000k -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f rtp rtp://127.0.0.1:30010 -vn -acodec aac -ar 32000 -b:a 128k -f rtp rtp://127.0.0.1:30012 > av.sdp
實際使用的時候,很多情況下是需要一個發送端,多個接收端,這個時候就需要有RTP的轉發伺服器。自己寫代碼的話,有兩種方式,一種是直接UDP接收,資料放在隊列裡,開一個線程把隊列裡面的UDP資料發出去。因為RTP實際上就是UDP的資料,是以這種方式也是能轉發的,但是丢包情況很感人,實測發現播放經常花屏、亂序。另外一種方式,可以使用開源的jrtplib,收到資料放到隊列以後,調用jrtplib的接口重新對裸資料封裝rtp包,打時間戳,加序号以後再發送。這樣的效果就非常好。兩個程式都寫了,做了對比,最後用rtp的這種形式,封裝了接口,很好用。目前還欠缺的是srtp的加密資料有點問題,還在研究中。