from2001vrです。
Unityで任意のフォルダに置いてあるスティッチ済み全天球動画ファイルを再生する環境の構築方法です。
ビデオ再生用アセットのAVPro QuickTimeを利用して、映像を全天球オブジェクトへ投影する方法を説明します。
Unity ProのMovie Textureを使う方法は
360度カメラTHETAで撮った写真・動画をUnityで使う
で紹介しましたが、AVProを使うことで下記のメリットがあります。
- 外部mp4ファイルの再生が可能(プロジェクトに事前インポート不要)
- 映像はライトの影響を受けず表示される(ライト不要)
- 映像を途中から再生するなど細かな制御ができる
- 動作が軽く安定している(気がする)
まずはAVPro QuickTimeを購入しインポートします。開発元のRenderHeads公式サイトでは透かしの入るトライアル版も公開されています。AVProにはQuicktime版とWindows Media版がありますが、QuickTime版はWindowsでもMacでも動きますのでQuickTime版を購入しましょう。
全天球動画投影のためのオブジェクトUVsphereを下記にアップしましたのでダウンロードしインポートします。ちなみにこのオブジェクトの作り方はこちら。
全天球用内側メッシュSphereオブジェクト UVsphere.blend @GoddoSukoupion作成
UVsphereをシーンに追加してください。この球に映像が投影されます。
空オブジェクトを作成しAVProMovieObjectとでも名づけます。
下記のスクリプトを追加していきます。デフォルト値以外に変更する場所を下記に示します。(下記画像では赤い点の場所)
- AVProQuickTimeMaterialApplyスクリプト
Material:UVsphere_material - AVProQuickTimeMovieスクリプト
Folder:再生するビデオの保存フォルダ
Filename:再生するビデオファイル名 - AVProQuickTimeManagerスクリプト
- Projector
Material:UVsphere_material
実行すると綺麗に全天球動画が再生されているのを確認できると思います。
AVProではスクリプトから動画の読み込みや再生に対応していますがドキュメントやサンプルがあまり整備されていません。
基本的な一時停止、再生、指定ファイルの読み込み再生を行うためのサンプルコードを作成しましたので載せておきます。
任意のオブジェクトにアタッチし、AVProQuickTimeMovieにAVProMovieObjectを設定してください。
using UnityEngine; using System.Collections; public class AVProFunctions : MonoBehaviour { //キーボードで制御サンプル // S: 一時停止 // P: 再生 // L: 指定のファイルを読み込んで再生 void Update () { if (Input.GetKeyDown(KeyCode.S)) { pause(); } if (Input.GetKeyDown(KeyCode.P)) { play(); } if (Input.GetKeyDown(KeyCode.L)) { loadMovieFile("T:/video.mp4"); } } public AVProQuickTimeMovie _movie; private AVProQuickTime moviePlayer; //再生 void play(){ moviePlayer = _movie.MovieInstance; moviePlayer.Play(); } //一時停止 void pause(){ moviePlayer = _movie.MovieInstance; moviePlayer.Pause(); } //ビデオファイル読み込み void loadMovieFile(string fileFullPath){ _movie._folder = System.IO.Path.GetDirectoryName (fileFullPath); _movie._filename = System.IO.Path.GetFileName (fileFullPath); _movie.LoadMovie(); play (); } }
上記全天球用Sphereオブジェクト、設定済みAVProMovieObject、サンプルシーン、サンプル360度映像、基本関数サンプルをセットにしたPackageファイルを用意しましたので公開しておきます。AVPro QuickTime製品版・トライアル版両方で動作することを確認済み。
- AVProアセットのインポート
- AVPro用360度設定済みパッケージAVPro360Sample.unitypackageのインポート(インポートに少し時間がかかります)
- AVPro_360というフォルダが作成され下記のファイルがインポートされます。
AVProMovieObject: 360度全天球設定済みPrefab
UVsphere: 全天球用球体オブジェクト
AVProFunctions: 基本関数サンプルセット
Sample/AVPro360Sample: サンプルシーン
Sample/RollerCoaster_Short: サンプル360度映像(SphericalImageCamで生成) - 初回実行時にはDLLコピーに関するアラートが上がるので「Yes, copy」を選択後、再度実行しなおしてください。
最後に、設定の勘違いで行き詰っていたところを助けていただいた@kojiokbさんどうもありがとうございました。
@from2001vr トライアル版で試してみましたが特に問題なく360度動画の表示できました。インスペクターはこんな感じです。(phong1が自作Sphereのマテリアルです) https://t.co/DDLrjbuns9 pic.twitter.com/eiGcl7n5p8
— koji okabe (@kojiokb) 2015, 1月 31
追記 2016/07/09
PC, Mac, Android, iOSに同じアセットで対応できるAVProがリリースされています。
スクリプトだけで、ビデオを任意のオブジェクト上のテクスチャに表示する方法がアセットに添付のサンプルやドキュメントではわかりにくかったのでメモしておきます。(Usingせずにコードにネームスペース書いてるのは再利用性高めるため)
//ビデオを再生するシンプルなサンプル using UnityEngine; using System.Collections; public class PlayAVPro : MonoBehaviour { public GameObject go; RenderHeads.Media.AVProVideo.MediaPlayer MPLayer; // Use this for initialization void Start () { string path = "SampleCube.mp4"; MPLayer = go.AddComponent<RenderHeads.Media.AVProVideo.MediaPlayer>(); MPLayer.m_AutoOpen = false; MPLayer.OpenVideoFromFile(RenderHeads.Media.AVProVideo.MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder, path, true); MPLayer.Control.SetTextureProperties(FilterMode.Bilinear, TextureWrapMode.Repeat,0); //Offset設定時に適切に表示されるように<br> } // Update is called once per frame void Update () { go.GetComponent<Renderer>().material.mainTexture = MPLayer.TextureProducer.GetTexture(); } }
AVProのイベントを拾うコードを追加したサンプル
using UnityEngine; using System.Collections; using RenderHeads.Media.AVProVideo; public class PlayAVPro : MonoBehaviour { public GameObject go; RenderHeads.Media.AVProVideo.MediaPlayer MPLayer; // Use this for initialization void Start () { string path = "SampleCube.mp4"; MPLayer = go.AddComponent<RenderHeads.Media.AVProVideo.MediaPlayer>(); MPLayer.m_AutoOpen = false; MPLayer.OpenVideoFromFile(RenderHeads.Media.AVProVideo.MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder, path, true); MPLayer.Events.AddListener(OnVideoEvent); } // Update is called once per frame void Update () { go.GetComponent<Renderer>().material.mainTexture = MPLayer.TextureProducer.GetTexture(); } public void OnVideoEvent(MediaPlayer mp, MediaPlayerEvent.EventType et) { switch (et) { case MediaPlayerEvent.EventType.MetaDataReady: Debug.Log("MediaPlayerEvent:MetaDataReady"); break; case MediaPlayerEvent.EventType.ReadyToPlay: Debug.Log("MediaPlayerEvent:ReadyToPlay"); //mp.Control.Play(); break; case MediaPlayerEvent.EventType.FirstFrameReady: Debug.Log("MediaPlayerEvent:FirstFrameReady"); mp.Control.SetTextureProperties(FilterMode.Bilinear, TextureWrapMode.Repeat, 0); //Offset指定時に正常に表示されるように break; case MediaPlayerEvent.EventType.FinishedPlaying: Debug.Log("MediaPlayerEvent:FinishedPlaying"); setThumbnail(); break; case MediaPlayerEvent.EventType.Started: Debug.Log("MediaPlayerEvent:Started"); break; } Debug.Log("Event:" + et.ToString()); } }
追記2016/07/16
テクスチャ貼付け時にOffsetを設定すると適切に設定しないかぎり下記のようになりオフセット部分がノイズが入ったように表示される。
・解決方法
AVPro設定でMediaPlayer.csの
Media Properties内WrapをCrampからRepeatに変更する。