How to selecting a video4linux camera based on its serial number from gst-launch?

Nicolas Dufresne nicolas at ndufresne.ca
Thu Feb 29 21:10:22 UTC 2024


Hi,

Le jeudi 29 février 2024 à 20:39 +0100, Henning Larsen via gstreamer-devel a
écrit :
> A command like this launches /dev/video0
> gst-launch-1.0 -v v4l2src device=/dev/video0 ! videoconvert ! autovideosink
> But when you have multiple cameras and they are enumerated in a random order
> you usually need to be able to identify each camera on - say its serial
> number.
> 
> It is easy to find the serial number including many other properties using the
> command
> $udevadm info /dev/video0
> The serial number for example, would be called 
> ID_SERIAL_SHORT=12345

In the UVC space, were cheap Chinese market too over, you'll quickly find that
serial number can be unreliable. You may have 0, or the same serial for all cams
of the same model/brand. libcamera made up a proper ID generator, though it will
change if you change the actual USB port.

> How to use this serial number in the gst-launch string instead of the
> /dev/videoX id?

Its not support directly. Instead, we offer a tool (for software to use) that is
called GstDeviceMonitor, and V4L2 plugin offer a matching DeviceProvider. There
is a command line to excersize that tool:

gst-device-monitor-1.0 Video/Source
Device found:

name : Integrated Camera: Integrated C
class : Video/Source
caps : video/x-raw, format=YUY2, width=1280, height=720, pixel-aspect-ratio=1/1,
framerate=10/1
video/x-raw, format=YUY2, width=960, height=540, pixel-aspect-ratio=1/1,
framerate=15/1
video/x-raw, format=YUY2, width=848, height=480, pixel-aspect-ratio=1/1,
framerate=20/1
video/x-raw, format=YUY2, width=640, height=480, pixel-aspect-ratio=1/1,
framerate=30/1
video/x-raw, format=YUY2, width=640, height=360, pixel-aspect-ratio=1/1,
framerate=30/1
video/x-raw, format=YUY2, width=424, height=240, pixel-aspect-ratio=1/1,
framerate=30/1
video/x-raw, format=YUY2, width=352, height=288, pixel-aspect-ratio=1/1,
framerate=30/1
video/x-raw, format=YUY2, width=320, height=240, pixel-aspect-ratio=1/1,
framerate=30/1
video/x-raw, format=YUY2, width=320, height=180, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=1280, height=720, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=960, height=540, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=848, height=480, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=640, height=480, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=640, height=360, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=424, height=240, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=352, height=288, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=320, height=240, pixel-aspect-ratio=1/1,
framerate=30/1
image/jpeg, parsed=true, width=320, height=180, pixel-aspect-ratio=1/1,
framerate=30/1
properties:
udev-probed = true
device.bus_path = pci-0000:05:00.4-usb-0:2.1:1.0
sysfs.path = /sys/devices/pci0000:00/0000:00:08.1/0000:05:00.4/usb4/4-2/4-2.1/4-
2.1:1.0/video4linux/video0
device.bus = usb
device.subsystem = video4linux
device.vendor.id = 04ca
device.vendor.name = 8SSC20F27068L1GZ9AN7T85
device.product.id = 7070
device.product.name = Integrated Camera: Integrated C
device.serial = 8SSC20F27068L1GZ9AN7T85_Integrated_Camera
device.capabilities = :capture:
device.api = v4l2
device.path = /dev/video0
v4l2.device.driver = uvcvideo
v4l2.device.card = Integrated Camera: Integrated C
v4l2.device.bus_info = usb-0000:05:00.4-2.1
v4l2.device.version = 395013 (0x00060705)
v4l2.device.capabilities = 2225078273 (0x84a00001)
v4l2.device.device_caps = 69206017 (0x04200001)
gst-launch-1.0 v4l2src ! ...


When programming the returned Device, can be use to create and configure the
source element correctly, without having to know about the device property. You
can see that it also provides bunch of information imported from udev, including
the serial number if that is what you want to use. An alternative is to install
libcamera with the gstreamer element, in there the camera names are unique and
reusable. The other options is to create udev rules that alias you camera device
names to a unique name instead of the auto-generated one.

Nicolas

> 
> I tried 
> gst-launch-1.0 -v v4l2src device=$(python find_camera_by_sn.py 12345) !
> videoconvert ! autovideosink
> And it works - inside a shell, but not inside a MediaMTX.yml configuration
> file, and I need it to work there. I suspect it is because it does not support
> the shell command. In any case it is not an elegant method - better to stick
> with what is provided by gstreamer - if possible.
> 
> I would think this must be a fairly common issue so does there exist a
> plugin/filter for gstreamer to achieve this device selection based on a
> specific property?
> 
> Any hints are appreciated.
> Thanks
> henning
> 
> 
> Should someone need it: This is the python code find_camera_by_sn.py
> import sys
> import pyudev
> 
> def find_camera_by_serial(serial):
>     context = pyudev.Context()
>     for device in context.list_devices(subsystem='video4linux'):
>         if 'ID_SERIAL_SHORT' in device.properties:
>             if device.properties['ID_SERIAL_SHORT'] == serial:
>                 return device.device_node
>     return None
> 
> if __name__ == '__main__':
>     # Example: Find camera with serial number 'ABC123'
>     # manual command to list video4linux cameras
>     # udevadm info /dev/video0,   etc for 0,1,,3
>     default_dev = "/dev/video0"
>     if len(sys.argv) == 2:
>         camera_device = find_camera_by_serial(sys.argv[1])
>         if camera_device:
>             print(camera_device)
>         else: 
>             print(default_dev)
>     else:
>         print(default_dev)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20240229/3f037e3f/attachment-0001.htm>


More information about the gstreamer-devel mailing list