VideoPlayerを作ろう - URL入力編
こんばんは。ハツェです。
久しぶりの投稿になりますね。
気づいたら前よりUdonGraphが使いやすくなっていたりしていますが、あのノードはまだまだ使いづらいですね。
今回は、最近来たVideo関係について少しお話しできればと思います。
動作環境は、Unity : 2018.4.20f1、VRCSDK : 2021.05.17.12.52、U# : v0.19.11です。
目次
今回の概要
シンプルに作れてLocalで動作するVideoPlayerについて紹介します。
Localで動作するため、これをそのままワールドに使用した際、みんなで見るものが違うVideoPlayerが出来上がりますのでご注意ください。
VideoPlayerに関する情報
少しだけ、VideoPlayerに関する情報を記載します。既にご存じの方は読み飛ばしてもらって結構です。
VideoPlayerの種類
SDK3.0になってから登場したVideoPlayerには、2種類あります。
- VRC Unity Video Player
- VRCAV Pro Video Player
UnityVideoPlayerは、一般の動画のみを再生できます。
一方、AVProVideoPlayerは、一般の動画に加えてライブ配信も再生することが出来ます。
ちなみに、本記事で紹介するコード等は、どちらのコンポーネントでも動作するようになっています。
コンポーネントを見てみる
AVPro Video Player
AVPro版のコンポーネントのインスペクタは以下の通りです。
色々設定項目がありますが、これらのほとんどが設定しても正しく動作しないため、ここのインスペクタを操作する必要性はないです。
そのため、URLは空にしておき、チェックマークはすべて外しておくことをオススメします。
Unity Video Player
Unity版のコンポーネントのインスペクタは以下の通りです。
AVPro版と同様の設定部はやはり機能していません。
AVPro版とは異なり、映像の出力と音声の出力は共に本体で設定します。
Render Mode
でRender Textureを選択するとTarget Textureに設定されたRenderTextureに映像が出力されます。
一方、Render Mode
でMaterial Overrideを選択するとTarget Material Rendererに設定されたメッシュについているマテリアルに出力されます。
出力させるマテリアルプロパティはシェーダー内の変数を指定することで設定できます。特段の理由が無ければ_MainTexで良いでしょう。
加えて、出力先となるAudioSourceはTarget Audio Source
で複数指定できます。
VideoScreenとVideoSpeaker
AVPro版は「本体・画面・音声」の三構成で出来ています。
本体はVRCAV Pro Video Playerのことを指しており、本体をアタッチしただけでは映像と音声は出力されません。
映像を反映したいメッシュにはVRCAV Pro Video Screenを、音声を出力したいAudioSourceにはVRCAv Pro Video Speakerをアタッチする必要があります。
VideoPlayerの型
VideoPlayerの型はVRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer
を宣言すると良いです。
AVProの変数型VRC.SDK3.Video.Components.AVPro.VRCAVProVideoPlayer
やUnityVideoの変数型VRC.SDK3.Video.Components.VRCUnityVideoPlayer
もありますが、コンパイルすると全てBaseVRCVideoPlayerに変わるので、結局VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer
を宣言すればよいと思います。
ちなみに、VideoScreenの型VRC.SDK3.Video.Components.AVPro.VRCAVProVideoScreen
とVideoSpeakerの型VRC.SDK3.Video.Components.AVPro.VRCAVProVideoSpeaker
は現状Udonで対応されてないので、宣言できません。
実際に作成してみる
完成図
だいたいは以下の通りに作ろうと思います。
画面と音声、加えて各種操作パネルとURL入力部があるという構成です。
今回はAVProを使って作成しますが、Unity版のコンポーネントを使用しても正しく動作すると思います。
Objectを配置する
Videoを表示するメッシュとかを配置します。
ビデオを表示するスクリーンにはAssets/VRChat Examples/Materials/AVProVideoScreen.mat
のマテリアルを適応しておくだけでかなり綺麗になります。
また、親オブジェクトを一個作っておいて、その下にメッシュとかAudioSourceとかを入れておくと後々便利なのでオススメです。
ちなみに、URLを送り込むInputfieldだけはVRChatが用意した独自のInputfieldVRC Url Input Field
を使用する必要があります。
まず普通にInputfieldを作成した後、コンポーネントを消してからVRC Url Input Field
を追加することで実装できます。
操作するUI系は忘れずにNavigationをNoneにしておきましょうね。(私は最初忘れてInputfieldが大変なことになった)
コンポーネントをアタッチする
VideoPlayerを作るための各種コンポーネントをアタッチします。
本体となるVRCAV Pro Video Player
はどこにアタッチしても良いのですが、分かりやすいために一番親のオブジェクトにアタッチしておきます。
次に、VRCAV Pro Video Screen
を表示するメッシュにアタッチします。
この時に本体とリンクさせておくのを忘れずに。
同じようにしてAudioSourceにもVRCAV Pro Video Speaker
をアタッチします。
スクリプトを作る
VRCAV Pro Video Player
をアタッチしたオブジェクトと同じオブジェクトにUdonBehaviorをアタッチしてスクリプトを生成します。
加えて、今回使用したコードは以下の通りです。
using UdonSharp; using UnityEngine; using UnityEngine.UI; using VRC.SDKBase; using VRC.Udon; public class LocalVideoController_InputURL : UdonSharpBehaviour { [SerializeField] private VRC.SDK3.Video.Components.Base.BaseVRCVideoPlayer _videoPlayer; [SerializeField] private VRC.SDK3.Components.VRCUrlInputField _inputfield; [SerializeField] private Text _playTimeDisplayText; private float _videoDuration; private bool _isPausing; private void Update() { if (_videoPlayer.IsPlaying) { _playTimeDisplayText.text = string.Format("{0:f} / {1:f}", _videoPlayer.GetTime(), _videoDuration); } } public override void OnVideoStart() { _videoDuration = _videoPlayer.GetDuration(); } public void PlayVideo() { _videoPlayer.Stop(); _videoPlayer.PlayURL(_inputfield.GetUrl()); } 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); } }
部分解説
Update内
再生時間を表示しています。
実際には以下のように表示されます。
左側に現在の再生時間を、右側には動画時間を表示している感じです。
動画時間の取得
OnVideoStartイベントでBaseVRCVideoPlayer.GetDuration()
を使用して変数に格納しています。
OnVideoStartイベントは、停止状態から再生した際に呼ばれるものなので、(後述にある)PlayVideo関数内では一度停止させてから再生させています。
ボタンから呼んでいる関数
UIからUdonの関数を動作させる方法については入門記事をご覧ください。
hatuxes.hatenablog.jp
OnVideoStart
以下に記述している関数は全てボタンから呼んでいます。
PlayVideo()
では、OnVideoStartイベントの関係から一度停止させた後に再生処理を行っています。PauseVideo()
では、ポーズとアンポーズを両方組み込んでいます。
動画の再生場所を変更する
SkipVideo()
とBackVideo()
では、動画の再生位置をずらすことによって実現させています。
BaseVRCVideoPlayer.GetTime()
で動画の再生時間が取得でき、BaseVRCVideoPlayer.SetTime()
で動画の再生時間を変更することが出来るので、現在の位置から+10秒の位置にズラすことでSkip処理を、現在の位置から-5秒の位置にずらすことでBack処理をしています。
実行
実際にVRChatで試してみると以下のように動作していました。
あとがき
今回は任意のURLを入力して動作させるVideoPlayerを紹介しました。
今回と次回の内容、それとUnityVideo版も含むサンプルはまとめてGithubに置いてあります。
ライセンスを確認したうえで、お使いください。
github.com
実は、Unity上で事前にプレイリストを作ってそれをループさせるということもできるので、次回はそれを紹介しようと思います。
ちなみに、他人にもしっかりと同期して動作するVideoPlayerはU#の制作者でもあるMerlinさんが制作されています。
特に理由なければ、これを使用するのが無難かと思われます。
github.com