Webcamize fails to detect or initialize existing v4l2loopback virtual devices
Describe the bug
webcamize fails to initialize the V4L2 device because the system does not automatically create or connect to any virtual devices
Terminal Output
webcamize: [WARN] Failed to open v4l2loopback control device, attempting to load kernel module: No such file or directory
webcamize: [WARN] Failed to open v4l2loopback control device after insertion: No such file or directory
webcamize: [FATL] Failed to initialize V4L2 device
Expected behavior
webcamize should detect and use any existing v4l2loopback device automatically, without relying on the system to create a specific virtual device
Desktop:
- Distro and Version:
Linux Mint 22.2 (Zara) - Camera/Device:
Sony ILCE-6500 - Webcamize version:
2.0.1
gphoto2 Information
- Output from
gphoto2 --summary
Manufacturer: Sony Corporation
Model: ILCE-6500
- Output from
gphoto2 --autodetect
Sony Alpha-A6500 (Control) usb:001,019
What I Tried
The system did not create any virtual V4L2 devices automatically.
To test, I manually created a virtual device using sudo modprobe v4l2loopback video_nr=10 card_label="Webcamize Virtual Cam". Ran webcamize again, but the same initialization error occurred.
When running with -b / --no-v4l2loopback to disable module loading and configuration:
webcamize: [WARN] Failed to open V4L2 device /dev/video-1: No such file or directory
webcamize: [FATL] Failed to initialize V4L2 device
All commands were executed with sudo.
Can you give me the output with debugging enabled? It's the -lDEBUG flag
webcamize -l DEBUG
webcamize: [DBUG] Using camera: Sony Alpha-A6500 (Control)
webcamize: [WARN] Failed to open v4l2loopback control device, attempting to load kernel module: No such file or directory
webcamize: [DBUG] The v4l2loopback module is present
webcamize: [WARN] Failed to open v4l2loopback control device: No such file or directory
webcamize: [FATL] Failed to initialize V4L2 device
webcamize: [DBUG] Cleaning up ffmpeg...
webcamize: [DBUG] Cleaning up gphoto2...
webcamize: [DBUG] Exiting, final ret = -1
Does /dev/v4l2loopback exist?
On this distro, /dev/v4l2loopback does not exist by default. The v4l2loopback kernel module is not loaded, so the virtual device isn’t present
ls -l /dev/v4l2loopback
ls: cannot access '/dev/v4l2loopback': No such file or directory
Same distro, same camera, exactly the same issue on my part.
I have set up /dev/video0 manually following Gemini and rebooted. Then loaded v4l2loopback manually and checked that it was loaded.
dmesg | grep v4l2loopback
[ 4.803581] v4l2loopback driver version 0.12.7 loaded
Then tried sudo ./webcamize again. It is giving me the same error.
Gemini's conclusion (I am not intending to say that it is correct) is that it is linked to Secure Boot and DKMS.
Here is a WORKAROUND (Gemini) for those who are affected by this bug.
Note, this workaround does not involve webcamize.
The thing that made the difference was loading the v4l2loopback module with additional parameters
sudo modprobe v4l2loopback exclusive_caps=1 card_label="VirtualDSLR"
instead of simply
sudo modprobe v4l2loopback
UPDATE This is NOT webcamize related. For some reason Chromium and Brave don't seem to pick up the DSLR-webcam reliably. At this stage I cannot tell why Brave and Chromium only see the DSLR-webcam sporadically. On the other hand, it seems to be working absolutely reliably in FF. After booting, I simply need to turn on my DSLR, then run
gphoto2 --stdout --capture-movie | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -f v4l2 /dev/video0,
and then start FF, and the camera is working as a webcam.
@godfatherjohn I'm not able to see anything at the link you've posted, would you mind explaining it here?
The link should take you to a page on which Gemini produces the "answer". I have tried it in incognito mode and it is working. Is JS blocked in your browser?
I have also added the 'deciding piece of the puzzle' and attached a screenshot of the full Gemini output. I don't know whether that is of any help for you, since webcamize is not involved. If you need anything, give me a shout.
Hey @cowtoolz ! Thank you for responding and working on this problem!
As a temporary workaround I made myself a small script that sets up v4l2loopback and streams the camera into it:
#!/usr/bin/env bash
sudo modprobe -r v4l2loopback
sudo modprobe v4l2loopback video_nr=10 card_label="Virtual Cam" exclusive_caps=1
gphoto2 --capture-movie --stdout | ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -f v4l2 /dev/video10
I tried to make it more complex (e.g. waiting for the camera to be connected, adding retries, etc.), but in the end this minimal version works for me, as long as the camera is already plugged in via USB and set to auto or movie mode.
I also analyzed your C code and represented the flow as a Mermaid diagram:
flowchart TD
A[Start] --> B[Parse CLI arguments]
B -->|--version/-v| C[Print version and exit]
B -->|--help/-h| D[Print usage and exit]
B -->|--status/-s| E[Print status and exit]
B --> F[Initialize signal handler]
F --> G[Initialize gPhoto2 context]
G --> H[Create camera object]
H --> I[Autodetect cameras]
I --> J{Camera specified?}
J -->|Yes| K[Lookup camera abilities and port info]
J -->|No| L[Use first detected camera]
K --> M[Set camera abilities and port info]
L --> M
M --> N[Initialize camera]
N --> O[Create CameraFile object]
O --> P{OS_LINUX and v4l2loopback enabled?}
P -->|Yes| Q[Initialize V4L2 device]
P -->|No| R[Skip V4L2 initialization]
Q --> R
R --> S{no_convert?}
S -->|No| T[Allocate FFmpeg frames and setup decoder]
S -->|Yes| U[Skip FFmpeg conversion]
T --> V[Main loop: capture preview]
U --> V
V --> W[Get image data from camera]
W --> X{no_convert?}
X -->|No| Y[Convert image using FFmpeg to YUYV]
X -->|Yes| Z[Use original image data]
Y --> AA{file_sink?}
Z --> AA
AA -->|Yes| AB[Write to file sink]
AA -->|No| AC{OS_LINUX and v4l2_fd > 0?}
AC -->|Yes| AD[Setup V4L2 format if needed and write to device]
AC -->|No| AE[Skip V4L2 write]
AD --> AF[End of loop: sleep to maintain target FPS]
AE --> AF
AF --> V
V -->|alive=false| AG[Cleanup resources]
AG --> AH[Close file sinks]
AG --> AI[Cleanup V4L2 devices]
AG --> AJ[Cleanup FFmpeg resources]
AG --> AK[Cleanup gPhoto2 resources]
AK --> AL[Exit]
According to this scheme, the critical moment is when the program tries to initialize the V4L2 device. If /dev/videoX from v4l2loopback does not already exist, initialization fails.
One idea that comes to mind is to simply try to load the v4l2loopback kernel module if it’s missing. However, this requires root privileges (modprobe), and the device node /dev/videoX only appears after the module is loaded.
In a shell script, it would be possible to catch this situation and print a friendly message like "Sorry, no v4l2loopback device found, you need root to create it using modprobe…", which would be safe and clear. But in a compiled C binary, it’s not so straightforward to do this elegantly. A normal user process cannot create kernel modules or device nodes on its own, and trying to do so automatically from the binary would go beyond normal user privileges and is not ideal from a security standpoint.
One pragmatic option is to ask the user to run a small bash command once to create the virtual device (or install it as a systemd unit so it only needs to be done once). For example, a minimal manual flow is:
# load v4l2loopback and create /dev/video10
sudo modprobe v4l2loopback video_nr=10 card_label="Virtual Cam" exclusive_caps=1
and
# /etc/systemd/system/v4l2loopback.service
[Unit]
Description=Load v4l2loopback module
[Service]
Type=oneshot
ExecStart=/sbin/modprobe v4l2loopback video_nr=10 card_label="Virtual Cam" exclusive_caps=1
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
The downside is obvious: asking the user to run sudo modprobe or to enable a systemd unit is an extra step and can be a friction point for someone who just wants to download the binary and try it immediately.
@cowtoolz what do you think?