Linux に USB で Web カメラを接続した際、Linux を再起動しても Web カメラのオーディオデバイスが一定の値に固定化されるようにしてみます。
Web カメラのオーディオデバイスの番号を固定化する目的としては、FFmpeg で Web カメラの映像とマイクの音声をリアルタイムにエンコードする際に、FFmpeg のオプションとして Web カメラのオーディオデバイスを “hw:0,0” のように固定化するためです。
例えば、マザーボードのオンボードのサウンドデバイスと Web カメラのマイクのように Linux PC が復数のオーディオデバイスを持っている場合、/proc/asound 下に card0, card1 ディレクトリができます。しかし、何も設定していない場合、OS を起動する度にオーディオデバイスと cardX の割り当て番号 (X は整数) が異なってしまう場合があります。つまり、オーディオデバイスと cardX の割り当てが固定化されない状況が発生します。
OS は Ubuntu 20.04 です。マザーボードは B85M-E です。マザーボードにはビデオカードとして NVIDIA GeForce GTX 1050 を接続しています。Web カメラは Logicool C910 です。
Web カメラ接続前
まず、dmidecode コマンドで、マザーボードの製品名を確認してみます。ASUSTeK の B85M-E でした。
$ sudo dmidecode -t 2
# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 2.7 present.
Handle 0x0002, DMI type 2, 15 bytes
Base Board Information
Manufacturer: ASUSTeK COMPUTER INC.
Product Name: B85M-E
Version: Rev X.0x
Serial Number:
Asset Tag: To be filled by O.E.M.
Features:
Board is a hosting board
Board is replaceable
Location In Chassis: To be filled by O.E.M.
Chassis Handle: 0x0003
Type: Motherboard
Contained Object Handles: 0
続いて、aplay コマンドを実行してみます。オーディオを再生するハードウェアの情報が表示されます。
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC887-VD Analog [ALC887-VD Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
/proc/asound を確認してみます。card0, card1 が存在していることがわかります。
$ ls -al /proc/asound
total 0
dr-xr-xr-x 6 root root 0 7月 11 22:05 .
dr-xr-xr-x 318 root root 0 7月 11 22:05 ..
dr-xr-xr-x 5 root root 0 7月 11 22:05 card0
dr-xr-xr-x 5 root root 0 7月 11 22:05 card1
-r--r--r-- 1 root root 0 7月 11 22:09 cards
-r--r--r-- 1 root root 0 7月 11 22:10 devices
-r--r--r-- 1 root root 0 7月 11 22:10 hwdep
-r--r--r-- 1 root root 0 7月 11 22:10 modules
lrwxrwxrwx 1 root root 5 7月 11 22:10 NVidia -> card1
dr-xr-xr-x 2 root root 0 7月 11 22:10 oss
lrwxrwxrwx 1 root root 5 7月 11 22:10 PCH -> card0
-r--r--r-- 1 root root 0 7月 11 22:10 pcm
dr-xr-xr-x 2 root root 0 7月 11 22:10 seq
-r--r--r-- 1 root root 0 7月 11 22:10 timers
-r--r--r-- 1 root root 0 7月 11 22:10 version
/proc/asound/cards を確認してみます。
$ cat /proc/asound/cards
0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xf7110000 irq 32
1 [NVidia ]: HDA-Intel - HDA NVidia
HDA NVidia at 0xf7080000 irq 17
/proc/asound/devices を確認してみます。
$ cat /proc/asound/devices
2: [ 0- 0]: digital audio playback
3: [ 0- 0]: digital audio capture
4: [ 0- 2]: digital audio capture
5: [ 0- 0]: hardware dependent
6: [ 0] : control
7: [ 1- 3]: digital audio playback
8: [ 1- 7]: digital audio playback
9: [ 1- 8]: digital audio playback
10: [ 1- 0]: hardware dependent
11: [ 1] : control
33: : timer
/proc/asound/pcm を確認してみます。
$ cat /proc/asound/pcm
00-00: ALC887-VD Analog : ALC887-VD Analog : playback 1 : capture 1
00-02: ALC887-VD Alt Analog : ALC887-VD Alt Analog : capture 1
01-03: HDMI 0 : HDMI 0 : playback 1
01-07: HDMI 1 : HDMI 1 : playback 1
01-08: HDMI 2 : HDMI 2 : playback 1
arecord コマンドを実行してみます。オーディオをキャプチャするハードウェアの情報が表示されます。
$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC887-VD Analog [ALC887-VD Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 2: ALC887-VD Alt Analog [ALC887-VD Alt Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
/proc/asound/modules を確認してみます。
$ cat /proc/asound/modules
0 snd_hda_intel
1 snd_hda_intel
Web カメラ接続後
Web カメラを USB でマザーボードに接続後、lsusb を実行してみます。
$ lsusb
Bus 003 Device 006: ID 046d:0821 Logitech, Inc. HD Webcam C910
dmesg を実行してみます。
[ 499.613082] usb 3-3: new high-speed USB device number 5 using xhci_hcd
[ 504.924948] usb 3-3: unable to read config index 0 descriptor/all
[ 504.924958] usb 3-3: can't read configurations, error -110
[ 505.260871] usb 3-3: new high-speed USB device number 6 using xhci_hcd
[ 505.680214] usb 3-3: New USB device found, idVendor=046d, idProduct=0821, bcdDevice= 0.10
[ 505.680221] usb 3-3: New USB device strings: Mfr=0, Product=0, SerialNumber=1
[ 505.680224] usb 3-3: SerialNumber:
[ 505.716113] videodev: Linux video capture interface: v2.00
[ 506.151191] usbcore: registered new interface driver snd-usb-audio
[ 506.151321] uvcvideo: Found UVC 1.00 device <unnamed> (046d:0821)
[ 506.189812] uvcvideo 3-3:1.2: Entity type for entity Extension 4 was not initialized!
[ 506.189817] uvcvideo 3-3:1.2: Entity type for entity Processing 2 was not initialized!
[ 506.189820] uvcvideo 3-3:1.2: Entity type for entity Camera 1 was not initialized!
[ 506.189823] uvcvideo 3-3:1.2: Entity type for entity Extension 5 was not initialized!
[ 506.189825] uvcvideo 3-3:1.2: Entity type for entity Extension 6 was not initialized!
[ 506.189826] uvcvideo 3-3:1.2: Entity type for entity Extension 7 was not initialized!
[ 506.189828] uvcvideo 3-3:1.2: Entity type for entity Extension 8 was not initialized!
[ 506.189951] input: UVC Camera (046d:0821) as /devices/pci0000:00/0000:00:14.0/usb3/3-3/3-3:1.2/input/input22
[ 506.190165] usbcore: registered new interface driver uvcvideo
[ 506.190167] USB Video Class driver (1.1.1)
v4l-utils をインストールし、v4l2-ctl で Web カメラのデバイス名を確認してみます。
sudo apt install v4l-utils
$ v4l2-ctl --list-devices
UVC Camera (046d:0821) (usb-0000:00:14.0-9):
/dev/video0
/dev/video1
/dev/media0
$ v4l2-ctl -d 0 -D
Driver Info:
Driver name : uvcvideo
Card type : UVC Camera (046d:0821)
Bus info : usb-0000:00:14.0-9
Driver version : 5.4.44
Capabilities : 0x84a00001
Video Capture
Metadata Capture
Streaming
Extended Pix Format
Device Capabilities
Device Caps : 0x04200001
Video Capture
Streaming
Extended Pix Format
Media Driver Info:
Driver name : uvcvideo
Model : UVC Camera (046d:0821)
Serial : 29249F90
Bus info : usb-0000:00:14.0-9
Media version : 5.4.44
Hardware revision: 0x00000010 (16)
Driver version : 5.4.44
Interface Info:
ID : 0x03000002
Type : V4L Video
Entity Info:
ID : 0x00000001 (1)
Name : UVC Camera (046d:0821)
Function : V4L2 I/O
Flags : default
Pad 0x01000007 : 0: Sink
Link 0x0200001c: from remote pad 0x100000a of entity 'Extension 4': Data, Enabled, Immutable
/proc/asound を確認してみます。card2 が追加されていました。
~$ ls -al /proc/asound
total 0
dr-xr-xr-x 7 root root 0 7月 11 22:05 .
dr-xr-xr-x 305 root root 0 7月 11 22:05 ..
dr-xr-xr-x 5 root root 0 7月 11 22:05 card0
dr-xr-xr-x 5 root root 0 7月 11 22:05 card1
dr-xr-xr-x 3 root root 0 7月 11 22:13 card2
-r--r--r-- 1 root root 0 7月 11 22:09 cards
-r--r--r-- 1 root root 0 7月 11 22:10 devices
-r--r--r-- 1 root root 0 7月 11 22:10 hwdep
-r--r--r-- 1 root root 0 7月 11 22:10 modules
lrwxrwxrwx 1 root root 5 7月 11 22:10 NVidia -> card1
dr-xr-xr-x 2 root root 0 7月 11 22:10 oss
lrwxrwxrwx 1 root root 5 7月 11 22:10 PCH -> card0
-r--r--r-- 1 root root 0 7月 11 22:10 pcm
dr-xr-xr-x 2 root root 0 7月 11 22:10 seq
-r--r--r-- 1 root root 0 7月 11 22:10 timers
lrwxrwxrwx 1 root root 5 7月 11 22:17 U0x46d0x821 -> card2
-r--r--r-- 1 root root 0 7月 11 22:10 version
/proc/asound/cards を確認してみます。Web カメラの番号は 2 に設定されていました。
$ cat /proc/asound/cards
0 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xf7110000 irq 32
1 [NVidia ]: HDA-Intel - HDA NVidia
HDA NVidia at 0xf7080000 irq 17
2 [U0x46d0x821 ]: USB-Audio - USB Device 0x46d:0x821
USB Device 0x46d:0x821 at usb-0000:00:14.0-3, high speed
/proc/asound/devices を確認してみます。
$ cat /proc/asound/devices
2: [ 0- 0]: digital audio playback
3: [ 0- 0]: digital audio capture
4: [ 0- 2]: digital audio capture
5: [ 0- 0]: hardware dependent
6: [ 0] : control
7: [ 1- 3]: digital audio playback
8: [ 1- 7]: digital audio playback
9: [ 1- 8]: digital audio playback
10: [ 1- 0]: hardware dependent
11: [ 1] : control
12: [ 2- 0]: digital audio capture
13: [ 2] : control
33: : timer
/proc/asound/pcm を確認してみます。
$ cat /proc/asound/pcm
00-00: ALC887-VD Analog : ALC887-VD Analog : playback 1 : capture 1
00-02: ALC887-VD Alt Analog : ALC887-VD Alt Analog : capture 1
01-03: HDMI 0 : HDMI 0 : playback 1
01-07: HDMI 1 : HDMI 1 : playback 1
01-08: HDMI 2 : HDMI 2 : playback 1
02-00: USB Audio : USB Audio : capture 1
arecord コマンドを実行してみます。オーディオをキャプチャするハードウェアで card 2 として Web カメラが設定されていました。
$ arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC887-VD Analog [ALC887-VD Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 2: ALC887-VD Alt Analog [ALC887-VD Alt Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: U0x46d0x821 [USB Device 0x46d:0x821], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
/proc/asound/modules を確認してみます。Web カメラを示す snd_usb_audio には 2 が設定されていました。
$ cat /proc/asound/modules
0 snd_hda_intel
1 snd_hda_intel
2 snd_usb_audio
Web カメラには必ず 0 が設定されるようにしてみます。例えば下記のように /etc/modprobe.d の下に conf ファイルを作成してみます。
sudo sh -c "echo 'options snd slots=snd_usb_audio,snd_hda_intel,snd_hda_intel' >> /etc/modprobe.d/alsa-base.conf"
sudo sh -c "echo 'options snd_usb_audio index=0' >> /etc/modprobe.d/alsa-base.conf"
sudo sh -c "echo 'options snd_hda_intel index=1' >> /etc/modprobe.d/alsa-base.conf"
sudo sh -c "echo 'options snd_hda_intel index=2' >> /etc/modprobe.d/alsa-base.conf"
作成後、OS を再起動してみます。再起動後 /proc/asound/cards を確認すると、Web カメラのオーディオデバイスの番号に 0 が設定されていました。
$ cat /proc/asound/cards
0 [U0x46d0x821 ]: USB-Audio - USB Device 0x46d:0x821
USB Device 0x46d:0x821 at usb-0000:00:14.0-9, high speed
1 [NVidia ]: HDA-Intel - HDA NVidia
HDA NVidia at 0xf7080000 irq 17
2 [PCH ]: HDA-Intel - HDA Intel PCH
HDA Intel PCH at 0xf7110000 irq 32
/proc/asound/modules を確認してみます。Web カメラを示す snd_usb_audio には 0 が設定されていました。
$ cat /proc/asound/modules
0 snd_usb_audio
1 snd_hda_intel
2 snd_hda_intel
/proc/asound/card0/pcm0c/info を確認してみます。Web カメラのオーディオデバイスの card は 0, device は 0 でした。
$ cat /proc/asound/card0/pcm0c/info
card: 0
device: 0
subdevice: 0
stream: CAPTURE
id: USB Audio
name: USB Audio
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 1
以上により、FFmpeg で Web カメラの映像とマイクの音声をリアルタイムにエンコードする際に、FFmpeg のオプションとして Web カメラのオーディオデバイスを “hw:0,0″ のように固定化することができます。”hw:X,Y” において,X は card, Y は device を指すようです。また、”hw:0,0″ は “default” として設定してもよさそうです。
なお、Web カメラの映像とマイクの音声をキャプチャしたい場合、キャプチャを実行するユーザーを video グループと audio グループに追加しておく必要があります。追加後、設定を反映させたい場合は、いったんログオフしてログインし直すか、OS を再起動する必要があります。
sudo gpasswd -a $USER video
sudo gpasswd -a $USER audio
Web カメラのマイクの音声をキャプチャしようとしているユーザーが audio グループに所属していない場合、FFmpeg では下記のようなエラーが表示されます。
ALSA lib pcm_hw.c:1401:(_snd_pcm_hw_open) Invalid value for card
[alsa @ 0x1217140] cannot open audio device hw:0,0 (No such file or directory)
hw:0,0: Input/output error