聚合推流 - 户外直播丝滑不卡顿的秘密

梦康 2023-06-07 13:49:19 120

部署流媒体服务

安装 nginx-rtmp

我是 mac 系统,记录的笔记都是 brew install 方式安装,其他环境自己搜索下即可。

使用以下命令添加 homebrew-nginx 仓库:

$ brew tap denji/nginx
$ brew install nginx-full --with-rtmp-module
Docroot is: /opt/homebrew/var/www

The default port has been set in /opt/homebrew/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /opt/homebrew/etc/nginx/servers/.

- Tips -
Run port 80:
 $ sudo chown root:wheel /opt/homebrew/opt/nginx-full/bin/nginx
 $ sudo chmod u+s /opt/homebrew/opt/nginx-full/bin/nginx
Reload config:
 $ nginx -s reload
Reopen Logfile:
 $ nginx -s reopen
Stop process:
 $ nginx -s stop
Waiting on exit process
 $ nginx -s quit

To start denji/nginx/nginx-full now and restart at startup:
  sudo brew services start denji/nginx/nginx-full
Or, if you don't want/need a background service you can just run:
  /opt/homebrew/opt/nginx-full/bin/nginx -g daemon off;

安装完成后,nginx-rtmp 模块的文件位于 /usr/local/Cellar/nginx-rtmp-module 目录下。

配置 nginx-rtmp 模块

在 nginx 的配置文件中增加以下配置:

load_module /usr/local/Cellar/nginx-rtmp-module/VERSION_NUMBER/nginx-rtmp-module.so;

rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        application live {
            live on;
        }
    }
}

在配置文件中,VERSION_NUMBER 需要根据实际安装的版本号进行替换。

启动 nginx

在终端中执行以下命令来启动 nginx 服务器:

sudo nginx

需要注意的是,启动 nginx 时需要使用 sudo 权限,否则无法绑定到 1935 端口。

推流和播放

在启动 nginx 后,可以使用流媒体软件或者 FFmpeg 等工具进行推流和播放测试。

overlay滤镜

FFmpeg提供了一些自带的滤镜,可以完成一些视频处理任务,比如叠加多个视频流。其中,overlay滤镜可以将多个视频流叠加在一起,并输出一个合成的视频流。

下面是一个使用overlay滤镜叠加多个视频流的FFmpeg命令行示例:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v]setpts=PTS-STARTPTS, scale=640x360[top]; [1:v]setpts=PTS-STARTPTS, scale=640x360[bottom]; [top][bottom]overlay=0:360" -c:a copy output.mp4

这个命令会叠加两个视频流input1.mp4和input2.mp4,将它们缩放为640x360分辨率,并在垂直方向叠加在一起。输出的视频流保存在output.mp4中。

在上面的命令中,filter_complex选项用于指定复杂的滤镜图表达式。在这个表达式中,我们首先对每个输入流进行setpts滤镜的处理,将PTS值重新从0开始计算,然后使用scale滤镜将它们缩放为相同的大小。最后,使用overlay滤镜将两个流叠加到一起。

需要注意的是,overlay滤镜的第二个参数是叠加的位置,这里我们将第二个视频流放在了第一个视频流的下方。如果需要调整叠加的位置,可以调整这个参数的值。

需要说明的是,滤镜处理需要占用大量的CPU资源和内存,因此在实际应用中,需要根据实际情况进行优化和调整。建议在使用自带滤镜处理视频时,尽可能使用硬件加速,以提高处理速度和效率。

一路断流如何处理

如果其中一路输入流没有信号,使用overlay滤镜合成的视频流中对应部分会显示为黑色。这是因为没有输入信号的流在视频帧中对应位置的像素值为0,即黑色。在overlay滤镜中,缺失部分会被视为黑色背景,因此最终合成的视频流中会显示为黑色。

如果要避免这种情况,可以使用blend滤镜代替overlay滤镜,它可以根据输入流的透明度进行叠加,能够更好地处理输入流缺失的情况。具体来说,可以在输入流中添加一个alpha通道,用于指示输入流的透明度,然后使用blend滤镜对输入流进行叠加。这样,如果某个输入流缺失,它对应的alpha通道值为0,就不会对最终的合成视频产生影响。

以下是一个使用blend滤镜叠加多个视频流的示例命令:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v]setpts=PTS-STARTPTS, scale=640x360, format=rgba[top]; [1:v]setpts=PTS-STARTPTS, scale=640x360, format=rgba[bottom]; [top][bottom]blend=all_mode='overlay':all_opacity=1" -c:a copy output.mp4

在这个命令中,我们使用format=rgba选项将输入流转换为RGBA格式,即带有alpha通道的格式。然后,使用blend滤镜对两个输入流进行叠加。这里我们使用all_mode='overlay'选项指定混合模式为overlay,使用all_opacity=1选项指定透明度为1,即完全不透明。

需要说明的是,使用blend滤镜进行叠加时,需要输入流中带有alpha通道,否则滤镜无法工作。因此,在输入流中没有alpha通道的情况下,仍然需要使用overlay滤镜进行叠加,并在处理过程中处理输入流缺失的情况。

音频的处理

如果其中一路视频流没有信号导致音频丢失,可以使用amix滤镜将多路音频流混合在一起。amix滤镜可以将多个音频流混合成一个音频流,可以指定每个输入流的音量大小,以及混音后的输出音量大小。

以下是一个使用amix滤镜混合多路音频流的FFmpeg命令行示例:

ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex "[0:v]setpts=PTS-STARTPTS, scale=640x360[top]; [1:v]setpts=PTS-STARTPTS, scale=640x360[bottom]; [top][bottom]overlay=0:360" -filter_complex "[0:a][1:a]amix=inputs=2:duration=first:dropout_transition=2" -c:v libx264 -c:a aac -strict experimental -b:a 128k output.mp4

在这个命令中,我们首先使用overlay滤镜合成了两个视频流,并将它们叠加在一起。然后,使用filter_complex选项再次指定滤镜图表达式,使用amix滤镜将两个输入流的音频混合在一起。在这个滤镜中,我们使用inputs=2指定输入流的数量为2,duration=first选项指定以第一个输入流的时长作为输出流的时长,dropout_transition=2选项指定混音时出现重复帧的处理方式。

需要注意的是,在使用amix滤镜时,如果有输入流缺失,该输入流对应位置的音频数据将无法混合到输出流中。因此,如果需要处理缺失音频的情况,可以先将每个输入流的音频提取出来,通过编程的方式进行处理和合成。