前回は、作成したプレイヤーを使用してOculus上で動画を再生しました。
今回は、外部サーバーにある動画ファイルを取得して、これまで作成したプレイヤーで再生する方法をご紹介します。
Unityには、Http通信関連の処理を行うために用意されているクラスとしてWWWがあります。
いろいろな箇所で使用方法が紹介されているため、今回使用するサンプルソースコードの内容のみを簡単に説明します。
//動画ファイル読み込み処理 private IEnumerator load(string url){ print(url); using (www = new WWW(url)) { movie = www.movie; while (!www.isDone) { if (!string.IsNullOrEmpty(www.error)) { print("www Error:" + www.error); yield break; } print("Now Loading... " + www.progress * 100 + "%"); yield return null; } go.GetComponent<Renderer>().material.mainTexture = movie; movie.Play(); } }
今回使用する動画は外部ファイルのため、ファイルの読み込みが完了するまで、「再生」処理を待つ必要があります。
読み込み完了まで待つという処理の実装には、コルーチンを使用すると効率的です。
コルーチンというのは、処理を一時的に中断し、その後中断した箇所から以降の処理を続けて行うためのプログラミング構造です。
※詳しくはこちらをご覧くださいwikipedia
コルーチンを使用する際は、関数の戻り値の型をIEnumeratorにする必要があり、IEnumerator以外の型を戻り値として定義するとコンパイルエラーとなります。
そして、処理を中断したい箇所に yield ~ と記載します。
上記のサンプルソースでは、whileの中で2箇所使用しています。
yield break
→コルーチンの処理を強制的に終了する
yield return null
→次フレームまで処理を中断する
yield returnには他にも書き方があり、以下のように指定すると、次に実行するまでの時間を指定することが出来ます。
yield return new WaitForSeconds (<秒数>);
コルーチンを使用した処理を実行するためには、StartContinue関数を使用する必要があります。
引数には、対象の関数名を渡します。
対象の関数に引数が必要な場合は、関数名を指定した後に、続けてパラメータを指定することで値を渡すことが出来ます。
StartContinue(“load”, url);
コルーチンで何を行っているかが大体分かったと思いますので、次に動画の取得についてです。
WWWの引数に外部ファイルのパス(URL)を指定します。
WWWクラスは受け取ったURLでインスタンスを生成し、通信を開始します。
取得した動画は、WWWクラスが持つmovieに格納され、MovieTextureとしてサポートされています。
そのため、前回まで使用していたMovieTextureに、WWWがもつmovieプロパティを設定するだけで取得した動画をCanvas上に反映させることが出来ます。
あとは、今までと同じように実行すると用意したCanvas上で取得した動画の再生を行うことが出来ます。
1点、外部ファイルを読み込む際に注意しなければいけないことで、動画ファイルの形式を Ogg Theoraにしておく必要があります。
Assetsから読み込んだ際は、mp4で問題なかったのですが、これはAssetsからインポートするときにUnity側で自動的にOgg形式に変換しているためです。
外部ファイルをAssetsと同じようにmp4やmov形式にすると読み込みがずっと終了しないので、使用するファイルは必ずOgg形式で用意してください。
コルーチンを使用することで、1つの関数内で 動画の取得~取得後のMovieTextureセットアップまでを直感的に書くことが出来ました。
とても便利なので、皆さんもぜひ活用してください。
おまけとして、取得した動画ファイルを永続データとして扱いたい場合は以下の処理をすればローカルの領域に保存されます。
File.WriteAllBytes(Application.persistentDataPath + "/sample.ogv", www.bytes);
Application.persistentDataPathで永続化データを保存する領域のパスを取得することが出来ます。
プラットフォームによる差異を吸収して、それぞれに適したパスを返却してくれるので、とても便利です。
階層をさらに深くしたい場合は、ディレクトリを作成するだけで好みの箇所に保存できます。
string path = Application.persistentDataPath + "/movie"; if (!Directory.Exists(path)) { //ディレクトリが存在しなかったら、新規作成 Directory.CreateDirectory(path); } //ファイル保存 File.WriteAllBytes(path + "/sample.ogv", www.bytes);
以上で、外部動画ファイルの取得・再生のご紹介は終了です。
最後までご覧頂き有難うございました。
■当記事のサンプルソース
前回まで使用していたButtonを4つに増やしました。
引数を渡せるClickメソッドを追加し、渡ってきたインデックスによって取得する動画を変えています。
using UnityEngine; using System.Collections; using System.IO; public class ButtonClick : MonoBehaviour { private readonly string URL = "http://xxxxxxxx/resource/movie/"; public GameObject go; public MovieTexture movie; private WWW www; void Start () { } void Update () { } public void OnClick() { } public void OnClick2(int idx){ string url = URL + "000" + idx + ".ogv"; StartCoroutine("load", url); } private IEnumerator load(string url){ print(url); using (www = new WWW(url)) { movie = www.movie; while (!www.isDone) { if (!string.IsNullOrEmpty(www.error)) { print("www Error:" + www.error); yield break; } print("Now Loading... " + www.progress * 100 + "%"); yield return null; } go.GetComponent<Renderer>().material.mainTexture = movie; movie.Play(); } } }
弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。