using UdonSharp; using UnityEngine; using VRC.SDK3.Components.Video; using VRC.SDK3.Video.Components.Base; using VRC.SDKBase; public enum VideoPlayerRound { INVALID_ROUND, Round1, Round2, Round3, MAX_ROUNDS } [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class MultiRoundVideoPlayer : UdonSharpBehaviour { [SerializeField] private BaseVRCVideoPlayer _VideoPlayer; [SerializeField] private UdonSharpBehaviour[] _RoundCallbacks; [UdonSynced, FieldChangeCallback(nameof(CurrentRound))] private VideoPlayerRound _CurrentRound = VideoPlayerRound.INVALID_ROUND; public void SetCurrentRound(VideoPlayerRound Round) { if (Round > VideoPlayerRound.INVALID_ROUND && Round < VideoPlayerRound.MAX_ROUNDS) { _CurrentRound = Round; Stop(); } RequestSerialization(); } public void LoadURL(VRCUrl URL) { _VideoPlayer.LoadURL(URL); } public void Play() { _VideoPlayer.Play(); } public void Stop() { _VideoPlayer.Stop(); } public bool IsReady() { return _VideoPlayer.IsReady; } public bool IsPlaying() { return _VideoPlayer.IsPlaying; } public float GetDuration() { return _VideoPlayer.GetDuration(); } public float GetTime() { return _VideoPlayer.GetTime(); } public override void OnVideoReady() { foreach (UdonSharpBehaviour Object in _RoundCallbacks) { _ExecuteCurrentRoundCallback_Private("VideoIsReady"); } base.OnVideoReady(); } public override void OnVideoStart() { _ExecuteCurrentRoundCallback_Private("VideoStarted"); base.OnVideoStart(); } public override void OnVideoEnd() { _ExecuteCurrentRoundCallback_Private("VideoEnded"); base.OnVideoEnd(); } public override void OnVideoError(VideoError VideoError) { switch (VideoError) { case VideoError.Unknown: Debug.LogError("[MultiRoundVideoPlayer] Unknown playback error."); break; case VideoError.InvalidURL: Debug.LogError("[MultiRoundVideoPlayer] Invalid URL."); break; case VideoError.AccessDenied: Debug.LogError("[MultiRoundVideoPlayer] Access denied."); break; case VideoError.PlayerError: Debug.LogError("[MultiRoundVideoPlayer] Error with video player."); break; case VideoError.RateLimited: Debug.LogError("[MultiRoundVideoPlayer] Rate limited. Attempting another reload in 2 seconds..."); SendCustomEventDelayedSeconds(nameof(LoadURL), 2.1f); return; } Stop(); _ExecuteCurrentRoundCallback_Private("VideoError"); base.OnVideoError(VideoError); } private void _ExecuteCurrentRoundCallback_Private(string Event) { if (_CurrentRound > VideoPlayerRound.INVALID_ROUND && _CurrentRound < VideoPlayerRound.MAX_ROUNDS) { _RoundCallbacks[(int)_CurrentRound - 1].SendCustomEvent(Event); } } public VideoPlayerRound CurrentRound { set { _CurrentRound = value; Stop(); } get => _CurrentRound; } }