Raspberry Pi で動いている Docker の中から PulseAudio 経由で音を鳴らす
環境
- ホスト: Arch Linux ARM on Raspberry Pi 2 Model B
- コンテナ: armv7/ubuntu:14.04 on Docker
たぶんホストが Arch Linux ARM ではなくても pacman
が apt-get
に変わるとかそれぐらいだと思います。
コンテナも ARM 版 Ubuntu である必要はないはずです。保証はしませんが……。
ホストの設定
PulseAudio のインストール
pacman
経由で PulseAudio をインストールします。
pulseaudio --start
で PulseAudio のデーモンが立ち上がり、
/run/user/$uid/pulse/native
というファイルができます
($uid
はデーモンを起動したユーザーのユーザー ID です)。
このファイルは Unix ドメインソケットになっていて、ここにデータを書き込むことで音声を再生できるようになります。
また、pulseaudio --kill
でデーモンを終了させることができます。
基本的にソケットファイルはデーモンが動いている間だけ存在しますが、
systemd のソケットアクティベーションという機能を使うと、
/run/user/$uid/pulse/native
にアクセスがあった場合に自動で PulseAudio を立ち上げることができるらしいです。
systemctl --user start pulseaudio.socket
でこの機能を有効化できて、
systemctl --user enable pulseaudio.socket
でこの機能を永続化できます。
クッキーの設定
デフォルトでは /run/user/$uid/pulse/native
への書き込みの際にクッキー (?) を用いた認証機能がついています。
この認証によって、音声を再生するためにはソケット (/run/user/$uid/pulse/native
) への書き込み権限のほかに、
クッキー (/home/$user/.config/pulse/cookie
) の読み込み権限が必要になります (/home/$user
はデーモンを立ち上げたユーザーのホームディレクトリです)。
/etc/pulse/default.pa
をいじることで、この機能を無効にできます。
load-module module-native-protocol-unix
という行を
load-module module-native-protocol-unix auth-anonymous=1
に変更することで達成できます。
認証が有効なままでもクッキーをコンテナへとマウントしてしまえばほとんど問題はないので、
以降は無効化しないときの設定方法を記述します。
無効化すると以降の記述で /home/$user/.config/pulse/cookie
および $SERVER_COOKIE
に関する
設定をスキップできます。
コンテナの設定
ソケット・クッキーのマウント
docker run
でコンテナを作成するわけですが、
その際に以下の 2 つを -v
オプションなどを使ってコンテナ内部にマウントします。
/run/user/$uid/pulse/native
/home/$user/.config/pulse/cookie
$user
と $uid
は適切なものに置き換えておいてください。
また、マウントしようとしているファイルがきちんと存在することも確認してください。
環境変数の設定
以下の環境変数をコンテナ内で設定します。
PULSE_SERVER=unix:/path/to/native
PULSE_COOKIE=/path/to/cookie
/path/to/native
および /path/to/cookie
はそれぞれ
/run/user/$uid/pulse/native
と /home/$user/.config/pulse/cookie
のマウント先のパスを指定してください。
PulseAudio のインストール
apt-get install pulseaudio
するだけです。
こうすることで、コンテナ内のプログラムたちは PulseAudio を通じてホスト側に音声を送ることが可能になります。
[ユーザープログラム] → [PulseAudio in Docker] → [Unix ドメインソケット] → [PulseAudio in Host] → [スピーカーなど]
おそらくこういう経路で音声が送られるはずです。
mpg321
音声を再生するプログラムとして今回は mpg321 を使います。
apt-get
経由でコンテナ内にインストールしてください。
あとは設定がうまくいっていれば mpg321 test.mp3
で音声が再生できていると思います。
デフォルト設定では mpg321 は ALSA を使って音声を再生しようとします。
これはコンテナ側の Ubuntu では (たぶん apt-get install pulseaudio
のときに ALSA から PulseAudio へのリダイレクトが自動で設定されるので) 問題ないですが、ホスト側の Arch Linux で mpg321 を用いて音声の同時再生をしようとすると問題になります。
ホスト側では /etc/libao.conf
の中身をすべて削除して default_driver=pulse
と書くことで解決できます。
pulseaudio-alsa パッケージをインストールして ALSA から PulseAudio へのリダイレクトを設定すると解決するのかもしれませんが、そちらの解決方法はよくわからなかったのでやめました。
参考資料
- https://wiki.archlinux.org/index.php/PulseAudio
- https://wiki.archlinux.org/index.php/PulseAudio/Configuration