Guide: Play a video or show a static image over a dummy webcam (no OBS needed)

This guide is for Ubuntu 22.x/23.x but it should work for Debian and Fedora with no or minor adjustment.

There seems to be a lot of information out there for this but none of the guides worked quite right for me and there’s not a lot of information on streaming a static image so I wrote this guide.

Install the v4l2loopback driver, utils and ffmpeg

# Debian/Ubuntu
sudo apt install v4l2loopback-dkms v4l2loopback-utils ffmpeg

# Fedora
sudo dnf install v4l2loopback v4l2loopback-utils ffmpeg

Prepare OS and test

# Give the current user group permissions to read from /dev/video* files
sudo usermod -aG video $USER

# Unload the v4l2loopback driver if it's loaded
sudo modprobe -r v4l2loopback

# Load the v4l2loopback driver with the exclusive_caps option
# Note: exclusive_caps=1 is necessary for some Chromium/WebRTC based applications like Jitsi or Zoom
sudo modprobe v4l2loopback exclusive_caps=1

# Test if the video device is visible
ls /dev/video*
ls -1 /sys/devices/virtual/video4linux
v4l2-ctl -d /dev/video0 -l

Play video

ffmpeg -re -i 'YOUR_VIDEO_HERE.mp4' -map 0:v -f v4l2 /dev/video0

# Test if you can see it playing
ffplay -f v4l2 /dev/video0

Play a static image

Note: Smaller sizes can work but you want a 640x420 image for best compatibility with yuv420p.
Note: Don’t use “-loop 1” in place of “-stream_loop -1” or it’ll loop as fast as your hardware allows even if framerate and fps are capped

ffmpeg -stream_loop -1 -i 'YOUR_IMAGE_HERE.png' -vf 'fps=0.07,format=yuv420p' -f v4l2 /dev/video0

# Test if you can see it playing
ffplay -f v4l2 /dev/video0

Getting the dummy webcam back after reboot

Note: “sudo modprobe -r v4l2loopback” is optional but it’s useful for removing the driver if it’s already loaded and something is buggy.

sudo modprobe -r v4l2loopback
sudo modprobe v4l2loopback exclusive_caps=1

Caveats

From my experience, browser tabs that ask for a webcam need to be reloaded if the dummy cam is started or restarted. I’m not sure about applications. So you want everything running before you open the tab that’ll ask for your webcam.

I’ve been able to stop ffmpeg and run a different ffmpeg command while the dummy cam was in use by jitsi or zoom but if I waited more than a few seconds between commands the webcam would show an error and the tab would need to be reloaded to see the webcam again.

1 Like

Bonus: Wrapping it into one script


Unloads and loads the v4l2loopback driver with a dummy cam named “CUSTOM_NAME” , streams the image: “/PATH/TO/MY_IMAGE.png”, then removes the driver if ffmpeg is ended with ctrl+c.

#!/usr/bin/env bash
printf '%s\n' 'Unloading v4l2loopback...'
sudo modprobe -r v4l2loopback

printf '%s\n' 'Loading v4l2loopback...'
sudo modprobe v4l2loopback \
	exclusive_caps=1 \
	card_label='CUSTOM_NAME'

printf '%s\n' 'Streaming image...'
ffmpeg \
	-stream_loop -1 \
	-i '/PATH/TO/MY_IMAGE.png' \
	-vf 'fps=0.07,format=yuv420p' \
	-f v4l2 \
	/dev/video0

printf '%s\n' 'Unloading v4l2loopback...'
sudo modprobe -r v4l2loopback