2010-11-27 28 views
19

Así que todo lo que necesito es simple: una lista de los dispositivos de captura de video actualmente disponibles (cámaras web). Lo necesito en una aplicación simple de consola C o C++. Por lista quiero decir algo como tales salida de la consola:¿Cómo obtener una lista de dispositivos de captura de video (cámaras web) en Linux (ubuntu)? (C/C++)

1) Asus Web Camera 
2) Sony Web Camera 

por lo que parece simple pero tengo un requisito - uso de las API de OS nativas tanto como sea posible - no hay librerías externas - después de todo - todo lo que queremos es imprimir ¡fuera una lista - no volar sobre la luna!)

¿Cómo hacer tal cosa?


también de esta serie:

+1

se puede obtener desde/proc// input/dispositivos de bus – chrisaycock

+1

La pregunta es ¿cómo es exactamente lo haga a partir del código? – Rella

Respuesta

11

Este es un fragmento de código que tuve por ahí. Probablemente de un libro. Supongo que podrías iterar sobre todos los nodos/dev/videoN y obtener la información.

#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; 
} 
+0

y ho para iterar thrue N? (No sabemos N, ¿verdad?) – Rella

+0

Derecho, tenemos que adivinar una N suficientemente grande. Use la función accept() para verificar qué/dev/video nodes con n de 0..N existe. Ver la respuesta aceptada aquí http: // stackoverflow.com/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c-cross-platform – BlueDog

+0

¿Cómo obtener los nombres de las cámaras? – Rella

25

Es fácil simplemente atravesando los dispositivos sysfs de una clase determinada. La siguiente línea de comandos de un trazador de líneas haría:

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

Usted puede hacer lo mismo en la aplicación C/C++, con sólo abrir hasta /sys/class/video4linux directorio, tendrá enlaces simbólicos a todas sus cámaras web como 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/ 

Usted puede seguir cada enlace simbólico a un directorio de todos los dispositivos y leer los contenidos completos de name archivo en ese directorio para obtener el nombre.

+0

лол =) ¿Qué tal un código compilable (como con la función principal incluye y así sucesivamente)? – Rella

+0

@Kabumbus el 1-liner anterior es bastante bueno y fácil de transformar en un código c. +1 de mí –

+0

One-liner perfecto para mí. ¡Gracias! Easy peasy para insertar en cualquier código. – Daniel

0

La documentación de V4L2 dice que puede haber 64 dispositivos permitidos para cada tipo. Por ejemplo, para path/dev/video puede haber 64 dispositivos direccionados como/dev/video0,/dev/video1,/dev/video2 ...

Iterar más de 64 dispositivos hasta que ioctl restablezca ENIVAL que especifica el final del árbol.

25

Usted puede utilizar el siguiente comando bash:

v4l2-ctl --list-devices 

Para utilizar el comando anterior, debe instalar el paquete v4l-utils antes. En Ubuntu/Debian puede utilizar el comando:

sudo apt-get install v4l-utils 
+0

Para aquellos en Arch Linux, 'v4l2-ctl' se proporciona en el paquete' v4l-utils'. – ElDog

+0

Encontré que '' 'v4l2-ctl --list-devices''' es la mejor respuesta para mi problema en particular. Terminé usándolo para un simple configurador de Python. Gist [aquí] (https://gist.github.com/kphretiq/e5b95e7fc2b11819121e). – lysdexia

Cuestiones relacionadas