ハツェの真時代傾向璋

興味を持ったことを書いていく鱗片的な場所から先の未来の場

VideoPlayerを作ろう - プレイリスト編

こんばんは。ハツェです。
前回に引き続きVideoPlayerに関して記事を書きたいと思います。
今回は、任意のURLを入力するタイプでなく、プレイリストをUnity上で作ろうというお話です。
動作環境は、Unity : 2018.4.20f1、VRCSDK : 2021.05.17.12.52、U# : v0.19.11です。

目次


今回の概要

シンプルに作れてLocalで動作するVideoPlayerについて紹介します。
今回は、事前にURLを組み込んでおいて動作させるプレイリストみたいなものを作る予定です。
Localで動作するため、これをそのままワールドに使用した際、みんなで見るものが違うVideoPlayerが出来上がりますのでご注意ください。

前回

前回は、任意のURLから動画を再生させる方法について紹介しました。
hatuxes.hatenablog.jp

プレイリスト

プレイリストと言っても事前にUnityにURLを書き込んだ配列を用意するだけです。
普通のStringではダメなんですが、VRCUrl型の配列だと下記画像のようにうまくプレイリストに落とし込むことが出来ます。

f:id:hatuxes:20200919225556p:plain

実際に作成してみる

完成図

だいたいは以下の通りに作ろうと思います。
画面と音声、加えて各種操作パネルがあるという構成です。
今回はAVProを使って作成しますが、Unity版のコンポーネントを使用しても正しく動作すると思います。

f:id:hatuxes:20200919223845p:plain

加えて今回、オブジェクトの作成とコンポーネントのアタッチについては前回とほぼ同様なため省略します。

スクリプトを作る

VRCAV Pro Video Playerをアタッチしたオブジェクトと同じオブジェクトにUdonBehaviorをアタッチしてスクリプトを生成します。
加えて、今回使用したコードは以下の通りです。

f:id:hatuxes:20200919164227p:plain
using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
using VRC.SDKBase;
using VRC.Udon;

public class LocalVideoController_PlayList : UdonSharpBehaviour
{
    [SerializeField]
    private VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer _videoPlayer;

    [SerializeField]
    private VRCUrl[] _playlistURL;

    [SerializeField]
    private Text _playTimeDisplayText;

    [SerializeField]
    private Text _indexDisplayText;

    [SerializeField]
    private Toggle _loopToggle;

    private float _videoDuration;
    private int _urlIndex;
    private bool _isPausing;

    private void Update()
    {
        _indexDisplayText.text = string.Format("Index : {0}", _urlIndex);

        if (_videoPlayer.IsPlaying)
        {
            _playTimeDisplayText.text = string.Format("{0:f} / {1:f}", _videoPlayer.GetTime(), _videoDuration);
        }
    }

    public override void OnVideoStart()
    {
        _videoDuration = _videoPlayer.GetDuration();
    }

    public override void OnVideoEnd()
    {
        if (_loopToggle.isOn)
        {
            _urlIndex = (_urlIndex + 1) >= _playlistURL.Length ? 0 : _urlIndex + 1;
        }
        else
        {
            if ((_urlIndex + 1) >= _playlistURL.Length)
            {
                return;
            }

            _urlIndex++;
        }

        PlayVideo();
    }

    public void PlayVideo()
    {
        _videoPlayer.Stop();
        _videoPlayer.PlayURL(_playlistURL[_urlIndex]);
    }

    public void PauseVideo()
    {
        _isPausing = !_isPausing;

        if (_isPausing)
        {
            _videoPlayer.Pause();
        }
        else
        {
            _videoPlayer.Play();
        }
    }

    public void StopVideo()
    {
        _videoPlayer.Stop();
    }

    public void SkipVideo()
    {
        _videoPlayer.SetTime(_videoPlayer.GetTime() + 10.0f);
    }

    public void BackVideo()
    {
        _videoPlayer.SetTime(_videoPlayer.GetTime() - 5.0f);
    }

    public void NextVideo()
    {
        _urlIndex = (_urlIndex + 1) >= _playlistURL.Length ? 0 : _urlIndex + 1;

        PlayVideo();
    }

    public void PreviousVideo()
    {
        _urlIndex = (_urlIndex - 1) < 0 ? _playlistURL.Length - 1 : _urlIndex - 1;

        PlayVideo();
    }
}


部分解説

Update内

再生時間を表示しています。
実際には以下のように表示されます。
左側に現在の再生時間を、右側には動画時間を表示している感じです。

f:id:hatuxes:20200919210302p:plain

動画時間の取得

OnVideoStartイベントでBaseVRCVideoPlayer.GetDuration()を使用して変数に格納しています。
OnVideoStartイベントは、停止状態から再生した際に呼ばれるものなので、(後述にある)PlayVideo関数内では一度停止させてから再生させています。

動画が終わったときの処理

OnVideoEndイベントを用いて、動画終了時に次のプレイリストの動画に移るという処理をしています。
UIのToggleにチェックマークが入ってた場合は、一周したらまた頭から再生し、チェックマークが入ってなかったらプレイリストの終わりで動画が止まるようになってます。

ボタンから呼んでいる関数

UIからUdonの関数を動作させる方法については入門記事をご覧ください。
hatuxes.hatenablog.jp
OnVideoStart以下に記述している関数は全てボタンから呼んでいます。
PlayVideo()からBackVideo()まではURLInput方式のVideoPlayerと同様の処理なので、詳しくはそちらをご覧ください。

進むボタンと戻るボタン

NextVideo()では次のプレイリストの動画に、PreviousVideo()では前のプレイリストの動画に移るようになっています。
ここの処理はLoopのUIチェックボックスに関係なく処理されるべきなので、そのように記述しています。

実行

実際にVRChatで試してみると以下のように動作していました。

f:id:hatuxes:20200919231736g:plain

あとがき

今回は事前にURLを指定しておいてプレイリストのように動作させるVideoPlayerを紹介しました。
前回と今回の内容、それとUnityVideo版も含むサンプルはまとめてGithubに置いてあります。
ライセンスを確認したうえで、お使いください。
github.com

ちなみに、他人にもしっかりと同期して動作するVideoPlayerはU#の制作者でもあるMerlinさんが制作されています。
プレイリストにも対応しているので、素直にこれを使うのがいいかもしれないですね。
github.com