O problema de vários dispositivos USB idênticos
Eu tenho um Rasperry Pi com quatro câmeras. Eu tomo pix com fswebcamque identifica as câmeras como /dev/video0.. video3. Às vezes, a câmera é video0, vide02, video4e video6mas podemos esquecer que, por enquanto.
Eu preciso de um ID persistente para identificar um número de câmera, de modo que, por exemplo, video0seja sempre a mesma câmera, porque eu legendo as fotos. Infelizmente, isso não acontece de maneira confiável - na inicialização, as câmeras são enumeradas como video0... video3mas nem sempre da mesma maneira.
As câmeras têm o mesmo ID e número de série.
A solução para esse problema envolve regras do udev, mas também existem muitos anzóis.
Se você emitir o comando
udevadm info –attribute-walk –path=/dev/video0
você obtém uma mesa de saída, mas os bits salientes são
KERNEL=”video0”, SUBSYSTEM=”video4linux” and KERNELS=”1:1.2.4:1.0”.
O bit KERNELS é uma porta de hub USB. Com quatro câmeras, há quatro delas - elas não mudam na reinicialização, mas a video{x}associada a uma porta pode mudar.
Portanto, precisamos de uma regra do udev para vincular um número de vídeo a uma porta de hub USB - algo como:
KERNEL==”video0”,SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0”,SYMLINK+=”camera0”
Parece simples - acesse a câmera com
fswebcam –d $realpath /dev/camera0
Exceto que não funciona - se você colocar isso em uma regra do udev e o sistema tiver alocado video0 (na inicialização) para uma porta diferente, a regra do udev será ignorada. O link simbólico para /dev/camera0basicamente diz no such device. Quadrado um.
O que queremos é vincular um link simbólico a um endereço de hub USB, não a um video{x}número. Foi necessário um programa Python.
O primeiro passo foi correr
fswebcam –d /dev/video${x} tst.jpg
para xentre 1 e 8. A existência de tst.jpgapós cada chamada identifica a existência de uma câmara nesta número de vídeo. A partir disso, faça uma lista dos números de vídeo ativos. Minha experiência tem sido que é tanto 0,1,2,3ou 0,2,4,6para câmeras que tenho usado.
Outros podem, é claro, criar essa lista usando um processo diferente.
Em seguida, para cada número de vídeo na lista, execute
udevadm info –attribute-walk –path=/dev/videox > dd
e extraia o KERNELS= linede dd. Nesse processo, você acaba com uma lista dos endereços de porta USB das câmeras. Classifique esta lista para que, na próxima etapa, você sempre a processe na mesma ordem. Chame isso de "lista de endereços".
Execute a udevadm … > ddcoisa novamente e faça uma lista que se parece com
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camerax”. Call this the “video list”.
Agora, percorra a lista de endereços - para cada entrada, encontre a entrada correspondente na lista de vídeos. Crie uma nova lista que se pareça com uma coleção de linhas como
KERNEL==”video0”, SUBSYSTEM=”video4linux”,KERNELS==”1:1.2.4:1.0 ”,SYMLINK+=”camera2”
O x (número do link simbólico) é substituído pelo número de sequência na lista de endereços.
Agora você tem uma regra do udev que funciona. Um link simbólico vinculado a um endereço de hub USB, independentemente do número de vídeo atribuído a essa porta na inicialização.
Escreva a lista final em um arquivo /etc/udev/rules.d/cam.rules. Execute udevadm triggerpara ativá-lo e o trabalho está concluído. /dev/camera2será a mesma câmera (porta USB), independentemente do número de vídeo.