Android
WebRTC
Theta
THETAPlugin

THETA プラグイン と WebRTC P2P で撮影アプリを作ってみた


はじめに

こんにちは、リコーの @shrhdk_ です。

今回は WebRTC という技術を利用して、RICOH THETA V の 360° 映像を遠隔からリアルタイムに確認しつつ、THETA V のシャッターを切れるプラグインを作ってみましたのでご紹介します。

THETA 標準アプリの撮影機能を WebRTC を使って Web ブラウザだけで実現してみたという話です。

プラグイン概要

ソースコード: https://github.com/ricohapi/theta-plugin-webrtc-sample


RICOH THETA プラグインパートナープログラムについて

THETAプラグインをご存じない方は こちら をご覧ください。

興味を持たれた方は Twitter のフォローと THETAプラグイン開発コミュニティ (Slack) への参加もよろしくお願いします。


WebRTC とは?

まず WebRTC とは Web ブラウザ上で音声や映像などのデータをリアルタイムにやり取りするための技術です。

Google によってオープンソース化されていて、IETF による関連プロトコルと W3C によるブラウザ対応 API の標準化が行われています。

WebRTC のライブラリは、BSD ライセンスの元でソースコードとビルドツール、および公式ビルドライブラリが配布されているので、ネイティブアプリの開発も可能です。

詳しくは公式サイトを参照してください。 https://webrtc.org/


WebRTC P2P 接続の流れ

WebRTC P2P 接続は大まかに行って 3 ステップに分けられます。

まずはじめに、セッション情報 (SDP) を交換します。ざっくり言うと「映像送るでー コーデックは H.264 と VP9 が使えるでー!」「じゃあ H.264 でお願いしまっす m(__)m」といったやり取りをします。

つぎに、通信経路候補 (ICE Candidate) を交換します。ざっくり言うと「IPアドレス x.x.x.x のポート1111で接続できるでー」「こっちは y.y.y.y のポート2222ですわ」といったやり取りをします。

最後に、交換した情報を使って P2P 接続を確立し、セッション情報交換で決めた映像を送受信します。

セッション情報の交換や通信経路候補の交換を仲介するサーバーをシグナリングサーバーといいます。

実はこの交換方法は規定されていなくて自由です。極端な話、口頭で交換して…手でポチポチ入力して…なんてことも OK です。実際は WebSocket を使って交換することが多いです。

P2P 接続の流れ


プラグインを動かしてみる

前置きが長くなりましたが、サンプルをビルドして動かしてみましょう。概要だけ知りたい! という方は読み飛ばして OK です。


THETA の Wi-Fi をクライアントモードにする

今回開発したプラグインを使うには THETA の Wi-Fi をクライアントモードにしておく必要があります。AP モードにすると肝心の WebRTC によるライブビューが動作しません。

THETA をクライアントモードにする方法はこちらの動画を参照してください。 https://www.youtube.com/watch?v=jE9_VqaVuLM


USB 接続中も Wi-Fi が使えるようにする

本プラグインは Wi-Fi 経由で THETA にアクセスして利用します。

しかし THETA はそのままの状態では USB を接続すると Wi-Fi が無効になってしまうので Android Studio でプラグインを実行しながら Web UI を確認することができずとても不便です。

そこで THETAのWi-FiをUSB接続中に有効化する方法で USB 接続中でも Wi-Fi が使えるようにしておきます。


プラグインをダウンロードしてビルドする

まず、 https://github.com/ricohapi/theta-plugin-webrtc-sample からプロジェクトをダウンロードします。

ダウンロードができたら Android Studio でプロジェクトをインポートします。build.gradle があるフォルダをインポートしてください。

プロジェクトのインポート1

プロジェクトのインポート2

はじめにツールチェーンやライブラリのインストールがあるので時間がかかります。しばしお待ち下さい。

インポートが完了したら、デバッグモードを有効にした THETA V を接続して、ツールバーの実行ボタンを押してください。プラグインのビルドと実行が始まります。

プラグインを起動

ビルド中に以下のようなエラーが出た場合は、エラーメッセージに従ってツールチェーンをインストールしてください。

Failed to find Build Tools revision 28.0.3

ビルドが成功してプラグインが実行されると、THETA からピピピッと音が鳴って、即終了します。これはプラグインに権限が設定されていないのが原因ですので、アプリ設定から権限を付与します。 THETA の仮想画面は Vysor で操作できます。

