Redian新闻
>
如何在 Linux 中使用旧相机作为网络摄像头 | Linux 中国

如何在 Linux 中使用旧相机作为网络摄像头 | Linux 中国

科技
 
导读:我用 gphoto2 给我的旧单反相机带来了新的生命,把它变成了 Linux 电脑的网络摄像头。   
本文字数:6607,阅读时长大约:8分钟

我用 gphoto2 给我的旧单反相机带来了新的生命,把它变成了 Linux 电脑的网络摄像头。

今年,在我基本上放弃了 MacBook,转而使用 NixOS 机器之后,我开始在与人进行视频通话时被要求“打开摄像头”。这是一个问题,因为我没有网络摄像头。我考虑购买一个,但后来我意识到我有一台完好无损的 2008 年产的佳能 EOS Rebel XS 数码单反相机放在书架上。这台相机有一个 mini-USB 接口,所以我自然而然地思考:一台数码单反相机、一个 mini-USB 接口和一台台式电脑,是否意味着我能拥有一个网络摄像头?

只有一个问题。我的佳能 EOS Rebel XS 不能录制视频。它可以拍摄一些漂亮的照片,仅此而已。所以这结束了?

还是有别的办法?

恰好有一个叫做 gphoto2🔗 gphoto.org 的神奇的开源软件。一旦安装,它允许你从计算机控制各种支持的相机,并拍摄照片和视频。

支持的相机

首先,了解你的设备是否得到支持:

  1. $ gphoto2 --list-cameras

拍摄图像

你可以用它拍照:

  1. $ gphoto2 --capture-image-and-download

快门触发,图像会保存到你当前的工作目录中。

录制视频

我意识到了这里的潜力,所以尽管我的相机没有视频功能,我还是决定尝试 gphoto2 --capture-movie 命令。不知怎么,尽管我的相机不支持视频功能,gphoto2 仍然能够生成一个 MJPEG 文件!

在我的相机上,我需要将其置于“实时预览”模式下,然后 gphoto2 才能录制视频。这包括将相机设置为纵向模式,然后按下 “设置(Set)” 按钮,使取景器关闭,相机屏幕显示图像。不幸的是,这还不足以将其用作网络摄像头。它仍然需要分配一个视频设备,例如 /dev/video0

安装 ffmpeg 和 v4l2loopback

毫不奇怪,有一个开源的解决方案来解决这个问题。首先,使用你的包管理器安装 gphoto2ffmpeg 和 mpv。例如,在 Fedora 、CentOS 、Mageia 和类似的 Linux 发行版上:

  1. $ sudo dnf install gphoto2 ffmpeg mpv

在 Debian、Linux Mint 及其类似发行版:

  1. $ sudo apt install gphoto2 ffmpeg mpv

我使用的是 NixOS,这是我的配置文件:

  1. # configuration.nix
  2. ...
  3. environment.systemPackages = with pkgs; [
  4.   ffmpeg
  5.   gphoto2
  6.   mpv
  7. ...
    ]

创建虚拟视频设备需要使用 v4l2loopback Linux 内核模块。在撰写本文时,该功能未包含在主线内核中,因此你需要自己下载和编译它:

  1. $ git clone https://github.com/umlaeute/v4l2loopback
  2. $ cd v4l2loopback
  3. $ make
  4. $ sudo make install
  5. $ sudo depmod -a

如果你像我一样使用 NixOS ,你可以在 configuration.nix 中添加额外的模块包:

  1. [...]
  2. boot.extraModulePackages = with config.boot.kernelPackages;
  3. [ v4l2loopback.out ];
  4. boot.kernelModules = [
  5.   "v4l2loopback"
  6. ];
  7. boot.extraModprobeConfig = ''
  8.   options v4l2loopback exclusive_caps=1 card_label="Virtual Camera"
  9. '';
  10. [...]

在 NixOS 上, 运行 sudo nixos-rebuild switch,然后重启。

创建一个视频设备

假设你的计算机当前没有 /dev/video 设备,你可以借助 v4l2loopback 在需要时创建一个。

运行以下命令,将 gphoto2 中的数据发送到 ffmpeg,使用设备如 /dev/video0 设备:

  1. $ gphoto2 --stdout --capture-movie |
  2.  ffmpeg -i - -vcodec rawvideo -pix_fmt yuv420p -f v4l2 /dev/video0

