I'm having trouble with an app I'm writing for a monitoring device. I've got a RaspberryPi4 that runs a python script with three threads. One of these threads manages a camera for recording video. When I startup the pi with the camera attached, it works just fine. However, when I startup the device without this USB camera attached my program fails to find the camera.
As is, the program looks for a valid video device under the /dev folder of the raspberrypi. I've noticed that when I disconnect the camera or reconnect it, these video devices will appear and disappear under the /def folder. However, my python program fails to detect these changes. It's like it has one chance to detect if the camera is attached at boot and then cannot detect it after.
What's interesting is that if it starts with the camera attached, I can disconnect and reconnect the camera without issue. Has anyone else run into an issue like this? Here is the part of my code that is meant to try and connect to the camera.
def cameraConnect(self,device):
# Clear the cache
os.sync()
# try connecting to camera
self.cap = cv2.VideoCapture(-1)
#Find the camera devices
devices = []
files = os.listdir('/dev/')
print(files)
for file in files:
if file.startswith('video'):
devices.append(os.path.join('/dev', file))
print("Devices found: ", devices)
#Check if the camera is attached
if len(devices) < 1:
print("No devices found, trying defaults")
devices = ['/dev/video0', '/dev/video1', '/dev/video2', '/dev/video3', '/dev/video4','-1']
for dev in devices:
print("Connecting to ", dev)
self.cap = cv2.VideoCapture(dev)
if self.cap.isOpened():
print(f"Successfully opened {dev}")
device = dev
self.is_camera_attached = True
break
else:
print(f"Failed to open {dev}")
Using os.listdir and os.scandir I try and find these video devices under /dev. Those being video0 through video3 which the code will then try to connect to each of them. This program will loop, trying to connect to either the default or found video devices under /dev but the devices are either found when the program starts or not at all. That is dependent on whether or not the camera is connected. I thought maybe it was a caching issue, but I believe os.sync should prove that is not the case. I'm uncertain if this is a python or a raspberrypi issue?
Any help would be greatly appreciated, thanks.
Edited for more detail.
Instead of using
/dev/video*paths in your code, install thev4l-utilsApt package, and then use the explicit ID paths that become visible under directories/dev/v4l/by-id/or/dev/v4l/by-path/.The enumerations of paths
/dev/video*may change boot-to-boot or even during continuous uptime when hot-unplugging/replugging a USB camera, or even as power and bandwidth limits toggle a connected USB camera ON/OFF, with the camera acquiring a different number each time (often incrementing).The way to assure getting a consistent path to your USB camera device, use instead paths visible in the
/dev/v4l/directory. These remain the same, even when a device toggles OFF and back ON intermittently.For example, my system shows:
With the example above, instead of using,
I would prefer to use,
While
/dev/video0may change to a different enumeration over time, the specific ID path will always point to originally-intended device since it is identified by a unique manufacturer-assigned ID.