4

How do you get a USB webcam’s serial number from the Linux command line?

I have multiple USB webcams connected to an Ubuntu machine. They all show up as /dev/video0, /dev/video1, /dev/video2, etc, but I can't seem to find any way to programmatically tell which is which. Several of the cameras are the same model, so just getting a model name isn't enough.

Note, I'm not asking how to use lsusb. Yes, I know you can use lsusb or libusb to get device serial number, product ID, manufacturer name, etc. But as far as I can tell, nothing shown by lsusb can be cross-referenced with a /dev/video* path.

e.g. If someone plugs in two identical webcams and they show up as /dev/video1 and /dev/video2 and then unplugs them and replugs them into completely different ports, so that /dev/video2 becomes /dev/video3 and /dev/video1 becomes /dev/video4, I can immediately know that the current /dev/video3 "used to be" /dev/video2.

The only similar questions I've found only suggest hacks like unplugging and and replugging it while scanning dmesg. I'm looking for a pure-programmatic solution that requires no hardware manipulation to identify the webcams.

6
  • This might not be possible. The question I am marking this as a duplicate of has a suggestion of using lsusb like this: lsusb -vvv to see what the output is. Depending on the manufacturer and/or device there might be a “serial number” field, but that number might just be the same across all devices; meaning that is far from a unique number. The broader suggestion is to detect what port they are connected to and always make sure that specific camera is connected to that specific port. – Giacomo1968 Apr 15 '15 at 18:44
  • what does lshw say about your device? – Frank Thomas Apr 15 '15 at 18:53
  • lspci --vvv may also in conjunction with lsusb -vvv may help – linuxdev2013 Apr 15 '15 at 18:55
  • @FrankThomas, That only lists my USB controllers. It doesn't list any peripherals. – Cerin Apr 15 '15 at 20:42
  • @linuxdev2013, like lshw, lspic only lists controllers. lsusb helps me uniquely identify the devices...but I can't find any link to /dev/video. – Cerin Apr 15 '15 at 20:43
11

It is possible to identify all cameras. The command

 $ sudo lsusb -v -d 046d:082d | grep -i serial
   iSerial                 1 05C6D16F

returns the Serial number of my camera (a Logitech HD Pro Webcam, used as an example with the correct Vendor:Product codes obtained from a previous use of lsusb). Please notice that the use of sudo is absolutely necessary: an unprivileged user does not get access to all info available thru the command.

The serial number is often, but not always, unique. If it is not unique (just compare the output of the above commands for two devices with the same Vendor:Product codes), you can set them so that they are distinct. There are guides all over Google for doing that, I will merely point to a couple of them, for the sake of thoroughness: here and here. But remember, this is a device-dependent procedure, so you will have to find out how to do it for your very own camera.

Now the command

$ sudo udevadm info --query=all /dev/video1 | grep 'VENDOR_ID\|MODEL_ID\|SERIAL_SHORT'
  E: ID_MODEL_ID=082d
  E: ID_SERIAL_SHORT=05C6D16F
  E: ID_VENDOR_ID=046d

returns the appropriate codes for this particular camera. Trial and error with all /dev/videoX devices allows pigeon-holing all of them.

1
  • I have several cameras for which the model, serial, and vendor id are all identical, so I cannot use this command. Still searching though... – bremen_matt Jul 21 '17 at 10:18
7

I had same problem too. I needed to identify 6 usb cameras connected to raspberry pi with 1 more usb hub. 6 cameras have all identical vendor id, model name and serial #. Whenever I turned off and on I was able to handle the cameras using '/dev/video0' ... '/dev/video5'. But I found that '/dev/videoX' was not always assigned to the same camera. So I've spent some time to solve this problem and finally solved it by using the bus#. Below is my raspberry pi's command result.

v4l2-ctl --list-devices

USB 2.0 Camera: HD USB Camera (usb-3f980000.usb-1.2):
     /dev/video0
USB 2.0 Camera: HD USB Camera (usb-3f980000.usb-1.3):
     /dev/video1
USB 2.0 Camera: HD USB Camera (usb-3f980000.usb-1.4):
     /dev/video2
USB 2.0 Camera: HD USB Camera (usb-3f980000.usb-1.5.1):
     /dev/video3
USB 2.0 Camera: HD USB Camera (usb-3f980000.usb-1.5.2):
     /dev/video4
USB 2.0 Camera: HD USB Camera (usb-3f980000.usb-1.5.3):
     /dev/video5

I found the bus number(1.2, 1.3, 1.4, 1.5.1, 1.5.2, 1.5.3) is always match to the physical usb port. So I parsed the result to find camera path for each bus# to identify each camera. Now it looks like work perfectly. I used below command to parse the result.

v4l2-ctl --list-devices | awk '{split($0,a,"-"); gsub(/[):]/,"",a[3]); getline; name=substr($0,2); print a[3] "-" name; getline}'

0

I had the same desire to get a specific camera from the command line, so I could get a shortcut to view my video to work no matter which port I plugged into, etc.. the answers here helped, but didn't quite give me a full recipe, so I'll post a full solution.

I have a usb camera I use for showing work I'm doing via a screen-share with my colleagues. I use VLC to just put the video feed in a window, so it can be seen next to the code I'm developing. This is a specific example, but the commands here will work for any programmatic use case.

Based on this answer and several others, I came up with this, which works as a desktop launcher (xfce):

bash -c "VID=$(v4l2-ctl --list-devices | grep 'H264 USB Camera' -A4 | sed -n '4p' | xargs) ; vlc v4l2://$VID --live-caching=250 --v4l2-width=1920 --v4l2-height=1080 "

To break it all down:

First, wrap in bash so you can use pipes and environment variables, etc. from a launcher:

bash -c "..."

Next, find the correct video device and put the name in a variable

VID=$(...)

First list all devices...

vfl2-ctl ...

Match the one you care about including enough lines to show all the /dev/video* names ...

grep ... -A4

Then grab the device number that has the right resolution/settigs...

sed -n ...

Trim spaces...

xargs

Finally, pass to vlc with settings to minimize the latency and set the resolution:

vlc v4l2://$VID --live-caching=250 --v4l2-width=1920 --v4l2-height=1080

References:

https://stackoverflow.com/questions/6022384/bash-tool-to-get-nth-line-from-a-file

https://unix.stackexchange.com/questions/493081/how-to-create-an-environment-variable-that-is-the-output-of-a-command

https://stackoverflow.com/questions/369758/how-to-trim-whitespace-from-a-bash-variable

https://askubuntu.com/questions/214977/how-can-i-find-out-the-supported-webcam-resolutions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.