systemd-nspawn コンテナの中の web ブラウザからホストに繋いだ web カメラを使う
人生とは不思議なもので、掲題のようなことをしたくなることがある。
より具体的には意地でも専用のクライアントをインストールしない(できない)という決意の下で Zoom や Meet を使わざるを得なくなることがあり、Zoom や Meet を web ブラウザで使うには Chrome 系のそれを使うのが確実である*1。しかし依存関係で GTK が入る為 Chromium を入れたくないという事情がある。
システムに直接いれたくないアプリケーションを誤魔化し使うにはコンテナにして使うのがそれなりにラクなので、必然的に nspawn コンテナへ Chromium をインストールして Zoom や Meet を使うということになる。そしてこれらを使う事情というのは web カメラで映像を写し、マイクに音を拾わせる、といったことになる。
そういったことをやる為に四苦八苦し、結果としてなんとかなったので記録しておく。
前提
たぶんデバイスに依存しない内容にはなっていると思うが一応記載しておく。使っている web カメラはこれ:
準備
web カメラがどのようなデバイスとして認識されているかを確認しておく:
$ v4l2-ctl --list-devices HD Pro Webcam C920 (usb-0000:00:1a.0-1.5.3): /dev/video0 /dev/video1 /dev/media0
この場合は以下が設定対象のデバイスとなる:
/dev/video0
/dev/video1
/dev/media0
以下、本項では上記3デバイスを設定対象としてゆく。
設定
nspawn コンテナ側と systemd-nspawn サービス側の各設定を修正する必要がある。
以下では nspawn コンテナの名前を CONTAINER
とする。
nspawn コンテナ側
/etc/systemd/nspawn/
下に存在するはずの CONTAINER.nspawn
設定内 [Files]
下に以下を追加する:
Bind=/dev/video0 Bind=/dev/video1 Bind=/dev/media0
これでひとまず対象のデバイスが nspawn コンテナ側からも見れるようになる。設定の意味合いは systemd-nspawn のドキュメント が詳しい。
systemd-nspawn サービス側
/etc/systemd/system/systemd-nspawn@CONTAINER.service.d/
下に override.conf
を以下のように用意する:
[Service] DeviceAllow=/dev/video0 rwm DeviceAllow=/dev/video1 rwm DeviceAllow=/dev/media0 rwm
これも詳細は systemd のドキュメント が詳しい。要するに当該デバイス名で参照されるデバイスを適切に使えるよう設定をいれるといったもの。
nspawn コンテナ準備
CONTAINER
なコンテナが既に起動していれば再起動する。止まっていれば起動する。
もちろん CONTAINER
なコンテナで web カメラを使いたい X アプリケーションが動くようになっている必要もある。このあたりは以下の拙稿が参考になるかもしれない:
Chromium を起動
nspawn コンテナ内に Chromium を何らかの方法で入れ、ホスト側から起動する。そのあたりも前掲の拙稿を参考のこと。
おわり
Chromium も専用クライアントもインストールしたくないが Linux 上で Zoom や Meet を使わなければならなくなった方のお役に立てれば幸い。
参考
- systemd.resource-control
- Access webcam using OpenCV (Python) in Docker? - Stack Overflow
- systemd-nspawn - ArchWiki
*1:別のネタになるかもしれなかったので Qt5 を使うブラウザで検証した:
qutebrowser:遅いがなんとか使える。
Falkon:一見使えそうだがマイクが音をうまく拾えない。
Konqueror:マイクもカメラも認識しない。
ただし検証に使用した機械は ThinkPad X201s などという12年前の代物であり、パフォーマンスの問題は機械の影響である可能性が非常に高い。