Linux 上的 v4l2loopback:安装、持久化与常见报错
Linux 本身没有虚拟摄像头。应用会打开 /dev/video0 这样的设备并从中读取画面帧,而内核默认它背后是真实的硬件。v4l2loopback 是一个内核模块,它创建的设备表现得像摄像头,但画面由软件写入。
它是 Linux 上一切虚拟摄像头方案的基础:OBS、ffmpeg 管道和 CamLooper 都是往回环设备里写数据。下面是正确的配置方法。
安装
请安装 DKMS 版本,这样内核每次更新时模块都会自动重新编译:
# Debian / Ubuntu
sudo apt install v4l2loopback-dkms
# Fedora / RHEL
sudo dnf install v4l2loopback
# Arch
sudo pacman -S v4l2loopback-dkms
DKMS 在这里很关键。没有它,模块只会针对你安装时的那个内核编译,等下一次内核更新之后,虚拟摄像头就会悄无声息地失效。
加载模块
sudo modprobe v4l2loopback
确认设备已经出现:
lsmod | grep v4l2loopback
ls -l /dev/video*
加载时几个有用的参数:
sudo modprobe v4l2loopback \
devices=1 \
video_nr=10 \
card_label="Virtual Camera" \
exclusive_caps=1
video_nr=10把设备固定为/dev/video10,避免和真实摄像头冲突card_label决定应用在摄像头列表里显示的名称exclusive_caps=1是最关键的一个:它让设备只在有内容写入时才声明自己具备采集能力。Chrome、Firefox 和一些 Electron 应用会忽略没有这个参数的回环设备——这正是为什么某个摄像头在v4l2-ctl里看得到,在浏览器里却没有
让它在重启后仍然存在
modprobe 的效果只持续到下次重启。两个文件可以让它永久生效:
# /etc/modules-load.d/v4l2loopback.conf
v4l2loopback
# /etc/modprobe.d/v4l2loopback.conf
options v4l2loopback devices=1 video_nr=10 card_label="Virtual Camera" exclusive_caps=1
前者负责开机加载模块,后者负责传入参数。很多人只写了前者,然后疑惑自己的参数怎么不见了。
不借助任何应用做测试
用 ffmpeg 把一个循环播放的视频推进设备:
ffmpeg -stream_loop -1 -re -i video.mp4 \
-f v4l2 -pix_fmt yuv420p /dev/video10
-re 让数据按实时速率推送(不加它,ffmpeg 会以最快速度写入,结果无法使用),-stream_loop -1 表示无限循环,yuv420p 则是摄像头使用方期待的像素格式。在浏览器里打开摄像头测试页面,应该就能看到画面。
常见报错
modprobe: ERROR: could not insert 'v4l2loopback': Required key not available
安全启动拒绝了未签名的模块。要么注册一个 Machine Owner Key 并给模块签名,要么在固件里关闭安全启动。发行版如果提供已签名的模块版本,就完全不会遇到这个问题。
模块编译成功,却没有出现 /dev/video 设备
在 modprobe 之后立刻查看 dmesg | tail。模块与正在运行的内核版本不匹配会在这里体现,这通常说明 DKMS 在更新之后没有重新编译。
设备存在,但浏览器看不到
加载模块时带上 exclusive_caps=1。这是最常见的原因,没有之一。
Flatpak 应用看不到摄像头
在你授权之前,沙箱会阻止对设备的访问:
flatpak override --user --device=all com.obsproject.Studio
跳过这一切
上面这些都是一次性配置,但在你能把视频当摄像头播放之前,仍然免不了一段终端操作和一次重启——这也正是「用 OBS 就行了」这个建议在 Linux 上比在 Windows 上难得多的原因。
CamLooper 的 .deb 和 .rpm 包会替你完成这些。它们把 v4l2loopback-dkms 声明为依赖,安装上面展示的 modules-load.d 和 modprobe.d 文件,并在安装过程中加载模块,因此安装程序一结束摄像头就可用,之后每次重启也一样。不用终端,不用重启,而且 DKMS 会让它在内核更新之后继续工作。