你得到的输出是这样的:

  1. ffmpeg version 4.4.1 Copyright (c) 2000-2021 the FFmpeg developers
  2.   built with gcc 11.3.0 (GCC)
  3.   configuration: --disable-static ...
  4.   libavutil      56. 70.100 / 56. 70.100
  5.   libavcodec     58.134.100 / 58.134.100
  6.   libavformat    58. 76.100 / 58. 76.100
  7.   libavdevice    58. 13.100 / 58. 13.100
  8.   libavfilter     7.110.100 /  7.110.100
  9.   libavresample   4.  0.  0 /  4.  0.  0
  10.   libswscale      5.  9.100 /  5.  9.100
  11.   libswresample   3.  9.100 /  3.  9.100
  12.   libpostproc    55.  9.100 / 55.  9.100
  13. Capturing preview frames as movie to 'stdout'. Press Ctrl-C to abort.[mjpeg @ 0x1dd0380] Format mjpeg detected only with low score of 25, misdetection possible!
  14. Input #0, mjpeg, from 'pipe:':
  15.   Duration: N/A, bitrate: N/A
  16.   Stream #0:0: Video: mjpeg (Baseline), yuvj422p(pc, bt470bg/unknown/unknown), 768x512 ...
  17. Stream mapping:
  18.   Stream #0:0 -> #0:0 (mjpeg (native) -> rawvideo (native))[swscaler @ 0x1e27340] deprecated pixel format used, make sure you did set range correctly
  19. Output #0, video4linux2,v4l2, to '/dev/video0':
  20.   Metadata:
  21.     encoder         : Lavf58.76.100
  22.   Stream #0:0: Video: rawvideo (I420 / 0x30323449) ...
  23.     Metadata:
  24.       encoder         : Lavc58.134.100 rawvideoframe=  289 fps= 23 q=-0.0 size=N/A time=00:00:11.56 bitrate=N/A speed=0.907x

要查看来自网络摄像头的视频,请使用 mpv 命令:

  1. $ mpv av://v4l2:/dev/video0 --profile=low-latency --untimed

Streaming a live feed from the webcam

自动启动你的网络摄像头

每次想使用网络摄像头时都需要执行一次命令有点麻烦。幸运的是,你可以在启动时自动运行此命令。我将其实现为一个 systemd 服务:

  1. # configuration.nix
  2. ...
  3.   systemd.services.webcam = {
  4.     enable = true;
  5.     script = ''
  6.       ${pkgs.gphoto2}/bin/gphoto2 --stdout --capture-movie |
  7.         ${pkgs.ffmpeg}/bin/ffmpeg -i - \
  8.             -vcodec rawvideo -pix_fmt yuv420p -f v4l2  /dev/video0
  9.     '';
  10. wantedBy = [ "multi-user.target" ];
  11.   };
  12. ...

在 NixOS 上,运行 sudo nixos-rebuild switch,然后重新启动你的计算机。你的网络摄像头已经开启并处于活动状态。

要检查是否存在任何问题,可以使用 systemctl status webcam 命令。它会告诉你服务最后一次运行的时间,并提供其以前输出的日志。这对于调试非常有用。

迭代以使其变得更好

止步于此也许很诱人。但是,考虑到当前的全球危机,我们可能需要思考是否有必要一直开着网络摄像头。这让我感到不太理想,原因如下:

◈ 这浪费电。
◈ 这类事情涉及隐私问题。

我的摄像头有一个镜头盖,所以说实话,第二个原因并不真的让我感到困扰。当我不使用网络摄像头时,我总是可以把镜头盖上。然而,让一个耗电量大的单反相机整天开着(更不用说需要解码视频所需的 CPU 开销),对我的电费并没有任何好处。

理想情况是:

◈ 我一直把相机插在电脑上,但是关闭的。
◈ 当我想使用网络摄像头时,我按下相机的电源按钮将其打开。
◈ 我的计算机会检测到相机并启动 systemd 服务。
◈ 使用网络摄像头完成后,我再次将其关闭。

为了实现这一点,你需要使用一个自定义的 udev 规则。

udev 规则可以告诉你的计算机,当它发现某个设备已经可用时执行某个任务。这可以是外部硬盘甚至是非 USB 设备。在这种情况下,你需要通过其 USB 连接识别相机。

首先,指定 udev 规则被触发时要运行的命令。你可以用一个 shell 脚本来完成(systemctl restart webcam 应该可以工作)。我运行的是 NixOS,所以我只需要创建一个派生包(一个 Nix 包),它会重新启动 systemd 服务:

  1. # start-webcam.nix
  2. with import <nixpkgs> { };
  3. writeShellScriptBin "start-webcam" ''
  4.   systemctl restart webcam
  5.   # debugging example
  6.   # echo "hello" &> /home/tom/myfile.txt
  7.   # If myfile.txt gets created then we know the udev rule has triggered properly''

