µStreamer 是一款轻量且非常快速的服务器,可将 MJPEG 视频从任何 V4L2 设备流式传输到网络。所有新浏览器以及大多数视频播放器(例如 mplayer、VLC 等)都原生支持此视频格式。 µStreamer 是 PiKVM 项目的一部分,旨在以尽可能高的分辨率和 FPS 流式传输 VGA 和 HDMI 截屏硬件数据。
µStreamer 与带有input_uvc.so
和output_http.so
插件的 mjpg-streamer 非常相似,但是,存在一些主要差异。关键是:
特征 | µStreamer | mjpg-流光 |
---|---|---|
多线程 JPEG 编码 | ✔ | ✘ |
硬件图像编码 在树莓派上 | ✔ | ✘ |
设备时的行为 流式传输时已断开连接 | ✔ 显示黑屏NO SIGNAL 直到重新连接 | ✘ 停止流媒体1 |
DV 计时支持 - 改变分辨率的能力 通过源信号即时运行 | ✔ | ☹ 部分是1 |
流式传输时跳过帧的选项 HTTP静态图片,节省流量 | ✔2 | ✘ |
通过 UNIX 域套接字进行流式传输 | ✔ | ✘ |
Systemd 套接字激活 | ✔ | ✘ |
调试日志而无需重新编译, 性能统计日志, 访问 HTTP 流参数 | ✔ | ✘ |
提供文件的选项 带有内置 HTTP 服务器 | ✔ | ☹ 仅常规文件 |
发出有关流状态的信号 使用 libgpiod 在 GPIO 上 | ✔ | ✘ |
访问网络摄像头控制(对焦、伺服系统) 以及通过 HTTP 进行亮度等设置 | ✘ | ✔ |
与 mjpg-streamer 的 API 的兼容性 | ✔ | :) |
脚注:
1
早在 µStreamer 之前,我就制作了一个补丁,为 mjpg-streamer 添加 DV-timings 支持,并防止它在设备断开连接时挂起。唉,这个补丁远非完美,我不能保证它每次都能工作 - mjpg-streamer 的源代码非常复杂,其结构也很难理解。考虑到这一点,加上未来需要多线程和 JPEG 硬件加速,我决定从头开始制作自己的流服务器,而不是支持遗留代码。
2
此功能可以在传输 HDMI 时将传出流量减少数倍,但会稍微增加 CPU 使用率。这个想法是 HDMI 是一个全数字接口,每个捕获的帧都可以与前一个字节相同。无需每秒通过网络多次传输同一图像。启用--drop-same-frames=20
选项后,µStreamer 将删除所有匹配的帧(连续最多 20 个)。每个新帧首先按长度与前一帧匹配,然后使用memcmp()
。
如果您要从后院网络摄像头进行直播并需要控制它,请使用 mjpg-streamer。如果您需要具有高 FPS 的高质量图像 - µStreamer 将为您带来胜利。
您需要将 µStreamer 下载到您的系统上并从源代码构建它。
您需要make
、 gcc
、带有pthreads
支持的libevent
、 libjpeg9
/ libjpeg-turbo
和libbsd
(仅适用于 Linux)。
sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd
。sudo apt install libevent-dev libjpeg62-turbo libbsd-dev
。为WITH_GPIO=1
添加libgpiod-dev
,为WITH_SYSTEMD=1
添加libsystemd-dev
,为WITH_JANUS=1
添加libasound2-dev libspeex-dev libspeexdsp-dev libopus-dev
。libjpeg62-turbo
替换为libjpeg62-turbo-dev
。sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev
。sudo apk add libevent-dev libbsd-dev libjpeg-turbo-dev musl-dev
。使用WITH_PTHREAD_NP=0
构建。要启用 GPIO 支持,请安装 libgpiod 并传递选项WITH_GPIO=1
。如果编译器报告缺少函数pthread_get_name_np()
(或类似函数),请添加选项WITH_PTHREAD_NP=0
(默认情况下启用)。对于setproctitle()
的类似错误,添加选项WITH_SETPROCTITLE=0
。
最方便的过程是将 µStreamer Git 存储库克隆到您的系统上。如果您没有安装 Git 并且也不想安装它,您可以使用wget https://github.com/pikvm/ustreamer/archive/refs/heads/master.zip
。
$ git clone --depth=1 https://github.com/pikvm/ustreamer
$ cd ustreamer
$ make
$ ./ustreamer --help
假设您有如上所述的 µStreamer 克隆,您可以按如下方式更新 µStreamer。
$ cd ustreamer
$ git pull
$ make clean
$ make
对于 Raspberry Pi 上的 M2M 硬件编码,您至少需要 5.15.32 内核。旧内核上的 OpenMAX 和 MMAL 支持已被弃用并删除。
如果没有参数, ustreamer
将尝试以 640x480 分辨率打开/dev/video0
并开始在http://127.0.0.1:8080
上进行流式传输。您可以使用参数--device
、 --host
和--port
覆盖此行为。例如,要流向全世界,请运行:
# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80
❗ 请注意,自 µStreamer v2.0 起,出于安全原因默认禁用跨域请求。要启用旧行为,请使用选项--allow-origin=*
。
在 Raspberry Pi 上使用基于 TC358743 的捕获设备运行 µStreamer 的推荐方法:
$ ./ustreamer
--format=uyvy # Device input format
--encoder=m2m-image # Hardware encoding on V4L2 M2M driver
--workers=3 # Workers number
--persistent # Suppress repetitive signal source errors (for example when HDMI cable was disconnected)
--dv-timings # Use DV-timings
--drop-same-frames=30 # Save the traffic
❗ 请注意,要对不同的浏览器使用--drop-same-frames
,您需要使用一些特定的 URL /stream
参数(详细信息请参阅 URL /
)。
您始终可以使用ustreamer --help
查看完整的选项列表。
将以下行添加到 /boot/firmware/usercfg.txt:
gpu_mem=128
dtoverlay=tc358743
检查 CMA 的大小:
$ dmesg | grep cma-reserved
[ 0.000000] Memory: 7700524K/8244224K available (11772K kernel code, 1278K rwdata, 4320K rodata, 4096K init, 1077K bss, 281556K reserved, 262144K cma-reserved)
如果小于 128M,请在 /boot/firmware/cmdline.txt 中添加以下内容:
cma=128M
保存更改并重新启动。
启动容器:
$ docker run --device /dev/video0:/dev/video0 -e EDID=1 -p 8080:8080 pikvm/ustreamer:latest
然后通过端口8080访问Web界面(例如http://raspberrypi.local:8080)。
$ docker run --rm pikvm/ustreamer:latest
--format=uyvy
--workers=3
--persistent
--dv-timings
--drop-same-frames=30
添加-e EDID=1
以在启动 ustreamer 之前设置 HDMI EDID。与-e EDID_HEX=xx
一起使用指定自定义 EDID 数据。
Raspberry Pi v3 相机的示例用法(需要libcamerify
,它位于 Raspbian 上的libcamera-tools
和libcamera-v4l2
(两者都安装)中):
$ sudo modprobe bcm2835-v4l2
$ libcamerify ./ustreamer --host :: --encoder=m2m-image
对于 v2 相机,您可以对libcamerify
使用相同的技巧,但在raspi-config
中启用旧相机模式。
Raspberry Pi v1 摄像头的使用示例:
$ sudo modprobe bcm2835-v4l2
$ ./ustreamer --host :: -m jpeg --device-timeout=5 --buffers=3 -r 2592x1944
❗ 请注意,较新的相机型号具有不同的最大分辨率。您可以在 PiCamera 文档中查看支持的分辨率。
❗ 如果帧速率很差,可能是相机切换到照片模式,这会产生低帧速率(但图像质量更高)。这是因为bcm2835-v4l2
在分辨率高于1280x720
时切换到照片模式。要解决此问题,请传递max_video_width
和max_video_height
模块参数,如下所示:
$ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944
µStreamer 使用 H.264 压缩和 Janus WebRTC 服务器支持带宽高效的流媒体。有关完整详细信息,请参阅 Janus 集成指南。
当 uStreamer 位于 Nginx 代理后面时,其缓冲行为会在视频流中引入延迟。可以禁用 Nginx 的缓冲来消除额外的延迟:
location /stream {
postpone_output 0;
proxy_buffering off ;
proxy_ignore_headers X-Accel-Buffering;
proxy_pass http://ustreamer;
}
v4l2 实用程序提供了管理 USB 网络摄像头设置和信息的工具。脚本可用于进行调整并手动或使用 cron 运行。例如,在 cron 中运行以更改一天中特定时间的曝光设置。该软件包在所有 Linux 发行版中均可用,通常称为v4l-utils
。
v4l2-ctl --list-devices
。v4l2-ctl -d /dev/video0 --list-ctrls
。v4l2-ctl -d /dev/video0 --list-formats-ext
。v4l2-ctl -d /dev/video0 --get-ctrl=exposure_auto
。v4l2-ctl -d /dev/video0 --set-ctrl=exposure_auto=1
。在这里您可以找到更多示例。文档可在man v4l2-ctl
中找到。
版权所有 (C) 2018-2024 马克西姆·德瓦耶夫 [email protected]
该程序是自由软件:您可以根据自由软件基金会发布的 GNU 通用公共许可证(许可证的第 3 版)或(由您选择)任何更高版本的条款重新分发和/或修改它。
分发此程序的目的是希望它有用,但不提供任何保证;甚至没有适销性或特定用途适用性的默示保证。有关更多详细信息,请参阅 GNU 通用公共许可证。
您应该随该程序一起收到 GNU 通用公共许可证的副本。如果没有,请参阅 https://www.gnu.org/licenses/。