ブラウザ同士で簡単に映像送信ができOBSにも取りこめるVDO.Ninja

Pocket

VDO.Ninjaの情報を求めて来られた方は次の見出しまでジャンプしてください!

■屋外UTの中継をするための試行錯誤

先日、複数の場所を往復しながら実施するUTがありました。インタビュー部屋とプロダクトを触る部屋が異なる、みたいな感じ。しかも後者はWi-Fiが使えない屋外。どうにかこれらの映像をシームレスに記録と見学者への配信を行いたい、というニーズ。セッション全体の1/3、30分位の時間ですが炎天下の屋外に移動する為、バッテリーが保つこと、機器やネットワークが安定した機能することも視野に入れなければなりませんでした。

250mほどの距離で当然HDMIケーブルやLANケーブルが敷ける距離でもなく、Wi-Fiも届きません。同一ネットワーク下にないので先日紹介したNDIなども使えません。別記事で紹介したRTMPも受信拠点側をポート開放する必要があったり遅延が大きめだったりで微妙に使いにくい。すぐに思い付くのはZoomやTeamsといったオンライン会議ツールでの参加ですが、スマホのカメラは光学ズームが弱いので、物理で寄らないと手元など細かい対象を撮ることができず、ソーシャルディスタンスやラポール形成的に不利。できれば光学ズームのビデオカメラ映像を使って配信したいなと思いました。(ちなみに最近では望遠レンズを備えたスマホもありますが、Zoomなどのアプリはそれらを使えません。ピンチズームしても標準カメラの像がデジタル拡大されるのみです。Android版に至ってはピンチズーム自体できませんでした(執筆時点)。屋外なので騒音対策としてきちんとワイヤレスマイク(Wireless GO 2)を使った音声収録をしたいのですが、これら外部マイクもスマホ版アプリは制限が大きかったりします(後述)。

そんなこんなでどこにも行けない御盆休みは手持ちのRTMP配信カメラ(HXR-NX80)、GoPro Hero9、スマホ版Zoomアプリ、UMPCなど持てる機材をあーでもないこーでもないと組み合わせて試行錯誤をしておりました。

本題と関係ないですが、その試行錯誤の様子を貼っておきます。

まずは手持ちスタイル案。

手持ちスタイル案

ビデオカメラのHDMI出力をAndroidでも使えるHDMIキャプチャアダプタBU110を経由してGalaxy Note 10+に入れています。ブラケットやホルダーも含めると845gにもなりました(笑)。ビデオカメラのバッテリーは小さいものだし、スマホのUSBポートもキャプチャで塞がるので外部給電もできず、スタミナにも不安。前述の通りAndroidのZoomアプリは外部カメラやマイクを認識しないので配信系のアプリでRTMP送信するしかない点もイマイチ。

そこでモビリティは落ちるものの、安定性やスタミナ重視で組んでみた装備がこちら。

三脚+UMPC案

三脚にセリアで買った木製パンチングボードをタイアップで吊り、そこに各種装備を固定しまいた。三脚の根元にぶら下げているだけなので、足をたたんで移動することも可能。PCは手持ちラインナップでCPUパワーとサイズのバランスをとってOneMix 3 Pro。Surface Go2 (CoreM3 + LTE版)だと見た目はスッキリしますがちと配信能力に不安があったので。OneMixはLTE非搭載などで別途モバイルルーターを追加。さらにはUSB PD給電のためのモバイルバッテリー、とか詰んでいったらこれまたエラい重量になってしまいました。ドリーが欲しいところです。ただWindowsなのでZoomなどのプライベート通信サービスでも外部カメラ、外部マイクは区別なく使えるので映像、音声の品質は向上させられます。

ちなみにどちらもビデオカメラ側で録画ができるので、保存用としての品質は保持できます。あと、最近の家庭用ビデオカメラによくあるスマホ用プレビューアプリを使い、スルー画をスマホに映した状態をZoom等の画面共有で流す、という方法も検討しましたが、

  • スマホプレビュー中はビデオカメラ側の液晶が真っ黒になってしまい、撮影に支障が出る(SONY、Panasonic)
  • Panasonicはアプリから音も拾えるがそれをZoomでキャプチャして流すことはできない。SONYはそもそも音は聞けない。
  • スマホに直接マイクを接続した場合も、やはりアプリが認識しなかったり、しても絵との同期に問題が出そう。

などの問題があってボツ。

で、結局のところどうなったかというと、先ほど先方から連絡があり、関係者に発熱者が出て実施が無期限延期になりましたorz。難しいですね。炎天下の屋外作業を伴うプロジェクトだったので発熱はしますわ。自分も昨年の案件で軽く熱中症と思われる発熱。PCR検査では陰性でしたが安全優先で実査を中止にさせてしまったことがあります。涼しくなった頃にまたリトライできるといいなと思います。

で、やっと本題。今回の試行錯誤の中で見つけたとある映像伝送手段が色々と応用が利きそうで、まだあまり日本語の解説ページが多くなさそうだったので、ご紹介してみようと。

■VDO.Ninjaの紹介と簡単な使い方(ここから本題)

上記の試行錯誤をしている間に、たまたまFacebookの(英語の)OBSグループで名前を見かけ、調べてみたらスゴいじゃんこれ!となりました。ちなみに少し前まではOBS.Ninjaという名前だったぽいです。実際にはOBS Studio以外でも使える汎用性の高いサービスなので改名したんでしょう。

簡単にいうと、ブラウザ同士で簡単に映像&音声伝送が低遅延で行えるサービスです。OBSには「ブラウザソース」という指定URLの内容をソースとして扱う仕組みがあるので、わざわざブラウザで当該ページを開いてそれをウインドウキャプチャする必要なく映像を受けることができます。無料です。

少し技術的な説明をした方が理解が深まりそうなので、ベースとして用いるWebRTCというプロトコルについて先に説明します。

WebRTCはモダンなブラウザが実装している映像、音声を伝送する標準規格で、暗号化もブラウザが受け持ってくれて、ZoomやTeamsがブラウザからも参加できているように、HTML5上で比較的簡単に映像、音声を伝送するサービスを構築することができる仕組みです。利用者は専用アプリをインストールしたりしなくていいし、開発者も本来高いスキルを要する映像通信技術の大半(ファイアウォール超えや暗号化、GPUのハードウェアエンコード支援の利用、etc.)をOSの区別すら必要なく実装できてしまいます。しかもRTMPのような従来のプロトコルよりも遅延が低いとか。

さてそのWebRTCですが映像伝送自体はPeer-to-Peer、つまり端末同士の直接通信で行われ、暗号化も自動で行われます。ただし最初のハンドシェイクの部分だけはインターネット上のサーバーが仲介する必要があります。VDO.Ninjaはその互いの紐付けの部分を代行してくれるWebサービスという理解でいいと思います。実際の映像通信はここのサーバーを経由しないので比較的小規模で運用できるのか、Steveさんという個人主体のプロジェクトのようです。しかもサーバー一式はGithubで公開されているので、自前サーバーや完全閉鎖LAN内で稼働させた人はそちらを利用することも可能でしょう。Steveさんはサーバー代月$1,500を支援するスポンサーを募集していますので、VDO.Ninjaが有用で長く続いて欲しいと思う方は是非寄付を検討しましょう。Github Sponsorsによる継続支援やPayPalなどによる一時寄付も選べます。

■VDO.Ninjaを使ってみる

全体的に英語UIですが、手順はクッソ簡単です。サービス名であるVDO.ninjaは実はそのままサービスのURLになっています(.ninjaなんていうgTLDがあったんだ…)。つまりブラウザのアドレス欄に「vdo.ninja」を打ってリターンをします。いくつか方法はありますが、まずは映像を送信する側の端末(スマホ等)で開きましょう。

トップページ

「Add your Camera to OBS」はカメラ映像の送信、「Remote Screenshare into OBS」は画面共有です。ただし現状スマホからは画面共有は使えずボタンも出現しません。

ここでは全者をPCから開いてみます。

準備画面(カメラ/マイク設定。実際には黒枠にカメラ映像が映ります)

「Video Source」と「Audio Souce」プルダウンメニューにOSが認識しているカメラとマイクが表示されるので選択します。その前にブラウザからカメラとマイクへのアクセス許可ダイアログが表示されるので許可します。一度拒否してしまうとこのサイトがブラックリストに入れられてダイアログも出ずに不許可になってしまう場合がありますが、その時は(操作はブラウザによりますが)プライバシー設定などから除外対象サイトから外すなどします。(ちなみにこのようにWebRTCはブラウザがカメラやマイクにアクセスする際に必ずユーザの許可を得る仕組みになっているので、URLを踏んだだけでカメラやマイクが不正アクセスされることはありません。)

実際には黒枠内に選択したカメラの映像が見え、「Audio Source」見出しの脇に音声に応じたピコピコ(レベルメーター)が表示されます。

次ページで発行されるURLの乱数部分が含まれますが偶然一致してしまう可能性もあるので、ここでパスワードを付加することもできます。

で、「START」を押すと送信が開始されます。

送信中画面(実際には黒枠内にカメラ映像)

右上にグリーンで表示されているURLが受信者用のURLになります。このURLを相手方にメールやMessengerなどで伝え、ブラウザで開いてもらえば映像と音声が流れるはずです。

ここの時のURLのフォーマットを比較してみると、

  • 送信者用: http://vdo.ninja/?push=hogehoge
  • 受信者用:https://vdo.ninha/?view=hogehoge

という感じで、pushかviewかの違いのみになります。要するに=の後のhogehgoeの部分が一致すれば映像/音声が流れます。このサイトでは乱数で決めてくれますが、自分で他の人とかぶらない文字列を指定しても大丈夫なはず。かぶりそうな時はパスワードを追加します。パスワードがついたURLは、

  • 送信者用: http://vdo.ninja/?push=hogehoge&pw=abcdef
  • 受信者用:https://vdo.ninha/?view=hogehoge&pw=abcdef

となります(abcdefがパスワード)。

OBS Studioにソースとして取り込む(1)

2つの方法があります。1つ目はもっとも簡単な方法で、OBS Studioのソースとして「ブラウザ」ソースを使います。

OBSの「ブラウザ」ソースに設定

URLに発行したID、PW入りのURLを貼り、表示したいサイズを指定、音声も取り込みたい場合は「OBSを介して音声を制御する」チェックボックスをONにします。

OBS Studioにソースとして取り込む(2)

もう一つの方法は作者のSteveさんがリリースしているElectron CaptureというビューワーでURLを入れ、表示された映像をOBS Studioのウインドウキャプチャで取り込む方法です(Windowsのみ)。一見、外部ツールを使う分効率が悪そうですが、Steveさん曰く「it may offer a more flexible and reliable method of capturing live video than the browser source plugin built into OBS.」とのことです。マウスカーソルが完全に隠せるとか、バッファー指定で音声同期が外れにくいなどあるようです。メリット一覧はこちら。パケットロス耐性が高く、システム負荷が低いということなので、面倒ですが使った方がよさそうですね。

送信側のハードウェアエンコード支援を使用する

一般にOBSを動かしたりする受信側ハードよりも、スマホ等を使う送信側の方が非力であることが多いでしょう。その時、ローエンドなCPUやモバイルSoCでも映像をリアルタイムに圧縮して送信するにはGPUのハードウェア支援を使用することが重要になってきます。WebRTCベースである利点として、ここいら辺は各OSのブラウザが(ハード的に対応していれば)活用してくれるという点。VDO.NinjaでこれをONにするには圧縮コーデックにH.264を指定するのみです。H.264はBlu-rayなどにも使われるメジャーなコーデックなので数年前のCPUやスマホでもフルHDくらいなら支援が受けられます。

送信側でハードウェア支援を有効化する為に、H.264を使うぞという宣言を受信側のURLオプションを使うのがミソです。

  • パスワード無し: http://vdo.ninja/?push=hogehoge&codec=h264
  • パスワード有り:https://vdo.ninha/?view=hogehoge&pw=abcdef&codec=h264

ブラウザにもよるかも知れませんが、標準ではVP9というYoutubeなどで使うコーデックが優先されるようです。ただ最新のハードだとVP9でもハードウェア支援が受けられたりするので、あまり違いは出ないかも知れません。スマホや非力なPCの場合に試してみて、画質やCPU付加を比べて良い方を使えば良いでしょう。

ちなみに送信側でハードウェア支援を活用できているかの確認は、映像送信中に送信側のブラウザ上でCtrlキーを押しながらプレビュー映像をクリックします。

送信側で詳細情報を確認

するとこんなリストが出てくるので「video_encoder」の欄が「ExternalEncoder」になっていればOKです。試しにURLから「&codec=h264」をなくすと「libvpx」となりVP8か9のソフトウェアエンコーダーライブラリが使われているのがわかります。

URLパラメーターにはコーデック以外にも色々指定できます。使い方はこちら。パラメーター一覧はこちらです。ビットレートを指定したり、カメラ/マイクデバイスのリストでデフォルト選択されるデバイス名を埋め込んだりできるようです。

再利用可能なリンクを作る

上記の手順でAdd your Camera to OBS」や「Remote Screenshare into OBS」から送信URLを生成すると毎度ランダムな文字列のIDが発行され、OBS Studioなど受け側で毎回URLを書き換えなければならず不便です。また上記のようなオプションパラメーターをURLに埋め込むのも骨がおれる作業です。

そういう場合はこちらのジェネレーターを使ってGUIでオプションを指定してURLを作成し、送信側、受信側に渡せば何度でも再利用することができます。

ルーム機能について(検証途中)

まだしっかり試せてないのですが、サーバー上に仮想ルームを作成し、一旦そこに複数のカメラ映像を集め、ブラウザ上でスイッチャーのように使ったり、音声のノイズ低減やテキストチャット機能が使えたりするぽいです。

■まとめ

驚くくらい簡単に遠方の端末のカメラ映像、音声、画面共有を表示したり、OBS Studioなどのソースに入力できるVDO.Ninjaを紹介しました。原理的にはNDIの遠隔版であるNDI Bridgeとほぼ同じ仕組みだと思いますが、送信側がブラウザなのは同様で、受信側があちらは専用ツールが必要、こちらは不要という点が異なります。厳密に画質や遅延、処理負荷などを比較したわけではないですが、おそらく原理上は似たり寄ったりになるんではないかと思います。だとしたら手軽さでは断然こちらに分があるのではないかなと思います。

望みはスマホからUSB(UVC規格)経由のWebカメラやHDMIキャプチャアダプタ経由のビデオカメラ映像を送信できるようになることですね。これはOS側の対応待ちというところです。ちなみにChromeOSはUSBカメラをソースとして指定できました。できるだけ軽量安価な端末というと現状ではChromeOS+Chromeが候補でしょうか。Raspberry Pi4やJetson NanoにLinuxを入れてChromeを使ってもいいようなので、いずれ自作でVDO.Ninjaエンコーダーユニットを組んでみたい気もします。

私の理解ではファイアウォールを超えられつつもきちんと暗号化でP2P通信ができるので、なんだかんだでZoomやTeamsになりがちな業務案件でも説得の余地があるかなと。最悪ソースもってきてローカルサーバーを建てたらどうなの、とか。まぁ企業さんだと現場寄りの人を説得するだけでなく、そこから伝言ゲームで情シスとか上司とかに納得してしてもらう必要があるので難しいかもですが…

ともあれ非常に汎用性が高く、手軽で、遅延が少なく、安全な映像伝送手段としてNDIと並んで注目株ではないかなと思います。どこか機会があったら活用してみようと思います。