跟着思兼学习Klipper(16) Klipper 网页使用摄像头比较全指南
##【思兼】Klipper 网页使用摄像头比较全指南## 前言
原创文章,转载引用请务必注明链接。水平有限,如有疏漏,欢迎指正交流。
本文分为两部分:一是针对我出售的 Klipper 免驱摄像头的专有内容,二是关于使用摄像头的通用内容。
文章如有更新请访问 (https://mc.dfrobot.com.cn/thread-313090-1-1.html?fromuid=725344) 或者 (https://www.cnblogs.com/sjqlwy/p/klipper_webcam.html)。
欢迎对 Klipper 固件感兴趣,以及对改版 CNC 加工的 Voron 三叉戟、v0、v2.4 感兴趣的朋友加群交流(QQ Group:490111638)
## 一、专有内容 | Exclusive Content
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220502013519.png)
请结合视频了解如何快速入门:[思兼的 Klipper 免驱摄像头快速使用指南](https://www.bilibili.com/video/BV1744y137gw),做这个主要是解决以下问题:
- 上位机支持什么样的摄像头/哪些摄像头免驱?
- 哪种摄像头价格便宜,成像质量好?
- 如何在 Fluidd/Mainsail/Octoprint 中设置使用摄像头?
- 众多摄像头选项,如何配置和选择?
- 为什么我步骤都对,就是没有图像,如何排除故障?
- 除了监控,摄像头还有没有其他玩法?
其实预算足够,可以考虑购买这篇文章 [*Best Cameras for OctoPrint of 2021*](https://all3dp.com/2/octoprint-webcam-octoprint-camera-buyer-s-guide/) 推荐的,比如 罗技C270 等。
## 1、关于 Klipper 使用摄像头的一些问题
* 除了树莓派,大部分上位机都不支持视频的硬件解码
* 大多数上位机使用 CPU 软件解码,如果性能不足会出现卡滞现象,可以适当降低分辨率和帧率
* Fluidd 默认的 640x480@10fps 多能满足需求
* 高性能 CPU 酌情使用 800x600 分辨率,并根据使用目的设置帧率
* 请为上位机提供稳定供电,5V@2A 以上比较稳妥
* 和 Windows 下一样,最大分辨率用于静态拍照,视频录制模式无法达到最大分辨率
* MJPG-Streamer 比较吃 CPU 资源,KlipperScreen 比较吃内存资源
* 使用过程中建议为上位机 CPU 增加主动散热,摄像头芯片可以贴一个小散热片
* 安装此 USB 摄像头时,请确保没有正在执行打印任务,避免意外中断通讯
* 在低性能 CPU 上如果摄像头移动过快超出 CPU 处理能力,可能会导致图像卡死,可以尝试使用 `µStreamer` 或者重启 `webcamd` 服务,并尽量固定摄像头位置
## 2、安装使用 Klipper 摄像头
### 2.1 安装摄像头软件依赖
```shell
# 使用一键脚本,第一种方式会导致 kiauh 报无效参数错误,原因暂未知。
# 脚本默认策略是不相信本地软件环境,会备份并删除旧文件:.gitconfig、klipper_config/webcamd.txt、kiauh
# curl -fsSL http://klipper.7130404.xyz:8001/enable_webcam.sh | bash
bash <(curl -fsSL http://klipper.7130404.xyz:8001/add_webcam.sh)
```
### 2.2 安装 MJPG-Streamer
如视频中所示,在出现的 KIAUH 助手中删除并重新安装 MJPG-Streamer:
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220502015152.png)
### 2.3 添加摄像头
添加摄像头,设置如下,刷新主面板即可看到摄像头内容:
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220502015847.png)
- **MJPEG Stream** | 传统方式,Fluidd 被动接收 上位机上的 MJPEG 服务以 webcamd.txt 中 配置好的分辨率和帧率 推送来的视频流(连续的图片序列),此种方式多数情况下占用大量带宽,并且网络不稳定时会出现问题。
- **MJPEG Adaptive** | 推荐方式,Fluidd 主动拉取 单帧图片组成视频流,因此你可以设置合适的帧率,此种方式更稳定,占用网络带宽也更小。
- **IP Camera**| 实验性选项,仅支持 HTML5 视频,具体未测试。
- **HTTP Page** |(内嵌网页,支持更多视频来源)
- **U4VL** (Mainsail)
## 3、修改基本参数:分辨率和帧率
```yaml
# 修改 ~/klipper_config/webcam.txt 最下面一行
camera_usb_options="-r 640x480 -f 10 -y -d /dev/v4l/by-id/usb-Etron_Technology__Inc._USB2.0_Camera-video-index0"
# -r (resolution, 分辨率):640x480 修改为你想要的分辨率如 800x600
# -f (fps,帧率):10 修改为 25
```
重启生效:`sudo systemctl restart webcamd`
## 二、通用内容 | Generic Content
### 2.1 启用简单安全认证 | Enable Authentication
```diff
# 修改 ~/klipper_config/webcam.txt 下面几行
-#camera_http_options="-n"
+camera_http_options="-n -c :"
```
默认使用http访问时,密码传输采用明文,存在一定安全隐患,如需更严格的安全保护,请参考 [*Secure Webcam streaming with MJPG-Streamer on a Raspberry Pi*](https://www.sigmdel.ca/michel/ha/rpi/streaming_en.html)。
### 2.2 启用多摄像头 | Enable Multiple Cameras
参考链接如下,注意是有先后传承顺序的,即使是使用 Fluidd,KIAUH 下载使用的摄像头依赖软件和配置文件也是来源于 Mainsail,所以我常说 Fluidd 有问题可以去看 Mainsial 文档:
* (https://community.octoprint.org/t/setting-up-multiple-webcams-in-octopi-the-right-way/32669)
* (https://docs.mainsail.xyz/features/webcams#webcams)
* (https://docs.fluidd.xyz/features/cameras) | 不建议
主要操作就是
1. 复制一份 `webcam1.txt` 配置文件
2. 更改监听端口:8080~8083,受限于 nginx 默认设置,目前最多支持四个摄像头。
3. 更改捕获的视频设备地址,注意相同设备的话,所以配置文件都要更改,可以使用 by-path
4. 重启服务
5. 新的视频地址为 `webcam2/?action=stream` 对应 `8081` 对应`webcam1.txt`
6. aka **配置文件从 0 开始,摄像头地址从 1 开始,fluidd 的文档错了**
```shell
# 复制一份配置文件
cp ~/klipper_config/webcam.txt ~/klipper_config/webcam1.txt
# 更改监听端口
sed -i '/#camera_http_options=/a camera_http_options="-n -p 8081"' ~/klipper_config/webcam1.txt
# 由于同一摄像头其 id 相同,所以我们用 path 来进行区分,此处类似 klipper 的 serial 地址查找方法:
ls /dev/v4l/by-path/*
# 地址分别对应不同的USB接口,选择 index0 地址修改所有 webcam*.txt,使每个配置文件中的设备号不同。例如
camera_usb_options="-r 640x480 -f 10 -y -d /dev/v4l/by-path/platform-xhci-hcd.3.auto-usb-0:2:1.0-video-index0"
# 重启服务生效
sudo systemctl restart webcamd.service
```
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220502030704.png)
### 2.3 启用延时摄影 | Enable Timelapse
上次研究这个还是在去年 8 月份,现在该组件已经合并到 Mainsail 里面了,话说 Mainsail 功能是真的丰富,不排除有一天切换到它。
* [项目地址](https://github.com/mainsail-crew/moonraker-timelapse),[项目镜像地址](https://hub.0z.gs/mainsail-crew/moonraker-timelapse)
* [安装指南](https://hub.0z.gs/mainsail-crew/moonraker-timelapse/blob/main/docs/installation.md)
```shell
# 安装 ffmpeg 用于合成视频
sudo apt install ffmpeg
# 下载并安装 moonraker timelapse 组件
cd ~/ && git clone https://hub.0z.gs/mainsail-crew/moonraker-timelapse.git
bash ~/moonraker-timelapse/install.sh
```
* [配置参考](https://hub.0z.gs/mainsail-crew/moonraker-timelapse/blob/main/docs/configuration.md)
**修改 `printer.cfg` 如下**
```yaml
# printer.cfg
```
**修改 `moonraker.cfg` 如下**
```yaml
# moonraker.conf
## 以下为默认设置,如果需要更改请取消注释
#output_path: ~/timelapse/
## 存储生成的延时摄影视频目录
#frame_path: /tmp/timelapse/
## 存储临时图像的目录
#ffmpeg_binary_path: /usr/bin/ffmpeg
## ffmpeg 所在路径
snapshoturl: http://localhost:8080/?action=snapshot
## 摄像头快照访问地址,如果有多个摄像头可以设置具体的端口号
```
新版组件采用 moonraker API 来进行修改参数,具体查看上面的文档,也可以手动设置参数,调整分辨率在 `webcam.txt` 中修改。可以手动在控制台输入 `TIMELAPSE_TAKE_FRAME` 拍摄图片。
> **注意:**
>
> * 即使网页没有添加摄像头,图像和视频也是可以通过上述被访问的,但是即使没有显示,系统资源也会被占用
> * 延时摄影相关宏 **不支持密码访问** 的摄像头
> * 用作延时摄影的摄像头可以采用高分辨率低帧率,如 1600x1200@7fps
* 优化:创建软链接,方便直接在网页查看图片和下载视频
```shell
mkdir /home/pi/gcode_files/timelapse/
ln -s /tmp/timelapse/ /home/pi/gcode_files/timelapse/tmp
ln -s /home/pi/timelapse/ /home/pi/gcode_files/timelapse/video
```
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220502035407.png)
### 2.4 使用人工智能自动检测打印失败
可以借助 (https://www.thespaghettidetective.com/) 服务来自动检测炒面,免费服务受限颇多,可以 [自己搭建服务器](https://www.thespaghettidetective.com/docs/open-source/) 使用,我手里有一台 (https://www.thespaghettidetective.com/blog/2021/06/06/nvidia-jetson-nano-fun-project-3d-printing/) 可以用于测试。
> combines improved webcam streaming with AI-driven print failure detection. You can access your printer’s webcam feed from any device, and time-lapses of all your past prints are available on your TSD dashboard. An additional beta feature is a secure tunnel through which you can access your entire OctoPrint interface from any device.
* 既往在 Octoprint 系统上安装插件使用
* 目前有一个 (https://github.com/TheSpaghettiDetective/tsd-moonraker) 可供测试使用。
* 此外 TSD 还有一个 [**摄像头放置建议**](https://www.thespaghettidetective.com/docs/optimal-camera-setup/),值得一看。
**TSD 免费版限制:**
1. Limited to 1 printer.
2. Basic Streaming is at 0.1fps (1 frame per 10 seconds).
3. The stream is on only when the printer is printing.
4. 10 free Detective Hours/month included
* Unused Detective Hours roll over month to month.
* You can also (https://www.thespaghettidetective.com/docs/how-does-credits-work/).
5. 50MB / month Tunneling
6. Detective Hour is sometimes abbreviated as **DH**.
### 2.5 使用 µStreamer 替代 MJPG-Streamer
虽然此实验版 (https://github.com/jacksonliam/mjpg-streamer) 使用 (https://www.libjpeg-turbo.org/)而非普通的 (http://www.ijg.org/) 库进行编译,编解码速度有所提升,但是还是有优化空间。这里介绍另一个类似的改进项目:[µStreamer](https://github.com/pikvm/ustreamer),它是这么自我介绍的:`µStreamer - Lightweight and fast MJPEG-HTTP streamer` 也就是更轻量更快速的 MJPG-Streamer 替代服务。我测试下来优点明显,比如:
* 代码配置更简洁
* 支持多线程 JPEG 编码
* 支持树莓派的硬件编码,基于 V4L2 M2M
* 支持断线重连后信号恢复,而无需重启服务
* 支持控制 GPIO 输出
* 支持 WebRTC 串流,降低网络带宽占用,借助 Janus 和 H.264
* 兼容 mjpg-streamer API
但是性能不如 mjpg-streamer,不知道是不是我参数设置不正确。好处是几乎可以完全替代后者,后面会持续关注它。
创建 systemd 服务请参考:(https://github.com/pikvm/ustreamer/issues/16),µStreamer 不需要 webcamd 和 webcam.txt。
### 2.6 降低系统和带宽占用 (TBD)
目的是研究如何优化性能、提高流畅度,以下项目需要整理、测试、验证。硬件加速基本就限定树莓派了。
1. Fluidd `HTTP Page` :(https://github.com/fluidd-core/fluidd/pull/425)
> Uses less bandwidth and runs with hw accel in your browser but needs to be setup as a simple web page
>
> 基于 **(https://github.com/dans98/pi-h264-to-browser)** |RPi Cam *Pi H264 To Browser* is a simple Python application designed to stream hardware encoded h.264 from a Raspberry Pi equiped with a V1, V2, or HQ camera module, directly to a browser. 以及 (https://github.com/fluidd-core/fluidd/issues/461)
>
2. **(https://github.com/mpromonet/webrtc-streamer)**
> I set up (https://github.com/mpromonet/webrtc-streamer) to get a very low latency (and low bandwidth) camera feed from my printer into a browser, sadly fluidd's options do not allow me to embed that at all.
>
> ./webrtc-streamer -vvv v4l2:///dev/video1
>
> https://www.cnblogs.com/savorboard/p/webrtc-rtsp.html
>
> https://community.octoprint.org/t/js-help-needed-better-webcam-streaming-webrtc/4969/10
3. (https://gitlab.com/dragonn/h264rcam)| This project was inspired by (https://github.com/dans98/pi-h264-to-browser) ,h264rcam provides an easy way to get a Raspberry Pi Camera stream inside web browser.
https://askubuntu.com/questions/881305/is-there-any-way-ffmpeg-send-video-to-dev-video0-on-ubuntu
4. (https://www.linux-projects.org/uv4l/) | https://www.jianshu.com/p/c08d68a1a505
## 2.7 远程监控
关于这部分我没有需求,简单说说。
* 建议使用萤石等家用监控摄像头进行监控,自带远程访问功能
* 有访问条件的可以使用 telegram-bot
* 基本方法就是暴露 8080 端口,做强加密;或者使用 VPN
* 还可以推流到 B 站
* 另外家用宽带如果上行下行不对等,上行带宽较小时效果可能不好
* 如果想要进行远程控制打印机,安全起见建议只暴露 moonraker 7125 端口,不要暴露 80 端口(运营商可能也不愿意),可以访问 `app.fluidd.xyz` 或者 `my.mainsail.xyz` 访问。如果是自有域名,一是可以创建用户,二是可以修改 `cors_domains` 策略。
## 三、其他摄像头方案
## 3.1 树莓派摄像头 | RPi Cam
> **注意:**树莓派官方以及一些优质厂商提供的摄像头质量很不错,但是也有一些兼容树莓派引脚的劣质摄像头存在,注意甄别。
树莓派官方摄像头出了 3 代,1代支持自动对焦;2代不支持自动对焦,但是性能更好;3代这里就不介绍了。
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220411200712.png)
我们这里都以`Raspberry Pi OS Bullseye` 为例,使用方法很简单,说是新版会自动侦测并启用,但是对于 RPi3 等老型号,还需要设置以启动硬件加速: `sudo raspi-config` ——> `Advanced Options` ——> `Glamor` ——> `Yes` ,重启生效。
然后配置文件修改分辨率帧率即可。更多内容可以查看 [官方文档](https://www.raspberrypi.com/documentation/accessories/camera.html)。不过最好购买官方的摄像头,很多很便宜的摄像头显示质量很差。
## 3.2 手机作为摄像头使用
前面讲过旧手机可以充当 KlipperScreen 的显示触摸屏,其实旧手机的摄像头也可以为我所用。最初尝试我常用的由 `沈垚` 开发的 `IP摄像头`,下图黄黑色图标,只能以 `http page` 方式使用;于是搜索下载安装了第二款国外开发的黑灰色图标的 `IP摄像头` (下文称为 (https://apkpure.com/cn/ip-webcam/com.pas.webcam)) 测试成功。xapk 安装器 [下载地址](https://www.appinn.com/xapk-installer/)。注意如果是 32bit 老安卓手机,要找到老版本 APK 的下载。
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220411212524.png)
灰色摄像头软件的界面如下图所示功能强大,免费版功能就够用了。
https://www.dev47apps.com/
https://wolicheng.com/womic/
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220411215333.png)
【图 】**IP Webcam APP 界面**,支持读取传感器数据,所以有无可能根据陀螺仪做视频后处理,或者 GoPro 那种自稳视频效果?
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220411215911.png)
【图 】**IP Webcam 网页管理界面**,支持多种操作,以及开启 LED 闪光灯等功能,还可以设置熄屏和网页管理,美滋滋。
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/20220411223507.png)
其他值得关注的软件还包括:
* (https://www.dev47apps.com/) | 高级功能需要收费
* (https://wolicheng.com/womic/) | 无线麦功能
* [手机物理工坊](https://www.appinn.com/phyphox-for-android/) | 手机物理工坊 – 利用 8 种手机传感器,做最强物理实验,可以保存陀螺仪等数据
* (https://oscarliang.com/how-to-use-gyroflow-video-stabilization-tool-for-fpv/) | 结合陀螺仪数据,使视频实现 GoPro 类似效果(大概这样)
## 四、进阶知识
## 4.1 获取 USB-Camera 参数
```shell
# 安装所需工具包
sudo apt install v4l-utils usbtop
# 查看已连接的摄像头设备
v4l2-ctl --list-devices
# 如果没有识别到相应设备,请检查设备是否连接良好,以及 lsusb、dmesg 等命令查看是否被系统识别
# 查看对应摄像头的支持格式
v4l2-ctl -d --list-formats-ext
v4l2-ctl --device=/dev/video* --all
# 查看并设置摄像头支持的控制参数
v4l2-ctl -d /dev/video0 --list-ctrls
# v4l2-ctl -d /dev/video1 --set-ctrl=zoom_absolute=170
# 部分参数如果启用了自动控制,需要先关闭,比如白平衡(色温)
```
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/202204031504453.png)
由上图我们就可以获得所需的配置:
1. 摄像头设备地址为:`/dev/video0`,非 `video1` 或者 `media0`
2. 此摄像头支持的最大分辨率和对应的帧率为 `1600×1200`,亦即 1080P, 纵横比为 4:3。
3. 用于 Fluidd/Mainsail 网页前端使用时,可以选择 `800×600@25fps` 以获取较好的显示兼容性和较低的系统占用,减少 CPU 发热,降低打印管理进程被干扰的可能。
4. 编码方法为 `YUYV`,在配置参数中添加 `-y` 选项。此外有的摄像头还支持 `MJPG` 等编码方式。
### 番外:
1. 通过 `lsusb` 命令获取设备 `Vendor ID` 和 `Device ID` 可以查询到相关设备信息。
!(https://cdn.githubjs.cf/sjqlwy/blog_imgs/raw/default/images/202204031521488.png)
继而可以从以下网址查询相关信息:
* (https://devicehunt.com/view/type/usb/vendor/1E4E/device/0109)
* (https://usb-ids.gowdy.us/read/UD/1e4e/0109)
2. 图形化设置摄像头参数工具:(https://sourceforge.net/projects/v4l2ucp/)
3. 获取更多 mjpg_streamer 选项,可以通过查看 ( https://faq.octoprint.org/mjpg-streamer-config) 也可以查看帮助文件
```shell
udevadm info --attribute-walk /dev/bus/usb//
cd ~/mjpg_streamer
./mjpg_streamer -i "input_uvc.so --help"
./mjpg_streamer -o "output_http.so --help"
```
## 4.2 固定摄像头设备地址
在有多个 video 设备时,插拔摄像头后,其 `/dev/video` 编号可能会发生改变,从而导致摄像头配置文件失效,这也是为什么很多人原来用的好好的,插拔之后不能用的原因。
> 此外有些设备自带 /dev/video0 设备,而 webcamd 会默认读取第一个 video 设备,应该访问 video1 却访问了 video0。
### 4.2.1 Method 1:创建 udev 规则(不推荐)
参考 (https://wiki.archlinux.org/title/Udev#Setting_static_device_names) ,创建 udev 规则:
```shell
# /etc/udev/rules.d/83-webcam.rules
KERNEL=="video*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e4e", ATTRS{idProduct}=="0109", ATTR{index}=="0", SYMLINK+="video-cam1"
```
* 使用 `sudo udevadm control --reload` 命令可以强制重载生效 udev 规则,重新插拔 USB 摄像头即可看到新的 `video-cam1` 设备
* 同时修改 `webcamd.txt` 指定设备地址 `-d /dev/video-cam1`,重启 webcamd 服务生效
* 注意设备名称必须以 `video` 开头,以被 v4l 使用
* 比较奇怪的是 `ls -al /dev/video-cam1` 可以看到链接到 video2(不显示参数那个),但是手动修改 `webcamd.txt` 又只能用 `video1` 才行
* 发现 mjpg_streamer 仅支持 video,不支持上述命名格式,webcamd.log 看到会自动忽略
* 如果制定的设备地址无效,会自动调用第一个 video 设备,从而有可能出错
* 更多信息可以参考 (https://github.com/obsproject/obs-studio/issues/3003)
### 4.2.2 Method 2:使用 v4l 设备地址
这个很像 Klipper 获取 serial 设备地址的方法,不会出现重新插拔后出错的问题,导致 `ttyAMA0` 等设备无法对应,klipper 读取的是 `/dev/serial/by-id/*`,摄像头读取的是 `/dev/v4l/by-id/*` ,同样也面临一个问题,比如 CH340 设备的 id 相同,此时多个 MKS Gen L 等主板无法区分,此问题同样也出现在这里,解决方法是使用 `/dev/v4l/by-path/*`,此路径与USB接口绑定。
## 4.3 为什么一个物理摄像头,有多个 video 设备?
参考这个回答:(https://unix.stackexchange.com/questions/512759/multiple-dev-video-for-one-physical-device) ,可知第一个用于传递图像,第二个用于传递 `V4L MetaData`,包含时间戳以及图像捕捉参数等信息。
> The second device provides metadata about the video data from the first device.
## 4.4 将摄像头图像输出到屏幕
参考 (http://www.lavrsen.dk/foswiki/bin/view/Motion/MplayerMjpegStreamViewing)
```shell
sudo apt install -y mplayer
mplayer -nolirc -vo fbdev2 -zoom -x 320 -y 240 test.mpg
mplayer -fps 4 -demuxer lavf http://localhost:8080/?action=stream
```
## 4.5 查看带宽、数据吞吐量
* **(https://linux.cn/article-2808-1.html)** | 用于查看网络带宽吞吐量,优化调试使用。可以看到 jpeg 质量对带宽占用影响很大
```shell
sudo nethogs
# 使用 r 和 s 键来排序传入和传出的实时及累计数据量
```
* **(https://ywnz.com/linux/5807.html)** | 用于查看 USB 接口数据吞吐量,也可以观察上位机一带多情况
```shell
# 列出所有可用的USB总线
usbtop --list
# 监控特定USB总线上的带宽流量
sudo usbtop --bus 有led 的摄像头 怎么 自定义led 开关https://cdn.jsdelivr.net/gh/master-of-forums/master-of-forums/public/images/patch.gif Ptsa 发表于 2022-8-20 22:44
有led 的摄像头 怎么 自定义led 开关
文章里有写,v4l2-control什么的
页:
[1]