I recently had to attend an online meeting for a software development event. While my PC did have a decent microphone, the built-in camera has been damaged to the extent that the best it can capture is this:
No, it’s not a close-up of the moon, it’s the refraction caused by the scuffs to the lens plus other sciency stuff I’m not qualified enough to explain to you.
I was aware that one can use ADB to use an Android phone’s camera as a makeshift webcam. Since I would need this ability for any future meetings as well, it was worth having the functionality packaged into a one click tool.
Enter NixOS. I have praised NixOS before and I’ll do it again because of the sheer ease with which it allows me to create desktop entries for small scripts. This is going to be relevant later but I’m going to assume that you’re running NixOS with home-manager enabled if you’re following along. First we have to enable developer mode and USB debugging on our phone.
To interact with our phone, we will need adb
and scrcpy
as dependencies.
If you have enabled flakes run the following:
nix shell nixpkgs#scrcpy nixpkgs#android-tools
If you don’t have flakes enabled, run the following:
nix-shell -p scrcpy android-tools
Next, we connect our phone to our PC with a cable (or through ADB TCP/IP) and list all the cameras by running the following:
scrcpy --list-cameras
You must allow any prompt on your phone requesting access to it from the computer, after which, you should see an output like the following:
[server] INFO: List of cameras:
--camera-id=0 (back, 4608x3456, fps=[10, 15, 24, 30])
--camera-id=1 (front, 2304x1728, fps=[15, 24, 30])
--camera-id=2 (back, 3264x2448, fps=[15, 24, 30])
--camera-id=3 (back, 1600x1200, fps=[15, 24, 30])
--camera-id=4 (back, 1600x1200, fps=[15, 24, 30])
--camera-id=5 (back, 4608x3456, fps=[10, 15, 24, 30])
--camera-id=6 (back, 4608x3456, fps=[10, 15, 24, 30])
--camera-id=7 (back, 4608x3456, fps=[10, 15, 24, 30])
Note down the number associated with the camera you want to use. Alternatively, you can also note whether the camera you wish to use is the front or the back camera.
Add the following to your configuration.nix
:
boot = {
kernelModules = [ "v4l2loopback" ];
extraModulePackages = [ pkgs.linuxPackages.v4l2loopback ];
extraModprobeConfig = ''
options v4l2loopback exclusive_caps=1 card_label="Virtual Webcam"
'';
};
This enables the v4l2loopback
kernel module to create a dummy video interface which allows us to route any video to this virtual camera.
In the extra options for this module, we have to add exclusive_caps=1
to make sure that the virtual camera exclusively announces itself as an output device.
This is important for compatibility with services like Zoom and Google Meet.
In the home-manager config for your user add the following:
home.xdg.desktopEntries.andcam = {
name = "Android Virtual Camera";
exec = "${pkgs.writeScript "andcam" ''
${pkgs.android-tools}/bin/adb start-server
${pkgs.scrcpy}/bin/scrcpy --camera-facing=back --video-source=camera --no-audio --v4l2-sink=/dev/video0 -m1024
''}";
};
This creates a desktop entry with the name “Android Virtual Camera” and runs
the script in the exec
field.
Here’s a breakdown of the script:
- The first line starts an ADB server required for
scrcpy
to pick up our device. - The second line runs
scrcpy
to pass the phone’s camera to the dummy virtual camera spawned by thev4l2loopback
kernel module.
We can use a named camera with the --camera-facing
flag as I did here for
the back camera using --camera-facing=back
. If you noted a camera ID eariler,
you can replace the --camera-facing=back
with --camera-id=
followed by the
identifying number.
For example, if you were to use the camera with the ID 0, you would add the following instead:
home.xdg.desktopEntries.andcam = {
name = "Android Virtual Camera";
exec = "${pkgs.writeScript "andcam" ''
${pkgs.android-tools}/bin/adb start-server
${pkgs.scrcpy}/bin/scrcpy --camera-id=0 --video-source=camera --no-audio --v4l2-sink=/dev/video0 -m1024
''}";
};
Now rebuild your system and reboot.
That’s it! Connect your phone to your PC and run on the “Android Virtual Camera” menu entry.
I was impressed that this has been possible on Linux since 2018 while Microsoft is introducing this feature now to Windows 11.
Remember kids, what Windows can be tomorrow, Linux is today. That’s all for now, see you around!