ArabDesert/Assets/USharpVideo/Examples/Scripts/ExampleVideoPlayer.cs

192 lines
5.0 KiB
C#

// A U# transcription of the VRC example video player graph
// Original graph script written by TCL
using UdonSharp;
using UnityEngine;
using VRC.SDK3.Components;
using VRC.SDK3.Components.Video;
using VRC.SDK3.Video.Components;
using VRC.SDK3.Video.Components.AVPro;
using VRC.SDK3.Video.Components.Base;
using VRC.SDKBase;
using VRC.Udon;
namespace UdonSharp.Video
{
[AddComponentMenu("Udon Sharp/Video/Examples/Example Video Player")]
public class ExampleVideoPlayer : UdonSharpBehaviour
{
public VRCUrlInputField inputField;
[Header("Video Player References")]
public VRCUnityVideoPlayer unityVideo;
public VRCAVProVideoPlayer avProVideo;
[Header("Sync parameters")]
public float syncFrequency = 5.0f;
public float syncThreshold = 1f;
[UdonSynced]
VRCUrl _syncedURL;
[UdonSynced]
int _videoNumber;
int _loadedVideoNumber;
BaseVRCVideoPlayer _currentPlayer;
[UdonSynced]
bool _ownerPlaying;
[UdonSynced]
float _videoStartNetworkTime;
bool _waitForSync;
float _lastSyncTime;
private void Start()
{
unityVideo.Loop = false;
_currentPlayer = unityVideo;
}
public void HandleURLInput()
{
if (!Networking.IsOwner(gameObject))
return;
_syncedURL = inputField.GetUrl();
_videoNumber++;
_loadedVideoNumber = _videoNumber;
_currentPlayer.Stop();
_currentPlayer.LoadURL(_syncedURL);
_ownerPlaying = false;
_videoStartNetworkTime = float.MaxValue;
Debug.Log("Video URL Changed to " + _syncedURL);
}
// Stop video button
public void StopVideo()
{
if (!Networking.IsOwner(gameObject))
return;
_videoStartNetworkTime = 0f;
_ownerPlaying = false;
_currentPlayer.Stop();
_syncedURL = VRCUrl.Empty;
}
public override void OnVideoReady()
{
if (Networking.IsOwner(gameObject)) // The owner plays the video when it is ready
{
_currentPlayer.Play();
}
else // If the owner is playing the video, Play it and run SyncVideo
{
if (_ownerPlaying)
{
_currentPlayer.Play();
SyncVideo();
}
else
{
_waitForSync = true;
}
}
}
public override void OnVideoStart()
{
if (Networking.IsOwner(gameObject))
{
_videoStartNetworkTime = (float)Networking.GetServerTimeInSeconds();
_ownerPlaying = true;
}
else if (!_ownerPlaying) // Watchers pause and wait for sync from owner
{
_currentPlayer.Pause();
_waitForSync = true;
}
}
public override void OnVideoEnd()
{
// When the video ends on Owner, set time to 0 and playing to false
if (Networking.IsOwner(gameObject))
{
_videoStartNetworkTime = 0f;
_ownerPlaying = false;
}
}
public override void OnVideoError(VideoError videoError)
{
_currentPlayer.Stop();
Debug.LogError("Video failed: " + _syncedURL);
}
public override void OnDeserialization()
{
// Load new video when _videoNumber is changed
if (Networking.IsOwner(gameObject))
return;
if (_videoNumber == _loadedVideoNumber)
return;
_currentPlayer.Stop();
_currentPlayer.LoadURL(_syncedURL);
SyncVideo();
_loadedVideoNumber = _videoNumber;
Debug.Log("Playing synced " + _syncedURL);
}
private void Update()
{
if (Networking.IsOwner(gameObject) || !_waitForSync)
{
SyncVideoIfTime();
return;
}
if (!_ownerPlaying)
return;
_currentPlayer.Play();
_waitForSync = false;
SyncVideo();
}
void SyncVideoIfTime()
{
if (Time.realtimeSinceStartup - _lastSyncTime > syncFrequency)
{
_lastSyncTime = Time.realtimeSinceStartup;
SyncVideo();
}
}
void SyncVideo()
{
float offsetTime = Mathf.Clamp((float)Networking.GetServerTimeInSeconds() - _videoStartNetworkTime, 0f, _currentPlayer.GetDuration());
if (Mathf.Abs(_currentPlayer.GetTime() - offsetTime) > syncThreshold)
{
_currentPlayer.SetTime(offsetTime);
Debug.LogFormat("Syncing Video to {0:N2}", offsetTime);
}
}
}
}