ArabDesert/Assets/USharpVideo/Scripts/VideoPlayerManager.cs

213 lines
7.0 KiB
C#

using UdonSharp;
using UnityEngine;
using VRC.SDKBase;
using VRC.Udon;
using VRC.SDK3.Video.Components;
using VRC.SDK3.Video.Components.AVPro;
using VRC.SDK3.Video.Components.Base;
#if UNITY_EDITOR && !COMPILER_UDONSHARP
using UnityEditor;
using UdonSharpEditor;
#endif
namespace UdonSharp.Video
{
/// <summary>
/// Forwards events sent by Udon video player components to the main video player controller and further abstracts the video players between AVPro and Unity players
/// This exists so that we can put the Udon video player components on a different object from the main video player
/// Prior to using this, people would get confused and change settings on the Udon video player components which would break things
/// </summary>
[UdonBehaviourSyncMode(BehaviourSyncMode.NoVariableSync)]
[AddComponentMenu("Udon Sharp/Video/Internal/Video Player Manager")]
public class VideoPlayerManager : UdonSharpBehaviour
{
public USharpVideoPlayer receiver;
public VRCUnityVideoPlayer unityVideoPlayer;
public VRCAVProVideoPlayer avProPlayer;
public Renderer unityTextureRenderer;
public Renderer avProTextureRenderer;
public AudioSource[] audioSources;
BaseVRCVideoPlayer _currentPlayer;
MaterialPropertyBlock _fetchBlock;
Material avproFetchMaterial;
bool _initialized = false;
public void Start()
{
if (_initialized)
return;
_currentPlayer = unityVideoPlayer;
Material m = unityTextureRenderer.material;
m = avProTextureRenderer.material;
_fetchBlock = new MaterialPropertyBlock();
avproFetchMaterial = avProTextureRenderer.material;
_initialized = true;
}
public override void OnVideoEnd()
{
receiver.OnVideoEnd();
}
public override void OnVideoError(VRC.SDK3.Components.Video.VideoError videoError)
{
receiver._OnVideoErrorCallback(videoError);
}
public override void OnVideoLoop()
{
receiver.OnVideoLoop();
}
public override void OnVideoPause()
{
receiver.OnVideoPause();
}
public override void OnVideoPlay()
{
receiver.OnVideoPlay();
}
public override void OnVideoReady()
{
receiver.OnVideoReady();
}
public override void OnVideoStart()
{
receiver.OnVideoStart();
}
public void Play() => _currentPlayer.Play();
public void Pause() => _currentPlayer.Pause();
public void Stop() => _currentPlayer.Stop();
public float GetTime() => _currentPlayer.GetTime();
public float GetDuration() => _currentPlayer.GetDuration();
public bool IsPlaying() => _currentPlayer.IsPlaying;
public void LoadURL(VRCUrl url) => _currentPlayer.LoadURL(url);
public void SetTime(float time) => _currentPlayer.SetTime(time);
public void SetLooping(bool loop)
{
unityVideoPlayer.Loop = loop;
avProPlayer.Loop = loop;
}
public void SetToStreamPlayerMode()
{
if (_currentPlayer == avProPlayer)
return;
_currentPlayer.Stop();
_currentPlayer = avProPlayer;
}
public void SetToVideoPlayerMode()
{
if (_currentPlayer == unityVideoPlayer)
return;
_currentPlayer.Stop();
_currentPlayer = unityVideoPlayer;
}
public Texture GetVideoTexture()
{
if (_currentPlayer == unityVideoPlayer)
{
unityTextureRenderer.GetPropertyBlock(_fetchBlock);
return _fetchBlock.GetTexture("_MainTex");
}
else
{
return avproFetchMaterial.GetTexture("_MainTex");
}
}
float _currentVolume = 1f;
bool _currentlyMuted = false;
public float GetVolume() => _currentVolume;
public bool IsMuted() => _currentlyMuted;
public void SetVolume(float volume)
{
if (!_currentlyMuted)
{
// https://www.dr-lex.be/info-stuff/volumecontrols.html#ideal thanks TCL for help with finding and understanding this
// Using the 50dB dynamic range constants
float adjustedVolume = Mathf.Clamp01(3.1623e-3f * Mathf.Exp(volume * 5.757f) - 3.1623e-3f);
foreach (AudioSource audioSource in audioSources)
audioSource.volume = adjustedVolume;
}
_currentVolume = volume;
}
public void SetMuted(bool muted)
{
_currentlyMuted = muted;
if (muted)
{
foreach (AudioSource audioSource in audioSources)
audioSource.volume = 0f;
}
else
{
SetVolume(_currentVolume);
}
}
}
#if UNITY_EDITOR && !COMPILER_UDONSHARP
[CustomEditor(typeof(VideoPlayerManager))]
class VideoPlayerManagerInspector : Editor
{
SerializedProperty receiverProperty;
SerializedProperty unityVideoProperty;
SerializedProperty avProVideoProperty;
SerializedProperty unityRendererProperty;
SerializedProperty avProRendererProperty;
SerializedProperty audioSourcesProperty;
private void OnEnable()
{
receiverProperty = serializedObject.FindProperty(nameof(VideoPlayerManager.receiver));
unityVideoProperty = serializedObject.FindProperty(nameof(VideoPlayerManager.unityVideoPlayer));
avProVideoProperty = serializedObject.FindProperty(nameof(VideoPlayerManager.avProPlayer));
unityRendererProperty = serializedObject.FindProperty(nameof(VideoPlayerManager.unityTextureRenderer));
avProRendererProperty = serializedObject.FindProperty(nameof(VideoPlayerManager.avProTextureRenderer));
audioSourcesProperty = serializedObject.FindProperty(nameof(VideoPlayerManager.audioSources));
}
public override void OnInspectorGUI()
{
if (UdonSharpGUI.DrawConvertToUdonBehaviourButton(target)) return;
if (UdonSharpGUI.DrawProgramSource(target, false)) return;
EditorGUILayout.HelpBox("Do not modify the video players on this game object, all modifications must be done on the USharpVideoPlayer. If you change the settings on these, you will break things.", MessageType.Warning);
EditorGUILayout.PropertyField(receiverProperty);
EditorGUILayout.PropertyField(unityVideoProperty);
EditorGUILayout.PropertyField(avProVideoProperty);
EditorGUILayout.PropertyField(unityRendererProperty);
EditorGUILayout.PropertyField(avProRendererProperty);
EditorGUILayout.PropertyField(audioSourcesProperty, true);
serializedObject.ApplyModifiedProperties();
}
}
#endif
}