ffmpeg rtp发送video和audio并播放

发送h264 video

ffmpeg -re -stream_loop -1 -i h264.mp4 -vcodec h264 -f rtp rtp://127.0.0.1:5006

SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 127.0.0.1
t=0 0
a=tool:libavformat LIBAVFORMAT_VERSION
m=video 5006 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1


Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))

执行这条命令,如上SDP端,会生成SDP信息输出,单独播放很简单,复制前面的sdp信息到a.sdp(也可以直接在命令后跟> v.sdp符号生成v.sdp文件),然后就可以用命令直接播放,其中Stream mapping可以确定指定codec参数是经过重新编码的。

ffmpeg -re -stream_loop -1 -i h264.mp4 -vcodec h264 -f rtp rtp://127.0.0.1:5006 > v.sdp
ffplay -protocol_whitelist "file,rtp,udp" -i v.sdp

发送aac audio

ffmpeg -re -stream_loop -1 -i aac.mp4 -acodec aac -f rtp rtp://127.0.0.1:5008

SDP:
v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 127.0.0.1
t=0 0
a=tool:libavformat LIBAVFORMAT_VERSION
m=audio 5008 RTP/AVP 97
b=AS:128
a=rtpmap:97 MPEG4-GENERIC/44100/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=121056E500


Stream mapping:
  Stream #0:0 -> #0:0 (aac (native) -> aac (native))

合并播放

根据前面audio和video输出的sdp信息,创建video.sdp文件,内容如下:

v=0
o=- 0 0 IN IP4 127.0.0.1
s=No Name
c=IN IP4 127.0.0.1
t=0 0
m=video 5006 RTP/AVP 96
b=AS:200
a=rtpmap:96 MP4V-ES/90000
m=audio 5008 RTP/AVP 97
b=AS:128
a=rtpmap:97 MPEG4-GENERIC/44100/2
a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=121056E500

播放命令:

ffplay -protocol_whitelist "file,rtp,udp" -i video.sdp -sync ext

-sync type:set audio-video sync. type (type=audio/video/ext),AV同步支持三个参数,前面的这个分离流发送,用ext做同步效果好一些,播放经过一段时间后,av同步比较好,能明显的听出来用ext同步,audio会被拉伸。

[udp @ 0x7fbfe8009260] bind failed: Address already in useB f=0/0   
video.sdp: Invalid data found when processing input
  • 如果出现这段error,修改端口就可以正常播放

ffmpeg rtp发送ts流

发送video

ffmpeg -re -stream_loop -1 -i h264.ts -vcodec h264 -rtpflags h264_mode0 -f rtp rtp://172.0.0.1:1234

报错:

[rtp @ 0x55cccc59c0f0] NAL size 2256 > 1460, try -slice-max-size 1460

去掉-rtpflags h264_mode0就好了,-vcodec 指定为copy也是可以的。

所以是:

ffmpeg -re -stream_loop -1 -i h264.ts -vcodec h264 -f rtp rtp://172.0.0.1:1234

这里源文件是ts,也输出了sdp信息,但是指定对应的sdp播放失败。

发送audio

ffmpeg -re -stream_loop -1 -i aac.ts -acodec copy -rtpflags latm -f rtp rtp://172.0.0.1:1235

如果没有参数-rtpflags latm,会报错:AAC with no global headers is currently not supported.,不要这个参数,实际acodec后面跟aac重新编码后就没问题了。

但是和前面一样,源文件是ts,指定对应的sdp播放失败。

AAC as an RTP payload

工作正常:

ffmpeg -re -i file.aac -c:a aac -f rtp rtp://127.0.0.1:8000

AAC with no global headers is currently not supported:

ffmpeg -re -i file.aac -c:a copy -f rtp rtp://127.0.0.1:8000

这个用了copy,应该是acc的frame可能不是adts,在指定codec为aac后重编码后的aac是adts格式,video也是一样的,这个需要看代码确定一下。

https://www.reddit.com/r/ffmpeg/comments/mq6jzv/aac_as_an_rtp_payload/

使用rtp_mpegts

Pro-MPEG Code of Practice #3 Release 2 FEC protocol.

The Pro-MPEG CoP#3 FEC is a 2D parity-check forward error correction mechanism for MPEG-2 Transport Streams sent over RTP.

Pro-MPEG-CoP#3:此协议必须与rtp_mpegts muxer和rtp协议一起使用,用于通过RTP发送的MPEG-2。

所以通过rtp_mpegts可以直接发送包含video和audio的ts流,也可以用来单独发送:

 ffmpeg -re -stream_loop -1 -i test.ts -vcodec copy -acodec copy -f rtp_mpegts rtp://239.0.0.1:5656

经过rtp_mpegts发送的流不需要指定sdp,ffplay直接跟url就可以播放,这里用了组播地址,用127.0.0.1也是可以的:

ffplay -protocol_whitelist "file,rtp,udp" rtp://239.0.0.1:5656

不支持

ffmpeg不支持两路流输入,下面这两种写法都不支持:

ffmpeg -re -stream_loop -1 -i aac.mp4 -i h264.mp4 -acodec copy -vcodec copy -f rtp rtp://172.0.0.1:1234

独立video和audio流作为输入不可以。

ffmpeg -re -stream_loop -1 -i test.mp4 -acodec copy -vcodec copy -f rtp rtp://172.0.0.1:1234

mp4文件中包含两路流也是不行的。

会报错:

[rtp @ 0x55e7023aa210] Only one stream supported in the RTP muxer
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Error initializing output stream 0:1 --

你可能感兴趣的:(ffmpeg)