【问题标题】:How to get a list of video capture devices (web cameras) on linux ( ubuntu )? (C/C++)如何在 linux ( ubuntu ) 上获取视频捕获设备 (网络摄像头) 的列表? (C/C++)
【发布时间】:2011-05-16 12:07:41
【问题描述】:

所以我需要的只是简单的 - 当前可用的视频捕获设备(网络摄像头)的列表。我在简单的 C 或 C++ 控制台应用程序中需要它。通过列表,我的意思是这样的控制台输出:

1) Asus Web Camera
2) Sony Web Camera

所以看起来很简单,但我有一个要求 - 尽可能使用本机 OS api - 没有外部库 - 毕竟 - 我们想要的只是打印出一个列表 - 而不是飞上月球!)

这样的事情怎么办?


也来自这个系列:

【问题讨论】:

  • 你能从 /proc/bus/input/devices 得到它吗
  • 问题是如何从代码中准确地做到这一点?
  • 如何读取相机、在 GPU 上处理并在实时窗口中显示两者的最小可运行示例:stackoverflow.com/questions/13693946/…

标签: c++ c linux webcam device


【解决方案1】:

您可以使用以下 bash 命令:

v4l2-ctl --list-devices

为了使用上述命令,您必须先安装包v4l-utils。在 Ubuntu/Debian 中,您可以使用以下命令:

sudo apt-get install v4l-utils

【讨论】:

  • 对于 Arch Linux 上的用户,v4l2-ctlv4l-utils 包中提供。
  • 我发现使用v4l2-ctl --list-devices 是解决我特定问题的最佳答案。我最终将它用于一个简单的 python 配置器。要点here.
【解决方案2】:

只需按给定的类遍历 sysfs 设备即可。以下命令行一班轮会这样做:

for I in /sys/class/video4linux/*; do cat $I/name; done

您可以在 C/C++ 应用程序中做同样的事情,只需打开 /sys/class/video4linux 目录,它就会有符号链接到您所有的网络摄像头作为 video4linux 设备:

$ ls -al /sys/class/video4linux                          
drwxr-xr-x  2 root root 0 Ноя 27 12:19 ./
drwxr-xr-x 34 root root 0 Ноя 26 00:08 ../
lrwxrwxrwx  1 root root 0 Ноя 27 12:19 video0 -> ../../devices/pci0000:00/0000:00:13.2/usb2/2-5/2-5:1.0/video4linux/video0/

您可以按照每个符号链接到每个设备的目录并读取该目录中name 文件的完整内容以获取名称。

【讨论】:

  • @Kabumbus 上面的 1-liner 相当不错,而且很容易转换成 c 代码。来自我的 +1
  • 单线非常适合我。谢谢!轻松插入任何代码。
【解决方案3】:

这是我放置的代码 sn-p。大概来自一本书。我想你可以遍历所有 /dev/videoN 节点并获取信息。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev.h>

int main(){
    int fd;
    struct video_capability video_cap;
    struct video_window     video_win;
    struct video_picture   video_pic;

    if((fd = open("/dev/video0", O_RDONLY)) == -1){
        perror("cam_info: Can't open device");
        return 1;
    }

    if(ioctl(fd, VIDIOCGCAP, &video_cap) == -1)
        perror("cam_info: Can't get capabilities");
    else {
        printf("Name:\t\t '%s'\n", video_cap.name);
        printf("Minimum size:\t%d x %d\n", video_cap.minwidth, video_cap.minheight);
        printf("Maximum size:\t%d x %d\n", video_cap.maxwidth, video_cap.maxheight);
    }

    if(ioctl(fd, VIDIOCGWIN, &video_win) == -1)
        perror("cam_info: Can't get window information");
    else
        printf("Current size:\t%d x %d\n", video_win.width, video_win.height);

    if(ioctl(fd, VIDIOCGPICT, &video_pic) == -1)
        perror("cam_info: Can't get picture information");
    else
        printf("Current depth:\t%d\n", video_pic.depth);

    close(fd);
    return 0;
}

【讨论】:

  • 以及如何遍历 N? (我们不知道 N 吗?)
  • 是的,我们必须猜测一个足够大的 N。使用 accept() 函数检查存在哪些 /dev/video 节点的 n 从 0..N。在此处查看已接受的答案stackoverflow.com/questions/230062/…
  • 鉴于@GregyCat 的下方,这个答案过于复杂了。
【解决方案4】:

V4L2 文档说每种类型可以有 64 个允许的设备。例如路径 /dev/video 可以有 64 个设备寻址为 /dev/video0、/dev/video1、/dev/video2 ...

迭代超过 64 个设备,直到 ioctl 返回指定树结束的 ENIVAL。

【讨论】:

    猜你喜欢
    • 2011-05-27
    • 2011-05-16
    • 2011-05-30
    • 1970-01-01
    • 2020-05-01
    • 2011-06-05
    • 1970-01-01
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多