Hassleless Droidcam v4l2loopback Config

Description

I have DroidCam and v4l2loopback installed and I can use them. However, each reboot requires that I run nix-shell -p linuxKernel.packages.linux_latest_libre.v4l2loopback, then v4l2loopback-ctl set-caps /dev/video<n> "YU12:<width>x<height>" in order for DroidCam not not fail to launch with the bellow error:

Fatal: droidcam video device reported pixel format 34524742 (BGR4), expected 32315559 (YU12/I420)
Try 'v4l2loopback-ctl set-caps "video/x-raw, format=I420, width=640, height=480" /dev/video<N>'

Goal(s)

  1. Not have to run v4l2loopback-ctl after each reboot (this is the primary goal).
  2. Install v4l2loopback-ctl via my configuration so I don’t have to use nix-shell each time I would like to change resolution of a loopback device.

My Setup

{ config, ... }: {
  # TODO: Get install of v4l2loopback-ctl working.
  environment.systemPackages = with config.boot.kernelPackages; [
    v4l2loopback <--_______________________________________________________ 
  ];              / Everything works the same without this. I only added    \
                  | this in an attempt to install v4l2loopback. It didn't   |
                  | work even though v4l2loopback in Nix packages says it   |
                  | includes it. Note that config.boot.kernelPackages is    |
                  | used so I get the same version as my kernel.            |
                  | Specifying pkgs.linuxKernel.packages.linux_latest_libre |
                  | also behaves the same.                                  |
  boot = {        \_________________________________________________________/
    # Make v4l2loopback kernel module available to NixOS.
    extraModulePackages = with config.boot.kernelPackages; [
      v4l2loopback
    ];
    # Activate kernel modules.
    kernelModules = [
      # Virtual camera.
      "v4l2loopback"
      # Virtual microphone, built-in.
#     "snd-aloop" <-- Not worried about getting this working right now.
    ];
    # Set initial kernel module settings.
    extraModprobeConfig = ''
      options v4l2loopback video_nr=2,3 width=640,1920 max_width=1920 height=480,1080 max_height=1080 format=YU12,YU12 exclusive_caps=1,1 card_label=Phone,Laptop debug=1
    '';                        ^          ^               ^              ^                ^              ^                    ^                ^                    ^
  };                           |          |               |              |                |              |                    |                |                    |
}                            Works,       ?,            Works,           ?,             Works,           ?,                 Works,           Works,               Works

What Works

I’ve confirmed that the bellow options set by boot.extraModprobeConfig work by checking the values in /sys/module/v4l2loopback/parameters/*, then changing the values and rebooting:

  • video_nr
  • max_width
  • max_height
  • exclusive_caps
  • debug

I’ve confirmed that card_label works through just using them and seeing those labels show up.

What Doesn’t Work

I have to manually set format and resolution of each virtual device after each reboot.

Potential Solution(s)

Maybe I could make a systemd service that configures this. My issues with this are:

  • Given that boot.extraModprobeConfig exists, I’d like to use it to do this if possible.
  • I’ve never created a systemd service, so it would likely take a while.

Note(s)

I’ve seen this thread by @tobiasBora. That’s where I got the idea that a systemd service might be needed. I also tried un-loading v4l2loopback and re-loading it, but to no avail.

I’ve done my testing by rebooting after each change.

I haven’t attempted to use DroidCam’s v4l2loopback-dc version because I’d like to figure this out first.

I’m using flakes, and Home Manager as a NixOS module. However, everything related to this, other than installing DroidCam, has been done via NixOS not Home Manager. I’ve tried switching over to using NixOS to install DroidCam, but it didn’t change anything.

Here is my config and this is the file that deals with v4l2loopback.

1 Like

You may want to look at v4l2 relayd options

1 Like

So v4l2-relayd connects a Gstreamer video source to v4l2loopback device. I presume this would mean I would need to setup a Gstreamer pipeline that accepted input from DroidCam (I don’t really understand what I just said)?