如何使用 ffmpeg 将 rtsp 流转换为 mjpeg (http)

问题描述

我希望捕获 rtsp 流并使用 ffmpeg 将其转换为 mjpeg(通过 http)流。我正在运行 Ubuntu 20。我已经搜索搜索解决方案,主要是找到:

a) 需要 ffserver 的解决方案(已弃用)

b) 从 mjpeg 转换为 rtsp 的解决方

c) 从 rtsp 转换为 hls(Nginx、wowza 等)的解决方案在我的应用程序中不起作用。我需要 http 输出为 mjpeg。

d) vlc - 确实有效,但需要太多可用的处理器 (80%)

e) rtsp2mjpg - 我安装的 github 项目,但无法开始工作,也无法获得任何支持

我不是 ffmpeg 专家,所以如果有人可以引导我完成 ffmpeg 解决方案(如果存在),我将不胜感激。

解决方法

在找到与您完全相同的东西后,我最近自己解决了这个问题。您需要的两部分是 (1) 脚本中的 ffmpeg 转换,以及 (2) 类似 lighttpd+cgibin 或 nginx+fastcgi 之类的东西以通过 http/https 提供服务。不过,我不希望您在 CPU 使用方面比 vlc 做得更好。

这个 bash 脚本会将 ffmpeg 转换为 MJPEG,并将输出发送到 stdout。把它放在 lighttpd 的 cgi-bin 文件夹中(对我来说是 /var/www/cgi-bin)。将其命名为“网络摄像头流”,并调整 rtsp:// URL 以适合您的相机:

#!/bin/bash

echo "Content-Type: multipart/x-mixed-replace;boundary=ffmpeg"
echo "Cache-Control: no-cache"
echo ""
ffmpeg -i "rtsp://192.168.60.13:554/user=admin&password=SECRET&channel=1&stream=0.sdp" -c:v mjpeg -q:v 1 -f mpjpeg -an -

为 lighttpd 启用 cgi-bin:

ln -s /etc/lighttpd/conf-available/10-cgi.conf /etc/lighttpd/conf-enabled/10-cgi.conf

..然后调整lighttpd的cgi-bin配置(/etc/lighttpd/conf-enabled/10-cgi.conf)如下图。 stream-response-body 设置很重要,因为它既会在客户端断开连接时停止流,也避免在向客户端发送任何内容之前让 lighttpd 尝试缓冲整个无限流。

server.modules += ( "mod_cgi" )

$HTTP["url"] =~ "^/cgi-bin/" {
        server.stream-response-body = 2
        cgi.assign = ( "" => "" )
        alias.url += ( "/cgi-bin/" => "/var/www/cgi-bin/" )
}

使 cgi-bin 脚本可执行并重新启动 lig​​httpd:

chmod +x /var/www/cgi-bin/webcamstream
systemctl restart lighttpd

...应该就是这样。然后,您可以通过这样的 URL 访问 MJPEG 流,其中最后一部分是您的脚本名称:

http://serveraddress/cgi-bin/webcamstream

我在这里写得更详细:Converting RTSP to HTTP on demand

据我所知,您无法避免转换对 CPU 的影响——RTSP 与 MJPEG 帧的格式/编码是不同的。我通过配置相机来降低源的帧速率和分辨率,直到它在 ffmpeg 上是可接受的负载,从而减少了我的 CPU 负载。您也可以使用 ffmpeg 参数更改分辨率和帧率,但它仍然必须先解码完整帧并进行调整大小的工作。

以上路径在 Debian 上,因此您可能需要调整它们以适合您的 Ubuntu 系统。