hacksider/Deep-Live-Cam · critical · RuntimeError
Failed to open camera
Error message
Failed to open camera
What it means
RuntimeError raised in VideoCapture.start (modules/video_capture.py) when every backend attempt fails to open the device: on Windows each (device id, backend, params) combination threw or failed isOpened; on Linux cv2.VideoCapture('/dev/video<N>') failed; on other platforms the default-open failed. It means OpenCV could not obtain a capture handle at all — the device is busy, absent, permission-denied, or not supported by the backend used.
Source
Thrown at modules/video_capture.py:80
(self.device_index, cv2.CAP_MSMF),
(self.device_index, cv2.CAP_ANY),
]
for dev_id, backend in capture_methods:
try:
self.cap = cv2.VideoCapture(dev_id, backend, open_params)
if self.cap.isOpened():
break
self.cap.release()
except Exception:
continue
elif platform.system() == "Linux":
self.cap = cv2.VideoCapture(f"/dev/video{self.device_index}")
else:
self.cap = cv2.VideoCapture(self.device_index)
if not self.cap or not self.cap.isOpened():
raise RuntimeError("Failed to open camera")
# Belt-and-braces: also set via cap.set() for backends that honor
# post-open changes (MSMF, V4L2). DSHOW ignores these, but the
# construction params above already handled it.
if platform.system() != "Windows":
self.cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
self.cap.set(cv2.CAP_PROP_FPS, fps)
# Read back resolution (usually reliable)
self.actual_width = int(self.cap.get(cv2.CAP_PROP_FRAME_WIDTH))
self.actual_height = int(self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# CAP_PROP_FPS is unreliable on DirectShow — often reports 30
# even when the camera delivers 60. Measure empirically by
# timing a burst of frames.
reported_fps = self.cap.get(cv2.CAP_PROP_FPS)View on GitHub (pinned to 987f6b392b)
Solutions
- Confirm nothing else holds the camera (close other conferencing/recording apps; kill stale processes) and retry.
- On Linux: check the node exists and you have access — ls -l /dev/video*, add user to the video group (sudo usermod -aG video $USER, re-login), and verify with v4l2-ctl --list-devices that you target a capture-capable node, not a metadata node.
- Verify the index/enumeration again right before start() (device may have disconnected after construction) and prefer selecting by device name.
- For packaging (Snap/Flatpak/Docker), grant camera device access or run outside the sandbox; in Docker map /dev/video* into the container.
- If all else fails, test the camera outside the app (e.g. cv2.VideoCapture(0) in a REPL, or cheese/guvcview) to isolate app vs system.
Example fix
# before
cap = VideoCapture(device_index=0)
if not cap.start():
pass # error swallowed, later frames fail confusingly
# after
cap = VideoCapture(device_index=0)
try:
cap.start()
except RuntimeError as e:
print(f"Camera unavailable: {e}; is another app using it?")
# fall back to a file source or exit cleanly Defensive patterns
Strategy: fallback
Validate before calling
# Linux: confirm the node exists, is capture-capable, and is readable/writable
import os, subprocess
node = f"/dev/video{device_index}"
if not os.path.exists(node):
raise SystemExit(f"{node} does not exist; list nodes with: v4l2-ctl --list-devices")
if not os.access(node, os.R_OK | os.W_OK):
raise SystemExit(f"No permission on {node}; add user to 'video' group and re-login") Try / catch
try:
cap.start()
except RuntimeError as e:
if "Failed to open camera" in str(e):
# device busy/absent: retry once after releasing, else fall back to file input
cap = None
source = fallback_video_path # e.g. a recorded clip for testing
else:
raise Prevention
- Always call cap.release()/destroy the object on shutdown so the camera isn't left held.
- Close other apps using the webcam (meetings, OBS, browser tabs) before starting capture.
- On Linux, target the capture-capable /dev/video node (v4l2-ctl --list-devices) — UVC cameras expose several nodes.
- Grant device access in sandboxed packaging (Snap/Flatpak/Docker --device).
- Disable USB autosuspend for external webcams that drop out intermittently.
When it happens
Trigger: Device already occupied by another process (Zoom/OBS/browser using the webcam, or a previous run that didn't release()); on Linux, /dev/videoN missing (wrong index — many cameras register multiple /dev/video nodes and only some capture), udev permission denied (user not in the video group), or the camera is a metadata-only node; on Windows, DSHOW/MSMF backend mismatch with the driver; headless machines with no camera at all; passing a device_index that passed construction-time checks but went invalid before start().
Common situations: Linux permission issues (no rw on /dev/video*); index confusion from multiple /dev/video nodes per UVC camera; another app holding the camera exclusively; camera suspended by USB autosuspend; Snap/Flatpak packaging lacking device access; CI/headless runs where /dev/video doesn't exist.
Related errors
- Invalid device index {device_index}. Available devices: {len
- embeddings must not be empty
- max_k must be at least 1
- {NAME}: Model not found at {model_path}
- {NAME}: Failed to load GFPGAN ONNX model: {e}
AI-assisted analysis of hacksider/Deep-Live-Cam@987f6b392b (2026-08-14).
Data as JSON: /api/errors/5da95bdffd605572.
Report an issue: GitHub.