我的设置如下:
- Nginx与RTMP模块
- 多个RTMP流对,每个流对都有一个主RTMP和备份RTMP端点(因此流到rtmp://localhost/main/$STREAM_NAME和rtmp://localhost/backup/$STREAM_NAME(
- 使用Nginx RTMP
module exec_publish
和exec_publish_done
挂钩,我将主或备份推送到FFmpeg CLI进程,该进程将其重新流式传输到远程RTMP端点(在本例中为Wowza服务器,但与我的问题不太相关(
我的问题是,目前,如果主流停止,我必须停止重新流到Wowza的FFmpeg CLI进程,并用新的输入源(备份流(启动另一个进程。这经常会引起沃扎方面的问题,所以我正在寻找一种避免这种情况的方法。
经过一些研究,我发现FFmpeg封装了ZMQ支持,但文档似乎非常稀疏。是否可以向正在运行的FFmpeg进程发送消息,提醒它必须将其源更改为不同的RTMP流?
非常感谢
如果有人感兴趣,我用不同的方式解决了我的问题。我现在使用命名管道,就像这样:
PIPE_FILE= /path/to/pip/file
mkfifo $PIPE_FILE
exec 7<>$PIPE_FILE
ffmpeg -nostdin -i /path/to/source -acodec copy -vcodec copy -vbsf h264_mp4toannexb -f mpegts pipe:1 > $PIPE_FILE
/path/to/source
可以是FS上的媒体文件,也可以是RTMP流。
然后,我从管道重新流式传输到最终RTMP终点:
ffmpeg -re -i $PIPE_FILE -c:v libx264 -preset veryfast -r 25 -g 50 -f flv $RTMP_ENDPOINT
当$PIPE_FILE
停止接收数据时(即,当流式传输停止时,或者在从本地媒体文件发送数据的情况下,当达到EOF时(,我会立即启动不同的FFmpeg CLI进程,并从备份媒体文件/流中馈送管道数据。
这使重新流式传输的FFmpeg CLI进程持续启动和运行。
有趣的方法。我也有类似的东西。我使用的不是Pipe,而是另一个本地rtmp目的地。
我有一个nginxrtmp设置与3个应用程序。一个是主应用程序,另一个是备份应用程序,还有一个是分发应用程序。所以我把主流媒体从我的流媒体软件发送到主应用程序。我有一个ffmpeg
进程正在运行:
ffmpeg -i rtmp://127.0.0.1/main/stream1 -c copy rtmp://127.0.0.1/distribute/stream1
如果这个过程由于输入关闭而中断,我会运行类似的命令从备份中提取输入:
ffmpeg -i rtmp://127.0.0.1/backup/stream1 -c copy rtmp://127.0.0.1/distribute/stream1
从我的分布式应用程序,我流式传输到我的外部输出。
这里唯一的问题是,我在切换后得到了非单调的DTS错误,所以当从distribute流到我的输出时,我不得不添加一些标志。命令是:
ffmpeg -fflags +genpts+igndts+ignidx -avoid_negative_ts make_zero -use_wallclock_as_timestamps 1 -i rtmp://127.0.0.1/distribute/stream1 -c:v libx264 -preset veryfast -r 25 -g 50 -c:a aac -b:a 128k -f flv $RTMP_ENDPOINT
我注意到,当我切换时,我在ffmpeg
过程中收到了一些警告,如果主流和备份流使用不同的x264配置文件,比如说一个在High,另一个在Baseline或main。