TECHブログ


OculusGoからWebサーバーにアクセスしてVR動画をダウンロードして視聴する

はじめに

OculusGoから同じネットワーク上に存在するWebサーバにアクセスして動画ファイルをダウンロードし、OculusGoで再生する方法を紹介します。

アプリ概要

今回紹介するアプリケーションは社内ネットワークなどのローカルネットワーク内で起動しているWebサーバーにアクセスして動画をダウンロードし、動画ファイルを再生するVR動画プレーヤーです。

OculusGoで動画再生をする場合、ビルド時に動画を埋め込むか、USB接続でOculusGoの内部ストレージに動画を保存して再生する方法しかないので、その工程を省くためにWebサーバーへアクセスして動画をダウンロードする機能を実装しました。

アプリの流れとしては以下の通りです。

  1. Webサーバー起動
  2. OculusGo起動
  3. サーバーへアクセスし、動画情報を記載したjsonファイルをダウンロード
  4. jsonファイルをもとに各動画ファイルをダウンロード実行
  5. 全動画のダウンロードが完了したら動画を再生する
  6. アプリケーションを終了するまで、動画をループする(複数動画ある場合は順番に再生)

以下システムイメージ

SystemImage1

SystemImage3

開発環境

  • Windows10 Pro
  • Unity2018 4.x
  • Visual Studio 2019
  • nginx 1.9.2
  • OculusGo 12.0.0.226.469
  • OculusIntegration 20.0

動画ファイル方式

VR動画では、HMD(ヘッドマウントディスプレイ)を装着するので没入感が高い映像を視聴することができます。

VR動画は立体視を行うため普通の動画と違い一つの動画に右目用の動画、左目用の動画が表示されています。

動画方式としてUnityで開発する際に選べるのが以下の二種類です

  • サイドバイサイド方式

サイドバイサイド方式は左側に左目用の映像、右側に右目用の映像を配置した配置した動画方式です。

SideBySide.png

  • トップアンドボトム方式

トップアンドボトム方式では上側に左目用の映像、下側に右目用の映像を配置した動画方式です。

OU

参考動画はこちらです。(サイドバイサイド方式180度動画)

180度動画とは

自分の前方180度のみに動画が表示されるもので、2018年夏ごろに「VR180」という180度動画の規格がGoogleによって策定されました。

  • メリット
    1. 撮影のハードルが下がる
    2. 360度VR動画と比べて動画のデータ量を抑えられる
    3. 視点が固定される
  • デメリット
    1. 360度動画と比べて視野が狭くなるので没入感が多少損なわれる
  • VR180が向いている動画ストーリー形式の動画

Unityでの実装

初期準備

OculusGoを開発するための準備

公式ドキュメントを参考に以下を行ってください

    1. 「ビルド設定」
    2. 「パッケージ識別詳細情報を追加する。」
    3. 「バーチャルリアリティ(VR)サポートを有効にする」

Assetstore->Search->Oculus Integrationを検索->importを実行

VR動画再生のための準備
    1. Assets->Oculus->VR->Prefabs->OVRCameraRigをHierarchyに配置
    2. MainCameraを削除
    3. VideoPlayerを配置

Materialの作成
        1. ShaderをSkybox/Panoramicに変更
        2. TintColorを白に
        3. Spherical(HDR)に作成したRender Textureをアタッチ
        4. ImageTpe,3DLayoutは動画の種類によって適宜変

Render Textureの作成
        1. Sizeを再生する動画に合わせて変更

VideoPlayerの設定
      1. Render ModeをRender Textureに変更
      2. Target Textureに作成したRender Textureをアタッチ

  1. Window->Rendering->LightSettings->SkyboxMaterialに作成したmaterialをアタッチ

以上で、VR動画再生が可能になる。

