2010-11-27 26 views
19

Quindi tutto ciò di cui ho bisogno è semplice: un elenco di dispositivi di acquisizione video attualmente disponibili (webcam). Ne ho bisogno in semplice app per console C o C++. Con la lista intendo qualcosa di simile come output della console:Come ottenere un elenco di dispositivi di acquisizione video (webcam) su linux (ubuntu)? (C/C++)

1) Asus Web Camera 
2) Sony Web Camera 

così sembra semplice, ma io ho un requisito - uso di API native del sistema operativo, per quanto possibile - senza librerie esterne - dopo tutto - tutto quello che vogliamo è quello di stampare fuori una lista - non volare sulla luna!)

Come fare una cosa del genere?


anche da questa serie:

+1

si può ottenere da/proc/bus/dispositivi di input/ – chrisaycock

+1

la questione è come esattamente farlo da codice? – Rella

risposta

11

Questo è uno snippet di codice che avevo messo in giro. Probabilmente da un libro. Suppongo che tu possa semplicemente iterare su tutti i nodi/dev/videoN e ottenere le informazioni.

#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

e ho per iterare la canna N? (non lo sappiamo N?) – Rella

+0

Destra dobbiamo indovinare un numero abbastanza grande. Usa la funzione accept() per verificare quali/dev/nodi video con n da 0..N esistono. Vedere la risposta accettata qui http: // stackoverflow.it/questions/230062/whats-the-best-way-to-check-if-a-file-exists-in-c-cross-platform – BlueDog

+0

Come ottenere i nomi delle telecamere? – Rella

25

È facile semplicemente attraversando i dispositivi sysfs di una determinata classe. La seguente riga di comando uno di linea avrebbe fatto:

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

Si può fare la stessa cosa in C application/C++, semplicemente aprendo /sys/class/video4linux directory, avrà collegamenti simbolici a tutte le vostre macchine fotografiche web come 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/ 

Puoi seguire ogni collegamento simbolico ad una directory di ogni dispositivo e leggere i contenuti completi di name file in quella cartella per ottenere il nome.

+0

лол =) Che dire di un codice compilabile (come con la funzione principale include e così via)? – Rella

+0

@Kabumbus il 1-liner sopra è abbastanza buono e facile da trasformare in un codice c. +1 da me –

+0

One-liner perfetto per me. Grazie! Facile da inserire in qualsiasi codice. – Daniel

0

La documentazione V4L2 indica che possono essere 64 dispositivi consentiti per ciascun tipo. Ad esempio per path/dev/video ci possono essere 64 dispositivi indirizzati come/dev/video0,/dev/video1,/dev/video2 ...

Iterare su 64 dispositivi finché l'ioctl non ritarda ENIVAL che specifica la fine del albero.

25

È possibile utilizzare il seguente comando bash:

v4l2-ctl --list-devices 

Per poter utilizzare il comando di cui sopra, è necessario installare il pacchetto v4l-utils prima. In Ubuntu/Debian è possibile utilizzare il comando:

sudo apt-get install v4l-utils 
+0

Per quelli su Arch Linux, 'v4l2-ctl' è fornito nel pacchetto' v4l-utils'. – ElDog

+0

Ho trovato che usare '' 'v4l2-ctl --list-devices''' per essere la migliore risposta per il mio particolare problema. Ho finito per usarlo per un semplice configuratore python. Gist [qui] (https://gist.github.com/kphretiq/e5b95e7fc2b11819121e). – lysdexia

Problemi correlati