ぶていのログでぶログ

思い出したが吉日

Linuxでもビデオチャットでバーチャル背景みたいなことがしたいのでゼーレになってみた

昨今のWFHの流れで弊社でもビデオチャットをしているわけですが、Linuxデスクトップ環境だとバーチャル背景が使えないんですよねぇ。。 WindowsやmacOSなら、Zoomの標準機能でできたりSnap Cameraなどのアプリを使えば実現できます。 これらの機能はLinuxデスクトップ環境ではオミットされているんですよね… 😢 WindowsやmacOSでできて、LinuxではできないわけがないのでOSSで頑張ってみた!というのがこの記事。 素直にiPad Proを買え

v4l2loopback

ビデオチャットアプリはWebカメラデバイスに直接アクセスして動画を生成しています。 その経路をインターセプトするのは難しいので仮想的なビデオデバイスを作ることで解決します。 それが、v4l2loopbackカーネルモジュールです。

github.com

このモジュールをインストールすると仮想的なWebカメラデバイスを作成してくれます。 v4l2互換なので、v4l2に対応したLinuxアプリから設定なしで利用できます。便利。

インストール

ここではUbuntu19.10での手順を書きます。私の手元の環境なのでこれ。 Ubuntuであれば、公式のパッケージ一覧にあるのでapt installするだけです。便利。

❯ sudo apt install v4l2loopback-dkms v4l2loopback-source v4l2loopback-utils

ここで注意しないといけないのは、Secure Bootが有効な場合サードパーティ製のドライバが利用できないこと。 しかしながら、ここらへんも良くできていてapt install実行中に以下のような画面が表示される。

f:id:buty4649:20200410185910p:plain

これの次の画面でパスワードを2回入力させられる。 その後一旦再起動すると、MOK Managerが起動して青い画面が表示される。 この画面で Enroll key を選択して先程入力したパスワードを入力すると、新しいkeyが登録されてサードパーティ製のドライバが使えるようになる。 MOK Managerの画面はUbuntu WIkiにのっているのでそちらを参考にしてほしい。

設定

インストールができたら早速modprobeする。 以下のようなコマンドを打つとロードされるはず。

❯ modprobe v4l2loopback devices=1 video_nr=20 card_label="v4l2loopback" exclusive_caps=1

仮想デバイスは1つ、ビデオ番号( /dev/videoXX )は20、ビデオデバイスの名前は v4l2loopback に設定される。 また exclusive_caps=1 をつけないとChromeで認識されないみたいなのをどこかでみた。

ロードができると /dev/video20 が生えているはず。

❯ ls -lah /dev/video20
crw-rw----+ 1 root video 81, 0  4月 10 18:22 /dev/video20

ただ、これだと再起動してしまうとロードされないので以下のような設定をすると再起動後にも自動でロードされるようになる。

❯ cat /etc/modules-load.d/v4l2loopbook.conf
v4l2loopback

❯ cat /etc/modprobe.d/v4l2loopback.conf
options v4l2loopback devices=1 video_nr=20 card_label="v4l2loopback" exclusive_caps=1

ffmpegを使って画像を配信してみる

これで下準備ができたので早速配信してみます。 ちょうど各企業が背景画像を配っているのでそれを使ってみます。 今回選んだのは、エヴァンゲリオン壁紙! ベタベタだけどゼーレになりきってみるw

www.evangelion.co.jp

上記サイトから壁紙をダウンロードして、以下のコマンドを打つと配信が開始できます。

❯ ffmpeg -loop 1 -re -i soundonly_1_re.jpg -vf scale=914:914,format=yuv420p -aspect 1:1 -f v4l2 -vcodec rawvideo -pix_fmt yuv420p /dev/video20

実際に、Meetでみてみるとこんな感じになります。

f:id:buty4649:20200410191544p:plain

画像が反転しているのはMeetの仕様のようです。 実物のWebカメラを使った場合は、左右反転することになるのでそれを意識して反転をかけているのだと思います。

おわりに

v4l2loopback+ffmpegを使えば簡単にゼーレになれることがわかりました。 ただし、この方法欠点があって、静止画像を配信しているだけなのですが、Meetで動画配信するとかなりのCPUパワーを持っていかれるということ。。 動画配信なしでアイコン表示にしたほうが、CPUパワーを抑えられてとてもエコです。。

また、最終的な目標である、バーチャル背景を再現するのにはまだ工夫が必要そうです。 しかし、実際にバーチャル背景アプリを作っている(提案している?)方がいるのでこちらを参考にすると実現できそうな気がします。

elder.dev

っと書いたのですが、実は↑のサイトを発見してv4l2loopbackを知って今回のネタに行き着いたのが真相だったりします 😅 上記サイトでは詳しく解説されているので、ドスキレアジの上ヒレ集めの合間に作ってみようかなぁって思ってます。