THETA V からリアルタイム360度動画を、Oculus Go のブラウザで見よう

# はじめに

Oculus Go のブラウザはChromiumをベースにしていてWebGLに対応しています。WebVRのライブラリであるA-FRAMEを使うことで、WebVRを利用することができます。

* 参考： [Oculus GoのブラウザについてのWeb開発者目線からのまとめ](https://qiita.com/wakufactory/items/98658e8d089386a7b073)

また、リアルタイム通信のWebRTCが使えることも、@gtk2k氏たちの実験で判明しています。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Oculus Go お持ちの方、Oculus GoのブラウザーがWebRTC及びgetUserMediaをサポートしているか調べたいですので、Oculus Goのブラウザーから下記のアドレスにアクセスしてみてください。<a href="https://t.co/ZdN5Kp93C3">https://t.co/ZdN5Kp93C3</a><br>すべてグリーンになればOKです。</p>&mdash; gtk2k (@gtk2k) <a href="https://twitter.com/gtk2k/status/998111274440404992?ref_src=twsrc%5Etfw">2018年5月20日</a></blockquote>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">こんな感じです。一度タップするとマイクの許可ダイアログが出て、許可するとループバックも流れてます。 <a href="https://t.co/5S8au2fxXs">pic.twitter.com/5S8au2fxXs</a></p>&mdash; H.Yoshitaka (@TyounanMOTI) <a href="https://twitter.com/TyounanMOTI/status/998119400619192320?ref_src=twsrc%5Etfw">2018年5月20日</a></blockquote>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Oculus Go WebRTCサポートOK! <a href="https://t.co/DXe3OAzMSF">https://t.co/DXe3OAzMSF</a></p>&mdash; gtk2k (@gtk2k) <a href="https://twitter.com/gtk2k/status/998163229472768000?ref_src=twsrc%5Etfw">2018年5月20日</a></blockquote> 

ならば、USB接続でWebカメラとして認識できるRICOH THETA Vを使えば、リアルタイムの360度映像をOculus Goのブラウザで見れるはずです。

# サンプルを動かしてみる

実際にTHETA-Vのリアルタイム映像をOculus Goで360度体験できるサンプルを作ってみました。GitHub Pagesで公開しています。

* サンプルの入り口 ... https://mganeko.github.io/aframe/
    * PCからの配信用のページ ... https://mganeko.github.io/aframe/pc.html
    * Oculus Goで見るためのページ ... https://mganeko.github.io/aframe/go.html
* サンプルのソースコード ... https://github.com/mganeko/aframe


## PCからの配信

* PCにRICOH THETA VをUSBで接続し、電源を入れてLiveモードに設定
* PCのChromeブラウザで、 https://mganeko.github.io/aframe/pc.html を開く
    * Roomがランダムに割り振られます。変更することも可能です
    * URLに ?apikey=ZZZZZZZZZ とつけることで、自分のSkayWayのAPI KEYを利用することができます(あらかじめ mganeko.github.io　ドメインでの利用を許可しておいてください）
<img width="663" alt="TV_360_OGO_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/19403/52bb9587-3eb7-57ab-1aad-d45dd975c7f9.png">


* [Get Devices]ボタンをクリックすると、利用可能な Videoデバイス(カメラ)、Audioデバイス(マイク)のリストを取得します
    * カメラ、マイクへのアクセスを聞かれるので、許可してください
    * THETA V が見つかれば、自動的に選択されます
    * THETA V を接続していても検出できない場合は、Chromeを一旦終了して、再度起動して見てください
<img width="799" alt="TV_360_OGO_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/19403/f601ad9c-cc47-b29e-d3e4-db5a3f068f92.png">

* [Start Video] ボタンをクリックしてください
    * 映像と音声が取得され、ブラウザ内に表示されます
* [Connect] ボタンをクリックしてください
    * SkyWay に接続され、指定されたRoomに参加します
    * 自分の映像の下に、Oculus Go で接続するためのURLが表示されます。
    * このURLを、Oculus Go のブラウザ（あるいは、他のWebVR 対応のブラウザ）で開くと映像を見ることができます
<img width="817" alt="TV_360_OGO_3.png" src="https://qiita-image-store.s3.amazonaws.com/0/19403/7309228c-a218-45d5-b25e-21cb6e5191d5.png">


* 配信を停止する場合には [Disconnect] → [Stop Video] の順にボタンをクリックしてください


## Oculus Go での視聴

* Oculus Go のブラウザ（あるいは、他のWebVR 対応のブラウザ）を起動してください
* 配信側で表示されたURLを、ブラウザでアクセスします
    * あらかじめ https://mganeko.github.io/aframe/go.html?room= までをブックマークに入れておき、最後にroom名だけ追加すると手間が少なくなるのでお勧めです
    * URLに ?room=xxxx&apikey=ZZZZZZZZZ とつけることで、自分のSkyWayのAPI KEYを利用することができます
    * あるいは、[https://mganeko.github.io/aframe/g.html](https://mganeko.github.io/aframe/g.html) を開いてroom名を入力後、[送信]ボタンをクリックすることも可能です(この場合はapikeyは指定できません)
* しばらくロードの時間がかかります
    * A-FRAMEの準備ができたら 中央にメッセージが表示されます(Please click window to start 360 video streaming)
* 画面をクリックしてください（Oculus Goのコントローラーでトリガーを引く）
    * SkyWay に接続され、指定されたRoomに参加します
    * PCに接続されている THETA V の360ど映像が表示されます
* 右下のメガネ型のVRモードボタンをクリックすると、360度モードになります（カーソルを合わせてOculus Goのコントローラーでトリガーを引く）
    * 自分の頭の向いている方向に応じて、映像の見える方向が変わります
* 360度モードを抜けるには コントローラの[戻る]ボタンを押します
* Skywayの接続を切る処理は未実装です。リロードするか、他のページに移動してください


# A-FRAMEを使った360度動画の表示

[A-FRAME](https://aframe.io) はWebVRのハードルを下げてくれるフレームワークです。Oculus Goのブラウザでも、A-FRAMEのサンプルを360度の3Dで見ることができます。サンプルには、保存済みの360度動画を見ることができるものもあります。

* [360° Video](https://aframe.io/examples/showcase/videosphere/)


また Oculus Goではありませんが、A-FRAMEを使ってRICOH Rの動画でWebVRで表示している取り組みがあります。

* [【WebVR】Theta R（RICOH R） の動画をUVCモードでWebVRしてみる【A-Frame】](https://qiita.com/gin9er69/items/fd98f1a3bf6ea5b3b523)

今回はこれをベースに360度リアルタイム映像をWebVRで見れるようにしました。るのは実現できそうです。

### 360度映像の形式について

360度映像には大きく分けて2種類の形式があります。

* dual-fisheye 形式（2つの魚眼映像） ... THETA S はUSB接続時はこちらの形式
* equirectangular 形式 （パノラマ状） ... THETA V, RICOH R はUSB接続時にこちらの形式

A-FRAMEが対応しているのは equirectangular 形式のため、今回はTHETA Sはそのままでは利用できません。未確認ですが [RICOH THETA UVC Blender](https://theta360.com/ja/about/application/pc.html)を使えばquirectangular 形式に変換して利用できそうです。

### A-FRAMEを使った360度映像の表示

詳細は他のA-FRAMEの解説に譲りますが、360度映像を表示するには次のようなコードで実現できます。

```html

  <a-scene>
    <a-assets>
      <video id="video1" autoplay loop crossorigin="anonymous" playsinline webkit-playsinline></video>
    </a-assets>
    <a-videosphere src="#video1" rotation="0 180 0">
    </a-videosphere>
  </a-scene>
```
a-assetsタグ内に元となるvideoタグを記述し、a-videosphereコンポーネントからvideoタグのidを参照します。
通常はvideo.srcにURLを指定しますが、WebRTCを使う場合はvideo.srcObjectにMediaStreamを渡してあげます。

### A-FRAMEのバージョン

A-FRAMEの最新のバージョンは0.8.0です(2018年5月現在)。しかしこのバージョンでは、私が試した限り360度動画がうまく表示できませんでした。0.7.1で試したところ無事表示できため、そちらを利用しています。


### Oculus Go 以外での視聴について

A-FRAMEはWebVRをサポートしているブラウザであれば、他のデバイスでも利用できます。

* PC(Windows/Mac/Linux)のChromeやFirefox
    * 未確認ですが、Oculus Rift や HTC Vive を使えば360度VRで見れるはず
* AndroidのChrome/Firefox
    * Cardboardを使えば、360度VRで見れます
* iOSのChrome/Firefox/Safari
    * Cardboardは惜しい感じ。~~アドレスバーが消えません~~ → ※解決策が分かりました！ 
    * [超お手軽VR開発フレームワーク　A-FRAME入門：番外編第１回 iPhoneアドレスバー問題](http://roman-tech.hatenablog.jp/entry/2016/07/04/230910) → これで iOS + Cardboard でも360度VRで見ることができます

> 僕はiPhone6に機種変更してから文字が小さくて見にくかったので拡大表示モードを使っており、実はこれが原因でした。
同じ問題に悩まされる方のために設定変更方法を記載します。


Oculus Go の手軽さにはかないませんが、他のデバイスでお楽しみいただけます。


# WebRTCによる映像/音声通信

Webブラウザでのリアルタイム映像/音声通信と言えば、WebRTCです。シグナリングサーバーやSTUN/TURNサーバーといったものが必要になります。自分で用意しても良いのですが、今回は実現スピードを優先してNTTコミュニケーションズ社が提供しているこちらのサービスを利用しました。

* [SkyWay - Enterprise Cloud WebRTC Platform](https://webrtc.ecl.ntt.com/)

WebRTCについては色々な記事があります。少し古くなってしまいますが、私が書いているものをありますので、ご覧ください。

* [WebRTC入門2016 (HTML5Experts.jp)](https://html5experts.jp/series/webrtc2016/)


### Video/Audioデバイスの取得と選択

先ほどのWebRTC入門2016では触れていませんが、PCに接続されているVideoデバイス（カメラ）と、Audioデバイス（マイク）を検出することができます。

```javascript

  function getDevice() {
    // カメラやマイクの名称を取得するために、映像と音声を取得（ユーザーに許可を求める）
    // -- enum device --
    navigator.mediaDevices.getUserMedia({video: true, audio: true})
    .then(stream => callBackDeviceList(stream))
    .catch(err => console.error(err));
  }

  // ユーザの許可をもらったら、デバイスの一覧を取得する
  function callBackDeviceList(stream) {
    navigator.mediaDevices.enumerateDevices()
    .then(function(devices) {
      devices.forEach(function(device) {
        if (device.kind === 'videoinput') {
          const id = device.deviceId;
          const label = device.label || 'camera' + '(' + id + ')';
          // .... videoデバイス検出時の処理 
        }
        else if (device.kind === 'audioinput') {
          const id = device.deviceId;
          const label = device.label || 'microphone' + '(' + id + ')';
          // .... audio デバイス検出時の処理 
        }
      });
    })
    .catch(function(err) {
      console.error("getDevices ERROR:", err);
    });

    stopLocalStream(stream);
  }

  // 映像、音声を停止
  function stopLocalStream(stream) {
    let tracks = stream.getTracks();
    for (let track of tracks) {
      track.stop();
    }
  }

```

Video/Audioデバイスを指定するには、検出されたidを利用します。

* Audioデバイスのid: xxxxxxx
* Videoデバイスのid: yyyyyyy
    * 希望の幅、高さ: wwww, hhhh

の場合は、以下のように指定します。

```javascript

let options = {
  audio : {
    deviceId : {exact: "xxxxxx" }
  },
  video : {
    deviceId : {exact: "yyyyyy" },
    width : { min : wwww, max : wwww },
    height : { min : hhhh, max : hhhh }
  }
}

navigator.mediaDevices.getUserMedia(options)
.then( stream => {
  // ... メディアストリーム取得成功時
})
.catch( err => {
  // ... エラー時
});
```



# おわりに

Oculus Goのアプリを開発するにはUnityなどが必要ですが、WebVRであればテキストエディタだけで開発できます。WebRTCを使えばリアルタイム通信も可能です。
またA-FRAMEを使えば、Oculus Go以外のデバイスでも利用できるので、ぜひお試しください。