Using v4l2loopback virtual cam with google-chrome or chromium on linux while having real webcam in use
Asked Answered
T

3

15

(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).

Teague answered 18/7, 2021 at 22:6 Comment(3)
Thank you for posting the answer! I was going crazy here :-)Lumenhour
Just using sudo modprobe v4l2loopback exclusive_caps=1 with exclusive_caps=1 did the trick for me. No further magic needed.Launalaunce
A quick tip if exclusive_caps=1 doesn't seem to fix it: If you already loaded the module once before issuing this flag, you need to unload the module first with sudo modprobe -r v4l2loopback. Otherwise the new command wont have an effect.Teran
T
6

Solution (short version):

  • find out which device your physical webcam is (it may be multiple devices) if your camera is pluggable you can disconnect it, then observe the result of 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
  • start your capturing program (the one that uses physical webcam and outputs to virtual camera) and make it output to virtual camera (virtual camera has to be fed with input to be opened by chrome)
  • disable access to physical webcam, which (in my case) can be done with:
sudo chmod 000 /dev/video0
sudo chmod 000 /dev/video1

(use the device names that you discovered your physical webcam is)

  • start the video capture in google chrome/chromium (by opening the webpage or pressing some sort of "Start webcam", it depends on the webpage)
  • you should see virtual camera feed in chrome now
  • enable access to physical webcam back, done (in my case) with:
sudo chmod 660 /dev/video0
sudo chmod 660 /dev/video1
  • and done! have fun camming on the web!

Solution (long version): Description, step by step, how to make OBS Cam Studio virtual output be visible in google chrome/chromium.

  • if you didn't do it yet, unload v4l2loopback module (do it if you weren't aware of "exclusive_caps" parameter):
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)

  • load v4l2loopback module (only "exclusive_caps" parameter matters):
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
  • start video capture program that uses your physical webcam and outputs to virtual webcam device (in my case it's OBS Cam Studio) - physical webcam should be busy (in use) now and virtual webcam should be fed input (important)
  • disable physical webcam devices access by (in my case):
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)

  • start using webcam with google chrome or chromium (enter the web page and open the webcam on it, for example by button "Use my webcam" on the web page - it is different from page to page)
  • you should see the virtual webcam feed now (if not, click the camera icon on the right of address bar, click "Manage" and select your virtual webcam by name in settings, make web page use webcam again)
  • enable physical webcam devices access back by (in my case):
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)

  • enjoy virtual webcam in chrome!

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.

Teague answered 18/7, 2021 at 22:8 Comment(1)
You need to add answer here. not just acknowledgmentMccarthy
C
2

Terse Answer: firejail

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.


Brief Answer: v4l2loopback, ffmpeg, and firejail

  1. sudo modprobe v4l2loopback exclusive_caps=1 \
                               max_width=4096 max_height=4096 \
                               video_nr=42 \
                               card_label="Oovideo Metamorphoses"
    
  2. ffmpeg -f x11grab -i ${DISPLAY} \
           -vcodec rawvideo -pix_fmt yuv420p \
           -f v4l2 /dev/video42
    
  3. firejail --blacklist=/dev/video? chromium
    

Verbose explanation

What causes the problem

Google's Chromium browser — which is the basis for Google Chrome — has trouble opening virtual cameras. (Note: Mozilla Firefox works fine.)

Issue #1: OUTPUT & CAPTURE capabilities

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.

Issue #2: Getting hung up on /dev/video0

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.

Necessary Software

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

Steps with garrulous explanation

  1. 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.

  2. 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).

  3. 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.

That's all

Please comment below if you have suggestions for how this answer could be better.

Canzona answered 19/7, 2023 at 20:22 Comment(4)
I try to use webcam inside a docker container. i do all the steps as you said. but the chrome wont be able to see my virtual webcam while firefox detect it like a charm. could you give me any other guide to fix my solution?Cassandra
@Cassandra I'm afraid docker is beyond the scope of this question and I do not know why my answer would not work.Canzona
I finally solved it. it was because i created several virtual device and v4l2loopback exclusive_caps=1 only work on one of the virtual devices. Thank youCassandra
I'm glad you got it solved. Let me know if you have any suggestions for how I can improve my answer to be helpful to others.Canzona
A
0

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.

Ahearn answered 24/11, 2023 at 8:27 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.