RTP在流媒體傳輸中是廣爲應用的一種協議,包括大家熟知的GB28181協議以及很多視頻會議的應用,都是採用RTP。常用的RTSP協議實際上也是在RTP基礎上實現的。RTP並不複雜,本質上可以理解爲RAW數據加上一些頭,封裝以後進行UDP傳輸。報文結構是這樣的:
0 | 1 | 2 | 3 | ||||||||||||||||||||||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 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的加密數據有點問題,還在研究中。