ローカルファイルの動画を再生する場合SourceをURLに変更して[file://ファイルパス]と入力すると再生が可能になる。

WebServerへのアクセス

Webサーバーへのアクセスをコルーチンで実装しています。

private IEnumerator GetItem(string url)
{
    //URLはwebサーバーに配置しているファイル(例)http://192.168.0.x/sample.mp4
    //nginxではhtmlフォルダ内にファイルを設置している。
    UnityWebRequest request = UnityWebRequest.Get(url);
    //SendWebRequestを実行、完了まで待機
    yield return request.SendWebRequest();
    //エラー判定    
    if (request.isNetworkError)
    {
        //エラー確認
        Debug.Log(request.error + ":" + request.responseCode);
    }
    else
    {
        //受け取ったデータをbyte[]に格納
        byte[] getByte = request.downloadHandler.data;
        //OculusGoのローカルストレージのパスを取得
        //
        localStragePath = Application.persistentDataPath;
        //ファイル名を取得して保存先のパスを指定
        string pathToFile = localStrage + Path.GetFileName(URL);
        //ファイルの書き出し
        File.WriteAllBytes(pathToFile, getByte);
    }
    //requsetの破棄
    request.Dispose();
}

参考:公式ドキュメント

OculusGoからwebサーバーにアクセスする際エラー「Unknown error」が発生しました。

解決法としては、BuildSettingsの[Build System]を[internal]に変更することで回避できました。

視線情報で動画プレイヤーを操作する

今回アプリケーションの操作は視線情報で行います。

Asetts->Oculus->VR->Prefabsから「OVRCameraRig」をHierarchyに配置、MainCameraを削除

OVRCameraRigの階層にはHMDやコントローラの位置情報を持ったオブジェクトが配置されています。

その中でCenterEyeAnchorを利用してRayを飛ばしていきます。

VideoPlayer操作用に「Cube」を配置しました

EditorUI

左:前の動画へ

中央:再生/停止

右:次の動画へ

それぞれに名前を付け、rayが当たったオブジェクトの名前を取得してVideoPlayerを操作する形になります。

public Class SampleScript:MonoBehaviour
{ 
//視線情報 OVRCameraRig->Trackingspace->CenterEyeAnchorをアタッチ
[SerializeField]
private transform _CenterEyeAnker;
[SerializeField]
private VideoPlayer videoPlayer;
	void Start()
	{
   		videoPlayer = gameObject.GetComponent<VideoPlayer>();
	}
    void Update()
    {
        //Rayを目線から前方向に発射
         Ray pointerRay = new Ray(_CenterEyeAnker.position, _CenterEyeAnker.forward);
        //ヒットしているならカウントの開始   
        if (Physics.Raycast(pointerRay, out RaycastHit hitInfo, _MaxDistance))
        {
                count += Time.deltaTime;
            	//カウントが2秒を超えたらVideoPlayer操作実行
                if (count >= 2)
                {
                    ///VideoPlayer操作
                    //操作実行後countを0に戻す。
                    count = 0;
                }
        }
    }
}

実際にOculusGoで実行した動画がこちらです 使用している動画は以下のURLからお借りしています。

180VR sample footage 3

3D Insane Effects | 3D Side by Side SBS VR Virtual Reality

動画の終了判定を受け取る

動画の終了判定を行うにはVideoPlayerのLoopをtrueにする方法が一番手軽です。

void Start()
{
    videoPlayer.loopPointReached += FinishVideo;
}
public void FinishVideo(VideoPlayer vp)
{
    videoPlayer.Stop();
    //動画終了後の処理を記載
}

これで動画が終了した際FinishVideo()が実行されます。

まとめ

今回OculusGoからWebサーバーにアクセスしてファイルをダウンロードすることが可能か検証ができました。

gRPCなどのフレームワークを利用すればリアルタイムでデータの送受信が可能なVRアプリケーションの開発などもできると思います。

今回はOculusGoをターゲットに開発しましたが、OculusIntegrationではほかのOculus製品を扱うことができるので、OculusQuestやOculusRiftでも同様なアプリケーションの開発可能できそうです。