FFmpeg实时切换输入源/实时映射/同时录制。

3

我有一个rtsp视频源 stream1 和一个音频源,我目前将它们合并并通过以下步骤发送到rtmp服务器:

stream1="rtsp://streamurl1"

/usr/bin/ffmpeg                    \
    [...]
    -i "$stream1"                  \
    [...]
    -itsoffset $AUDIOVIDEOOFFSET   \
    -f pulse                       \
    -i default                     \
    [...]
    -vcodec copy                   \
    -map 0:v -map 1:a              \
    [...]
    -f flv "rtmp://streamingserver"

我现在想要添加第二个视频源“stream2”,并能够在不中断音频的情况下在“stream1”和“stream2”之间切换。这两个流是相同的/来自相同的摄像头。
有没有什么理智的方法可以使用FFmpeg完成这个任务?或者你会如何建议实现?
只是停止进程,然后使用“stream2”重新启动它可行,但会导致几秒钟的流中断,并且这是当前最糟糕的情况,我希望改进。

你正在对视频流进行编码吗?两个流的分辨率相同吗? - Gyan
@Gyan 是的和不是的。只是从两个相同的相机中传递。我已经相应地更新了上面的问题。 - Suuuehgi
1个回答

2

我无法在合理的时间内使用纯 ffmpeg 使其正常工作,但nginx-rtmp模块可以直接使用。

基本上只需要运行 apt install libnginx-mod-rtmp nginx,然后添加..

rtmp {
        server {
                listen 1935;
                chunk_size 4096;

                application live {
                        live on;
                        record off;
                        # Only localhost is allowed to publish
                        allow publish 127.0.0.1;
                        deny publish all;
                }
        }
}

将内容添加到nginx.conf文件中,执行systemctl restart nginx命令,然后nginx将作为本地回环设备在rtmp://localhost/live上运行。

如果您现在有n个流需要复用,则可以创建n个systemd服务camera_i.service

[Unit]
Description=Send stream i to local nginx loopback device
# List all other
Conflicts=camera_1.service, camera_2.service, [...]

[Service]
ExecStart=/usr/bin/ffmpeg -i rtsp://mystreamurl_i -c copy -f flv rtmp://localhost/live
Type=simple
Restart=on-failure
KillSignal=SIGINT
SuccessExitStatus=255

[Install]
WantedBy=xsession.target

并通过启动camera_i.service切换到流i

systemctl --user start camera_i.service

所有在Conflicts=选项中列出的其他服务都将被systemd自动终止,从而有效地复用相机流。

然后可以使用以下类似的内容来记录生成的流:

/usr/bin/ffmpeg                    \
    [...]
    -use_wallclock_as_timestamps 1 \
    -fflags +genpts                \
    -i "rtmp://localhost/live"     \
    [...]
    -itsoffset $AUDIOVIDEOOFFSET   \
    -f pulse                       \
    -i default                     \
    [...]
    -vcodec copy                   \
    -map 0:v -map 1:a              \
    [...]
    OUTPUT

结果是连续音频的平滑翻转。
如果您不使用-vsync 0,则-use_wallclock_as_timestamps 1 -fflags +genpts可能是不必要的。但我还没有测试过。
附录
正如在ffmpeg邮件列表上提出的那样,有一个zmq过滤器,据说可以实时更改过滤器设置。 这个想法是将两个流叠加在一起,并切换顶部流的不透明度,有效地切换流。
我无法让它工作,但任何人都可以尝试:
# compiled with --enable-libzmq
ffmpeg -i INPUT -filter_complex 'null[main];movie=INPUT2,zmq,lumakey@toggle=tolerance=1,[main]overlay,realtime' OUTPUT

echo lumakey@toggle tolerance 0 | zmqsend

zmqsend 的来源:

git clone https://github.com/FFmpeg/FFmpeg
cd FFmpeg/
./configure
cd tools/
gcc zmqsend.c -o zmqsend -I.. `pkg-config --libs --cflags libzmq libavutil`

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接