はじめに
最近はUnityを使用する事が多く、C#スクリプトによるRender Textureを使用したVideo Playerの再生で手こずったので、その時のメモです。
なお、Video Playerの詳細は、Unityの公式ドキュメントを参照願います。
環境
確認環境は以下です。
Unity 5.6.4p4
Mac High Sierra(Ver 10.13.2)
再生仕様
- Canvasに貼られたボタンによって、ボタンに割り当たっている動画を再生します。
- 再生画面はプレハブ化し、再生時にプレハブから生成されるようにします。
- 再生する動画は、"Resources/Movie" の下に保存していることとします。
(まずは再生のみの実装とします)
##Project構成
以下のようなUnityプロジェクトの構成イメージです。
###Hierarchyビューのツリー
Scene
├Canvas
│ └Button
└Video Player
###Projectのツリー
Assets
├Resources
│ ├Movie
│ │ └再生動画
│ └Prefabs
│ └Raw Image
└Scripts
└Sample.cs
##Hierarchyビューでの操作
Hierarchyビューで以下の操作を行います
- Canvasを準備します
- スマホでの再生を前提にしているので、UI Scale Modeは、”Scale With Screen Size” に設定しました。
- Canvasの下に再生用のボタンを準備します
- Canvasの下にRaw Imageを準備します
- Raw ImageのInspector画面で、適切な大きさにサイズを調整し、プレハブ化します
- プレハブは、"Resources/Prefabs" の下に保存します
- Raw Imageは、動画の再生画面になるので、あらかじめ位置と大きさを決めておきま
- Video Playerを準備します
- Video PlayerのInspector画面の、Add Componentで、Audio Sourceを追加します
- ボタンと再生処理を行うスクリプトを作成し、上記2.で作成したボタンにスクリプトを登録し、OnClickイベントに登録します。(以下のサンプルコードでは、VideoStart())
##スクリプト
以下サンプルコード
(ボタンの処理と動画の再生処理はコードを分けた方が良いと思いますが、サンプルなので、、、)
Sample.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.UI;
public class VideoPlayController : MonoBehaviour {
// とりあえず特定のファイル名を指定
string videoclipfile = "Movie/動画ファイル名";
// 再生画面用のRaw Imageは「MovieRawImage」という名称でプレハブ化されている前提
string rawImage = "Prefabs/MovieRawImage";
public void VideoStart(){
// ボタンクリック処理
StartCoroutine (VideoPlayStart ());
}
private IEnumerator VideoPlayStart()
{
// あらかじめVideo PlayerがSceneに登録されている前提
var obj = GameObject.Find ("Video Player");
VideoPlayer videoPlayer = obj.GetComponent<VideoPlayer> ();
Application.runInBackground = true;
// あらかじめVideo PlayerにAudio Sourceが登録されている前提
var audioSource = videoPlayer.GetComponent<AudioSource>();
// ファイルをロードし、再生する動画のサイズに合わせてRender Textureを準備する
VideoClip vclip = (VideoClip)Resources.Load (videoclipfile);
RenderTexture _renderTexture = new RenderTexture ((int)vclip.width, (int)vclip.height, 24);
// Video Playerの設定を行う
videoPlayer.playOnAwake = false;
audioSource.playOnAwake = false;
videoPlayer.source = VideoSource.VideoClip;
videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
videoPlayer.renderMode = VideoRenderMode.RenderTexture;
videoPlayer.EnableAudioTrack(0, true);
// Audio SourceにあらかじめVideo Playerに追加したAudio Sourceを設定する
videoPlayer.SetTargetAudioSource(0, audioSource);
videoPlayer.clip = vclip;
videoPlayer.targetTexture = _renderTexture;
// Video Playerの準備(完了まで待つ)
videoPlayer.Prepare();
while (!videoPlayer.isPrepared)
yield return null;
// Video Playerの準備が完了した後
// プレハブから動画再生用のRawImageをロードする
var _prefab = Resources.Load(rawImage);
GameObject _rawImg = Instantiate(_prefab) as GameObject;
// Canvasが親になるようにtransformを代入する
GameObject cvs = GameObject.Find("Canvas");
_rawImg.transform.parent = cvs.transform;
_rawImg.transform.localPosition = Vector3.zero;
_rawImg.transform.localScale = new Vector3 (1, 1, 1);
// RawImageに動画再生用のRenderTextureを設定する
RawImage screen = _rawImg.GetComponent<RawImage>();
screen.texture = _renderTexture;
// 動画の再生開始(再生完了まで待つ)
videoPlayer.Play();
while (videoPlayer.isPlaying)
yield return null;
// 動画の再生完了
videoPlayer.clip = null;
videoPlayer.targetTexture = null;
GameObject.Destroy (_rawImg.gameObject);
}
}
##注意点
- Video PlayerのTarget Textureに登録するRender Textureについては、再生する動画の縦横サイズを設定する必要があるようです。スクリプト例では再生コンテンツのサイズを設定しています
- Video Playerの設定を行なった後、Prepare()によって準備を行う必要があるようです。
- 設定が抜けると、正しく再生できません。私はtargetTextureの設定がPrepare()の後になっていて正しく再生できませんでした
- Raw Imageには、Video Playerに登録したTarget Textureと同じRender Textureを登録します
- Video Playerの再生完了後、Video Clipを初期化しないと2回目以降の再生が正しく表示できないようです。
- スクリプト例では、念のためにTarget Textureも初期化しています。
以上、ご参考まで。