目次
HDMI のキャプチャのことをいろいろ調べていたら おもしろそうなブログ を見つけたので、実際に遊んでみました。これはその記録です。
免責
- 安定性は不明 です、実験程度 に捉えてください
- 当然ながら ハードウェア HDMI キャプチャのほうがよい です。もしくはプラグインを書くべきです
- 映像は 実測で 0.5 秒ほど遅延 しますし、画質は落ちます し、CPU をとても食い ます
- 音声は得られません
- 何かが起きても ぼくは責任は取りません
TL; DR
手順
- Lenkeng の HDMI 延長器(LKV373)の送信機(約 5,000 円)に任意の HDMI 出力を突っ込む
- 受信機の代わりにソフトウェア
golkv373
でデータを受け取ってデコードし、Motion JPEG としてストリームする - OBS Studio で Motion JPEG を映像ソースとして取り込む
- 映像を OBS Studio で仮想カメラ化する
結論
- 使えないことはないけれど、CPU をほんとうに食うし、0.5 秒くらい遅延するので、この方法が活用できるシーンは限られそうだ
- 素直にハードウェア HDMI キャプチャを使うか、LKV373 を使うにしてもプラグインを書く方がよいだろう
概要
できることと注意
この方法によって、
- PC やゲーム機の映像を、YouTube Live などの生配信で使う
- デジタル一眼レフカメラの映像を Zoom や Teams や Meets で使う
などが、ハードウェアの HDMI キャプチャを用意するよりは比較的低コスト(約 5,000 円)でできるようになります。
ただし、端的に言って 品質を相当犠牲にする ことになり、
- CPU をめっちゃ食う
- 映像が 0.5 秒くらい遅延して配信される
- 音声は別に工夫(分離器で音だけ取り出す、コードを追加する、など)が必要
- 安定して動作するかどうか誰もわからない
な点には注意が必要です。
別解
単に デジタル一眼レフカメラの映像を Web カメラ化したいだけ であれば、macOS なら Camera Live と CamTwist、キヤノン製のカメラなら EOS Webcam Utility など、より低コストかつ理想的な別解があります。
また、LKV373 を使う場合でも、macOS であれば、別の方のブログで OBS Studio のプラグインを実装している偉大な例があります。
で、Windows でソニーの α7iii なぼくはこれが使えず、とはいえ、OBS Studio のプラグイン作りはいきなり手を出すにはしんどかったので、手間がかからない代わりに CPU にはめっちゃ優しくない 方法でがんばる、のが本エントリです。
必要なもの
- Lenkeng の HDMI 延長器 LKV373(またはその OEM 品)の、送信機(TX、Sender)
- 受信機は不要
- Amazon だと これ とか。約 5,000 円
- 後継の LKV373A だと使えないのでややこしい
- 本体の裏に
V2.0
があれば LKV373(使える)、V3.0
だと LKV373A(使えない)らしい?
- PC の有線 LAN ポート
golkv373
- VLC media player
- OBS Studio
キモはいちばん上のこれです。
裏の V2.0
が大事みたいです。
手順
配線
HDMI ソースと LKV373(TX)をつなぎ、LKV373(TX)と PC を LAN ケーブルで直結します。
LKV373(TX)がデフォルトで 192.168.168.55/24
を持っているので、PC 側の NIC には同じセグメントの適当な IP アドレスを固定で割り当てます。LKV373(TX)の IP アドレスは Web の管理画面から変えられますが、その場合は、PC 側も併せて変えます。
golkv373
の準備
golkv373
のバイナリをダウンロード してきて、起動します。自分でビルドしてもよいです。署名がどうのこうので怒られたら、納得の上でとにかく実行します(ダブルクリックで起動せずにコマンドプロンプトや PowerShell から叩けば怒られませんが、どちらでもよいです)。
ファイアウォールの穴あけも必要です。LKV373(TX)と接続している NIC のプロファイルを Get-NetConnectionProfile
かなにかで調べて、そのプロファイルで通信を許可します。
起動するとなんやかや出力されて、
2020/xx/xx xx:xx:xx Program started as: [C:\...\golkv373-v0.5.2-win64.exe]
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
2020/xx/xx xx:xx:xx No active transmitters
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /src/:IP/frame.mjpg --> main.main.func2 (4 handlers)
[GIN-debug] GET /src/:IP/frame.jpeg --> main.main.func3 (4 handlers)
[GIN-debug] GET /src/:IP/ --> main.main.func4 (4 handlers)
[GIN-debug] GET /status --> main.main.func5 (3 handlers)
[GIN-debug] GET / --> main.main.func6 (3 handlers)
[GIN-debug] Listening and serving HTTP on :8080
続けて毎秒のログが出始めるはずです。状況に応じて出方が変わります。
ファイアウォールに阻まれているなど、LKV373(TX)と疎通できていない状態のときは、No active transmitters
だけが繰り返し出力されます。この場合、設定を見直してどうにかします。
...
2020/xx/xx xx:xx:xx No active transmitters
2020/xx/xx xx:xx:xx No active transmitters
2020/xx/xx xx:xx:xx No active transmitters
...
疎通できているけれども映像が入力されていない場合は、keepalive sent
と No active transmitters
が両方出力されます。この場合は HDMI のソースに何の信号も来ていない可能性があります。
2020/xx/xx xx:xx:xx keepalive sent to 192.168.168.55:48689
2020/xx/xx xx:xx:xx No active transmitters
2020/xx/xx xx:xx:xx keepalive sent to 192.168.168.55:48689
2020/xx/xx xx:xx:xx No active transmitters
2020/xx/xx xx:xx:xx keepalive sent to 192.168.168.55:48689
2020/xx/xx xx:xx:xx No active transmitters
疎通できていて映像も送られてきているときは、フレームレートなどが表示されます。
2020/xx/xx xx:xx:xx keepalive sent to 192.168.168.55:48689
2020/xx/xx xx:xx:xx 192.168.168.55: MB/s=2.66 FPS=30.00 lost=0
2020/xx/xx xx:xx:xx keepalive sent to 192.168.168.55:48689
2020/xx/xx xx:xx:xx 192.168.168.55: MB/s=2.69 FPS=30.00 lost=0
2020/xx/xx xx:xx:xx keepalive sent to 192.168.168.55:48689
2020/xx/xx xx:xx:xx 192.168.168.55: MB/s=2.71 FPS=30.00 lost=0
ブラウザで http://localhost:8080/
にアクセスして、LKV373(TX)の IP アドレス(デフォルトなら 192.168.168.55
)を選択すると、転送されてきている映像が表示されます。単に映像が観たいだけであれば、これで終わりです。
この段階で、192.168.168.55
からの映像は、
http://localhost:8080/src/192.168.168.55/frame.mjpg
で Motion JPEG としてストリーミングされています。ここから、OBS Studio でこの Motion JPEG を映像ソースとして取り込めるように設定していきます。
プレイリストファイル(XSPF)の作成
OBS Studio では、メディアソース
で Motion JPEG の URL を直接指定しても映像は取り込めます。が、
- バッファされるので遅延が増えるうえ、バッファの設定を変えられない
- 遅延が蓄積していく(ように見える)
ので、URL だけでなくキャッシュ設定も含まれたプレイリストファイルを作って、それを OBS Studio から読ませる方法を取ります。
プレイリストの作成には、VLC media player を使います。VLC media player を起動して、
- [
メディア
] > [ネットワークストリームを開く
] を開き、 - URL に
http://localhost:8080/src/192.168.168.55/frame.mjpg
を入力して、 - [
詳細オプション
] で [キャッシュ
] を [0 ms
] にして - [
再生
]
します。この段階で遅延がひどかったりフレームレートが低かったりする場合は、余計なものを閉じてやり直すなどするとよさげです。
キャッシュを増やすとより安定しますが、増やしただけ遅延が純増します。ここでは強気に 0 ms
です。
で、映像が極端な遅延なく見えていれば、[メディア
] > [プレイリストファイルを保存
] して、XSPF ファイルを保存します。この XSPF ファイルがプレイリストで、キャッシュの設定もここに含まれています。
保存したら、VLC media player はもう要らないので閉じます。
OBS Studio の設定
最後に、OBS Studio で、ソースとして VLC ビデオソース
を追加し、その設定画面で先ほどの XSPF ファイルを追加すれば、完了です。
ここからさらに OBS-VirtualCam などを使って仮想デバイスに出力すれば、別のソフトウェア(Zoom など)でも映像を利用できることになります。
実測
次のパタンで遅延や CPU 使用率などを比較してみます。
- Web カメラとして使うパタン
- 本エントリの方法を使った場合
- ハードウェア HDMI キャプチャを使った場合
- 市販の Web カメラを使った場合
- HDMI キャプチャとして使うパタン
- 本エントリの方法を使った場合
- ハードウェア HDMI キャプチャを使った場合
登場人物
- PC
- Intel NUC6i5SYH
- Intel Core i5-6260U @ 1.80 GHz
- 32 GB RAM
- ハードウェア HDMI キャプチャ
- Ezcap269
- 市販の Web カメラ
- Logicool C270
測定方法
ブラウザでストップウォッチを表示 させて、測定パタンに応じた経路で最終的に Zoom に表示します。
各画面に時間が表示されている状態で、充分に速いシャッタスピード(1/800 程度)で全体を撮影すると、撮影できた各画面の時間の差が遅延時間そのものを表すことになります。
Inter BEE などの展示会では、似た方法をよく低遅延伝送のデモンストレーションで見かけますね。表示させるソースをストップウォッチとフレーム数とで迷いましたが、遅延はミリ秒表記のほうが個人的に馴染みがあるのこうしています。
Web カメラとして使うパタン
本エントリの LKV373 を使った方法は、遅延も CPU 使用率も圧倒的に大きくなりました。
方法 | 遅延 | CPU 使用率 | 経路 |
---|---|---|---|
本エントリ(LKV373) | 460 ms 程度 | 80 ~ 100 % | ソース → α7iii → LKV373 → OBS Studio → Zoom |
ハードウェアキャプチャ | 150 ms 程度 | 20 ~ 40 % | ソース → α7iii → Ezcap269 → Zoom |
市販 Web カメラ | 60 ms 程度 | 20 ~ 40 % | ソース → c270 → Zoom |
そもそも、ある瞬間を α7iii が取り込んで HDMI で出力する(≒ カメラの液晶に表示される)までに 70 ms くらいの遅延があるみたいでした(カメラ側の設定で変わる部分かもですが未調査です)。460 ms の内訳は、
経路 | 遅延 |
---|---|
ソース → α7iii | 70 ms |
α7iii → LKV373 → OBS Studio | 220 ms |
OBS Studio → Zoom | 170 ms |
な具合です。OBS Studio の仮想カメラでは、デフォルトで入る 3 フレームのバッファ設定をそのままにしているので、その分も含まれるでしょう。
HDMI キャプチャとして使うパタン
カメラを経由しない分遅延は改善されますが、それでも LKV373 を使った方法は、遅延も CPU 使用率も圧倒的に大きいままです。
方法 | 遅延 | CPU 使用率 | 経路 |
---|---|---|---|
本エントリ(LKV373) | 370 ms 程度 | 80 ~ 100 % | ソース → LKV373 → OBS Studio → Zoom |
ハードウェアキャプチャ | 80 ms 程度 | 20 ~ 40 % | ソース → Ezcap269 → Zoom |
370 ms の内訳は、
経路 | 遅延 |
---|---|
ソース → LKV373 → OBS Studio | 200 ms |
OBS Studio → Zoom | 170 ms |
な具合でした。
画質
LKV373 を通すと、JPEG らしさのある圧縮ノイズが視認できるレベルで乗ってきます。
自分のブログを映した別 PC の画面を LKV373 経由で OBS Studio に取り込んで等倍キャプチャしたものがこれです。
ハードウェア HDMI キャプチャだとこういう劣化はなく、ここにさらに配信プラットフォーム側の圧縮が乗ってくることになるので、画質面もこの方式のデメリットです。
まとめ
強引に多段変換してどうにかする手法では、遅延も CPU 使用率も大きくなるというごく当たり前のことが確認できました。
同じ LKV373 を使う手法でも、先の macOS 用の OBS Studio のプラグイン を使うのであれば、原理的にはオーバヘッドは相当減らせると推測できるため、プラグインの開発に至ったモチベーションも合理的なものと言えそうです。
CPU 使用率の高騰が許容できるなら、例えば録画や生配信の用途であれば、音声に意図的に遅延を入れて同期を取れば使えないこともないかもしれません。一方、オンライン会議などでは、音声を遅延させるわけにもいかず、そうすると声と映像が 0.5 秒ズレることになってしまうので、なかなか使いづらそうです。そしてどちらの場合でも、この方式の安定性はだれにも保証できません。
いずれにせよ、最近は安いハードウェアキャプチャは 10,000 円強で手に入りますし、予算が許せばそうする方が、あらゆる面で合理的だと思いました。