v4l2loopback
関連記事
プロジェクトのリポジトリより:
- v4l2loopback - V4L2 ループバックデバイスを作成するためのカーネルモジュール
- このモジュールにより、"仮想ビデオデバイス"を作成することができます。通常の (v4l2) アプリケーションは仮想ビデオデバイスを通常のビデオデバイスかのように読み取りますが、ビデオはキャプチャカードなどから読み取られずに他のアプリケーションによって生成されます。
インストール
v4l2loopback-dkms パッケージに加えて対象のカーネルのヘッダーファイルもインストールしてください (Dynamic Kernel Module Support#インストール を参照)。例えば、デフォルトの linux カーネルの場合、ヘッダファイルは linux-headers です。他のカーネルにはそれぞれのヘッダファイルパッケージがあります
コマンドラインユーティリティは v4l2loopback-utils と v4l-utils によって提供されています。
この記事で紹介している使用例の多くは ffmpeg も使用します。
カーネルモジュールをロードする
v4l2loopback
カーネルモジュールは Dynamic Kernel Module Support でロードすることができます:
# modprobe v4l2loopback
v4l2-ctl
を使って全てのビデオデバイスを一覧表示することができます。v4l2loopback
デバイスが新たに現れるはずです:
$ v4l2-ctl --list-devices
v4l2loopback
は、デバイスの作成に関する様々なオプションを指定してロードすることができます:
# modprobe v4l2loopback video_nr=9 card_label=Video-Loopback exclusive_caps=1
このコマンドにより、/dev/video9
がループバックデバイスとして作成されます。exclusive_caps=1
は一部の Chromium/WebRTC ベースのアプリケーション (jitsi-meet-desktop-binAUR や zoomAUR など) で必要です。その他のオプションは公式のドキュメントで確認できます。
モジュールがすでにロードされている場合、上記のコマンドを実行してもおそらく何も起こりません。モジュールをまずアンロードし、その後にロードし直す必要があります:
# modprobe -r v4l2loopback
詳細は カーネルモジュール#手動でモジュールを扱う を参照してください。
devices
引数を使うことで、複数のループバックデバイスを作成することができます。それぞれのデバイスのオプションはコンマで区切って指定します。以下のコマンドは、exclusive_caps
が有効化された 3 つのループバックデバイスを作成します。ループデバイスは、/dev/video8
、/dev/video9
、そして利用可能な最初の /dev/videoX
となります。
# modprobe v4l2loopback devices=3 video_nr=8,9 exclusive_caps=1,1,1 card_label="Loopback-1,Loopback-2,Loopback-3"
システムを再起動するとモジュールがアンロードされてしまいますが、起動時にカスタムのデバイスオプションを指定してモジュールを自動的にロードさせることができます。これは、ループバックデバイスが内部ウェブカメラとして使用されている場合に便利です。詳細は カーネルモジュール#モジュールの自動ロード と公式のドキュメントを参照してください。
v4l2loopback のビデオフィードを見る
ループバックデバイス /dev/video0
は、ffplay
(ffmpeg に同梱)、mpv、または gst-launch
(gstreamer に同梱) を使ってプレビューすることができます:
$ ffplay /dev/video0 $ mpv av://v4l2:/dev/video0 $ gst-launch-1.0 -v v4l2src device=/dev/video0 ! glimagesink
#カーネルモジュールをロードする で説明されている通り、exclusive_caps=1
を使えば、Chromium や jitsi-meet-desktop-binAUR や zoomAUR といったアプリケーションはループバックデバイスを仮想ウェブカメラとして使用することができるようになるはずです (ビデオストリームがそのループバックデバイスにパイプで接続されている限り)。webcamtests.com でブラウザで仮想ウェブカメラをテストできます。
ウェブカメラ#アプリケーション も参照してください。
使用例
一般に、FFmpeg は v4l2loopback と組み合わせて使うと非常に便利です。FFmpeg は、ffmpeg
の引数 -vf format=yuv420p -f v4l2
を使用することにより、様々な入力ストリームを広くサポートされている yuv420p ピクセルフォーマットにトランスコードし、その出力を v4l2loopback デバイスにパイプで接続できるからです。以下の例を参照してください。
また、FFmpeg は v4l2loopback デバイスを入力ストリームとして使用することもできます。FFmpeg#ウェブカメラの録画 を参照してください。
GStreamer もまた、v4l2loopback デバイスをソースやシンクとして使用することができます。
その他の例はv4l2loopback の公式 wikiにあります。
スクリーンキャスト
以下は、仮想ウェブカメラとして使用できる v4l2 ループバックデバイスにスクリーンをストリーミングして、画面共有を実装する例です。
FFmpeg を使って X11 をキャストする
FFmpeg を使用することにより、X11 ディスプレイ上の領域を選択して、その領域を v4l2 ループバックデバイスへストリーミングすることができます:
$ ffmpeg -f x11grab -select_region 1 -show_region 1 -framerate 25 -i $DISPLAY -vf format=yuv420p -f v4l2 /dev/video0
全ての引数説明は x11grab docs を参照してください。
wf-recorder を使って Wayland をキャストする
wf-recorder (または wf-recorder-gitAUR) をインストールしてください。wf-recorder
で画面の録画を開始し、映像を v4l2 ループバックデバイスにストリーミングするには、以下を使用してください:
$ wf-recorder --muxer=v4l2 --codec=rawvideo --file=/dev/video0 -x yuv420p
Unknown V4L2 pixel format equivalent for rgb0
というエラーが発生した場合、--force-yuv
または -t
を付けて wf-recorder
を実行して、GPU へデータを送る前にデータから yuv フォーマットへの変換を強制してください。[1]
特定の領域のみをスクリーンキャストする
先のセクションで説明した通り、slurp で領域を選択しておくことにより、wf-recorder
は画面の一部分のみを録画することができます。この機能を使って仮想ビデオデバイスを介して特定の領域/アプリケーションウィンドウを共有するには、以下の修正されたコマンドを使って画面の録画を開始してください:
$ wf-recorder -g "$(slurp)" --muxer=v4l2 --codec=rawvideo --file=/dev/video0 -x yuv420p
gPhoto でフォトカメラをウェブカメラとして使う
gPhoto がインストールされていて、あなたのカメラで動作可能である場合、gphoto2
と FFmpeg を使ってカメラのライブビューストリームを v4l2 ループバックデバイスにパイプで流すことができます:
$ gphoto2 --stdout --capture-movie | ffmpeg -i - -vf format=yuv420p -f v4l2 /dev/video0
トラブルシューティングは gPhoto#トラブルシューティング を参照してください。この方法は、official gPhoto のウェブサイトにリストアップされているライブビュー機能を搭載している全てのカメラでうまく行くはずです。
ネットワークストリームをウェブカメラとして使う
FFmpeg を使って、ネットワークストリームをキャプチャし、そのデータを v4l2 ループバックデバイスにパイプで流すことができます:
$ ffmpeg -i http://ip_address:port/video -vf format=yuv420p -f v4l2 /dev/video0
Android デバイスをウェブカメラとして使う
Android では、IP Webcam を使って、ネットワークビデオストリームをブロードキャストすることができます。その場合、上記のコマンドを使ってデータを v4l2 ループバックデバイスにパイプで流し、デバイスをウェブカメラのように使用することができます。IP Webcam はデフォルトで 8080 ポートを使用します。
ネットワーク接続にもよりますが、WiFi 経由のネットワークストリームは高レイテンシである場合があり、スタッタリングが発生する可能性があります。あなたのコンピュータと Android デバイスで Android Debug Bridge が設定されている場合、adb forward
を使って USB ケーブル経由でストリームをトンネルすることができます。これにより、より安定した接続を得られます:
$ adb wait-for-usb-device && adb forward tcp:8080 tcp:8080 && ffmpeg -i http://127.0.0.1:8080/video -vf format=yuv420p -f v4l2 /dev/video0
ビデオ会議で背景画像を使用する
Microsoft Teams や Zoom といったビデオ会議ソフトウェアで背景を隠す/置き換える方法がいくつかあります。
OBS
OBS は動画配信者がビデオフィードの切り替えのためにリアルタイムの動画管理システムとして使っています。複数の "シーン" をセットアップすることができ (例えば、それぞれに異なる背景画像を設定するなど)、ボタンクリックでそれらを切り替えることができます。また、他のビデオフィルタを提供したり (新しいフィルタ用のプラグインシステムがあります)、複数のビデオフィードを同時に表示したりなどもできます。OBS は出力を v4l2loopback デバイスに送ることができ、V4L2 カメラをサポートする他のアプリケーションで使用することができます。
これをセットアップするには:
- メインの obs-studio パッケージと obs-backgroundremovalAUR プラグインをインストールしてください。
obs
を起動し、実際のカメラを入力ソースとしてシーンに追加してください。- カメラソースを右クリックしてフィルターを編集し、背景除去フィルタを追加してください。この状態では、背景が除去され、黒い背景のみが表示されているはずです。(詳細設定で、背景の除去ではなくぼかしを掛けることもできます。)
- "画像" タイプの他の入力ソースを追加し、所望の背景画像を選択してください。ソースのタイプは動画ファイルや他のウェブカメラにすることもできますが、うまく行くまでは画像で試しましょう。
- ソースリスト内の画像エントリをドラッグし、映像ソースより下に配置してください。これで、背景画像が映像ソースより前ではなく後ろに表示されます。
- 背景画像を移動/リサイズして、シーンの大部分を占めるようにしてください。
- 仮想出力を有効化すれば、仮想ウェブカメラの準備は完了です。
obs
は、ビデオ会議ソフトウェアで仮想カメラを使えるようにするには、仮想出力を有効化した状態で走らせ続けておく必要があります。
映像がおかしかったり何も表示されない場合は (出力の解像度を変更した後によく起こります)、V4L2 ループバックデバイスを一旦削除し、再度作り直す必要があるかもしれません (または、v4l2loopback
モジュールを一旦アンロードし、再度ロードし直す)。
トラブルシューティングは上記の #v4l2loopback のビデオフィードを見る を見てください。これらのプログラムでフィードを正しく再生できるのであれば、問題はビデオフィードを取り入れている側のアプリケーションにあります。これらのユーティリティで動画を正しく再生できない場合は、ループバックデバイスのセットアップに問題があります。
トラブルシューティング
Firefox
Firefox がビデオストリームを読み込むことができず、AbortError: Starting video failed
のようなメッセージが出力される場合、v4l2compat.so をプリロードしてみてください:
$ LD_PRELOAD=/usr/lib/v4l1compat.so firefox
ioctl(VIDIOC_G_FMT)
ffmpeg
でビデオデバイスを使おうとしたときに ioctl(VIDIOC_G_FMT)
エラーが発生する場合、カーネルモジュールを一旦アンロードし、再びロードし直してみてください。 [2]