ラズパイのmomoで音声付きでWebRTCで配信する

WebRTC界隈で最近momoが流行っているようなので私も試してみました。

# WebRTC Native Client Momo
https://github.com/shiguredo/momo


ラズパイの場合は実行ファイルがダウンロードできるので、コンパイルすることなしにすぐに試すことができます。
以下の手順に従うと音声無しの映像の配信はすぐに行うことができました。
https://github.com/shiguredo/momo/blob/develop/doc/USE.md

しかし、音声と映像を配信するときにちょっと手間取りました。

# オーディオキャプチャデバイスが見つからない？

最初に`--no-audio` をつけずに動かすと映像は出るのに音声は出ませんでした。
`--log-level 0` をつけて動かしてログを調べてみると、どうやらALSAの`default` というオーディオキャプチャデバイスにつなごうとしてそれが見つからないようでした。
さらに試行錯誤して、サンプリングレート48kHz, ステレオ に対応するマイクが`default` という名前で参照可能になっている必要があることがわかりました。

# オーディオキャプチャデバイスの指定方法

オーディオキャプチャデバイスの指定方法として以下の2つがあります。これのどちらかをすればよいです。それぞれ説明します。
- pulseaudio を入れてそれに任せる
- ALSAのconfigファイルを用意する


## pulseaudio を入れてそれに任せる

pulseaudio をインストールします。
するとpulseaudioサーバが利用可能なオーディオキャプチャデバイスを`default` という名前で参照可能にしてくれます。大抵の場合はこれでうまくいくと思います。

```
sudo apt install pulseaudio
```

Desktop版のRaspbianをインストールしてあると最初からこれが入っています。

## ALSAのconfigファイルを用意する

pulseaudioサーバを入れると依存関係から多くのライブラリがインストールされます。システムをシンプルに保ちたいならば、これを入れるのでなくてALSAのコンフィグファイルを書いて明示的に`default`の割り当てを行います。

### pulseaudioが入っている場合はそれをuninstallする

```
sudo apt remove pulseaudio
sudo reboot
```

### 利用可能なオーディオキャプチャデバイスの確認

マイクとして、Logicoolのc270 のWebcamの内蔵のマイクをつないでいます。
このマイクは サンプリングレート32kHz モノラルなので、サンプリングレート48kHz ステレオにするためにはソフトウェア的に変換が必要です。このためにALSAの`plughw`で始まるデバイスを使用します。

```
$ arecord -L
null
    Discard all samples (playback) or generate zero samples (capture)
default:CARD=U0x46d0x825
    USB Device 0x46d:0x825, USB Audio
    Default Audio Device
sysdefault:CARD=U0x46d0x825
    USB Device 0x46d:0x825, USB Audio
    Default Audio Device
front:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    Front speakers
surround21:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    4.0 Surround output to Front and Rear speakers
surround41:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    IEC958 (S/PDIF) Digital Audio Output
dmix:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    Direct sample mixing device
dsnoop:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    Direct sample snooping device
hw:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    Direct hardware device without any conversions
plughw:CARD=U0x46d0x825,DEV=0
    USB Device 0x46d:0x825, USB Audio
    Hardware device with all software conversions
```

`CARD=` の部分は使用するマイクによって異なってきます。

最後に出た `plughw:CARD=U0x46d0x825,DEV=0` を`default` として参照できるように設定ファイルを書きます。

設定ファイルにはいくつか選択肢がありますが `~/.asoundrc` にしました。


```~/.asoundrc
pcm.!default {
    type plug
    slave {
       pcm "hw:CARD=U0x46d0x825,DEV=0"
    }
}

ctl.!default {
    type hw
    card U0x46d0x825
}
```

### 確認

```
$ arecord -D default -f dat a.wav
Recording WAVE 'a.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
```

これがエラーにならないことを確認します。適当なところでCrtl-Cで止めます。

これでmomoから音声付きで配信できるようになりました。

# 付録

## うまくオーディオキャプチャデバイスが見つかって、音声と映像の配信ができるときのログ

```
 $ ./momo --log-level 2 --port 8000 p2p
[002:001] [624] (device_video_capturer.cpp:80): Get Capture
[002:004] [624] (audio_device_impl.cc:274): Linux ALSA APIs will be utilized.
[002:023] [627] (audio_device_alsa_linux.cc:160): failed to open X display, typing detection will not work
[002:220] [627] (audio_mixer_manager_alsa_linux.cc:941): Could not find output volume in the mixer.
[002:221] [627] (adm_helpers.cc:48): Unable to access speaker.
[002:270] [627] (audio_mixer_manager_alsa_linux.cc:941): Could not find output volume in the mixer.
[002:270] [627] (audio_device_alsa_linux.cc:763): InitSpeaker() failed
[002:319] [627] (audio_device_alsa_linux.cc:800): unable to open playback device: No such file or directory (-2)
[003:592] [627] (audio_device_generic.cc:17): BuiltInAECIsAvailable: Not supported on this platform
[003:594] [627] (render_delay_buffer.cc:341): Applying total delay of 5 blocks.
[003:598] [627] (audio_device_generic.cc:27): BuiltInAGCIsAvailable: Not supported on this platform
[003:598] [627] (audio_device_generic.cc:37): BuiltInNSIsAvailable: Not supported on this platform
```

`InitSpeaker() failed` と出ているが音は出さないので気にしなくてよい。


## オーディオキャプチャデバイスが見つからずに音が出ないときのログ


```
$ ./momo --log-level 2 --port 8000 p2p
[001:996] [637] (device_video_capturer.cpp:80): Get Capture
[001:999] [637] (audio_device_impl.cc:274): Linux ALSA APIs will be utilized.
[002:017] [640] (audio_device_alsa_linux.cc:160): failed to open X display, typing detection will not work
[002:467] [640] (audio_mixer_manager_alsa_linux.cc:880): Could not find capture volume on the mixer.
[002:467] [640] (adm_helpers.cc:68): Unable to access microphone.
[002:516] [640] (audio_mixer_manager_alsa_linux.cc:880): Could not find capture volume on the mixer.
[002:516] [640] (audio_device_alsa_linux.cc:884): InitMicrophone() failed
[002:567] [640] (audio_device_alsa_linux.cc:923): unable to open record device: No such file or directory
[002:569] [640] (audio_device_generic.cc:17): BuiltInAECIsAvailable: Not supported on this platform
[002:571] [640] (render_delay_buffer.cc:341): Applying total delay of 5 blocks.
[002:573] [640] (audio_device_generic.cc:27): BuiltInAGCIsAvailable: Not supported on this platform
[002:574] [640] (audio_device_generic.cc:37): BuiltInNSIsAvailable: Not supported on this platform
```

`Unable to access microphone.` と出てる。

## 関連

[ラズパイ+momoでWebRTCで送信するときにマイクの代わりに音声ファイルを使用する](https://qiita.com/tetsu_koba/items/b887c1a0be9f26b795f2)