将网络摄像头分配给特定的 /dev/video#

Pan*_*nos 10 webcam udev

我的 Ubuntu 服务器 14.04 上有三个网络摄像头。lsusb 的输出:

Bus 006 Device 002: ID 0bda:8153 Realtek Semiconductor Corp.
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 003: ID 2537:1066
Bus 004 Device 002: ID 05e3:0616 Genesys Logic, Inc.
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 005: ID 1871:0101 Aveo Technology Corp. UVC camera (Bresser microscope)
Bus 003 Device 004: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB
Bus 003 Device 003: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB
Bus 003 Device 002: ID 05e3:0610 Genesys Logic, Inc. 4-port hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 005: ID 046d:0807 Logitech, Inc. Webcam B500
Bus 001 Device 004: ID 1871:0101 Aveo Technology Corp. UVC camera (Bresser microscope)
Bus 001 Device 003: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB
Bus 001 Device 002: ID 1a40:0101 Terminus Technology Inc. 4-Port HUB
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Run Code Online (Sandbox Code Playgroud)

我想为每个人分配一个特定的 /dev/video#。我已经读到我必须在 /etc/udev/rules.d/ 中创建一个 udev 规则,但是我读到的大部分内容似乎已经过时,我不想给我的服务器造成问题。我正在考虑创建一个包含以下内容的 25-name-video-devices.rules:

SUBSYSTEM=="video4linux", BUS=="usb", SYSFS{idVendor}=="1871", SYSFS{idProduct}=="0101", NAME="video10"
SUBSYSTEM=="video4linux", BUS=="usb", SYSFS{idVendor}=="1871", SYSFS{idProduct}=="0101", NAME="video11"
SUBSYSTEM=="video4linux", BUS=="usb", SYSFS{idVendor}=="046d", SYSFS{idProduct}=="0807", NAME="video12"
Run Code Online (Sandbox Code Playgroud)

我遇到的另一个问题是 3 个网络摄像头中的 2 个看起来相同(虽然它们不是,但它们是从 ebay 购买的,用于监控不同的区域)。那么我的案件的规则是什么?谢谢

Chr*_*iki 9

没有 Udev 规则的解决方案

video4linux 可能已经为您提供了稳定的设备名称。您可能要检查的目录/dev/v4l/by-id/,并/dev/v4l/by-path/为这个。将您的设备连接到不同的 USB 端口并比较创建的设备名称以确保它们确实稳定。

使用 Udev 规则的解决方案

否则,这取决于您的两个看似相同的设备是否至少具有不同的序列号,该序列号可由 udev 访问。您可以通过lsusb在以下命令的输出中使用正确的“总线”和“设备”编号来找到这一点:

udevadm info --attribute-walk /dev/bus/usb/003/005
Run Code Online (Sandbox Code Playgroud)

如果在键/值对的第一个块中有类似以下的某种输出,并且两个设备之间的序列号不同,那么您可以在您的 udev 规则中使用它:

ATTR{串行}=="68974689267119892"

您的 udev 规则可能如下所示:

SUBSYSTEM=="usb", ATTR{serial}=="68974689267119892", ATTR{idVendor}=="1871", ATTR{idProduct}=="0101", NAME="video10"
SUBSYSTEM=="usb", ATTR{serial}=="12345698798725654", ATTR{idVendor}=="1871", ATTR{idProduct}=="0101", NAME="video11"
SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="0807", NAME="video12"
Run Code Online (Sandbox Code Playgroud)

如果没有序列号(或类似的唯一)编号,那么我只看到以下可能性:您必须确保您的设备始终连接在相同的 USB 端口上。在这种情况下,您可以使用以下规则:

SUBSYSTEM=="usb", KERNEL=="2-3", ATTR{idVendor}=="1871", ATTR{idProduct}=="0101", NAME="video10"
SUBSYSTEM=="usb", KERNEL=="2-4", ATTR{idVendor}=="1871", ATTR{idProduct}=="0101", NAME="video11"
SUBSYSTEM=="usb", KERNEL=="2-2", ATTR{idVendor}=="046d", ATTR{idProduct}=="0807", NAME="video12"
Run Code Online (Sandbox Code Playgroud)

您必须KERNEL通过再次运行上述udevadm命令并查找KERNEL键/值对来找出要使用的 ID 。

小调

只创建新的符号链接而不是新的设备名称可能更好/更好,甚至可能将它们分组在一个公共目录下:

SUBSYSTEM=="usb", KERNEL=="2-3", ATTR{idVendor}=="1871", ATTR{idProduct}=="0101", SYMLINK+="foo/video10"
Run Code Online (Sandbox Code Playgroud)

例如,之前的规则会在/dev/foo/video10.

我可能也会简单地命名规则文件name-video-devices.rules,即,将前导数字排除在外。规则何时执行可能无关紧要,因此无需使用(相当高的)优先级 25。

  • 如果我错了,请纠正我,但似乎无法更改 NAME,除非在网络设备的特殊情况下。来自`man udev`:`NAME 用于网络接口的名称。udev 不能更改设备节点的名称,只能创建额外的符号链接。` 来自 `udevadm test <devpath>`:`NAME="/dev/video99" 被忽略,内核设备节点不能重命名;请在 /etc/udev/rules.d/50-blah.rules:5` 中修复它 (3认同)