I don’t own a camera that is compatible with my system and I’m not interesting in purchasing a bunch of webcams to test their quality when I’m already satisfied with image quality provided by my phone. It would be neat if I could use my phone as a substitute for a webcam which led to the creation of this setup.

Also some applications don’t support desktop capture or have limited options when it comes to capturing specific windows but do support capturing a connected camera. By augmenting the above setup with Open broadcast studio (OBS) I’m able to provide a richer experience than previously allowed.

My Devices: Arch Linux 5.5.10, Pixel 3a (Android 10)

Requirements

A Linux system and Android device that has a camera.

If you only want to use your phone as a webcam then simply follow Android Device Bridge, IPCamera, GStreamer, v4l2loopback sections and skip to the execution section.

Android Device Bridge

Android Device Bridge

Install adb which is required for rerouting network requests over USB. Your distribution should supply this. For Arch it is supplied by android-tools

IPCamera

Install IPCamera on your android device and configure it.

My configuration:

Optional permissions --> Allow streaming in background: Enabled
Video Preferences --> Video resolution: 1920x1080
                      Photo resolution: 1920x1080
                      Quality: 100
                      Fps Limit: 30
                      Video  Recording --> Video bitrate: 12000 kbits/s

Tweak your configuration to fit your device’s specifications.

GStreamer

GStreamer

Your distribution should supply this but may split different modules into different packages. We want the base installation and good plugins. For Arch these are supplied by ‘gst-plugins-base’ and ‘gst-plugins-good’.

Augmenting your stream with obs assumes that computer supports the Video Acceleration API to decode the video feed provided by OBS. In particular VA-API is used and requires an additional gstreamer dependency called gstreamer-vaapi. In my case, my cpu is a Ryzen 2400G which supports hardware acceleration through the amdgpu module.

Hardware Video acceleration

Gstreamer VA API

v4l2loopback

v4l2loopback

Follow the installation instructions provided at the repository. Depending on your Linux distribution this kernel module may be available by your package manager. For Arch Linux it is available from the AUR under v4l2loopback-dkms-git

v4l2loopback creates devices located at /dev prefixed by video and ending with a number. Depending on your distribution you may require write permissions for the deivce. For Arch these devices are owned by root and group video. Run the following the command to grant write access for these devices and exit your current login session and relogin to ensure that you are a member of the group.

sudo usermod -a -G video $(whoami)

To test if your installation is successful try running the following commands: Note the second command with begin a shell job in the background when successful be sure to terminate it.

sudo modprobe v4l2loopback exclusive_caps=1 
gst-launch-1.0 videotestsrc ! v4l2sink device=/dev/video0 & gst-launch-1.0 v4l2src device=/dev/video0 ! autovideoconvert ! autovideosink

Nginx

We require a endpoint that accepts RTMP that we control so we configure OBS to stream to this endpoint which will be directed to a v4l2loopback device.

I use the following fork of nginx which on Arch can be found on the user repository nginx-rtmp-sergey-git.

After installation, edit your nginx configuration (Located at /etc/nginx/nginx.conf) by adding the following

rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        application live {
             live on;
             record off;
             allow publish 127.0.0.1;
             deny publish all;
        }
    }
}

Restart nginx by executing

systemctl restart nginx

Open Broadcast System

Install Open broadcast System (obs) which on Arch is provided by obs-studio. If you use a compositor with wayland as the backend then you will have to do some extra work by compiling a fork that supports an EGL backend and an additional plugin. During my installation I also merged upstream version of OBS and the fork.

Test that OBS works and is able to capture your workspace by recording to a file and replaying it. If your installation is successful then modify the stream location.

Settings -> Stream -> Service: Custom
                      Server: rtmp://localhost:1935/live
                      Stream Key: video

Confirm that your local nginx installation functions by streaming to the local endpoint and view it on a video player on mpv you can run ‘mpv rtmp://localhost:19235/live’.

Execution

IPCam provides a script for forwarding an IPCam instance to a local v4l2loopback devices but the provided gstreamer pipeline attempts to reencode the MJPEG stream. This had a negative impact on performance for me so I modified the pipeline to avoid any reencoding. Download my fork here: ipwebcam-gst

Preprarion: Connect your phone to your computer by usb and that the usb mode is set to File transfer. Launch IPWebcam and start the video server.

In a terminal run the following command:

sudo modprobe v4l2loopback devices=2 exclusive_caps=1,1

then run prepare-videochat.sh

Your phone will now function as a webcam. There are multiple ways of testing if this worked. Try Cheese, Google hangouts, or Discord.

To enchance your webcam experience launch OBS and add a video capture device configured to use your phone and starting streaming to the local endpoint setup earlier. Then execute the forward-obs-stream.sh script from my fork. This will forward the stream provided by OBS into a v4l2loopback device.

Issues

Sometimes the pipeline for ‘forward-obs-stream’ will not preroll and hangs. Currently restarting the script is the best way to deal will this issue.