跳转至内容

v4l2loopback

来自 ArchWiki

来自项目 仓库

v4l2loopback - 用于创建 V4L2 环回设备的内核模块
此模块允许您创建“虚拟视频设备”。普通的 (v4l2) 应用程序会将这些设备读取为普通视频设备,但视频不是从捕获卡等设备读取的;相反,它是由另一个应用程序生成的。

安装

安装 v4l2loopback-dkms 包 **以及** 目标内核/内核的头文件(参见 Dynamic Kernel Module Support#Installation)。例如,对于默认的 linux 内核,这将是 linux-headers。其他内核有各自的头文件包。

命令行工具由 v4l2loopback-utilsv4l-utils 提供。

本文档中的许多用例示例也使用了 ffmpeg

加载内核模块

v4l2loopback 内核模块可以通过 Dynamic Kernel Module Support 加载。

# modprobe v4l2loopback

可以使用 v4l2-ctl 来列出所有视频设备,其中应该会显示新的 v4l2loopback 设备。

$ v4l2-ctl --list-devices

v4l2loopback 可以通过各种选项加载以创建设备。

# modprobe v4l2loopback video_nr=9 card_label=Video-Loopback exclusive_caps=1

这应该会创建 /dev/video9 作为环回设备。exclusive_caps=1 对于某些基于 Chromium/WebRTC 的应用程序是必需的,例如 jitsi-meet-desktop-binAURzoomAUR。这将启用 exclusive_caps 模式,该模式仅独占报告 CAPTURE/OUTPUT 功能。新创建的设备将仅声明 OUTPUT 功能(因此普通的网络摄像头应用程序(包括 Chrome)将看不到它)。一旦您连接了生产者,它将开始仅声明 CAPTURE 功能(因此拒绝打开除捕获功能以外的其他功能的设备的应用也可以打开它)。有关更多选项,请参阅 官方文档

如果模块已加载,则上述命令可能无效。必须先卸载模块,然后才能重新加载。

# modprobe -r v4l2loopback

有关更多详细信息,请参阅 Kernel module#Manual module handling

提示 也可以使用 v4l2loopback-ctl 来动态管理设备,而无需重新加载内核模块,具体说明请参见 官方文档

您可以通过使用 devices 参数来创建多个环回设备,并用逗号分隔每个设备的选项。以下命令创建了三个环回设备:/dev/video8/dev/video9 以及第一个可用的 /dev/videoX,所有设备都启用了 exclusive_caps

# modprobe v4l2loopback devices=3 video_nr=8,9 exclusive_caps=1,1,1 card_label="Loopback-1,Loopback-2,Loopback-3"

重新启动系统将卸载模块,但可以使用自定义设备选项在启动时自动加载模块,这对于使用内部网络摄像头的环回设备很有用。有关详细信息,请参阅 Kernel module#Automatic module loading官方文档

查看 v4l2loopback 视频流

注意 v4l2loopback 视频设备只有在有流输入时才会输出视频,如 #Use cases 部分的示例所示。如果没有输入流,许多应用程序将无法检测到这些视频设备。

/dev/video0 处的环回视频设备可以使用以下任一工具进行测试:ffplay(来自 ffmpeg),mpv,或 gst-launch(来自 gstreamer)。

$ ffplay /dev/video0
$ mpv av://v4l2:/dev/video0
$ gst-launch-1.0 -v v4l2src device=/dev/video0 ! glimagesink

#Loading the kernel module 中所述,当使用 exclusive_caps=1 时,Chromiumjitsi-meet-desktop-binAURzoomAUR 等应用程序应该能够将环回设备用作虚拟网络摄像头,同时将视频流输入其中。在浏览器中,您可以在 webcamtests.com 上测试虚拟网络摄像头。

另请参阅 Webcam setup#Applications

提示 如果您将视频流传输到视频设备,但您的应用程序未检测到它,请尝试使用 exclusive_caps=1 和不使用 exclusive_caps=1 进行测试。
注意 据报道,Firefox 存在各种其他问题。

用例

注意 由于 v4l2loopback 设备可以作为 v4l2 设备处理,因此许多应用程序可以与之交互。有关 v4l2 设备 的更多信息,请参阅 Webcam setup 文章。

通常,FFmpeg 与 v4l2loopback 结合使用非常方便,因为它可以使用 ffmpeg 参数 -vf format=yuv420p -f v4l2 将各种输入流转码为广泛支持的 yuv420p 像素格式并将其输出到 v4l2loopback 设备。请参阅本文档中的示例。

FFmpeg 也可以将 v4l2loopback 设备用作输入流。请参阅 FFmpeg#Recording webcam

GStreamer 也可以将 v4l2loopback 设备用作 接收器

其他示例可在 官方 v4l2loopback wiki 中找到。

提示 PipeWire 是一个新的底层多媒体框架,它也可以做一些 v4l2loopback 用于实现的功能。

屏幕投射

以下是如何通过将屏幕流式传输到 v4l2 环回设备来实现屏幕共享的示例,该设备然后可以作为虚拟网络摄像头使用。

使用 FFmpeg 投射 X11

注意 这需要使用 exclusive_caps=1 #Loading the kernel module,并假定创建的视频设备是 /dev/video0

FFmpeg 可用于选择 X11 显示器上的一个区域,然后将其流式传输到 v4l2 环回设备。

$ ffmpeg -f x11grab -select_region 1 -show_region 1 -framerate 25 -i $DISPLAY -vf format=yuv420p -f v4l2 /dev/video0

有关所有参数的说明,请参阅 x11grab 文档

使用 wf-recorder 投射 Wayland

安装 wf-recorder。要使用 wf-recorder 开始录制屏幕并将其流式传输到 v4l2 环回设备,请使用

$ wf-recorder --muxer=v4l2 --codec=rawvideo --file=/dev/video0 -x yuv420p

如果您遇到 Unknown V4L2 pixel format equivalent for rgb0 错误,请运行 wf-recorder 并带上 --force-yuv-t 参数,在将数据发送到 GPU 之前强制将其转换为 yuv 格式。 [1]

只投射特定区域的屏幕
Warning This method does not involve a proper implementation of individual application sharing as the region being shared will not change after resizing any windows。

As explained above, wf-recorder is able to record only a portion of the screen by first selecting a region with slurp. To use this functionality for sharing a specific region/application window through a virtual video device, start recording the screen with the following modified command

$ wf-recorder -g "$(slurp)" --muxer=v4l2 --codec=rawvideo --file=/dev/video0 -x yuv420p

将照相机用作网络摄像头 (gPhoto)

注意 这需要使用 exclusive_caps=1 #Loading the kernel module,并假定创建的视频设备是 /dev/video0

如果安装了 gPhoto 并且它与您的相机正常工作,您可以使用 gphoto2FFmpeg 将相机的实时视图流传输到 v4l2 环回设备。

$ gphoto2 --stdout --capture-movie | ffmpeg -i - -vf format=yuv420p -f v4l2 /dev/video0

有关故障排除,请参阅 gPhoto#Troubleshooting。这应该适用于所有相机,其实时视图功能列在 官方 gPhoto 网站 上。

将网络流用作网络摄像头

注意 这需要使用 exclusive_caps=1 #Loading the kernel module,并假定创建的视频设备是 /dev/video0

FFmpeg 可用于捕获网络流并将其传输到 v4l2 环回设备。

$ ffmpeg -i http://ip_address:port/video -vf format=yuv420p -f v4l2 /dev/video0

将 Android 设备用作网络摄像头

在 Android 上,可以使用 IP Webcam 来广播网络视频流。然后可以使用上面的命令将其传输到 v4l2 环回设备并像网络摄像头一样使用。IP Webcam 默认为端口 8080。

根据网络连接的不同,Wi-Fi 上的网络流可能会有很大的延迟和卡顿。如果您已在计算机和 Android 设备之间配置了 Android Debug Bridge,则可以使用 adb forward 通过 USB 数据线隧道传输流,这提供了更稳定的连接。

$ adb wait-for-usb-device && adb forward tcp:8080 tcp:8080 && ffmpeg -i http://127.0.0.1:8080/videofeed -vf format=yuv420p -f v4l2 /dev/video0

另一种更简单的方法是使用 scrcpy

$ scrcpy --video-source=camera --camera-id=0 --camera-size=1920x1080 --video-bit-rate=20M --v4l2-sink=/dev/video0 --no-playback
提示 另一个选择是使用 Iriuniriunwebcam-binAUR

在视频会议中使用背景图片

有多种不同的选项可用于隐藏/替换 Microsoft Teams 和 Zoom 等视频会议软件的背景。

OBS

OBS 被主播用作实时视频管理系统,用于切换视频流。它可以设置多个“场景”(例如,每个场景都有不同的背景图片),然后可以通过单击按钮进行切换。它还可以提供其他视频滤镜,具有用于新滤镜的插件系统,可以同时显示多个视频流,等等。它可以将其输出发送到与支持 V4L2 摄像头的任何应用程序兼容的 v4l2loopback 设备。

设置方法

  1. 安装obs-studio 包和 obs-backgroundremovalAUR 插件。
  2. 加载 obs 并将真实摄像头添加为场景的输入源。
  3. 右键单击源并编辑滤镜,然后添加背景移除滤镜。您现在应该会看到背景被擦除,只显示黑色。(您也可以选择模糊背景而不是移除它,在高级选项中。)
  4. 添加一个类型为“Image”的另一个输入源,并选择您喜欢的背景图片。源类型也可以是视频文件或其他网络摄像头,但请先从图片开始,直到一切正常。
  5. 在源列表中拖动图片条目,使其位于视频源条目下方,以便图片出现在视频后面而不是前面。
  6. 移动/调整背景图片的大小,使其占据场景的大部分。
  7. 启用虚拟输出,虚拟网络摄像头即可使用。

为了让视频会议软件能够使用虚拟网络摄像头,obs 必须保持运行并启用虚拟输出。

如果出现损坏或空白图像(在更改输出分辨率后很常见),您可能需要删除并重新创建 V4L2 环回设备(或卸载并重新加载 v4l2loopback 模块)。

有关故障排除,请参阅上面的 #Viewing a v4l2loopback video feed - 如果这些程序可以正常播放视频流,则问题在于消耗视频的应用程序。如果这些实用程序也无法正常显示视频,则问题在于环回设置。

故障排除

Firefox

如果 Firefox 无法读取视频流并显示类似 AbortError: Starting video failed 的消息,请尝试预加载 v4l2compat.so。

$ LD_PRELOAD=/usr/lib/v4l2compat.so firefox

ioctl(VIDIOC_G_FMT)

如果您在尝试使用 ffmpeg 视频设备时遇到 ioctl(VIDIOC_G_FMT) 错误,请尝试卸载并重新加载内核模块。 [2]

参见