🍒

WebRTC momoでカメラのサポートしていない解像度、フレームレートで送信する

2023/04/04に公開

momoでの--resolution--framerate のオプションはカメラにそれを伝えるだけで、実際の解像度とフレームレートはカメラが決めます。指定できる値はカメラによって異なります。それを調べる方法はことページを参照してください。
https://qiita.com/tetsu_koba/items/01491f96daddf15677df

では、カメラがサポートしていない解像度、フレームレートで配信したいときはどうすればよいでしょうか?
例えば、640x640の正方形で12fpsで配信したいとします。
momoが直接カメラデバイスを読むのでなく、カメラデバイスから読んだ映像をffmpegで加工し、v4l2loopbackで仮想ビデオデバイスに書き込み、momoはそこから読むようにすれば実現できます。

動作環境

jetson nano 2GBを使用しました。

$ cat /proc/version 
Linux version 4.9.299-tegra (buildbrain@mobile-u64-5333-d8000) (gcc version 7.3.1 20180425 [linaro-7.3-2018.05 revision d29120a424ecfbc167ef90065c0eeb7f91977701] (Linaro GCC 7.3-2018.05) ) #1 SMP PREEMPT Tue Nov 22 09:24:39 PST 2022
$ ./momo --version
nvbuf_utils: Could not get EGL display connection
WebRTC Native Client Momo 2022.4.1 (75f36b51)

WebRTC: Shiguredo-Build M107.5304@{#4} (107.5304.4.0 eef098d1)
Environment: [aarch64] Ubuntu 18.04.6 LTS (nvidia-l4t-core 32.7.3-20221122092935)

USE_MMAL_ENCODER=0
USE_JETSON_ENCODER=1
USE_NVCODEC_ENCODER=0
USE_SDL2=1

v4l2loopback

インストール

$ sudo apt install v4l2loopback-dkms

動作確認

$ ls /dev/video*
/dev/video0
$ sudo modprobe v4l2loopback
$ ls /dev/video*
/dev/video0  /dev/video1

/dev/video1ができました。

v4l2loopbackとffmpeg を使って映像を加工し、それをmomoで送信する

ffmpeg -loglevel error -f v4l2 -s 640x640 -i /dev/video0 \
	-vf crop=w=480:h=480 -r 12 -pix_fmt yuv420p -f v4l2 /dev/video1 &

sleep 3
./momo --no-audio-device --log-level 3 --video-device /dev/video1 \
	--resolution 480x480 --framerate 12 --hw-mjpeg-decoder false \
	ayame --signaling-url $SIGNALING_URL --room-id $ROOM_ID --signaling-key $SIGNALING_KEY

ポイントはffmpegでv4l2に出力するときに明示的にピクセルフォーマットを指定すること。-pix_fmt yuv420pmomo--hw-mjpeg-decoder false をつけることです。これでI420のビデオフォーマットでやりとりされます。
ffmpegの動作が安定するまで、3秒間待ってからmomoを起動しています。早すぎるとmomoがvideoデバイスの読み込みに失敗します。

今回は640x480の映像の両サイドを削って正方形にするのでcropのビデオフィルターを使いました。必要に応じて、scaleも併用してください。

関連

https://qiita.com/tetsu_koba/items/789a19cb575953f41a1a
https://qiita.com/tetsu_koba/items/01491f96daddf15677df

Discussion