VideoPlayer でハマったポイントの対処法(時間・シーク・終了イベント)

こないだ、UnityのVideoPlayerの機能を使っていたのですが、何か所かハマったポイントがあったのでメモがてら整理しておきます。難しい内容ではなく、知っているかどうかがメインかと思います。では、早速!

URL形式でビデオクリップの時間を取得する

URL形式でビデオを再生した際に「VideoPlayer.clip」がどうも(null)になってしまうことに気付きました。ビデオクリップが(null)だとLengthが取れず、ビデオの時間/尺が分からないぞ…ってなります。

じゃあ、どうするか? 自分で計算します。

下記の内容はURL形式でも分かるので、そのデータを元に算出できます。計算式は単純に割ってください。

  • VideoPlayer.frameCount: ビデオ全体のフレーム総数
  • VideoPlayer.frameRate: ビデオのフレームレート

var videoDuration = (float)VideoPlayer.frameCount / VideoPlayer.frameRate;

注意点としてはまず、frameCountの方のデータ型がulongなのでキャストしてあげましょう。次に、ビデオがロードされきる前に上記の変数を読み込むと値が入っていないことがあったので、ロードが終わった後に計算するようにした方が良いです。ロードが終わった後に処理させるには下記の感じになります。

VideoPlayer.prepareCompleted += StartProcess;

VideoPlayer.Prepare();

メソッドとして入れ込んでいる StartProcess ですが、引数にVideoPlayerを設定してあげる必要がありそうでした。ちなみに、StartProcessは自身で用意するメソッドなので名称は何でも大丈夫です。

(Sliderとかを使って)シークさせる

シークに関しては、YouTubeなどでも分かるように再生ポイントをSliderや指定の位置をクリックして移動させる方法のことです(よね…?)

細かいことはさておき、VideoPlayerでシークさせるには上記のフレーム情報を使うと簡単にできます。とりあえず、ここではSliderでやる前提で考えますが、基本的には以下のことが出来れば問題ないかと思います。

  • VideoPlayer.frameCount を、SliderのMaxValue として設定する(初期処理)
  • VideoPlayer.frame から現在再生中のフレームを取得する/移動させるフレームを設定する(SliderのValue値として扱う)

といった形で、ごにょごにょ出来るかと思います。ただ毎フレーム並みにフレームを移動させたりすると負荷が高そうなのでプレビューしながらとかは難しいかなとは考えています。

終了時にイベント処理を発生させる

単純に考えたら、再生時間を待ってあげれば良いですが、シークなどが発生するとその限りではないので、終了時にイベントを仕込みたくなります。ので、仕込んでみましょう。

VideoPlayer.isLooping = true;

VideoPlayer.loopPointReached += EndProcess;

基本的にはビデオプレイヤーのループ機能を使うといった具合になります。ループをする際にループポイント(=ビデオの終端)に到達したことが分かるので、それを利用しています。

注意点としては、ループ機能をオンにしていないと呼ばれない噂?(未検証です…)があったので、一応ループにしておいた方が良いかと思います。その影響で、再生終了時にStopをかけたり、ループをオフにするといったフォローも入れておくと良いです。あとは、先ほどと同じようにEndProcessのメソッドにVideoPlayerの引数は必要だったかと。

VideoPlayerに関してはまだ奥が深そうではありますが、個人的には使いやすい感がありますし、仕様的にも上記のことが出来たて一通りこなせたので便利だなーって思っています。