From 56aad146df21d744aee1c14ba0cc0913b97354fa Mon Sep 17 00:00:00 2001 From: Vadim Peretokin Date: Fri, 30 Jan 2026 12:19:14 +0100 Subject: [PATCH] Deduplicate cameras sharing same physical device --- postured/pose_detector.py | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/postured/pose_detector.py b/postured/pose_detector.py index a45bb2d..314eae0 100644 --- a/postured/pose_detector.py +++ b/postured/pose_detector.py @@ -197,10 +197,21 @@ def available_cameras() -> list[tuple[int, str]]: """Return list of (index, name) for available cameras.""" import subprocess import re + import os cameras = [] + seen_devices = set() + for i in range(10): device = f"/dev/video{i}" + + sysfs_device = f"/sys/class/video4linux/video{i}/device" + if os.path.islink(sysfs_device): + physical_device = os.path.realpath(sysfs_device) + if physical_device in seen_devices: + continue + seen_devices.add(physical_device) + try: result = subprocess.run( ["v4l2-ctl", "-d", device, "--all"], @@ -222,7 +233,6 @@ def available_cameras() -> list[tuple[int, str]]: if "Video Capture" not in device_caps: continue - # Extract camera name name_match = re.search(r"Card type\s*:\s*(.+)", output) name = ( name_match.group(1).strip().rstrip(":") @@ -235,7 +245,15 @@ def available_cameras() -> list[tuple[int, str]]: # v4l2-ctl not available, fall back to OpenCV detection cap = cv2.VideoCapture(i) if cap.isOpened(): - cameras.append((i, f"Camera {i}")) + name = f"Camera {i}" + name_path = f"/sys/class/video4linux/video{i}/name" + if os.path.exists(name_path): + try: + with open(name_path) as f: + name = f.read().strip().rstrip(":") + except OSError: + pass + cameras.append((i, name)) cap.release() return cameras