読者です 読者をやめる 読者になる 読者になる

Tutti Lab

元シリコンバレー在住のおっさん技術者、モバイルVRアプリ開発に挑戦中

Cardboardで360度立体視動画ビューワーを作る(2)

360度立体視 Cardboard EasyMovieTexture THETA THETA UVC BLENDER Open Broadcast Software nginx

はじめに

前回は、EasyMovieTextureを使い、360度立体視動画ビューワーを開発しました。前回は、Assets/StreamingAssetsに360度立体視動画形式のmp4を直接配置して、これを視聴するという形でしたが、今回は二台のTheta Sより撮影した右目・左目用の360度画像をブロードキャストし、Cardboardにて視聴するところまで開発を進めます。
f:id:tuti107:20160420162743j:plain

Easy Movie Textureはライブストリーミングに対応しているのか?

まずは確認から。HLS形式のストリーミングを再生できるかどうか、テストしてみました。Media Player CtrlのStr File Nameに、適当なURL(http://..../**.m3u8)を指定し実行したところ、問題なく再生されました。Easy Movie Textureは、少なくともHLS形式のライブストリーミングに対応しているようです(他のプロトコルについては試しておりません。iOSへの配信を考慮するとHLS形式一択ですので)。
なお、「Http://..../**.mp4」形式の動画も問題なく再生されました。ご参考まで。

Theta Sの360度動画をPCへ取り込む

Theta Sには、USB/HDMIでPCに接続して、PC側でライブストリーミング表示する機能が搭載されています。USBなら1280x720 15fpsで取り込みが可能です。ただ、形式はDual Fisheye形式であり、このままでは前回開発したアプリで使用することができません。
f:id:tuti107:20160420145003p:plain
前回開発したアプリで360度立体視表示するためには、以下のような形式への変換が必要となります。
f:id:tuti107:20160420141059p:plain
以前はこの変換を自力でやる必要がありました(例えばこちらなどで取り上げられています)。しかし先月リリースされたRICOH THETA UVC Blenderを利用することで、Dual Fisheye形式ではなく変換後の形式でのライブストリーミングが可能となりました。
RICOH THETA UVC Blenderは、こちらよりダウンロード可能です(ライブストリーミング用アプリ、という名前です。なお基本アプリを未インストールの場合は、こちらを先にインストールしておく必要があります)。
インストール後、Theta Sの電源を入れずに、PCとTheta SをUSB接続し、THETA UVC Registerを起動してください。
f:id:tuti107:20160420142632p:plain
これで、そのTheta SがTHETA UVC BLENDERとして登録されます。試しに、Googleハングアウト等、USBカメラ画像を取り込むことができるアプリにて、カメラリストを表示してみると、THETA UVC BLENDER(***)が追加されていることを確認できます。これを選択すると、Dual Fisheye形式ではなく、本開発アプリで利用可能な形式にて表示されます。
今回は、右目・左目用の二台のTheta Sがありますので、それぞれ上記の手順で登録を行いました。

Open Broadcast Software

次に、撮影画像をブロードキャスト配信するための用意を行います。いろいろな方法・ソフトウェアがあるようですが、調べたところ、Open Broadcast Softwareを利用するのが良さそうです。Open Broadcast Softwareは、こちらからダウンロード可能です。
このアプリは、カメラキャプチャ映像のみならず、静止画・ウィンドウ・画面全体など様々なソースを組み合わせて一つの動画を構成し、これを録画・配信する機能を備えています。例えば、以下のように右目・左目用それぞれのTHETA UVC BLENDERを縦に並べて配置すると、あっという間に360度立体視動画の形式になります。
f:id:tuti107:20160420144221p:plain
ところが、実際この方法ではうまくいきません。右目用と左目用の映像が全くシンクロせず・フレームレートもバラバラのため、本映像を前回のアプリで視聴しても全く立体視動画には見えません。そこで、右目・左目をシンクロさせて縦に並べる方法を検討してみます。

OpenCVで二つのTHETA UVC BLENDERをキャプチャ・合成

できるだけ簡単な方法で、といろいろネットを探索したのですが、残念ながらコードを書くのが一番手っ取り早そうです。今回は、OpenCV3.1 + Javaで、二つのTHETA UVC BLENDERをキャプチャ・合成のコードを作成しました。
なお、OpenCV3.1の導入とJava(Eclipse)での利用手順については、設定が少し面倒なのですが、こちらにわかりやすく手順がまとめられておりますので、これを参考に進めてください。なお今回、別にJavaである必要性は特にないのですが、現在Macで開発している本環境を近日中にWindowsへ移植することを検討しており、移植性を考えてJavaにしてみました。
コードは以下の通りとなります。なお、24行目・25行目のnew VideoCapture()の引数値は、実行環境毎に異なります。それぞれ左目・右目用のTHETA UVC BLENDERの映像が取れるように調整をしてください。

これを実行すると、以下のように、二つのTHETA UVC BLENDER映像が縦に並べられた映像が表示されます。
f:id:tuti107:20160420151352p:plain
このプログラムを起動した状態で、再度Open Broadcast Softwareを起動し、今後は、ソースとしてウィンドウキャプチャを選択してください。
f:id:tuti107:20160420152052p:plain
空の名前でウィンドウを表示をチェックすると、ウィンドウから、先ほど起動したプログラムのウィンドウを選択可能となります。表示サイズがおかしい場合は、設定→映像→キャンバス解像度を1280x1440に設定の後、赤枠の丸部分をドラッグして、位置・サイズをキャンバスの大きさに合わせてください。
f:id:tuti107:20160420152846p:plain
f:id:tuti107:20160420152859p:plain
これで左右両眼の映像のタイミング・フレームレートがあった形での映像配信が可能となります(ただ当方のMacではすでに処理の限界に近づいており、ファンが猛烈に周り始めました)。

配信用のサーバを用意する

わざわざサーバを立てなくても、UStream等の既存のライブ配信サーバーを活用すれば、上記の設定だけで動画配信が可能です。ただし、インターネット上のサーバへアップロードするためレスポンスはそれ相当となってしまいます。今回はメイカーフェアー向けに可能な限り高速な動画配信を行いたいため、ローカルでサーバを立ち上げ、ローカルネットワーク内でのみ動画配信を行う形としました。
HLS形式のライブストリーミングを配信可能で、かつ軽量なサーバとしては、nginxというWEBサーバの人気が高いようです。なお、nginxはデフォルトでは、ライブ配信用のモジュール「nginx-rtmp-module」がdisableのため、これを有効化してコンパイル・インストールする必要があります。
nginx導入の手順、およびライブ配信のためのOpen Broadcast Softwareの設定については、こちらを参考にさせていただきました。なお、当方の環境(Mac)に合わせて、./configureで設定するパスを/usr/local/...に変更しました(/usr/local/etc/nginx/nginx.confのrtmp設定についても同様)。Open Broadcast Softwareの配信設定については、こちらに記載の通り、以下のように指定することで、http://PCのIPアドレス:8080/test.m3u8へアクセスすることで、前回開発したアプリからTheta Sで撮影の360度立体視映像を視聴することができました(冒頭、及び以下のCardboard映像は、本仕組みで視聴した我が家の天井です)。
f:id:tuti107:20160420160111p:plain
f:id:tuti107:20160420162743j:plain

まとめ

今回は、前回開発したCardboard用360度立体視動画ビューワーにて、Theta S(左右両眼用)で撮影・リアルタイム配信した映像を視聴するための環境を実現しました。確かにCardboardでTheta Sで撮影の映像を視聴することはできるのですが、処理負荷の高さからフレームレートは数FPSという状況、またライブ配信の遅延が20秒近くあるため、メイカーフェアーで「リアルタイム配信」を謳うのは厳しい感じの仕上がりです。
次回は、一旦Cardboardから離れて、Oculusにて、PCで取り込んだ右目・左目映像を直接表示する仕組みを作ってみたいと思います。