rtp,对于它的实现ffmpeg和gstreamer。对于这种复杂协议,实现肯定会有不同和妥协。
下面都是用命令窗口操作。命令换行( on Linux,
^
on Windows),环境变量访问 ($NAME
or ${NAME}
on Linux, %NAME%
on Windows).
先理解概念 转码:
由于发送端和接收端需要的文件格式不一致,需要:
1)解码媒体,成raw格式和信息部分;2)编码raw格式用不同的编码器codec。
上图有个mkv文件,音频OPUS,视频是vp8.转码成视频h264,音频MP3,然后用mp4 container封装。
我们用rtp是不用封装到container的。
FFmpeg
ffmpeg [global_options] { [input_options] -i input_url } { [output_options] output_url }
命令是有序的,一般是上面这个结构。
RTP流命令概览
ffmpeg -re -i video.mp4 -an -c:v copy -f rtp -sdp_file video.sdp "rtp://192.168.1.109:5004"
参数意义:
-re
: 模拟直播流,慢速推;否则ffmpeg会尽快发送完成.-i video.mp4
: Input file.-an
: 输出不要音频.-c:v copy
: 视频不转码,直接拷贝输出.-f rtp
: 输出格式,rtp。如果想保存成文件,直接写文件名,会根据后缀猜测转成的类型.-sdp_file video.sdp
: 生成sdp文件,这个文件能拷贝给另外一个去播放.rtp://192.168.1.109:5004
: 输出的url.
添加音频 -c:a copy
("copy audio"), 有下面报错:
[rtp @ 0x6fec300] Only one stream supported in the RTP muxer
BUG:
事实上,生成的sdp文件多了行
SDP:
需要去掉:sed -i '/^SDP:/d' video.sdp
FFmpeg ≥ 4.3没有这个问题。
附加特性:
RTCP端口设定:
ffmpeg -re -i video.mp4 -an -c:v copy -f rtp -sdp_file video.sdp "rtp://192.168.1.109:5004?rtcpport=54321"
但是ffmpeg有个bug,生成的sdp里面不包含这个
rtcpport=54321
端口的生成,需要手动加上。
Symmetric RTP
ffmpeg -re -i video.mp4 -an -c:v copy -f rtp -sdp_file video.sdp "rtp://192.168.1.109:5004?rtcpport=5005&localrtpport=5004&localrtcpport=5005"
可以inspect这个口的rtp和rtcp包。
RTP and RTCP multiplexing
不支持
Timestamps 纠正
ffmpeg -re -fflags +genpts -i video.mp4 -an -c:v copy -f rtp -sdp_file video.sdp "rtp://192.168.1.109:5004"
输入时转码
-c:v vp8 替换 copy
注意用htop去看cpu从0.7%到转码飙升到10-55%
播放 RTP流
由于 dynamic Payload Types的使用,必须用sdp文件播放,没有工具用rtp播放的。
FFmpeg playback
ffplay -protocol_whitelist file,rtp,udp -i video.sdp
GStreamer playback
安装:
sudo apt-get update && sudo apt-get install --yes gstreamer1.0-plugins-{good,bad,ugly} gstreamer1.0-{libav,tools}
播放:
gst-launch-1.0 playbin uri="sdp://$PWD/video.sdp"
等价于命令
gst-launch-1.0 filesrc location=video.sdp ! sdpdemux timeout=0 ! queue ! rtph264depay ! h264parse ! avdec_h264 ! videoconvert ! autovideosink