権限設定

以下のコマンドでも設定できます。

$ adb shell pm grant com.theta360.pluginapplication.webrtc.sample android.permission.CAMERA 

$ adb shell pm grant com.theta360.pluginapplication.webrtc.sample android.permission.RECORD_AUDIO

権限設定は初回のみ必要です。また、実際にプラグインストアで配布する際は、自動設定されるようになっています。

設定ができたら、改めてツールバーから実行しましょう。

プラグインを起動

起動するとこんな画面になります。

プラグイン画面

この例では 192.168.1.5:8888 で HTTP サーバーが起動しています。 IP アドレスは環境によって異なります。


アプリを使ってみる

プラグインが起動できたら、 THETA と同じネットワークにいる端末の Web ブラウザから http://192.168.1.5:8888 にアクセスします。 IP アドレスはネットワーク環境によって異なります。

今回は Nexus 5X 上の Google Chrome からアクセスしました。アクセスに成功すると次のようなページが表示されます。

Web ブラウザの画面

部屋が汚いのでモザイクをかけていますが、実際は鮮明なライブビューが表示されています。

これで、動作確認は成功です! 標準アプリのようにオプションを設定したり、シャッターを切ったりできます。


プラグインの構成

今回作ったプラグインの構成を紹介します。水色のブロックがプラグインで、黄色のブロックが今回実装した部分です。

特徴として、シグナリングサーバー (WebSocket サーバー) と Web サーバーをプラグインの中に持っています。

外部のサーバー無しで THETA に直接アクセスするだけで Web アプリとして使える様になっています。

ブロック図


シグナリングサーバー

シグナリングサーバーは前述のとおり WebRTC のセッション情報 (SDP) と通信経路候補 (ICE Candidate) を交換するサーバーです。

実態はシンプルな WebSocket サーバーです。受信したメッセージを送信者以外にブロードキャストするように作られています。

Java WebSockets というライブラリを利用しています。

実装はSignalingServer.java にあります。


Web サーバー

Web サーバーは Web ブラウザ上で動かす アプリファイル (HTML/CSS/JavaScript) の配信をしています。また、撮影設定の変更やシャッター動作といったコマンドの受付を担っています。

AndroidAsyncというライブラリを利用しています。

実装はWebServer.javaにあります。

アプリファイル (HTML/CSS/JavaScript) は assets フォルダにいれて APK に同梱しています。

また Web サーバーを起動するために THETA 独自の設定ファイルである settings.json も同梱しています。

このあたりの解説は以下の記事が詳しいです。

THETAプラグインのWeb UIの実装方法【THETA プラグイン開発】 - Qiita


WebRTC ライブラリ

WebRTC のライブラリとして google-webrtc を利用しています。セッション情報 (SDP) の生成や映像のエンコード・デコード、ストリーミングはこのライブラリで処理されます。

THETA のカメラにはいくつか独自の設定が必要なため、それらを設定する THETA 用の拡張を追加しています。

このあたりの事情や WebRTC ライブラリの使い方については以下の記事で解説しています。

THETA V 単体で 360° 映像をリアルタイム配信する - Qiita


THETA 基本アプリ

プラグインではなく、普通の THETA としての機能を実現しているアプリです。THETA API v2 (プラグイン API ではなくWeb API の方) のサーバーにもなっています。

今回はプラグインから THETA API v2 を呼ぶことで撮影設定の変更やシャッター動作を実現しています。


MainActivity

周辺ブロック制御するのが MainActivity です。これがプラグインのエントリポイントです。セッション情報の送受信や撮影設定を仲介したり、IP アドレスや動作状況を画面に表示したりします。


アプリ (フロントエンド)

フロントエンドは HTML + CSS + JavaScript のベーシックな構成で、JavaScript 部分も jQuery を使った素朴なものになっています。タッチ操作スライダーの実装に Swiper を利用しています。

GUI の提供と シグナリングサーバーとのやり取り、Webサーバーへのコマンドの送信、WebRTC の制御を担っています。


まとめ


  • ライブビュー機能つきの撮影アプリプラグインを作成した。

  • WebRTC を使うことで、ブラウザ上で動く Web アプリとして実現した。

  • P2P モードを使うことで外部サーバー無しで動くようにした。