<html><head><style>pre,code,address {
margin: 0px;
}
h1,h2,h3,h4,h5,h6 {
margin-top: 0.2em;
margin-bottom: 0.2em;
}
ol,ul {
margin-top: 0em;
margin-bottom: 0em;
}
blockquote {
margin-top: 0em;
margin-bottom: 0em;
}
</style></head><body><div>Hi,</div><div><br></div><div>Le jeudi 29 février 2024 à 20:39 +0100, Henning Larsen via gstreamer-devel a écrit :</div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div dir="ltr">A command like this launches /dev/video0<div><i>gst-launch-1.0 -v v4l2src device=/dev/video0 ! videoconvert ! autovideosink</i><br></div><div>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.</div><div><br></div><div>It is easy to find the serial number including many other properties using the command</div><div><i>$udevadm info /dev/video0</i></div><div>The serial number for example, would be called </div><div>ID_SERIAL_SHORT=12345</div></div></blockquote><div><br></div><div>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.</div><div><br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div dir="ltr"><div><b>How to use this serial number in the gst-launch string instead of the /dev/videoX id?</b></div></div></blockquote><div><br></div><div>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:<br><br>gst-device-monitor-1.0 Video/Source</div><div>Device found:</div><div><br></div><div> name : Integrated Camera: Integrated C</div><div> class : Video/Source</div><div> caps : video/x-raw, format=YUY2, width=1280, height=720, pixel-aspect-ratio=1/1, framerate=10/1</div><div> video/x-raw, format=YUY2, width=960, height=540, pixel-aspect-ratio=1/1, framerate=15/1</div><div> video/x-raw, format=YUY2, width=848, height=480, pixel-aspect-ratio=1/1, framerate=20/1</div><div> video/x-raw, format=YUY2, width=640, height=480, pixel-aspect-ratio=1/1, framerate=30/1</div><div> video/x-raw, format=YUY2, width=640, height=360, pixel-aspect-ratio=1/1, framerate=30/1</div><div> video/x-raw, format=YUY2, width=424, height=240, pixel-aspect-ratio=1/1, framerate=30/1</div><div> video/x-raw, format=YUY2, width=352, height=288, pixel-aspect-ratio=1/1, framerate=30/1</div><div> video/x-raw, format=YUY2, width=320, height=240, pixel-aspect-ratio=1/1, framerate=30/1</div><div> video/x-raw, format=YUY2, width=320, height=180, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=1280, height=720, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=960, height=540, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=848, height=480, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=640, height=480, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=640, height=360, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=424, height=240, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=352, height=288, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=320, height=240, pixel-aspect-ratio=1/1, framerate=30/1</div><div> image/jpeg, parsed=true, width=320, height=180, pixel-aspect-ratio=1/1, framerate=30/1</div><div> properties:</div><div> udev-probed = true</div><div> device.bus_path = pci-0000:05:00.4-usb-0:2.1:1.0</div><div> 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</div><div> device.bus = usb</div><div> device.subsystem = video4linux</div><div> device.vendor.id = 04ca</div><div> device.vendor.name = 8SSC20F27068L1GZ9AN7T85</div><div> device.product.id = 7070</div><div> device.product.name = Integrated Camera: Integrated C</div><div> device.serial = 8SSC20F27068L1GZ9AN7T85_Integrated_Camera</div><div> device.capabilities = :capture:</div><div> device.api = v4l2</div><div> device.path = /dev/video0</div><div> v4l2.device.driver = uvcvideo</div><div> v4l2.device.card = Integrated Camera: Integrated C</div><div> v4l2.device.bus_info = usb-0000:05:00.4-2.1</div><div> v4l2.device.version = 395013 (0x00060705)</div><div> v4l2.device.capabilities = 2225078273 (0x84a00001)</div><div> v4l2.device.device_caps = 69206017 (0x04200001)</div><div> gst-launch-1.0 v4l2src ! ...</div><div><br></div><div><br></div><div>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.</div><div><br></div><div>Nicolas</div><div><br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>I tried </div><div><i>gst-launch-1.0 -v v4l2src device=$(python find_camera_by_sn.py 12345) ! videoconvert ! autovideosink</i><br></div><div>And it works - inside a shell, but <b>not </b>inside a <a href="https://github.com/bluenviron/mediamtx">MediaMTX.yml </a>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.</div><div><br></div><div>I would think this must be a fairly common issue so <b>does there exist a plugin/filter for gstreamer to achieve this device selection based on a specific property?</b></div><div><br></div><div>Any hints are appreciated.</div><div>Thanks</div><div>henning</div><div><br></div><div><br></div><div><i>Should someone need it: This is the python code find_camera_by_sn.py</i></div><div>import sys<br>import pyudev<br><br>def find_camera_by_serial(serial):<br> context = pyudev.Context()<br> for device in context.list_devices(subsystem='video4linux'):<br> if 'ID_SERIAL_SHORT' in device.properties:<br> if device.properties['ID_SERIAL_SHORT'] == serial:<br> return device.device_node<br> return None<br><br>if __name__ == '__main__':<br> # Example: Find camera with serial number 'ABC123'<br> # manual command to list video4linux cameras<br> # udevadm info /dev/video0, etc for 0,1,,3<br> default_dev = "/dev/video0"<br> if len(sys.argv) == 2:<br> camera_device = find_camera_by_serial(sys.argv[1])<br> if camera_device:<br> print(camera_device)<br> else: <br> print(default_dev)<br> else:<br> print(default_dev)<br></div></div></blockquote><div><br></div><div><span></span></div></body></html>