I attach 2 webcam to computer and it was listed in /dev folder: /dev/video0; /dev/video1.
Can you help me write C code to get serial number of webcam with input: /dev/video[0;1]
I attach 2 webcam to computer and it was listed in /dev folder: /dev/video0; /dev/video1.
Can you help me write C code to get serial number of webcam with input: /dev/video[0;1]
You can use lsusb
, but you need to add verbose flag and make sure you use sudo
with it, otherwise the serial will be incorrect.
sudo lsusb -v
If that is too verbose, then run lsusb
to get the device id:
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 012: ID 1ab1:0e11 Rigol Technologies
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Then run lsusb
with device flag and grep the serial number.
So for the serial number of Rigol device:
$ sudo lsusb -s 012 -v|grep -i iserial
iSerial 3 DP8C221100000
Based on the hint of using udevadm and the tutorial from http://www.signal11.us/oss/udev/ I got below code to get the serial info of my webcam.
#include "stdio.h"
#include <libudev.h>
int main(int argc, char **argv)
{
struct udev *udev;
struct udev_device *dev;
struct udev_enumerate *enumerate;
struct udev_list_entry *list, *node;
const char *path;
udev = udev_new();
if (!udev) {
printf("can not create udev");
return 0;
}
enumerate = udev_enumerate_new(udev);
udev_enumerate_add_match_subsystem(enumerate, "video4linux");
udev_enumerate_scan_devices(enumerate);
list = udev_enumerate_get_list_entry(enumerate);
udev_list_entry_foreach(node, list) {
path = udev_list_entry_get_name(node);
dev = udev_device_new_from_syspath(udev, path);
printf("Printing serial for %s\n", path);
printf("ID_SERIAL=%s\n",
udev_device_get_property_value(dev, "ID_SERIAL"));
printf("ID_SERIAL_SHORT=%s\n",
udev_device_get_property_value(dev, "ID_SERIAL_SHORT"));
udev_device_unref(dev);
}
return 0;
}
Playing around with libusb, it looks like there's a standard getSerialNumber()
method. Unfortunately, not all USB devices implement this. I have a couple cheap $4 webcams that return None for it. These interfaces expose other metadata, like VendorID and ProductID, which I've seen some code try and use as a unique identifier, but it's not guaranteed to be unique, especially if you have multiple devices of the same make and model.
But assuming you get a serial number for your device, the next problem is figuring out which /dev/videoN file it corresponds to. I have an old version of libusb installed, so I couldn't get the method working that returned the full sysfs path of the USB device, so instead I scrapped the output from hwinfo
. I extracted all the chunks corresponding to cameras, and then from those I extracted the piece that looked like:
SysFS BusID: 1-1.2:1.0
USB devices actually form a complicated tree, and that BusID encodes where the device is located in that tree.
You can then take that BusID to find where the device lives in the filesystem as well as the video path, which should be at:
/sys/bus/usb/devices/<BusID>/video4linux/
That's a directory, and inside it you'll find a videoN file matching one in /dev.
Just ran into this same problem and it took a bit to find the solution. Any solution which starts with "just use lsusb" is incorrect. You can figure out the devices serial, but none of the extra information it provides help you determine which /dev/video it links to.
Solution:
/bin/udevadm info --name=/dev/video1 | grep SERIAL_SHORT
Output:
E: ID_SERIAL_SHORT=256DEC57
Looking at
lsusb
you find out that it uses libusb, it has many functions, notably for usb device handling and enumeration. libudev might be relevant too.Alternatively,
popen
thelsusb
command...