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

How to convert rtsp stream to mjpeg (http) using ffmpeg

我希望捕获 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 或 nginix+fastcgi 这样的东西来为它提供服务 http/https。不过,我不希望您在 CPU 使用方面比 vlc 做得更好。

此 bash 脚本会将 ffmpeg 转换为 MJPEG,并将输出发送到标准输出。把它放在 lighttpd 的 cgi-bin 文件夹中(对我来说 /var/www/cgi-bin)。将其命名为“webcamstream”之类的名称,并调整 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

..然后调整 lighttp 的 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 帧的 format/encoding 是不同的。我通过配置相机来降低源的帧速率和分辨率,直到它在 ffmpeg 上达到可接受的负载,从而减少了我的 CPU 负载。您也可以使用 ffmpeg 参数更改分辨率和帧率,但它仍然必须首先解码完整帧并进行调整大小的工作。

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

通过 FFSERVER 将 RTSP 转换为 MJPEG

ffmpeg 下载:

https://ffmpeg.org/releases/

选择3.4之前的旧版本(因为这个版本FFSERVER被移除),推荐使用3.2.16

编译

./configure --prefix=/u/tool/ffserver
make && make install

FFSERVER

cd /u/tool/ffserver/bin

编辑{ffserver.conf}

HTTPPort 8090
HTTPBindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 10000

<Feed feed.ffm>
File /tmp/feed.ffm
FileMaxSize 50M
</Feed>

<Stream live.mjpeg>
Feed feed.ffm
Format mpjpeg
VideoFrameRate 5
VideoIntraOnly
VideoSize 720x405
VideoQMin 5
VideoQMax 20
NoAudio
Strict -1
NoDefaults
</Stream>

<Stream still.jpg>
Feed feed.ffm
Format jpeg
VideoFrameRate 2
VideoSize 720x404
VideoQMin 1
VideoQMax 15
VideoIntraOnly
NoAudio
Strict -1
NoDefaults
</Stream>

运行 FFSERVER

./ffserver -f ./ffserver.conf

像素错误

1280x720 == 720x405

如果使用VideoSize 720x405,启动报错信息显示:

ffserver.conf "Image size is not a multiple of 2"

将 405 修复为 404。

饲料流

ffmpeg 提要,请勿使用系统构建 FFMPEG!!原因在版本 3.4 之后,它已被删除!

使用你刚刚编译的 ffmpeg 与 ffserver 相同的目录。

./ffmpeg -rtsp_transport tcp -i "rtsp://127.0.0.1:8554/000FFC52F1D3" -r 15 -an http://127.0.0.1:8090/feed.ffm

浏览 mjpeg:

http://192.168.1.17:8090/live.mjpeg

浏览快照图像:

http://192.168.1.17:8090/still.jpg

mjpeg 状态

http://localhost/tool/mjpeg.htm

防止RTSP停止破坏mjpeg图像更新,每N秒在JS中循环更新图像路径(ig: 15):

setInterval(function() {
    var myImg = $('#myJpeg').attr('src', "http://192.168.1.17:8090/live.mjpeg?rand=" + Math.random()); 
}, 15000);

运行 服务器

ffserver -f /etc/ffserver.conf

运行调试模式

ffserver -d -f /etc/ffserver.conf

如果你想在控制台后台使用 运行 FFMPEG,请尝试对 FFMPEG 使用 -nostdin 或在终端多路复用器中使用 运行,例如 SCREENTMUX.