Raspberry Pi 4でUSBカメラ映像をHDMIに変換できるか実験(ATEM Miniと使いたい)

最近、ユーザテストの撮影用カメラとしてOBSBot Tinyが小さくて画角調整がしやすくて大変気に入っています。この製品はUSB接続のWebカメラなので、PCでOBS Studioなどで録画/配信するには適していますが、HDMI入力しかないATEM Miniシリーズには使えません。

そこで、Raspberry Pi 4(以下RP4)でUSBカメラとして認識してそのリアルタイムスルー画をHDMIというかX上でフルスクリーン表示すればATEM Miniシリーズでキャプチャできるんじゃないかという発想です。しかもRP4にはHDMI出力が2つあります。複数のUSBカメラを接続し、それぞれを個別のHDMI出力に出せれば、2カメを1台のRP4で変換できるんじゃないか、とか。

■RP4の設定

今RP4は半導体不足の煽りで品不足、価格高騰気味なようですが、幸い少し買ったものがありました。

確か1万強くらいだったと思うので、お急ぎでない方は価格が落ち着いてから買った方がよろしいかと思います。

ケースはこちら。RP4のボードより一回り大きくなりますが、内部変換ケーブルによってフルサイズのHDMIポートが2つになる点が魅力です。

+1,000円でUSB電源アダプタが付属するセットもあるようです。自分は当初適当なUSB充電器を使えばいいやと買わなかったんですが、実際にUSBにWebカメラを接続してキャプチャしたりすると電圧不足警告が表示されました。一般的な非PDの5V充電器だと2.0Aが上限なので、やはりRP4に売られている3.0Aのものを買った方が良さそうということで結局追加しました。少し割安なので最初からセットで買うのがオススメです。

また派生モデルとして下部にM2 SSD(USB接続)を追加したモデルもあるようです。録画なども考える場合はこちらも良さげです。

ウチはとりあえずこちらのSDカードでセットアップしました。

小さいmicroSDは「あれ、どこいった?」となりがちですが、そんな時この水色のカラーが目立つので扱い易いです。

■OSインストール

ちょうどRaspiOSの64bit版が正式扱いになったというニュースをみたので、これを機に新規セットアップしました。公式から2022-01-28-raspios-bullseye-arm64.zipを落としてきて解凍し、これまた公式ツールのRaspberry Pi Imagerを使ってSDカードに展開しました。

当初X-WindowのないLiteで軽量なシステムを構築できないかもトライしましたが、色々ツールを入れるのが大変で断念。キーボードやらネットワーク設定やらもひと手間です。結局あきらめてフルバージョン(X-Windowsあり)で仕切り直し。結果的に必要なツールは揃っており苦労なく表示できました。

■USBカメラの映像をウインドウに表示する

当たり前っちゃ当たり前ですが、OBSBot tinyの初代および4Kモデル双方とも差すだけで認識しました。

表示ツールはVLCなども試したんですが遅延が大きく、ffplayがマシという感じです。ただしフルHDにするとかなり遅延が出てATEM Miniへの入力ソースとしては致命的。1280×720ならほぼ気にならないですがフレームレートは10fpsに強制的に落とされてしまいました。

起動はターミナルからこんな感じ。

-iで入力デバイス。OBSBot Tiny初代と4Kを同時に挿した場合、それぞれ/dev/video0と/dev/video2にアサインされました。

-video_sizeは1280×720や1920×1080のように書いてもいいですし、hd720、hd1080のような略記も使えます。

-anは音声無効化、-fsは全画面表示です(ESCで終了)。

-framerate 30などとつけるとフレームレート指定ができますが、hd720でも強制的に10fpsに落とすよ、というウォーニングが出て上書きされてしまいます。

実験したところ、サイズをwvgaにすると950×540になり15fps、vgaなら640×360で30fpsになりました。30fpsあると明らかに残像感がなく綺麗ですが、遅延としては差は感じません。HD720/10fpsかWVGA/15fpsが実用上バランスが良いかなと思います。

正直もうちょっと行けるかと思ってたんですが微妙な結果でした。もしかするとハードウェアデコーダーを使うなど何かしら設定で改善する余地もあるかもですが、吊しの状態だとこれが限度でした。

追記:

オプションでMotionJPEGを明示したところ改善がありました。v4l2-ctlコマンドで対応コーデックを調べたところ、こんな結果が。

先に書いた上限値はYUYVモードのもののようで、MotionJPEGとH.264ならばMax 60fpsが目指せそうだったので追加検証してみた結果、

  • H.264は重く、MotionJPEGが良いカンジ
  • それでもフルHDは遅延発生

ということで、現状のベストコマンドは、

ということになりそうです。これで30fpsになりました。-framerate 60を明示的につけるとlow voltage警告が出て絵が止まったりシステムがフリーズしたので、こちらは別途3A電源が届いてから実験します。とりあえず720p/30fpsが出ればATEMなどでPinPするソースとしては充分かなと思います。

・デュアルディスプレイに同時表示は無理そう

残念ながら1台のRP4でHDMI 2系統にそれぞれWebカメラ映像を出すことは現状ダメぽいです。上記の限界があるので単純に負荷2倍だと厳しいというのもありそうですが、どもそもffplayが現状マルチストリームに対応してないようです。別々のターミナルから同時起動しても、最初のプロセスを閉じるまで2つ目が開かない感じです。

■まとめ

Raspberry Pi 4を使って、USB接続のWebカメラを簡単にHDMI出力デバイスとして扱うことができました。ただしせっかくHDMI出力が2系統あるRP4でも並行出力は無理そう。そろそろ日本でも出回るRaspberry Pi Zero 2で同等のことができるなら、Webカメラ1台ごとにこちらを装着するのも良いかも知れません。結局電源がいるという意味ではビデオカメラを使うのとかわらないですが、物理サイズが大きく違うので、運搬が楽になったり、撮影中の存在感を減らすことができる点はメリットかと思います。なにか3DプリンターでOBSBot Tinyと一緒にマウントできるケースを作ってみたいです。

今後の課題としては、

  • 電源オンでHDMIに全画面出力が出るところまで起動処理の自動化
  • SDカードを損耗を防ぐためにシステムのRead Only化
  • 長時間耐久テスト

などを行っていきたいと思います。