接下来,实际定义 udev 规则。查找摄像头的设备和厂商 ID。使用 lsusb 命令可以完成此操作。该命令可能已经安装在你的发行版上,但我不经常使用它,因此我只需要根据需要使用 nix-shell 安装它:

  1. $ nix-shell -p usbutils

无论你的计算机上已经安装了它,还是刚刚安装,请运行 lsusb :

  1. $ lsusb
  2. Bus 002 Device 008: ID 04a9:317b Canon, Inc. Canon Digital Camera[...]

在此输出中,厂商 ID 为 04a9,设备 ID 为 317b。这已足以创建 udev 规则:

  1. ACTION=="add", SUBSYSTEM=="usb",
  2. ATTR{idVendor}=="04a9",
  3. ATTR{idProduct}=="317b",
  4. RUN+="/usr/local/bin/start-webcam.sh"

或者,如果你使用的是 NixOS:

  1. # configuration.nix[...]let
  2.   startWebcam = import ./start-webcam.nix;[...]
  3. services.udev.extraRules = ''
  4.   ACTION=="add",  \
  5.   SUBSYSTEM=="usb", \
  6.   ATTR{idVendor}=="04a9", \
  7.   ATTR{idProduct}=="317b",  \
  8.   RUN+="${startWebcam}/bin/start-webcam"'';[...]

最后,在你的 start-webcam systemd 服务中删除 wantedBy = ["multi-user.target"]; 这一行。(如果保留它,则无论相机是否开启,该服务都会在下次重启时自动启动。)

重复使用旧技术

我希望这篇文章能让你在放弃一些旧技术之前三思而后行。Linux 可以为技术注入活力,无论是你的电脑还是数码相机或其他外围设备等简单的东西。


via: https://opensource.com/article/22/12/old-camera-webcam-linux

作者:Tom Oliver 选题:lkxed 译者:Pabloxllwe 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

LCTT 译者 :李进
🌟
翻译: 1.0 篇
|
贡献: 5 天
2023-03-17
2023-03-21
https://linux.cn/lctt/Pabloxllwe
欢迎遵照 CC-BY-SA 协议规定转载,
如需转载,请在文章下留言 “转载:公众号名称”,
我们将为您添加白名单,授权“转载文章时可以修改”。


微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
如何在 Linux 系统中使用 Ventoy 创建多重引导的 U 盘 | Linux 中国H&M女试衣间竟藏摄像头,偷拍影片遭网络贩卖疯传如何在 Java 中使用方法 | Linux 中国马克谈天下(358) AI作图谱曲贺新年《触摸美国》的意义如何在 Arch Linux 中安装 MATE 桌面 | Linux 中国用旧衣橱的拉链毛衣穿出新风格细思极恐!澳洲交通摄像头能拍到你内裤?!女司机惶恐,隐私何在!Agustín Hernández:中美洲建筑背景下的未来主义巨构满街都是摄像机!芝新规:公车、路灯都装摄像头 违停就罚单如何在 Ubuntu 和其他 Linux 下安装 IDLE Python IDE | Linux 中国非虚构写作营 | 流量时代,我们依旧相信写作的笨功夫使用 ChatGPT AI 从英文文本生成 Linux 命令 | Linux 中国在 OBS 中将摄像头锁定到特定的 USB 端口 | Linux 中国世界上只有两个 Linux 发行版:Arch Linux 与其它 | Linux 中国Rust 基础系列 #2: 在 Rust 程序中使用变量和常量 | Linux 中国天赋“易昺(bǐng)”,创造历史!如何在 Arch Linux 中安装 GNOME 桌面 | Linux 中国最新报告称 75% 的网民缺乏安全感,66% 的网民认为网络安全过于复杂【信息安全三分钟】2023.02.22如何入门 Linux Shell 脚本编写 | Linux 中国ViewSonic 推 24/27 英寸 VG56V 系列显示器:配可升降网络摄像头如何在 Linux 中合并 PDF 文件 | Linux 中国奥威尔在西班牙的奇幻冒险——Homage to Catalonia读后感彩平图的铺装贴图,千万别用旧的!risiOS:一个易于使用的基于 Fedora 的 Linux 发行版 | Linux 中国聊一聊:你怎么处理/利用旧设备?CTO:禁止在项目中使用 BeanUtils 属性转换工具。。。TUXEDO Stellaris 16(Gen5)是目前所能找到的终极 Linux 笔记本电脑 | Linux 中国新年好在 C 语言中使用 getopt 解析命令行短选项 | Linux 中国在 Linux 命令行上使用 dict 文字工具 | Linux 中国就地取材的年夜饭
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。