ffmpeg合并两路rtmp流并推送
ffmpeg实现两路流的覆盖
实现两路流的覆盖可以使用ffmpeg的overlay参数,将一路流覆盖到另外一路流之上。
overlay参数简介
overlay=x:y
这里x和y表示距离左上角的坐标偏移
例子
ffmpeg -i “rtmp://ip:port/firststream” -i “rtmp://ip:port/secondstream” -filter_complex overlay=20:16 -f flv “rtmp://ip:port/addstream”
将secondstream这路流覆盖到firststream这路流之上,secondstream的坐标位于左上角偏移20:16的位置,也就是x偏移20像素,y偏移16像素。
ffmpeg实现四路流的合并
这部分参考了ffmpeg官方的wikihttp://trac.ffmpeg.org/wiki/Create%20a%20mosaic%20out%20of%20several%20input%20videos#no1
命令
ffmpeg -i “rtmp://ip:port/onestream” -i “rtmp://ip:port/threestream” -i “rtmp://ip:port/fourstream” -i “rtmp://ip:port/twostream” -filter_complex “nullsrc=size=640x480 [base];[0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright];[2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft];[3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright];[base][upperleft] overlay=shortest=1 [tmp1];[tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=320:y=240” -f flv “rtmp://ip:port/outstream”
整个命令特别复杂,但是仔细分析起来,确实还是比较清晰。
整体的逻辑是
ffmpeg -i 多路流 -filter_complex 合并参数 -f flv 合并后的一路流
核心部分就是合并参数。
参数简介
filter_complex
filter complex可以很好的解决我们视频流合并的问题,complex的简单原理如下:
filter complex参数
nullsrc=size=640x480 [base];[0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright];[2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft];[3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright];[base][upperleft] overlay=shortest=1 [tmp1];[tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=320:y=240
整个参数可以分为两个部分,第一部分:
nullsrc=size=640x480 [base];[0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]; [1:v] setpts=PTS-STARTPTS, scale=320x240 [upperright];[2:v] setpts=PTS-STARTPTS, scale=320x240 [lowerleft];[3:v] setpts=PTS-STARTPTS, scale=320x240 [lowerright];
这个部分主要是划分了基础层和上面的四个分区,对每个分区输入的流和分辨率、pts作何设置。
首先定义了基础的layer:nullsrc=size=640x480 [base],输入是null。大小是640x480,名字是base。然后定义了之上的四个部分:
[0:v] setpts=PTS-STARTPTS, scale=320x240 [upperleft]
[0:v]告诉ffmpeg从第一个输入来获取流,设置pts,设置大小320x240,名字upperleft。
第二部分:
[base][upperleft] overlay=shortest=1 [tmp1];[tmp1][upperright] overlay=shortest=1:x=320 [tmp2]; [tmp2][lowerleft] overlay=shortest=1:y=240 [tmp3]; [tmp3][lowerright] overlay=shortest=1:x=320:y=240
主要是设置这四个部分在整个显示层上的分布。
[base][upperleft] overlay=shortest=1 [tmp1]
[upperleft]是第一部分定义好的输入流,overlay在[base]之上。shortest=1就是当输入停止的时候延迟1秒结束。坐标是默认[0,0]。tmp1是给这个部分取的名字,方便后续使用。
[tmp1][upperright] overlay=shortest=1:x=320 [tmp2];
[upperright]overlay在[tmp1]之上,坐标是[320,0]。这部分的名字是[tmp2]。