[時間:2018-07] [狀態:Open]
[關鍵詞:rtp,rtcp, ffmpeg,ffplay,sdp,h264,mp2,ts,推流]
近期在學習有關RTP/RTCP的資料,發現看了很多資料,還是不如搭建一個RTP推流端和接收端。這樣可以加深些理解,
從我目前的獲得信息來看,RTP是位於傳輸層的協議,其可以基於UDP、TCP等協議傳輸,通常使用較多的是UDP,主要為了降低延時等。
RTP支持的負載格式一般是分開的,也就是說音頻和視頻是通過獨立的RTP協議傳輸的。RTP支持H264、HEVC、AAC等常見音視頻的格式(更詳細的RTP支持格式可參考RTP profile),其廣泛應用於視頻會議及IP電話中。
為了直觀點,我們還是直接用FFmpeg模擬一個RTP推流端,然后用ffplay作為客戶端播放之。
先說明下我用的FFmpeg版本是v4.0,我們全程將僅使用ffmpeg和ffplay兩個可執行程序。
RTP推送h264流及驗證方法
ffmpeg中的RTP muxer僅支持一個流作為輸入,比如推送h264流可以使用下面命令:
./ffmpeg -re -stream_loop -1 -i zhen_h264+mp2.ts -vcodec copy -an -f rtp rtp://10.10.50.90:9999 > h264.sdp
可使用下面命令驗證推流情況:
./ffplay -protocol_whitelist "file,rtp,udp" h264.sdp
實際上ffmpeg內部RTP默認使用UDP協議發送數據,所以可以指定單播或者組播地址。
上述命令生成的sdp文件內容如下:(對於RTP協議,sdp作為重要的流描述信息,是必須存在的)
SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 10.10.50.90
t=0 0
a=tool:libavformat 58.11.100
m=video 9999 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1; sprop-parameter-sets=Z01AHpZWBaHpKEAAAPpAAB1MIQ==,aO48gAA=; profile-level-id=4D401E
這里解釋下上述參數的意義:
-re
該參數表示按照實際幀率發送,否則按照最快速度發送數據(視具體主機性能而定)-stream_loop -1
表示循環播放,這里的是數字-1(不是字母L),本地文件串流結束后直接從頭開始-vcodec copy
/-acodec copy
表示復制視頻或者音頻,不做轉碼-vn
/-an
表示禁用視頻或音頻```````
RTP推送mp2流及驗證方法
推送音頻流命令如下:
./ffmpeg -re -stream_loop -1 -i zhen_h264+mp2.ts -acodec copy -vn -f rtp rtp://10.10.50.90:9999 > mp2.sdp
可使用下面命令驗證推流情況:
./ffplay -protocol_whitelist "file,rtp,udp" mp2.sdp
所生成的sdp文件格式如下:
SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 10.10.50.90
t=0 0
a=tool:libavformat 58.11.100
m=audio 9999 RTP/AVP 14
b=AS:128
RTP推送mpegts流及驗證方法
參考了下wiki及ffmpeg源碼發現,還有一個rtp_mpegts的muxer,可以支持推送mpeg-ts流(這也是我能找到的RTP唯一支持的容器格式)。
驗證下命令如下,首先推流端:
./ffmpeg -re -stream_loop -1 -i zhen_h264+mp2.ts -vcodec copy -acodec copy -f rtp_mpegts rtp://127.0.0.1:9999
接收端就簡單了,給個IP地址和端口就可以播放了:
./ffplay rtp://127.0.0.1:9999
小結
從上面三個實例可以看出,正常接收rtp需要一個sdp后綴的文件作為描述信息,否則客戶端無法獲知音頻或視頻信息。所以要學習並理解RTP協議,除了協議本分,還包括其負載的分包和sdp文件格式。