即使使用自定义 udev 规则,Logitech c930e focus 也会恢复为默认设置

即使使用自定义 udev 规则,Logitech c930e focus 也会恢复为默认设置

操作系统:Ubuntu 20.04(Focal Fossa)

我最近买了一个 Logitech c930e 摄像头,用于在线监考考试,监考人员可能会要求出示政府签发的身份证。该摄像头具有自动对焦功能,最初可以对焦近距离物体(如果在启动时将近距离物体放在摄像头前面),但一旦将焦点转移到远处的物体,它就无法重新检测并重新对焦随后放在摄像头前面的近距离物体。这会导致放在摄像头前面的政府签发的身份证上的文字变得难以辨认。

经过一些初步研究,我发现我可以安装v4l-utils并获取我可以在相机上调整的参数列表,如下所示(假设关联的设备节点是/dev/video1):

$ v4l2-ctl -d /dev/video1 --list-ctrls

过滤输出仅包含与焦点相关的选项可得出:

$ v4l2-ctl -d /dev/video1 --list-ctrls | grep focus
                 focus_absolute 0x009a090a (int)    : min=0 max=255 step=5 default=0 value=0 flags=inactive
                     focus_auto 0x009a090c (bool)   : default=1 value=1

因此默认focus_auto设置为和1,也可以通过运行以下命令查看:focus_absolute0

$ v4l2-ctl -d /dev/video1 --get-ctrl focus_auto
focus_auto: 1
$ v4l2-ctl -d /dev/video1 --get-ctrl focus_absolute
focus_absolute: 0

经过一些手动实验后,似乎focus_auto: 0focus_absolute: 75在使特写文本足够清晰与不使远处物体模糊太多之间取得了良好的平衡:

$ v4l2-ctl -d /dev/video1 --set-ctrl focus_auto=0
$ v4l2-ctl -d /dev/video1 --set-ctrl focus_absolute=75

因此我编写了一个 udev 规则文件/etc/udev/rules.d/90-logitech-c930e.rules来应用这些设置:

KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="0843", RUN+="/usr/bin/v4l2-ctl -d $devnode --set-ctrl focus_auto=0", RUN+="/usr/bin/v4l2-ctl -d $devnode --set-ctrl focus_absolute=75"

该文件也可以找到在 GitHub 上

idVendor: 046didProduct: 0843获得的是lsusb

$ lsusb | grep Logitech
Bus 001 Device 002: ID 046d:0843 Logitech, Inc. Webcam C930e

然后我重新启动systemd-udevd.service

$ sudo systemctl restart systemd-udevd.service

拔下相机插头,然后重新插入。在最初的几秒钟内,focus_auto设置为0并按预期设置focus_absolute为:75

$ v4l2-ctl -d /dev/video1 --get-ctrl focus_auto
focus_auto: 0
$ v4l2-ctl -d /dev/video1 --get-ctrl focus_absolute
focus_absolute: 75

但最多几十秒后,设置就会恢复为默认设置:

$ v4l2-ctl -d /dev/video1 --get-ctrl focus_auto
focus_auto: 1
$ v4l2-ctl -d /dev/video1 --get-ctrl focus_absolute
focus_absolute: 0

为什么会这样? 是否可以禁用此行为? 如果可以,该怎么做?

答案1

经过一些额外的研究后,似乎自动恢复默认设置是一个功能,而不是一个错误(TM):https://www.reddit.com/r/obs/comments/fflg5g/logitech_cam_keeps_resetting_video_settings_back/

因此我想到了一个主意:如果我可以每隔几秒左右设置一次焦点,以防止设置回到默认值,会怎么样?事实证明这是可能的,尽管不能直接使用 udev,因为它是一个长期运行的过程,并且 udev 规则正在阻止。相反,我使用了 udev 规则、systemd 设备单元和服务单元的组合。

高层思路如下:

  • 创建一个标记 systemd 的 udev 规则文件,以便创建关联的设备单元,并将其设置SYSTEMD_WANTS为指向服务模板单元文件,并将次设备号传递给模板
  • 服务模板单元运行一个脚本,并将其参数(次设备号)传递给脚本
  • 该脚本使用次设备号来引用正确的相机,并以 5 秒的间隔重复设置该相机的对焦参数

详细解决方案可以参见这个要点

相关内容