Reputation: 366
(I hope posting an answer to own question is not against TOS here, I made it because I discovered the solution while writing this post, and extensive googling didn't help, so I hope I can help some people looking for solution.)
Problem: Google chrome / chromium doesn't open v4l2loopback virtual camera device (won't access it) and report "No camera available", even if it is listed and selected in settings page sometimes.
Observed cause of problem: (noticed when using OBS Cam Studio) Google chrome / chromium WILL NOT access (open) virtual camera device if it finds real camera device being in use (busy).
Upvotes: 17
Views: 12029
Reputation: 1
For me, just sudo modprobe -r v4l2loopback
did the trick. Now I can see the virtual webcam. Only, it asks for the root password when you start from OBS.
One downside is that it is not permanent, so you need to remember how to do it next time.
Upvotes: 0
Reputation: 366
Solution (short version):
ls /dev/video*
, connect it, and try ls /dev/video*
again to see which devices appeared (in my case it's /dev/video0
and /dev/video1
) - in most cases it will be /dev/video0
sudo chmod 000 /dev/video0
sudo chmod 000 /dev/video1
(use the device names that you discovered your physical webcam is)
sudo chmod 660 /dev/video0
sudo chmod 660 /dev/video1
Solution (long version): Description, step by step, how to make OBS Cam Studio virtual output be visible in google chrome/chromium.
sudo modprobe -r v4l2loopback
(you need to stop any virual camera feed and stop application that uses virtual cam, otherwise you will get modprobe: FATAL: Module v4l2loopback is in use.
error)
sudo modprobe v4l2loopback devices=1 video_nr=21 exclusive_caps=1 card_label="Virtual Webcam"
(this command will create one loopback device with name /dev/video21
and name (caption) "Virtual Webcam")
simpler version of the command, that really matters:
sudo modprobe v4l2loopback exclusive_caps=1
sudo chmod 000 /dev/video0
sudo chmod 000 /dev/video1
(device names may be different in your case and there may be just one of them) (if you have no sudo access and your camera is pluggable you can just unplug it)
sudo chmod 660 /dev/video0
sudo chmod 660 /dev/video1
(in case you unplugged the webcam plug it back and (possibly) reopen it in your program)
I hope it helps as I struggled for a long time with no effect to make google chrome open virtual webcam in OBS Cam Studio.
Edited: Found working solution that is based on similar principle, it's here: https://www.scs.stanford.edu/~dm/blog/hide-webcam.html It hides physical webcam from the list of visible webcams, so you need to enter the path to it manually or in the config settings of the program.
Upvotes: 7
Reputation: 1912
Forbid chromium from accessing any actual video cameras.
firejail --blacklist=/dev/video{0,1} chromium
If you already have v4l2loopback and ffmpeg figured out, then that is all you need to get it working with Chromium.
sudo modprobe v4l2loopback exclusive_caps=1 \
max_width=4096 max_height=4096 \
video_nr=42 \
card_label="Oovideo Metamorphoses"
ffmpeg -f x11grab -i ${DISPLAY} \
-vcodec rawvideo -pix_fmt yuv420p \
-f v4l2 /dev/video42
firejail --blacklist=/dev/video? chromium
Google's Chromium browser — which is the basis for Google Chrome — has trouble opening virtual cameras. (Note: Mozilla Firefox works fine.)
Chromium refuses to open any device that can do anything but CAPTURE video. Of course, a virtual camera can also be opened by a video producer, such as ffmpeg, as OUTPUT. The workaround is to have the kernel module lie to Chromium.
By setting the exclusive_caps=1
option when loading the vl42loopback module, the device will announce that it has only CAPTURE capabilities once a producer has started writing to it. This is enough to appease Chromium.
If Chromium is able open any physical camera attached to the system, it gives no option to switch to the virtual camera. The solution is to refuse Chromium access to actual cameras. That is what firejail
does for us.
The software you'll need is the v4l2loopback kernel module, ffmpeg, and firejail. Most systems have these pre-packaged. For example, on a Debian GNU/Linux system, you'd type:
sudo apt install v4l2loopback-{dkms,utils} ffmpeg firejail
Load the v4l2loopback kernel module by running this from the command line:
sudo modprobe v4l2loopback exclusive_caps=1 \
max_width=4096 max_height=4096 \
video_nr=42 \
card_label="Oovideo Metamorphoses"
That command creates a pseudo device named /dev/video42
.
The exclusive_caps=1
parameter is the fix for Chromium.
The max_height
and _width
parameters are needed by websites opening your camera. They just need to be larger than any screen you'll be sharing.
The custom video_nr
is so that we'll know exactly where to send the output for ffmpeg in the next step.
The card_label
is optional, but without it websites will see the name of your webcam as "Dummy video device (0x0000)".
Note: This modprobe
step will need to be repeated if the system reboots, so consider adding v4l2loopback and its parameters to /etc/modules
to make it load at boot time.
Start an ffmpeg
process grabbing the screen and writing it to /dev/video42
.
ffmpeg -f x11grab -i ${DISPLAY} \
-vcodec rawvideo -pix_fmt yuv420p \
-f v4l2 /dev/video42
That command captures your entire screen at 30fps. It will keep working until you cancel ffmpeg by pressing Ctrl+C. You can test if it is working using ffplay /dev/video42
.
To adjust the frames per second and region being captured you can use a command like this:
ffmpeg -framerate 15 -f x11grab \
-video_size 1280x720 -i ${DISPLAY}+200,300 \
-vcodec rawvideo -pix_fmt yuv420p \
-f v4l2 /dev/video42
The example above captures at 15fps a 1280x720 rectangle with the upper left hand corner at screen coordinate (200, 300).
Finally, start chromium
(or google-chrome
) within a Firejail that forbids access actual video cameras:
firejail --blacklist=/dev/video? chromium
The ?
in the above command is a filename wildcard that matches any single character. In this case, we use it to match /dev/video0, /dev/video1, …, /dev/video9, which should hopefully cover every physical webcam. Of course, /dev/video42 has two digits,so it will be accessible to the browser and our virtual camera will be used.
Please comment below if you have suggestions for how this answer could be better.
Upvotes: 3