Fake virtual backgrounds for your online meeting on Linux

I’ve been attending a lot of video conference calls lately — like so many of us.
Others had nice-looking virtual backgrounds. But there was no option to create those backgrounds on my Linux machine.

For example, the Zoom version for Linux only allows me to “touch up my appearance”. But there is no option to set a virtual background.

Luckily, I am not the only one with this problem.

In this blog post I’ll show you how to create a fake virtual background for your web cam using Docker (docker-compose) and akvcam.

Using this setup, you can use fake backgrounds with Google Chrome (e.g., Jitsi) or stand-alone applications like Zoom.

This article mirrors the Github repository for Linux-Fake-Background-Webcam. Some steps from the README were unclear to me. That’s why I listed the steps here.

In this article, we will do the following:

  1. Create a virtual camera
  2. Setup Docker-Compose to use the virtual camera
  3. Use the fake virtual background with Zoom or Chromium-based browsers

Install akvcam & Linux-Fake-Background-Webcam

akvcam is a virtual camera driver for Linux.

  1. On Arch Linux/Manjaro Linux, install akvcam with yay or a different AUR helper:

    yay -S akvcam-dkms
    

    It seems that no pre-build images are available for Ubuntu, so you’ll need to follow the akvcam wiki.

    We need a driver to create a virtual camera.
    I prefer akvcam over the v4l2loopback-dkms driver as it works with Chrome/Chromium, too.
    akvcam works with browser-based video conferencing software like Jitsi or Wonder.me.

  2. Clone the Linux-Fake-Background-Webcam repository to your local machine.

    Example commands using the terminal:

    git clone https://github.com/fangfufu/Linux-Fake-Background-Webcam.git
    cd Linux-Fake-Background-Webcam
    
  3. Create a virtual camera.

    Check for known video ports before loading the akvcam driver:

    ls /dev/video*
    

    Configure and load the driver:

    sudo cp -r fakecam/akvcam /etc/
    sudo modprobe videodev
    

    You should now see additional video ports:

    ls /dev/video*
    

    Alternative command with example output:

    v4l2-ctl --list-devices
    >
    akvcam (out) (platform:akvcam-2): /dev/video2
    akvcam (platform:akvcam-3): /dev/video3
    
    HD User Facing: HD User Facing (usb-0000:00:14.0-5):
    /dev/video0
    /dev/video1
    /dev/media0
    

    The virtual camera is available as /dev/video2 output.
    dev/video0, dev/video1 and dev/media0 are the hardware ports.

  4. Docker and Docker-Compose Setup

    The repository has an example docker-compose.yml file that uses the v4l2loopback driver. We can fix that manually.

    First, copy the environment file:

    cp docker_defaults.env .env
    

    You can change user settings in the .env file.
    For example, I downloaded a living room image from unsplash and copied it to the fakecam folder as fake-living-room.jpg.

    Example settings in .env:

    # change images using a volume mapping
    IMAGE_BACKGROUND=./fakecam/fake-living-room.jpg
    

    Important: The video input device must be your HD User Facing camera, the output device must be the akvcam (out) camera. The default settings (see below) should normally work.
    But check them again with v4l2-ctl --list-devices.
    After a reboot, my devices “switched places” and the whole setup broke.

    # change the device mappings if you are using diffent devices
    VIDEO_INPUT=/dev/video0 # this needs to be your hardware camera
    VIDEO_OUTPUT=/dev/video2 # this is the akvcam (out) channel
    

    Adjust docker-compose.yml. We need to adjust the command section for the fakecam service (at the end of the file):

        # command: ["--bodypix-url", "http://bodypix:9000/",
        #           "-b", "background-custom", "-f", "foreground-custom" , "-m", "foreground-mask-custom",
        #           "--webcam-path", "/dev/video0", "--v4l2loopback-path", "/dev/video2"]
        command: ["--bodypix-url", "http://bodypix:9000/",
                  "-b", "background-custom",
                  "--webcam-path", "/dev/video0", "--akvcam"]
    

    The changes instruct Docker to use the akvcam driver and removes the foreground image. If you want to use the image (a fake podium), you can keep that part from the original command.

    The hardware camera uses /dev/video0 as input. If your hardware port is different, don’t forget to change it!

    Adjust the Dockerfile in fakecam/Dockerfile. I removed the images as we load them via docker-compose:

    FROM python:3.8
    
    RUN apt-get update && \
        apt-get install -y --no-install-recommends \
          python3-numpy \
          python3-opencv \
          python3-requests \
          && rm -rf /var/cache/apt/* /var/lib/apt/lists/*
    
    WORKDIR /src
    
    COPY fake.py \
        akvcam.py \
        requirements.txt \
        /src/
    
    RUN pip3 install --no-cache-dir -r requirements.txt
    
    ENTRYPOINT ["python3", "-u", "fake.py"]
    CMD ["--bodypix-url", "http://bodypix:9000/"]
    
  5. Run the service with docker-compose:

    docker-compose up --build
    

    Or, if you want to run the service in the background:

    docker-compose up --build -d
    
  6. Use the virtual camera.

You can now open a video conferencing application and select akvcam as your video device.