using UdonSharp; using UnityEngine; using VRC.SDK3.Video.Components.Base; using VRC.SDKBase; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class CaseVideoSyncPlayer : UdonSharpBehaviour { [SerializeField] private BaseVRCVideoPlayer VideoPlayer; [UdonSynced, FieldChangeCallback(nameof(VideoURL))] private VRCUrl _VideoURL; [UdonSynced, FieldChangeCallback(nameof(TimeAndOffset))] private Vector2 _TimeAndOffset; public float SyncFrequency = 15.0f; public override void OnVideoStart() { UpdateTimeAndOffset(); } private void UpdateTimeAndOffset() { if (Networking.IsOwner(gameObject)) { TimeAndOffset = new Vector2(VideoPlayer.GetTime(), (float)Networking.GetServerTimeInSeconds()); RequestSerialization(); if (SyncFrequency > 0.0f) { SendCustomEventDelayedSeconds(nameof(UpdateTimeAndOffset), SyncFrequency); } } else { SendCustomEvent(nameof(Resync)); } } public void Resync() { VideoPlayer.SetTime(TimeAndOffset.x + ((float)Networking.GetServerTimeInSeconds() - TimeAndOffset.y)); } public VRCUrl VideoURL { set { if (_VideoURL != value) { _VideoURL = value; VideoPlayer.PlayURL(_VideoURL); RequestSerialization(); } } get => _VideoURL; } public Vector2 TimeAndOffset { set { _TimeAndOffset = value; if (!Networking.IsOwner(gameObject)) { SendCustomEvent(nameof(Resync)); } } get => _TimeAndOffset; } }