first commit

This commit is contained in:
2026-02-09 20:10:14 +08:00
commit 47a5cff08b
2638 changed files with 322636 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: bdad1096e91a02f44bfdeb7ce4e8d8f7
folderAsset: yes
timeCreated: 1591790245
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
// We could set up the asmdef to reference the package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
//#define AVPRO_PACKAGE_TIMELINE
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using System.Collections.Generic;
//-----------------------------------------------------------------------------
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Playables
{
[System.Serializable]
public class MediaPlayerControlAsset : PlayableAsset
{
public Object binding { get; set; }
//public ExposedReference<MediaPlayer> mediaPlayer;
public MediaReference mediaReference;
[Range(0f, 1f)]
public float audioVolume = 1f;
public double startTime = -1.0;
public bool pauseOnEnd = true;
public override Playable CreatePlayable (PlayableGraph graph, GameObject owner)
{
var playable = ScriptPlayable<MediaPlayerControlBehaviour>.Create(graph);
var behaviour = playable.GetBehaviour();
//behaviour.mediaPlayer = mediaPlayer.Resolve(graph.GetResolver());
behaviour.audioVolume = audioVolume;
behaviour.pauseOnEnd = pauseOnEnd;
behaviour.startTime = startTime;
behaviour.mediaReference = mediaReference;
behaviour.mediaPlayer = (MediaPlayer)binding;
return playable;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 55976ecf17b24e6438718da0257699d3
timeCreated: 1605888478
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,64 @@
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
// We could set up the asmdef to reference the package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
//#define AVPRO_PACKAGE_TIMELINE
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using System.Collections.Generic;
//-----------------------------------------------------------------------------
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Playables
{
public class MediaPlayerControlBehaviour : PlayableBehaviour
{
public MediaPlayer mediaPlayer = null;
public MediaReference mediaReference = null;
public float audioVolume = 1f;
public double startTime = -1.0;
public bool pauseOnEnd = true;
public override void OnBehaviourPlay(Playable playable, FrameData info)
{
if (mediaPlayer != null)
{
if (Application.isPlaying)
{
if (mediaReference != null && mediaReference != mediaPlayer.MediaReference)
{
mediaPlayer.OpenMedia(mediaReference, true);
if (mediaPlayer.Control != null)
{
mediaPlayer.Control.SeekFast(startTime);
}
}
else
{
mediaPlayer.Play();
}
}
}
}
public override void OnBehaviourPause(Playable playable, FrameData info)
{
if (mediaPlayer != null)
{
if (pauseOnEnd)
{
mediaPlayer.Pause();
}
}
}
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: d76b1588cab8f6f4282ca316e24ea365
timeCreated: 1605888480
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
// We could set up the asmdef to reference the package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
//#define AVPRO_PACKAGE_TIMELINE
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using System.Collections.Generic;
//-----------------------------------------------------------------------------
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Playables
{
public class MediaPlayerControlMixerBehaviour : PlayableBehaviour
{
public float audioVolume = 1f;
public string videoPath = null;
public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
MediaPlayer mediaPlayer = playerData as MediaPlayer;
float finalVolume = 0f;
if (!mediaPlayer)
return;
int inputCount = playable.GetInputCount(); //get the number of all clips on this track
for (int i = 0; i < inputCount; i++)
{
float inputWeight = playable.GetInputWeight(i);
ScriptPlayable<MediaPlayerControlBehaviour> inputPlayable = (ScriptPlayable<MediaPlayerControlBehaviour>)playable.GetInput(i);
MediaPlayerControlBehaviour input = inputPlayable.GetBehaviour();
// Use the above variables to process each frame of this playable.
finalVolume += input.audioVolume * inputWeight;
}
if (mediaPlayer != null)
{
mediaPlayer.AudioVolume = finalVolume;
if (mediaPlayer.Control != null)
{
mediaPlayer.Control.SetVolume(finalVolume);
}
}
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: c390934e9ad7c29478a96808ee101c87
timeCreated: 1605888480
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,41 @@
// You need to define AVPRO_PACKAGE_TIMELINE manually to use this script
// We could set up the asmdef to reference the package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
//#define AVPRO_PACKAGE_TIMELINE
#if (UNITY_2018_1_OR_NEWER && AVPRO_PACKAGE_TIMELINE)
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using System.Collections.Generic;
//-----------------------------------------------------------------------------
// Copyright 2020-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Playables
{
[TrackClipType(typeof(MediaPlayerControlAsset))]
[TrackBindingType(typeof(MediaPlayer))]
public class MediaPlayerControlTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
// before building, update the binding field in the clips assets;
var director = go.GetComponent<PlayableDirector>();
var binding = director.GetGenericBinding(this);
foreach (var c in GetClips())
{
var myAsset = c.asset as MediaPlayerControlAsset;
if (myAsset != null)
{
myAsset.binding = binding;
}
}
//return base.CreateTrackMixer(graph, go, inputCount);
return ScriptPlayable<MediaPlayerControlMixerBehaviour>.Create(graph, inputCount);
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 971a512f8f09bfb4aa96fb25d0439255
timeCreated: 1605888480
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
{
"name": "AVProVideo.Extensions.Timeline",
"references": [
"AVProVideo.Runtime"
],
"includePlatforms": [],
"excludePlatforms": []
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 417edd1c17e270f4a9afe6e95eff9b6e
timeCreated: 1591797492
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e82bc7b2e03389f44a7c4c7f38f0db58
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: b801737c3821d6e438ecf2a742d4f04b
folderAsset: yes
timeCreated: 1591797492
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,172 @@
// UnityEngine.UI was moved to a package in 2019.2.0
// Unfortunately no way to test for this across all Unity versions yet
// You can set up the asmdef to reference the new package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
#define AVPRO_PACKAGE_UNITYUI
#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)
using UnityEngine;
using UnityEditor;
using UnityEditor.UI;
//-----------------------------------------------------------------------------
// Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Editor
{
/// <summary>
/// Editor for the DisplayUGUI component
/// </summary>
[CustomEditor(typeof(DisplayUGUI), true)]
[CanEditMultipleObjects]
public class DisplayUGUIEditor : GraphicEditor
{
// Note we have precedence for calling rectangle for just rect, even in the Inspector.
// For example in the Camera component's Viewport Rect.
// Hence sticking with Rect here to be consistent with corresponding property in the API.
private static readonly GUIContent m_guiTextUVRectContent = new GUIContent("UV Rect");
private SerializedProperty _propMediaPlayer;
private SerializedProperty _propUVRect;
private SerializedProperty _propDefaultTexture;
private SerializedProperty _propNoDefaultDisplay;
private SerializedProperty _propDisplayInEditor;
private SerializedProperty _propSetNativeSize;
private SerializedProperty _propScaleMode;
[MenuItem("GameObject/UI/AVPro Video uGUI", false, 0)]
public static void CreateGameObject()
{
GameObject parent = Selection.activeGameObject;
RectTransform parentCanvasRenderer = ( parent != null ) ? parent.GetComponent<RectTransform>() : null;
if( parentCanvasRenderer )
{
GameObject go = new GameObject("AVPro Video");
go.transform.SetParent(parent.transform, false);
go.AddComponent<RectTransform>();
go.AddComponent<CanvasRenderer>();
go.AddComponent<DisplayUGUI>();
Selection.activeGameObject = go;
}
else
{
EditorUtility.DisplayDialog("AVPro Video", "You must make the AVPro Video uGUI object as a child of a Canvas.", "Ok");
}
}
public override bool RequiresConstantRepaint()
{
DisplayUGUI displayComponent = target as DisplayUGUI;
return (displayComponent != null && displayComponent.HasValidTexture());
}
protected override void OnEnable()
{
base.OnEnable();
_propMediaPlayer = this.CheckFindProperty("_mediaPlayer");
_propUVRect = this.CheckFindProperty("_uvRect");
_propSetNativeSize = this.CheckFindProperty("_setNativeSize");
_propScaleMode = this.CheckFindProperty("_scaleMode");
_propNoDefaultDisplay = this.CheckFindProperty("_noDefaultDisplay");
_propDisplayInEditor = this.CheckFindProperty("_displayInEditor");
_propDefaultTexture = this.CheckFindProperty("_defaultTexture");
SetShowNativeSize(true);
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.PropertyField(_propMediaPlayer);
EditorGUILayout.PropertyField(_propDisplayInEditor);
EditorGUILayout.PropertyField(_propNoDefaultDisplay);
if (!_propNoDefaultDisplay.boolValue)
{
EditorGUILayout.PropertyField(_propDefaultTexture);
}
AppearanceControlsGUI();
RaycastControlsGUI();
EditorGUILayout.PropertyField(_propUVRect, m_guiTextUVRectContent);
EditorGUILayout.PropertyField(_propSetNativeSize);
EditorGUILayout.PropertyField(_propScaleMode);
SetShowNativeSize(false);
NativeSizeButtonGUI();
serializedObject.ApplyModifiedProperties();
}
private void SetShowNativeSize(bool instant)
{
base.SetShowNativeSize(_propMediaPlayer.objectReferenceValue != null, instant);
}
/// <summary>
/// Allow the texture to be previewed.
/// </summary>
public override bool HasPreviewGUI()
{
DisplayUGUI rawImage = target as DisplayUGUI;
return rawImage != null;
}
/// <summary>
/// Draw the Image preview.
/// </summary>
public override void OnPreviewGUI(Rect drawArea, GUIStyle background)
{
DisplayUGUI rawImage = target as DisplayUGUI;
Texture tex = rawImage.mainTexture;
if (tex == null)
return;
// Create the texture rectangle that is centered inside rect.
Rect outerRect = drawArea;
Matrix4x4 m = GUI.matrix;
// Flip the image vertically
if (rawImage.HasValidTexture())
{
if (rawImage.Player.TextureProducer.RequiresVerticalFlip())
{
GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0f, outerRect.y + (outerRect.height / 2f)));
}
}
EditorGUI.DrawTextureTransparent(outerRect, tex, ScaleMode.ScaleToFit);//, outer.width / outer.height);
//SpriteDrawUtility.DrawSprite(tex, rect, outer, rawImage.uvRect, rawImage.canvasRenderer.GetColor());
GUI.matrix = m;
}
/// <summary>
/// Info String drawn at the bottom of the Preview
/// </summary>
public override string GetInfoString()
{
DisplayUGUI rawImage = target as DisplayUGUI;
string text = string.Empty;
if (rawImage.HasValidTexture())
{
text += string.Format("Video Size: {0}x{1}\n",
Mathf.RoundToInt(Mathf.Abs(rawImage.mainTexture.width)),
Mathf.RoundToInt(Mathf.Abs(rawImage.mainTexture.height)));
}
// Image size Text
text += string.Format("Display Size: {0}x{1}",
Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.width)),
Mathf.RoundToInt(Mathf.Abs(rawImage.rectTransform.rect.height)));
return text;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0e20933bfdb909544b98bc0de2926c4c
timeCreated: 1438726873
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,12 @@
{
"name": "AVProVideo.Extensions.UnityUI.Editor",
"references": [
"AVProVideo.Runtime",
"AVProVideo.Editor",
"AVProVideo.Extensions.UnityUI"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": []
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 163aa7dfc21664e47a9d1ce803fb3e3f
timeCreated: 1591797492
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d60008e579848de489d8104d999e0afa
folderAsset: yes
timeCreated: 1591797614
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,715 @@
//-----------------------------------------------------------------------------
// Copyright 2015-2025 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
// UnityEngine.UI was moved to a package in 2019.2.0
// Unfortunately no way to test for this across all Unity versions yet
// You can set up the asmdef to reference the new package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
#define AVPRO_PACKAGE_UNITYUI
#if (UNITY_2019_2_OR_NEWER && AVPRO_PACKAGE_UNITYUI) || (!UNITY_2019_2_OR_NEWER)
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS
#define UNITY_PLATFORM_SUPPORTS_YPCBCR
#endif
#define UNITY_PLATFORM_SUPPORTS_LINEAR
#if (!UNITY_STANDALONE_WIN && !UNITY_EDITOR_WIN) && (UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IOS || UNITY_TVOS || UNITY_VISIONOS || UNITY_ANDROID)
#define UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
#endif
#if (UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN))
#define UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO
#endif
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Serialization;
namespace RenderHeads.Media.AVProVideo
{
/// <summary>
/// Displays the video from MediaPlayer component using uGUI
/// </summary>
[HelpURL("http://renderheads.com/products/avpro-video/")]
[AddComponentMenu("AVPro Video/Display uGUI", 200)]
[RequireComponent(typeof(CanvasRenderer))]
//[ExecuteInEditMode]
public class DisplayUGUI : MaskableGraphic
{
[SerializeField] MediaPlayer _mediaPlayer;
public MediaPlayer Player
{
get { return _mediaPlayer; }
set { ChangeMediaPlayer(value); }
}
[Tooltip("Default texture to display when the video texture is preparing")]
[SerializeField] Texture _defaultTexture;
public Texture DefaultTexture
{
get { return _defaultTexture; }
set { if (_defaultTexture != value) { _defaultTexture = value; } }
}
[FormerlySerializedAs("m_UVRect")]
[SerializeField] Rect _uvRect = new Rect(0f, 0f, 1f, 1f);
public Rect UVRect
{
get { return _uvRect; }
set { _uvRect = value; }
}
[SerializeField] bool _setNativeSize = false;
public bool ApplyNativeSize
{
get { return _setNativeSize; }
set { _setNativeSize = value; }
}
[SerializeField] ScaleMode _scaleMode = ScaleMode.ScaleToFit;
public ScaleMode ScaleMode
{
get { return _scaleMode; }
set { _scaleMode = value; }
}
[SerializeField] bool _noDefaultDisplay = true;
public bool NoDefaultDisplay
{
get { return _noDefaultDisplay; }
set { _noDefaultDisplay = value; }
}
[SerializeField] bool _displayInEditor = true;
public bool DisplayInEditor
{
get { return _displayInEditor; }
set { _displayInEditor = value; }
}
private int _lastWidth;
private int _lastHeight;
private Orientation _lastOrientation;
private bool _flipY;
private Texture _lastTexture;
private static Shader _shaderStereoPacking;
private static Shader _shaderAlphaPacking;
private static Shader _shaderAndroidOES;
private static Shader _shaderAndroidOESAlphaPacking;
private bool _isUserMaterial = true;
private Material _material;
private List<UIVertex> _vertices = new List<UIVertex>(4);
private static List<int> QuadIndices = new List<int>(new int[] { 0, 1, 2, 2, 3, 0 });
private Vector4 _drawingDimensions = Vector4.zero;
public Vector4 DrawingDimensions
{
get => _drawingDimensions;
}
protected override void Awake()
{
if (_mediaPlayer != null)
{
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
}
base.Awake();
}
// Callback function to handle events
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
{
switch (et)
{
case MediaPlayerEvent.EventType.FirstFrameReady:
if (_isUserMaterial && null != GetRequiredShader())
{
Debug.LogWarning("[AVProVideo] Custom material is being used but the video requires our internal shader for correct rendering. Consider removing custom shader or modifying it for AVPro Video support.", this);
}
LateUpdate();
break;
case MediaPlayerEvent.EventType.PropertiesChanged:
case MediaPlayerEvent.EventType.ResolutionChanged:
case MediaPlayerEvent.EventType.Closing:
LateUpdate();
break;
}
// TODO: remove this, we're just doing this so we can make sure texture is correct when running in EDIT mode
LateUpdate();
}
private void ChangeMediaPlayer(MediaPlayer player)
{
if (_mediaPlayer != player)
{
if (_mediaPlayer != null)
{
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
}
_mediaPlayer = player;
if (_mediaPlayer != null)
{
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
}
LateUpdate();
}
}
private static Shader EnsureShader(Shader shader, string name)
{
if (shader == null)
{
shader = Shader.Find(name);
if (shader == null)
{
Debug.LogWarning("[AVProVideo] Missing shader " + name);
}
}
return shader;
}
private static Shader EnsureAlphaPackingShader()
{
_shaderAlphaPacking = EnsureShader(_shaderAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo)");
return _shaderAlphaPacking;
}
private static Shader EnsureStereoPackingShader()
{
_shaderStereoPacking = EnsureShader(_shaderStereoPacking, "AVProVideo/Internal/UI/Stereo");
return _shaderStereoPacking;
}
private Shader EnsureAndroidOESShader()
{
_shaderAndroidOES = EnsureShader(_shaderAndroidOES, "AVProVideo/Internal/UI/Stereo - AndroidOES");
return _shaderAndroidOES;
}
private static Shader EnsureAndroidOESAlphaPackingShader()
{
_shaderAndroidOESAlphaPacking = EnsureShader(_shaderAndroidOESAlphaPacking, "AVProVideo/Internal/UI/Transparent Packed (stereo) - AndroidOES");
return _shaderAndroidOESAlphaPacking;
}
protected override void Start()
{
_isUserMaterial = (this.m_Material != null);
if (_isUserMaterial)
{
_material = new Material(this.material);
this.material = _material;
}
base.Start();
}
protected override void OnDestroy()
{
// Destroy existing material
if (_material != null)
{
this.material = null;
#if UNITY_EDITOR
Material.DestroyImmediate(_material);
#else
Material.Destroy(_material);
#endif
_material = null;
}
ChangeMediaPlayer(null);
base.OnDestroy();
}
private Shader GetRequiredShader()
{
Shader result = null;
if (result == null && _mediaPlayer.TextureProducer != null)
{
switch (_mediaPlayer.TextureProducer.GetTextureStereoPacking())
{
case StereoPacking.Monoscopic:
break;
case StereoPacking.LeftRight:
case StereoPacking.TopBottom:
case StereoPacking.MultiviewLeftPrimary:
case StereoPacking.MultiviewRightPrimary:
result = EnsureStereoPackingShader();
break;
}
if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)
{
result = EnsureAlphaPackingShader();
}
switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())
{
case AlphaPacking.None:
break;
case AlphaPacking.LeftRight:
case AlphaPacking.TopBottom:
result = EnsureAlphaPackingShader();
break;
}
}
#if UNITY_PLATFORM_SUPPORTS_LINEAR
if (result == null && _mediaPlayer.Info != null)
{
if (QualitySettings.activeColorSpace == ColorSpace.Linear && !_mediaPlayer.Info.PlayerSupportsLinearColorSpace())
{
result = EnsureAlphaPackingShader();
}
}
#endif
if (result == null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTextureCount() == 2)
{
result = EnsureAlphaPackingShader();
}
// if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath() && (_defaultTexture == null || _lastTexture != _defaultTexture ))
if (_mediaPlayer.TextureProducer != null && _mediaPlayer.IsUsingAndroidOESPath())
{
// This shader handles stereo too
result = EnsureAndroidOESShader();
if (_mediaPlayer.TextureProducer.GetTextureTransparency() == TransparencyMode.Transparent)
{
result = EnsureAndroidOESAlphaPackingShader();
}
switch (_mediaPlayer.TextureProducer.GetTextureAlphaPacking())
{
case AlphaPacking.None:
break;
case AlphaPacking.LeftRight:
case AlphaPacking.TopBottom:
result = EnsureAndroidOESAlphaPackingShader();
break;
}
}
return result;
}
/// <summary>
/// Returns the texture used to draw this Graphic.
/// </summary>
public override Texture mainTexture
{
get
{
Texture result = Texture2D.whiteTexture;
if (HasValidTexture())
{
Texture resamplerTex = _mediaPlayer.FrameResampler == null || _mediaPlayer.FrameResampler.OutputTexture == null ? null : _mediaPlayer.FrameResampler.OutputTexture[0];
result = _mediaPlayer.UseResampler ? resamplerTex : _mediaPlayer.TextureProducer.GetTexture();
}
else
{
if (_noDefaultDisplay)
{
result = null;
}
else if (_defaultTexture != null)
{
result = _defaultTexture;
}
#if UNITY_EDITOR
if (result == null && _displayInEditor)
{
result = Resources.Load<Texture2D>("AVProVideoIcon");
}
#endif
}
return result;
}
}
public bool HasValidTexture()
{
return (Application.isPlaying && _mediaPlayer != null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTexture() != null);
}
private void UpdateInternalMaterial()
{
if (_mediaPlayer != null)
{
// Get required shader
Shader currentShader = null;
if (_material != null)
{
currentShader = _material.shader;
}
Shader nextShader = GetRequiredShader();
// If the shader requirement has changed
if (currentShader != nextShader)
{
// Destroy existing material
if (_material != null)
{
this.material = null;
#if UNITY_EDITOR
Material.DestroyImmediate(_material);
#else
Material.Destroy(_material);
#endif
_material = null;
}
// Create new material
if (nextShader != null)
{
_material = new Material(nextShader);
}
}
this.material = _material;
}
}
// We do a LateUpdate() to allow for any changes in the texture that may have happened in Update()
void LateUpdate()
{
if (_setNativeSize)
{
SetNativeSize();
}
if (_lastTexture != mainTexture)
{
_lastTexture = mainTexture;
SetVerticesDirty();
SetMaterialDirty();
}
if (HasValidTexture())
{
if (mainTexture != null)
{
Orientation orientation = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());
if (mainTexture.width != _lastWidth || mainTexture.height != _lastHeight || orientation != _lastOrientation)
{
_lastWidth = mainTexture.width;
_lastHeight = mainTexture.height;
_lastOrientation = orientation;
SetVerticesDirty();
SetMaterialDirty();
}
}
}
if (Application.isPlaying)
{
if (!_isUserMaterial)
{
UpdateInternalMaterial();
}
}
if (material != null && _mediaPlayer != null)
{
// TODO: only run when dirty
VideoRender.SetupMaterialForMedia(materialForRendering, _mediaPlayer);
}
}
/// <summary>
/// Texture to be used.
/// </summary>
public MediaPlayer CurrentMediaPlayer
{
get
{
return _mediaPlayer;
}
set
{
if (_mediaPlayer != value)
{
_mediaPlayer = value;
//SetVerticesDirty();
SetMaterialDirty();
}
}
}
/// <summary>
/// UV rectangle used by the texture.
/// </summary>
public Rect uvRect
{
get
{
return _uvRect;
}
set
{
if (_uvRect == value)
{
return;
}
_uvRect = value;
SetVerticesDirty();
}
}
/// <summary>
/// Adjust the scale of the Graphic to make it pixel-perfect.
/// </summary>
[ContextMenu("Set Native Size")]
public override void SetNativeSize()
{
Texture tex = mainTexture;
if (tex != null)
{
int w = Mathf.RoundToInt(tex.width * uvRect.width);
int h = Mathf.RoundToInt(tex.height * uvRect.height);
if (_mediaPlayer != null)
{
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)
if (_mediaPlayer.Info != null)
{
Orientation ori = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());
if (ori == Orientation.Portrait || ori == Orientation.PortraitFlipped)
{
w = Mathf.RoundToInt(tex.height * uvRect.width);
h = Mathf.RoundToInt(tex.width * uvRect.height);
}
}
#endif
if (_mediaPlayer.TextureProducer != null)
{
if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)
{
w /= 2;
}
else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)
{
h /= 2;
}
}
}
rectTransform.anchorMax = rectTransform.anchorMin;
rectTransform.sizeDelta = new Vector2(w, h);
}
}
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
_OnFillVBO(_vertices);
vh.AddUIVertexStream(_vertices, QuadIndices );
}
private void _OnFillVBO(List<UIVertex> vbo)
{
_flipY = false;
if (HasValidTexture())
{
_flipY = _mediaPlayer.TextureProducer.RequiresVerticalFlip();
}
Rect uvRect = _uvRect;
Vector4 v = GetDrawingDimensions(_scaleMode, ref uvRect);
_drawingDimensions = v;
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
Matrix4x4 m = Matrix4x4.identity;
if (HasValidTexture())
{
m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));
}
#endif
vbo.Clear();
var vert = UIVertex.simpleVert;
vert.color = color;
vert.position = new Vector2(v.x, v.y);
vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMin);
if (_flipY)
{
vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMin);
}
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
#endif
vbo.Add(vert);
vert.position = new Vector2(v.x, v.w);
vert.uv0 = new Vector2(uvRect.xMin, uvRect.yMax);
if (_flipY)
{
vert.uv0 = new Vector2(uvRect.xMin, 1.0f - uvRect.yMax);
}
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
#endif
vbo.Add(vert);
vert.position = new Vector2(v.z, v.w);
vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMax);
if (_flipY)
{
vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMax);
}
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
#endif
vbo.Add(vert);
vert.position = new Vector2(v.z, v.y);
vert.uv0 = new Vector2(uvRect.xMax, uvRect.yMin);
if (_flipY)
{
vert.uv0 = new Vector2(uvRect.xMax, 1.0f - uvRect.yMin);
}
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM
vert.uv0 = m.MultiplyPoint3x4(vert.uv0);
#endif
vbo.Add(vert);
}
private Vector4 GetDrawingDimensions(ScaleMode scaleMode, ref Rect uvRect)
{
Vector4 returnSize = Vector4.zero;
if (mainTexture != null)
{
var padding = Vector4.zero;
var textureSize = new Vector2(mainTexture.width, mainTexture.height);
{
// Adjust textureSize based on orientation
#if UNITY_PLATFORM_SUPPORTS_VIDEOTRANSFORM && !(!UNITY_EDITOR && UNITY_ANDROID)
if (HasValidTexture())
{
Matrix4x4 m = Helper.GetMatrixForOrientation(Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform()));
textureSize = m.MultiplyVector(textureSize);
textureSize.x = Mathf.Abs(textureSize.x);
textureSize.y = Mathf.Abs(textureSize.y);
}
#endif
#if UNITY_PLATFORM_SUPPORTS_VIDEOASPECTRATIO
if (HasValidTexture())
{
float par = _mediaPlayer.TextureProducer.GetTexturePixelAspectRatio();
if (par > 0f)
{
if (par > 1f)
{
textureSize.x *= par;
}
else
{
textureSize.y /= par;
}
}
}
#endif
// Adjust textureSize based on alpha/stereo packing
if (_mediaPlayer != null && _mediaPlayer.TextureProducer != null)
{
if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.LeftRight ||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.LeftRight)
{
textureSize.x /= 2;
}
else if (_mediaPlayer.TextureProducer.GetTextureAlphaPacking() == AlphaPacking.TopBottom ||
_mediaPlayer.TextureProducer.GetTextureStereoPacking() == StereoPacking.TopBottom)
{
textureSize.y /= 2;
}
}
}
Rect r = GetPixelAdjustedRect();
// Fit the above textureSize into rectangle r
int spriteW = Mathf.RoundToInt( textureSize.x );
int spriteH = Mathf.RoundToInt( textureSize.y );
var size = new Vector4( padding.x / spriteW,
padding.y / spriteH,
(spriteW - padding.z) / spriteW,
(spriteH - padding.w) / spriteH );
{
if (textureSize.sqrMagnitude > 0.0f)
{
if (scaleMode == ScaleMode.ScaleToFit)
{
float spriteRatio = textureSize.x / textureSize.y;
float rectRatio = r.width / r.height;
if (spriteRatio > rectRatio)
{
float oldHeight = r.height;
r.height = r.width * (1.0f / spriteRatio);
r.y += (oldHeight - r.height) * rectTransform.pivot.y;
}
else
{
float oldWidth = r.width;
r.width = r.height * spriteRatio;
r.x += (oldWidth - r.width) * rectTransform.pivot.x;
}
}
else if (scaleMode == ScaleMode.ScaleAndCrop)
{
float aspectRatio = textureSize.x / textureSize.y;
float screenRatio = r.width / r.height;
if (screenRatio > aspectRatio)
{
float adjust = aspectRatio / screenRatio;
uvRect = new Rect(uvRect.xMin, (uvRect.yMin * adjust) + (1f - adjust) * 0.5f, uvRect.width, adjust * uvRect.height);
}
else
{
float adjust = screenRatio / aspectRatio;
uvRect = new Rect(uvRect.xMin * adjust + (0.5f - adjust * 0.5f), uvRect.yMin, adjust * uvRect.width, uvRect.height);
}
}
}
}
returnSize = new Vector4( r.x + r.width * size.x,
r.y + r.height * size.y,
r.x + r.width * size.z,
r.y + r.height * size.w );
}
return returnSize;
}
}
}
#endif

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 0f17cdc186456a4469a139a104d2ca72
timeCreated: 1544813301
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,130 @@
using UnityEngine;
using UnityEngine.UI;
//-----------------------------------------------------------------------------
// Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo
{
/// <summary>
/// Update a standard uGUI Text element with subtitle text as it plays from the MediaPlayer
/// </summary>
[AddComponentMenu("AVPro Video/Subtitles uGUI", 201)]
[HelpURL("http://renderheads.com/products/avpro-video/")]
public class SubtitlesUGUI : MonoBehaviour
{
[SerializeField] MediaPlayer _mediaPlayer = null;
[SerializeField] Text _text = null;
[SerializeField] Image _backgroundImage = null;
[SerializeField] int _backgroundHorizontalPadding = 32;
[SerializeField] int _backgroundVerticalPadding = 16;
[SerializeField, Range(-1, 1024)] int _maxCharacters = 256;
public MediaPlayer Player
{
set { ChangeMediaPlayer(value); }
get { return _mediaPlayer; }
}
public Text Text
{
set { _text = value; }
get { return _text; }
}
void Start()
{
ChangeMediaPlayer(_mediaPlayer);
}
void OnDestroy()
{
ChangeMediaPlayer(null);
}
void Update()
{
// TODO: Currently we need to call this each frame, as when it is called right after SetText()
// the ContentSizeFitter hasn't run yet, so effectively the box is a frame behind.
UpdateBackgroundRect();
}
public void ChangeMediaPlayer(MediaPlayer newPlayer)
{
// When changing the media player, handle event subscriptions
if (_mediaPlayer != null)
{
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
_mediaPlayer = null;
}
SetText(string.Empty);
if (newPlayer != null)
{
newPlayer.Events.AddListener(OnMediaPlayerEvent);
_mediaPlayer = newPlayer;
}
}
private void SetText(string text)
{
_text.text = text;
UpdateBackgroundRect();
}
private string PrepareText(string text)
{
// Crop text that is too long
if (_maxCharacters >= 0 && text.Length > _maxCharacters)
{
text = text.Substring(0, _maxCharacters);
}
// Change RichText for Unity uGUI Text
text = text.Replace("<font color=", "<color=");
text = text.Replace("</font>", "</color>");
text = text.Replace("<u>", string.Empty);
text = text.Replace("</u>", string.Empty);
return text;
}
private void UpdateBackgroundRect()
{
if (_backgroundImage)
{
if (string.IsNullOrEmpty(_text.text))
{
_backgroundImage.enabled = false;
}
else
{
_backgroundImage.enabled = true;
_backgroundImage.rectTransform.sizeDelta = _text.rectTransform.sizeDelta;
_backgroundImage.rectTransform.anchoredPosition = _text.rectTransform.anchoredPosition;
_backgroundImage.rectTransform.offsetMin -= new Vector2(_backgroundHorizontalPadding, _backgroundVerticalPadding);
_backgroundImage.rectTransform.offsetMax += new Vector2(_backgroundHorizontalPadding, _backgroundVerticalPadding);
}
}
}
// Callback function to handle events
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
{
switch (et)
{
case MediaPlayerEvent.EventType.Closing:
{
SetText(string.Empty);
break;
}
case MediaPlayerEvent.EventType.SubtitleChange:
{
SetText(PrepareText(_mediaPlayer.Subtitles.GetSubtitleText()));
break;
}
}
}
}
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2d4bbe43657314a49a5f730e66dafebd
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
userData:

View File

@@ -0,0 +1,8 @@
{
"name": "AVProVideo.Extensions.UnityUI",
"references": [
"AVProVideo.Runtime"
],
"includePlatforms": [],
"excludePlatforms": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 3bd657f68851a7f448c82186c6797ee0
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fd124b806b72636469008bf42969d370
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2aad57afcbe67ad4baddc85a2c4b8136
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,778 @@
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.AnimatedValues;
using UnityEngine;
using static RenderHeads.Media.AVProVideo.MediaPlayer;
//-----------------------------------------------------------------------------
// Copyright 2015-2024 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Editor
{
[CanEditMultipleObjects]
[CustomEditor(typeof(VideoPlayer_AVPro))]
public partial class VideoPlayer_AVPro_Editor : UnityEditor.Editor
{
#region Variables
SerializedProperty m_source;
SerializedProperty m_clip;
SerializedProperty m_url;
SerializedProperty m_playOnAwake;
SerializedProperty m_autoOpen;
SerializedProperty m_loop;
SerializedProperty m_skipOnDrop;
SerializedProperty m_playbackSpeed;
SerializedProperty m_renderMode;
SerializedProperty m_targetMaterialRenderer;
SerializedProperty m_targetMaterialName;
SerializedProperty m_targetMaterial;
SerializedProperty m_color;
SerializedProperty m_aspectRatio;
SerializedProperty m_aspectRatioRenderTexture;
SerializedProperty m_fullscreen;
SerializedProperty m_audioOutputMode;
SerializedProperty m_controlledTracks;
SerializedProperty m_volume;
SerializedProperty m_muted;
SerializedProperty m_audioSource;
SerializedProperty m_canvas;
SerializedProperty m_targetTexture;
SerializedProperty m_uGUIComponent;
SerializedProperty m_UVRect;
SerializedProperty m_alpha;
public readonly GUIContent sourceContent = EditorGUIUtility.TrTextContent("Source", "Type of source the media will be read from\n Reference - AVPro's VideoClip\n URL - Either path or URL");
public readonly GUIContent clipContent = EditorGUIUtility.TrTextContent("Media Reference", "Can be created through the context menu. \n AVPro's VideoClip");
public readonly GUIContent urlContent = EditorGUIUtility.TrTextContent("URL", "URLs\n Either URL or filepath");
public readonly GUIContent playOnAwakeContent = EditorGUIUtility.TrTextContent("Play On Awake", "Start playback as soon as the game is started.");
public readonly GUIContent autoOpenContent = EditorGUIUtility.TrTextContent("Auto Open", "Automatically opens the selected media as soon as the game is started");
public readonly GUIContent loopContent = EditorGUIUtility.TrTextContent("Loop", "Start playback at the beginning when end is reached.");
public readonly GUIContent playbackSpeedContent = EditorGUIUtility.TrTextContent("Playback Speed", "Increase or decrease the playback speed. 1.0 is the normal speed.");
public readonly GUIContent renderModeContent = EditorGUIUtility.TrTextContent("Render Mode", "Type of object on which the played images will be drawn.");
public readonly GUIContent rendererContent = EditorGUIUtility.TrTextContent("Renderer", "Renderer that the images will be displayed on");
public readonly GUIContent texturePropertyContent = EditorGUIUtility.TrTextContent("Material Property", "Texture Property of the current material that will recive the images");
public readonly GUIContent materialContent = EditorGUIUtility.TrTextContent("Material", "Material that the images will be writted to");
public readonly GUIContent colorContent = EditorGUIUtility.TrTextContent("Color", "Default color");
public readonly GUIContent aspectRatioContent = EditorGUIUtility.TrTextContent("Aspect Ratio", "How the video content will be fit into the target area");
public readonly GUIContent fullscreenContent = EditorGUIUtility.TrTextContent("Fullscreen", "Force the video to take up the entire screen");
public readonly GUIContent audioOutputModeContent = EditorGUIUtility.TrTextContent("Audio Output Mode", "where the audio of the video will be output");
public readonly GUIContent volumeContent = EditorGUIUtility.TrTextContent("Volume", "Volume of the output audio");
public readonly GUIContent mutedContent = EditorGUIUtility.TrTextContent("Mute", "Mute the audio");
public readonly GUIContent audioSourceContent = EditorGUIUtility.TrTextContent("Audio Source", "AudioSource component that will recive this videos audio samples");
public readonly GUIContent targetTextureContent = EditorGUIUtility.TrTextContent("Render Texture", "Render texture to draw the current frame to");
public readonly GUIContent browseContent = EditorGUIUtility.TrTextContent("Browse...", "Click to set a file:// URL. http:// URLs have to be written or copy-pasted manually.");
public readonly GUIContent uvRectContent = EditorGUIUtility.TrTextContent("UV", "Sets the UV rect of the image allowing, scaling and positioning of the image");
public readonly GUIContent displayUGUIContent = EditorGUIUtility.TrTextContent("uGUI Component", "The UGUI componenet that will handle the rendering");
public readonly GUIContent nativeSizeContent = EditorGUIUtility.TrTextContent("Set Native Size", "Sets the image to be its native size");
public readonly GUIContent alphaContent = EditorGUIUtility.TrTextContent("Alpha", "Set the alpha of the video stream");
//public readonly GUIContent = EditorGUIUtility.TrTextContent("", "");
public readonly string uGUIUsageInformation = "Ensure you have placed a Display uGUI component on a GameObject containing a Canvas Renderer, and linked it with this";
// local video path selection
public readonly string selectMovieFile = "Select movie file.";
public readonly string selectMovieFileRecentPath = "VideoPlayer_AVProSelectMovieFileRecentPath";
public readonly string[] selectMovieFileFilter = {
L10n.Tr("Movie files"), "asf,avi,dv,m4v,mp4,mov,mpg,mpeg,m4v,ogv,vp8,webm,wmv",
L10n.Tr("All files"), "*"
};
#if UNITY_STANDALONE_WIN
// facebook 360 audio options
private readonly string _optionAudio360ChannelModeName = ".audio360ChannelMode";
#endif
private readonly GUIContent _optionAudio360ChannelModeContent = new GUIContent("Channel Mode", "Specifies what channel mode Facebook Audio 360 needs to be initialised with");
private readonly GUIContent[] _audio360ChannelMapGuiNames =
{
new GUIContent("(TBE_8_2) 8 channels of hybrid TBE ambisonics and 2 channels of head-locked stereo audio"),
new GUIContent("(TBE_8) 8 channels of hybrid TBE ambisonics. NO head-locked stereo audio"),
new GUIContent("(TBE_6_2) 6 channels of hybrid TBE ambisonics and 2 channels of head-locked stereo audio"),
new GUIContent("(TBE_6) 6 channels of hybrid TBE ambisonics. NO head-locked stereo audio"),
new GUIContent("(TBE_4_2) 4 channels of hybrid TBE ambisonics and 2 channels of head-locked stereo audio"),
new GUIContent("(TBE_4) 4 channels of hybrid TBE ambisonics. NO head-locked stereo audio"),
new GUIContent("(TBE_8_PAIR0) Channels 1 and 2 of TBE hybrid ambisonics"),
new GUIContent("(TBE_8_PAIR1) Channels 3 and 4 of TBE hybrid ambisonics"),
new GUIContent("(TBE_8_PAIR2) Channels 5 and 6 of TBE hybrid ambisonics"),
new GUIContent("(TBE_8_PAIR3) Channels 7 and 8 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL0) Channels 1 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL1) Channels 2 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL2) Channels 3 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL3) Channels 4 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL4) Channels 5 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL5) Channels 6 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL6) Channels 7 of TBE hybrid ambisonics"),
new GUIContent("(TBE_CHANNEL7) Channels 8 of TBE hybrid ambisonics"),
new GUIContent("(HEADLOCKED_STEREO) Head-locked stereo audio"),
new GUIContent("(HEADLOCKED_CHANNEL0) Channels 1 or left of head-locked stereo audio"),
new GUIContent("(HEADLOCKED_CHANNEL1) Channels 2 or right of head-locked stereo audio"),
new GUIContent("(AMBIX_4) 4 channels of first order ambiX"),
new GUIContent("(AMBIX_4_2) 4 channels of first order ambiX with 2 channels of head-locked audio"),
new GUIContent("(AMBIX_9) 9 channels of second order ambiX"),
new GUIContent("(AMBIX_9_2) 9 channels of second order ambiX with 2 channels of head-locked audio"),
new GUIContent("(AMBIX_16) 16 channels of third order ambiX"),
new GUIContent("(AMBIX_16_2) 16 channels of third order ambiX with 2 channels of head-locked audio"),
new GUIContent("(MONO) Mono audio"),
new GUIContent("(STEREO) Stereo audio"),
};
// material options
private GUIContent[] _materialTextureProperties = new GUIContent[0];
private readonly GUIContent _guiTextTextureProperty = new GUIContent("Texture Property", "Texture Property of the current material that will recive the images");
// animations
readonly AnimBool m_SourceReference = new AnimBool();
readonly AnimBool m_SourceUrl = new AnimBool();
readonly AnimBool m_RenderMesh = new AnimBool();
readonly AnimBool m_RenderMaterial = new AnimBool();
readonly AnimBool m_RenderuGUI = new AnimBool();
readonly AnimBool m_RenderIMGUI = new AnimBool();
readonly AnimBool m_RenderFarPlane = new AnimBool();
readonly AnimBool m_RenderTexture = new AnimBool();
readonly AnimBool m_AudioOutSystem = new AnimBool();
readonly AnimBool m_AudioOutUnity = new AnimBool();
readonly AnimBool m_AudioOutFacebook = new AnimBool();
readonly AnimBool m_AudioOutNone = new AnimBool();
#endregion Variables
#region Enable/Disable
void OnEnable()
{
m_SourceReference.valueChanged.AddListener(Repaint);
m_SourceUrl.valueChanged.AddListener(Repaint);
m_RenderMesh.valueChanged.AddListener(Repaint);
m_RenderMaterial.valueChanged.AddListener(Repaint);
m_RenderuGUI.valueChanged.AddListener(Repaint);
m_RenderIMGUI.valueChanged.AddListener(Repaint);
m_RenderFarPlane.valueChanged.AddListener(Repaint);
m_RenderTexture.valueChanged.AddListener(Repaint);
m_AudioOutSystem.valueChanged.AddListener(Repaint);
m_AudioOutUnity.valueChanged.AddListener(Repaint);
m_AudioOutFacebook.valueChanged.AddListener(Repaint);
m_AudioOutNone.valueChanged.AddListener(Repaint);
m_source = serializedObject.FindProperty("Source");
m_clip = serializedObject.FindProperty("Clip");
m_url = serializedObject.FindProperty("Url");
m_playOnAwake = serializedObject.FindProperty("PlayOnAwake");
m_autoOpen = serializedObject.FindProperty("AutoOpening");
m_loop = serializedObject.FindProperty("IsLooping");
m_skipOnDrop = serializedObject.FindProperty("SkipOnDrop");
m_playbackSpeed = serializedObject.FindProperty("PlaybackSpeed");
m_renderMode = serializedObject.FindProperty("RenderMode");
m_targetMaterialRenderer = serializedObject.FindProperty("TargetMaterialRenderer");
m_targetMaterialName = serializedObject.FindProperty("TargetMateralProperty");
m_targetMaterial = serializedObject.FindProperty("TargetMaterial");
m_color = serializedObject.FindProperty("Colour");
m_aspectRatio = serializedObject.FindProperty("AspectRatio");
m_aspectRatioRenderTexture = serializedObject.FindProperty("AspectRatioRenderTexture");
m_fullscreen = serializedObject.FindProperty("Fullscreen");
m_audioOutputMode = serializedObject.FindProperty("AudioOutputMode");
m_controlledTracks = serializedObject.FindProperty("ControlledAudioTrackCount");
m_volume = serializedObject.FindProperty("Volume");
m_muted = serializedObject.FindProperty("Muted");
m_audioSource = serializedObject.FindProperty("AudioSourceE");
m_canvas = serializedObject.FindProperty("canvasObj");
m_targetTexture = serializedObject.FindProperty("TargetTexture");
m_uGUIComponent = serializedObject.FindProperty("displayUGUI");
m_UVRect = serializedObject.FindProperty("UVRect");
m_alpha = serializedObject.FindProperty("TargetCameraAlpha");
m_SourceReference.value = m_source.intValue == 0;
m_SourceUrl.value = m_source.intValue == 1;
m_RenderMesh.value = m_renderMode.intValue == 0;
m_RenderMaterial.value = m_renderMode.intValue == 1;
m_RenderuGUI.value = m_renderMode.intValue == 2;
m_RenderIMGUI.value = m_renderMode.intValue == 3;
m_RenderFarPlane.value = m_renderMode.intValue == 4;
m_RenderTexture.value = m_renderMode.intValue == 5;
m_AudioOutSystem.value = m_audioOutputMode.intValue == 0;
m_AudioOutUnity.value = m_audioOutputMode.intValue == 1;
m_AudioOutFacebook.value = m_audioOutputMode.intValue == 2;
m_AudioOutNone.value = m_audioOutputMode.intValue == 3;
}
private void OnDisable()
{
m_SourceReference.valueChanged.RemoveListener(Repaint);
m_SourceUrl.valueChanged.RemoveListener(Repaint);
m_RenderMesh.valueChanged.RemoveListener(Repaint);
m_RenderMaterial.valueChanged.RemoveListener(Repaint);
m_RenderuGUI.valueChanged.RemoveListener(Repaint);
m_RenderIMGUI.valueChanged.RemoveListener(Repaint);
m_RenderFarPlane.valueChanged.RemoveListener(Repaint);
m_RenderTexture.valueChanged.RemoveListener(Repaint);
m_AudioOutSystem.valueChanged.RemoveListener(Repaint);
m_AudioOutUnity.valueChanged.RemoveListener(Repaint);
m_AudioOutFacebook.valueChanged.RemoveListener(Repaint);
m_AudioOutNone.valueChanged.RemoveListener(Repaint);
}
#endregion Enable/Disable
public override void OnInspectorGUI()
{
VideoPlayer_AVPro player = (VideoPlayer_AVPro)target;
serializedObject.Update();
// Media Source
HandleSourceField(player);
// Play on awake
EditorGUILayout.PropertyField(m_playOnAwake, playOnAwakeContent);
if (m_playOnAwake.serializedObject.ApplyModifiedProperties())
player.playOnAwake = m_playOnAwake.boolValue;
// auto open
EditorGUILayout.PropertyField(m_autoOpen, autoOpenContent);
if (m_autoOpen.serializedObject.ApplyModifiedProperties())
player.AutoOpen = m_autoOpen.boolValue;
// Loop
EditorGUILayout.PropertyField(m_loop, loopContent);
if (m_loop.serializedObject.ApplyModifiedProperties())
player.isLooping = m_loop.boolValue;
// Playback Speed
EditorGUILayout.Slider(m_playbackSpeed, -4f, 4f, playbackSpeedContent);
if (m_playbackSpeed.serializedObject.ApplyModifiedProperties())
player.playbackSpeed = m_playbackSpeed.floatValue;
EditorGUILayout.Space(10);
// Render Mode
HandleRenderModeField(player);
// Audio Output Mode
HandleAudioOutputModeField(player);
serializedObject.ApplyModifiedProperties();
}
#region GUI Handlers
#region Source Field
/// <summary>
/// Draws the source field, giving functionality to both the Path/URL, <see cref="MediaReference"/> fields
/// </summary>
/// <param name="player"><see cref="VideoPlayer_AVPro"/> to use</param>
public void HandleSourceField(VideoPlayer_AVPro player)
{
// to be used within the fadegroups, resulting in only the selected group being shown.
m_SourceReference.target = m_source.intValue == 0;
m_SourceUrl.target = m_source.intValue == 1;
// Source Type
EditorGUILayout.PropertyField(m_source, sourceContent);
// the below code will be used whenever we need to update the value on the target object
// to reduce performnace cost, and infinite calls this is only updated when the UI for
// that value is changed
if (m_source.serializedObject.ApplyModifiedProperties())
player.sourceAVPro = (MediaSource)m_source.enumValueIndex;
// Reference (MediaReference)
EditorGUI.indentLevel++;
if (EditorGUILayout.BeginFadeGroup(m_SourceReference.faded))
{
EditorGUILayout.PropertyField(m_clip, clipContent);
if (m_clip.serializedObject.ApplyModifiedProperties())
{
player.clip = (MediaReference)m_clip.objectReferenceValue;
}
}
EditorGUILayout.EndFadeGroup();
// URL
if (EditorGUILayout.BeginFadeGroup(m_SourceUrl.faded))
{
// URL (web)
EditorGUILayout.PropertyField(m_url, urlContent);
// BROWSE (local)
Rect browseRect = EditorGUILayout.GetControlRect(true, EditorGUIUtility.singleLineHeight);
browseRect.xMin += EditorGUIUtility.labelWidth;
browseRect.xMax = browseRect.xMin + GUI.skin.label.CalcSize(browseContent).x + 10;
if (EditorGUI.DropdownButton(
browseRect, browseContent, FocusType.Passive, GUI.skin.button))
{
string path = EditorUtility.OpenFilePanelWithFilters(
selectMovieFile,
EditorPrefs.GetString(selectMovieFileRecentPath),
selectMovieFileFilter);
if (!string.IsNullOrEmpty(path))
{
m_url.stringValue = "file://" + path;
EditorPrefs.SetString(selectMovieFileRecentPath, path);
}
if (m_url.serializedObject.ApplyModifiedProperties())
player.url = new MediaPath(m_url.stringValue, MediaPathType.AbsolutePathOrURL);
EditorGUIUtility.ExitGUI();
}
if (m_url.serializedObject.ApplyModifiedProperties())
player.url = new MediaPath(m_url.stringValue, MediaPathType.AbsolutePathOrURL);
}
EditorGUILayout.EndFadeGroup();
EditorGUI.indentLevel--;
}
#endregion
#region Render Mode Field
/// <summary>
/// Handles Drawing all the differernt rendering options to the inspector,
/// with only the current selected being shown.
/// </summary>
/// <param name="player"><see cref="VideoPlayer_AVPro "/> to use</param>
public void HandleRenderModeField(VideoPlayer_AVPro player)
{
// current rendering mode
EditorGUILayout.PropertyField(m_renderMode, renderModeContent);
if (m_renderMode.serializedObject.ApplyModifiedProperties())
player.rendererMode = (DisplayType)m_renderMode.enumValueIndex;
// setup fade groups to only show the active render mode
m_RenderMesh.target = m_renderMode.intValue == 0;
m_RenderMaterial.target = m_renderMode.intValue == 1;
m_RenderuGUI.target = m_renderMode.intValue == 2;
m_RenderIMGUI.target = m_renderMode.intValue == 3;
m_RenderFarPlane.target = m_renderMode.intValue == 4;
m_RenderTexture.target = m_renderMode.intValue == 5;
// Note:
// - the fade groups dont work here as the AddComponent breaks them (they dont fade), their does not seem to
// be any way of fixing it
EditorGUI.indentLevel++;
// render mesh
if (EditorGUILayout.BeginFadeGroup(m_RenderMesh.faded))
{
if (player.applyToMesh)
{
// target remderer
EditorGUILayout.PropertyField(m_targetMaterialRenderer, rendererContent);
if (m_targetMaterialRenderer.serializedObject.ApplyModifiedProperties())
{
Debug.Log("Sertting Target Renderer to: " + (Renderer)m_targetMaterialRenderer.objectReferenceValue);
player.applyToMesh.MeshRenderer = (Renderer)m_targetMaterialRenderer.objectReferenceValue;
player.targetMaterialRenderer = (Renderer)m_targetMaterialRenderer.objectReferenceValue;
}
// material properties
DrawMaterialPropertieDropdown(m_targetMaterialRenderer, m_targetMaterialName, DisplayType.Mesh);
if (m_targetMaterialName.serializedObject.ApplyModifiedProperties())
{
player.applyToMesh.TexturePropertyName = m_targetMaterialName.stringValue;
player.targetMateralProperty = m_targetMaterialName.stringValue;
}
}
}
EditorGUILayout.EndFadeGroup();
// render material
if (EditorGUILayout.BeginFadeGroup(m_RenderMaterial.faded))
{
if (player.applyToMaterial)
{
// target material
EditorGUILayout.PropertyField(m_targetMaterial, materialContent);
if (m_targetMaterial.serializedObject.ApplyModifiedProperties())
{
player.applyToMaterial.Material = (Material)m_targetMaterial.objectReferenceValue;
player.targetMaterial = (Material)m_targetMaterial.objectReferenceValue;
}
// material properties
DrawMaterialPropertieDropdown(m_targetMaterial, m_targetMaterialName, DisplayType.Material);
if (m_targetMaterialName.serializedObject.ApplyModifiedProperties())
{
player.applyToMaterial.TexturePropertyName = m_targetMaterialName.stringValue;
player.targetMateralProperty = m_targetMaterialName.stringValue;
}
}
}
EditorGUILayout.EndFadeGroup();
// uGUI
if (EditorGUILayout.BeginFadeGroup(m_RenderuGUI.faded))
{
EditorGUILayout.PropertyField(m_uGUIComponent, displayUGUIContent);
// when the user has not set a the uGUI componenet, infom them that they need to set this component
// and where they need to set it.
if (!player.displayUGUI)
{
EditorGUILayout.HelpBox(uGUIUsageInformation, MessageType.Info, false);
}
else
{
// color
EditorGUILayout.PropertyField(m_color, colorContent);
if (m_color.serializedObject.ApplyModifiedProperties())
{
player.displayUGUI.color = m_color.colorValue;
player.color = m_color.colorValue;
}
// UV
EditorGUILayout.PropertyField(m_UVRect, uvRectContent);
if (m_UVRect.serializedObject.ApplyModifiedProperties())
{
player.uvRect = m_UVRect.rectValue;
}
// Native (using full screen, as their is no need to create another serialized property,
// so just use fullscreen)
EditorGUILayout.PropertyField(m_fullscreen, nativeSizeContent);
if (m_fullscreen.serializedObject.ApplyModifiedProperties())
{
player.displayUGUI.ApplyNativeSize = m_fullscreen.boolValue;
player.fullScreen = m_fullscreen.boolValue;
}
// Scale
EditorGUILayout.PropertyField(m_aspectRatio, aspectRatioContent);
if (m_aspectRatio.serializedObject.ApplyModifiedProperties())
{
player.displayUGUI.ScaleMode = (ScaleMode)m_aspectRatio.enumValueIndex;
player.aspectRatio = (ScaleMode)m_aspectRatio.enumValueIndex;
}
}
}
EditorGUILayout.EndFadeGroup();
// render IMGUI
if (EditorGUILayout.BeginFadeGroup(m_RenderIMGUI.faded))
{
if (player.displayIMGUI)
{
// Fullscreen
EditorGUILayout.PropertyField(m_fullscreen, fullscreenContent);
if (m_fullscreen.serializedObject.ApplyModifiedProperties())
{
player.displayIMGUI.IsAreaFullScreen = m_fullscreen.boolValue;
player.fullScreen = m_fullscreen.boolValue;
}
// color
EditorGUILayout.PropertyField(m_color, colorContent);
if (m_color.serializedObject.ApplyModifiedProperties())
{
player.displayIMGUI.Color = m_color.colorValue;
player.color = m_color.colorValue;
}
// scale mode
EditorGUILayout.PropertyField(m_aspectRatio, aspectRatioContent);
if (m_aspectRatio.serializedObject.ApplyModifiedProperties())
{
player.displayIMGUI.ScaleMode = (ScaleMode)m_aspectRatio.enumValueIndex;
player.aspectRatio = (ScaleMode)m_aspectRatio.enumValueIndex;
}
}
}
EditorGUILayout.EndFadeGroup();
// render far plane
if (EditorGUILayout.BeginFadeGroup(m_RenderFarPlane.faded))
{
if (player.applyToFarPlane)
{
// Color
EditorGUILayout.PropertyField(m_color, colorContent);
if (m_color.serializedObject.ApplyModifiedProperties())
player.color = m_color.colorValue;
// aspect ratio (scale mode)
EditorGUILayout.PropertyField(m_aspectRatioRenderTexture, aspectRatioContent);
if (m_aspectRatioRenderTexture.serializedObject.ApplyModifiedProperties())
player.aspectRatioRenderTexture = (VideoResolveOptions.AspectRatio)m_aspectRatioRenderTexture.enumValueIndex;
// alpha
EditorGUILayout.Slider(m_alpha, 0, 1, alphaContent);
if (m_alpha.serializedObject.ApplyModifiedProperties())
player.targetCameraAlpha = m_alpha.floatValue;
}
}
EditorGUILayout.EndFadeGroup();
// render texture
if (EditorGUILayout.BeginFadeGroup(m_RenderTexture.faded))
{
if (player.applyToTexture)
{
// target texture
EditorGUILayout.PropertyField(m_targetTexture, targetTextureContent);
if (m_targetTexture.serializedObject.ApplyModifiedProperties())
{
player.applyToTexture.ExternalTexture = (RenderTexture)m_targetTexture.objectReferenceValue;
player.targetTexture = (RenderTexture)m_targetTexture.objectReferenceValue;
}
// aspect ratio
EditorGUILayout.PropertyField(m_aspectRatioRenderTexture, aspectRatioContent);
if (m_aspectRatioRenderTexture.serializedObject.ApplyModifiedProperties())
{
var options = player.applyToTexture.VideoResolveOptions;
options.aspectRatio = (VideoResolveOptions.AspectRatio)m_aspectRatioRenderTexture.enumValueIndex;
player.applyToTexture.VideoResolveOptions = options;
player.aspectRatioRenderTexture = (VideoResolveOptions.AspectRatio)m_aspectRatioRenderTexture.enumValueIndex;
}
}
}
EditorGUILayout.EndFadeGroup();
EditorGUI.indentLevel--;
EditorGUILayout.Space(10);
}
#endregion Render Mode Field
#region Audio Output Field
/// <summary>
/// Handles drawing the Audio Output options for the inspector, based on the current
/// output mode that has been selected
/// </summary>
/// <param name="player"><see cref="VideoPlayer_AVPro"/> that is being used</param>
public void HandleAudioOutputModeField(VideoPlayer_AVPro player)
{
// output mode
EditorGUILayout.PropertyField(m_audioOutputMode, audioOutputModeContent);
if (m_audioOutputMode.serializedObject.ApplyModifiedProperties())
{
#if UNITY_STANDALONE_WIN
player.audioOutputModeAVPro = (Windows.AudioOutput)m_audioOutputMode.enumValueIndex;
#elif UNITY_WSA_10_0
player.audioOutputModeAVPro = (WindowsUWP.AudioOutput)m_audioOutputMode.enumValueIndex;
#elif UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX || UNITY_TVOS || UNITY_VISIONOS
player.audioOutputModeAVPro = (PlatformOptions.AudioMode)m_audioOutputMode.enumValueIndex;
#endif
}
// setup fade groups to only show the active audio mode
m_AudioOutSystem.target = m_audioOutputMode.intValue == 0;
m_AudioOutUnity.target = m_audioOutputMode.intValue == 1;
m_AudioOutFacebook.target = m_audioOutputMode.intValue == 2;
m_AudioOutNone.target = m_audioOutputMode.intValue == 3;
#if UNITY_STANDALONE_WIN
EditorGUI.indentLevel++;
// system audio
if (EditorGUILayout.BeginFadeGroup(m_AudioOutSystem.faded))
{
// volume
EditorGUILayout.Slider(m_volume, 0f, 1f, volumeContent);
if (m_volume.serializedObject.ApplyModifiedProperties())
player.volume = m_volume.floatValue;
// muted
EditorGUILayout.PropertyField(m_muted, mutedContent);
if (m_muted.serializedObject.ApplyModifiedProperties())
player.muted = m_muted.boolValue;
}
EditorGUILayout.EndFadeGroup();
// unity audio
if (EditorGUILayout.BeginFadeGroup(m_AudioOutUnity.faded))
{
// audio source
EditorGUILayout.PropertyField(m_audioSource, audioSourceContent);
if (m_audioSource.serializedObject.ApplyModifiedProperties())
player.audioSource = (AudioSource)m_audioSource.objectReferenceValue;
// vlumvolume
EditorGUILayout.Slider(m_volume, 0f, 1f, volumeContent);
if (m_volume.serializedObject.ApplyModifiedProperties())
player.volume = m_volume.floatValue;
// muted
EditorGUILayout.PropertyField(m_muted, mutedContent);
if (m_muted.serializedObject.ApplyModifiedProperties())
player.muted = m_muted.boolValue;
}
EditorGUILayout.EndFadeGroup();
// facebook audio
if (EditorGUILayout.BeginFadeGroup(m_AudioOutFacebook.faded))
{
// Channel Mode (Only Windows and Android can change this value)
#if UNITY_STANDALONE_WIN || UNITY_ANDROID
var optionsVarName = "_optionsWindows";
DisplayPlatformOptionEnum(this.serializedObject, optionsVarName + _optionAudio360ChannelModeName, _optionAudio360ChannelModeContent, _audio360ChannelMapGuiNames);
#endif
// Device (Windows Only)
#if UNITY_STANDALONE_WIN
SerializedProperty propForceAudioOutputDeviceName = serializedObject.FindProperty(optionsVarName + ".forceAudioOutputDeviceName");
if (propForceAudioOutputDeviceName != null)
{
string[] deviceNames = { "Default", Windows.AudioDeviceOutputName_Rift, Windows.AudioDeviceOutputName_Vive, "Custom" };
int index = 0;
if (!string.IsNullOrEmpty(propForceAudioOutputDeviceName.stringValue))
{
switch (propForceAudioOutputDeviceName.stringValue)
{
case Windows.AudioDeviceOutputName_Rift:
index = 1;
break;
case Windows.AudioDeviceOutputName_Vive:
index = 2;
break;
default:
index = 3;
break;
}
}
int newIndex = EditorGUILayout.Popup("Audio Device Name", index, deviceNames);
if (newIndex == 0)
{
propForceAudioOutputDeviceName.stringValue = string.Empty;
}
else if (newIndex == 3)
{
if (index != newIndex)
{
if (string.IsNullOrEmpty(propForceAudioOutputDeviceName.stringValue) ||
propForceAudioOutputDeviceName.stringValue == Windows.AudioDeviceOutputName_Rift ||
propForceAudioOutputDeviceName.stringValue == Windows.AudioDeviceOutputName_Vive)
{
propForceAudioOutputDeviceName.stringValue = "?";
}
}
EditorGUILayout.PropertyField(propForceAudioOutputDeviceName, new GUIContent("Audio Device Name", "Useful for VR when you need to output to the VR audio device"));
}
else
{
propForceAudioOutputDeviceName.stringValue = deviceNames[newIndex];
}
}
#endif
// volume
EditorGUILayout.Slider(m_volume, 0f, 1f, volumeContent);
if (m_volume.serializedObject.ApplyModifiedProperties())
player.volume = m_volume.floatValue;
// muted
EditorGUILayout.PropertyField(m_muted, mutedContent);
if (m_muted.serializedObject.ApplyModifiedProperties())
player.muted = m_muted.boolValue;
}
EditorGUILayout.EndFadeGroup();
if (EditorGUILayout.BeginFadeGroup(m_AudioOutNone.faded))
{
// Nothing for this little guy
}
EditorGUILayout.EndFadeGroup();
EditorGUI.indentLevel--;
#endif
}
#endregion Audio Output Field
#endregion GUI Handlers
#region Helpers
/// <summary>
/// Draws the material properties as a dropdown
/// </summary>
/// <param name="renderer"><see cref="SerializedProperty"/> containing either a <see cref="Renderer"/> or <see cref="Material"/> to get the list of materials from</param>
/// <param name="name">the name of the current selected material propertie</param>
/// <param name="type">what the current <see cref="DisplayType"/> is</param>
public void DrawMaterialPropertieDropdown(SerializedProperty renderer, SerializedProperty name, DisplayType type)
{
bool hasKeywords = false;
int materialCount = 0;
int texturePropertyIndex = 0;
_materialTextureProperties = new GUIContent[0];
if (renderer.objectReferenceValue != null)
{
List<Material> nonNullMaterials = new List<Material>();
if (type == DisplayType.Mesh || type == DisplayType.CameraFarPlane || type == DisplayType.RenderTexture)
{
Renderer r = (Renderer)(renderer.objectReferenceValue);
materialCount = r.sharedMaterials.Length;
nonNullMaterials = new List<Material>(r.sharedMaterials);
}
else if (type == DisplayType.Material)
{
Material m = (Material)renderer.objectReferenceValue;
materialCount = 1;
nonNullMaterials = new List<Material>() { m };
}
// Remove any null materials (otherwise MaterialEditor.GetMaterialProperties() errors)
for (int i = 0; i < nonNullMaterials.Count; i++)
{
if (nonNullMaterials[i] == null)
{
nonNullMaterials.RemoveAt(i);
i--;
}
}
if (nonNullMaterials.Count > 0)
{
// Detect if there are any keywords
foreach (Material mat in nonNullMaterials)
{
if (mat.shaderKeywords.Length > 0)
{
hasKeywords = true;
break;
}
}
// Get unique list of texture property names
List<GUIContent> items = new List<GUIContent>(16);
List<string> textureNames = new List<string>(8);
foreach (Material mat in nonNullMaterials)
{
// NOTE: we process each material separately instead of passing them all into MaterialEditor.GetMaterialProperties() as it errors if the materials have different properties
MaterialProperty[] matProps = MaterialEditor.GetMaterialProperties(new UnityEngine.Object[] { mat });
foreach (MaterialProperty matProp in matProps)
{
#if UNITY_6000_2_OR_NEWER
if (matProp.propertyType == UnityEngine.Rendering.ShaderPropertyType.Texture)
#else
if (matProp.type == MaterialProperty.PropType.Texture)
#endif
{
if (!textureNames.Contains(matProp.name))
{
if (matProp.name == name.stringValue)
{
texturePropertyIndex = items.Count;
}
textureNames.Add(matProp.name);
items.Add(new GUIContent(matProp.name));
}
}
}
}
_materialTextureProperties = items.ToArray();
}
}
int newTexturePropertyIndex = EditorGUILayout.Popup(_guiTextTextureProperty, texturePropertyIndex, _materialTextureProperties);
if (newTexturePropertyIndex >= 0 && newTexturePropertyIndex < _materialTextureProperties.Length)
{
name.stringValue = _materialTextureProperties[newTexturePropertyIndex].text;
}
if (hasKeywords && name.stringValue != Helper.UnityBaseTextureName)
{
EditorGUILayout.HelpBox("When using an uber shader you may need to enable the keywords on a material for certain texture slots to take effect. You can sometimes achieve this (eg with Standard shader) by putting a dummy texture into the texture slot.", MessageType.Info);
}
}
/// <summary>
/// Displays the platform options as an enum, this is used by facebook audio to convert <see cref="_audio360ChannelMapGuiNames"/>
/// to a selectable enum
/// </summary>
/// <param name="so">The <see cref="SerializedObject"/> to use </param>
/// <param name="fieldName">Name of the propertie attatched to the <see cref="SerializedObject"/></param>
/// <param name="description"><see cref="GUIContent"/> to show as description</param>
/// <param name="enumNames">list of names to convert into enum <see cref="_audio360ChannelMapGuiNames"/></param>
/// <returns>The created <see cref="SerializedProperty"/> Enum containing all of the data from the inputterd <c>enumNames</c></returns>
private static SerializedProperty DisplayPlatformOptionEnum(SerializedObject so, string fieldName, GUIContent description, GUIContent[] enumNames)
{
SerializedProperty prop = so.FindProperty(fieldName);
if (prop != null)
prop.enumValueIndex = EditorGUILayout.Popup(description, prop.enumValueIndex, enumNames);
else
Debug.LogWarning("Can't find property `" + fieldName + "`");
return prop;
}
#endregion Helpers
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4fe6468cd70ffae49aac59cdc8288ca7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,20 @@
{
"name": "_AVProVideo.Extensions.VideoPlayer.Editor",
"rootNamespace": "",
"references": [
"GUID:367c3c6f75a457f40a6e4cc7207b4438",
"GUID:3ca842002c51d0a43b73e45298809a13",
"GUID:3bd657f68851a7f448c82186c6797ee0"
],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7f8bc0448be4d1a429da6d5434966567
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d344cf7c252267542827c6e0f67ad60f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 948fd3d3ecd4d0543b363b933cccd957
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: bb83b41b53a59874692b83eab5873998, type: 3}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d21d56e3a2281184ea7ab971ac27e705
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,196 @@
Shader "AVProVideo/Background/AVProVideo-ApplyToFarPlane"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_ChromaTex ("Chroma", 2D) = "gray" {}
_Color("Main Color", Color) = (1,1,1,1)
[Toggle(APPLY_GAMMA)] _ApplyGamma("Apply Gamma", Float) = 0
[Toggle(USE_YPCBCR)] _UseYpCbCr("Use YpCbCr", Float) = 0
_Alpha("Alpha", Float) = 1
_DrawOffset("Draw Offset", Vector) = (0,0,0,0)
_CustomScale("Custom Scaling", Vector) = (0,0,0,0)
_Aspect("Aspect Ratio", Float) = 1
//_TargetCamID("Target Camera", Float) = 0
//_CurrentCamID("Current Rendering Camera", Float) = 0
}
SubShader
{
// this is the important part that makes it render behind all of the other object, we set it to be 0 in the queue
// Geometry is 2000 and you cant just put a number so Geometry-2000 it is
Tags { "Queue" = "Geometry-2000" "RenderType"="Opaque" }
LOD 100
// then set ZWrite to off so all other items are drawn infront of this one, this is important as the actual object
// for this is at the near clipping plane of the camera
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// TODO: replace use multi_compile_local instead (Unity 2019.1 feature)
#pragma multi_compile __ APPLY_GAMMA
#pragma multi_compile __ USE_YPCBCR
#pragma multi_compile_fog
#include "UnityCG.cginc"
#include "../../../Runtime/Shaders/AVProVideo.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
uniform sampler2D _MainTex;
#if USE_YPCBCR
uniform sampler2D _ChromaTex;
uniform float4x4 _YpCbCrTransform;
#endif
uniform float4 _MainTex_ST;
uniform float4 _MainTex_TexelSize;
uniform fixed4 _Color;
uniform float _Alpha;
uniform float2 _DrawOffset;
uniform float _Aspect;
uniform float2 _CustomScale;
uniform int _TargetCamID;
uniform int _CurrentCamID;
v2f vert(appdata_img v)
{
v2f o;
// if our position is within 2 unitys of the camera position that is being rendered to
if (_TargetCamID == _CurrentCamID)
{
// scaling
float height = 1;
float width = 1;
// only use AspectRatio scaling if a custom scale has not been set
if (_CustomScale.x == 0 || _CustomScale.y == 0)
{
float2 targetSize = float2(_MainTex_TexelSize.z, _MainTex_TexelSize.w);
float2 currentSize = float2(_ScreenParams.x / 2, _ScreenParams.y / 2);
float2 targetAreaSize = float2(_ScreenParams.x, _ScreenParams.y);
float originalAspectRatio = targetSize.x / targetSize.y;
float baseTextureAspectRatio = currentSize.x / currentSize.y;
float targetAspectRatio = baseTextureAspectRatio;
int finalWidth, finalHeight;
if (_Aspect == 0) // No Scaling
{
// no change wanted here so set the final size to be the size
// of the orignal image
finalWidth = (int)targetSize.x;
finalHeight = (int)targetSize.y;
}
else if (_Aspect == 1) // Fit Vertically
{
// set the height to that of the target area then mutliply
// the height by the orignal aspect ratio to ensure that the image
// stays with the correct aspect.
finalHeight = (int)targetAreaSize.y;
finalWidth = round(finalHeight * originalAspectRatio);
}
else if (_Aspect == 2) // Fit Horizontally
{
// do the same as with FitVertically, just replace the width and heights
finalWidth = (int)targetAreaSize.x;
finalHeight = round(finalWidth / originalAspectRatio);
}
else if (_Aspect == 3) // Fit Inside
{
// if the width is larger then expand to be the same as the target area,
// cropping the height
if (targetAspectRatio < originalAspectRatio)
{
finalWidth = (int)targetAreaSize.x;
finalHeight = round(finalWidth / originalAspectRatio);
}
// if the height is larger then expand to be the same as the target area,
// cropping the width
else
{
finalHeight = (int)targetAreaSize.y;
finalWidth = round(finalHeight * originalAspectRatio);
}
}
else if (_Aspect == 4) // Fit Outside
{
// if the width is smaller, then expand the width to be the same
// size as the target then expand the height much like above to ensure
// that the correct aspect ratio is kept
if (targetAspectRatio > originalAspectRatio)
{
finalWidth = (int)targetAreaSize.x;
finalHeight = round(finalWidth / originalAspectRatio);
}
// if the hight is small, expand that first then make the width follow
else
{
finalHeight = (int)targetAreaSize.y;
finalWidth = round(finalHeight * originalAspectRatio);
}
}
else if (_Aspect == 5) // Stretch
{
// set the width and the height to be the same size as the target area
finalWidth = (int)targetAreaSize.x;
finalHeight = (int)targetAreaSize.y;
}
else // No Scalling
{
// make no change keeping them as the orignal texture size (1/4) of the screen
finalWidth = (int)currentSize.x;
finalHeight = (int)currentSize.y;
}
height = (float)finalHeight / (float)_ScreenParams.y;
width = (float)finalWidth / (float)_ScreenParams.x;
}
else
{
// use custom scaling
width = _CustomScale.x / (float)_ScreenParams.x;
height = _CustomScale.y / (float)_ScreenParams.y;
}
float2 pos = (v.vertex.xy - float2(0.5, 0.5) + _DrawOffset.xy) * 2.0;
pos.x *= width;
pos.y *= height;
// flip if needed then done
if (_ProjectionParams.x < 0.0)
{
pos.y = (1.0 - pos.y) - 1.0;
}
o.vertex = float4(pos.xy, UNITY_NEAR_CLIP_VALUE, 1.0);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
else
{
o.vertex = UnityObjectToClipPos(float4(0,0,0,0));
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col;
#if USE_YPCBCR
col = SampleYpCbCr(_MainTex, _ChromaTex, i.uv, _YpCbCrTransform);
#else
col = SampleRGBA(_MainTex, i.uv);
#endif
col *= _Color;
// alpha now avaialbe to be controleld via user
return fixed4(col.rgb, _Alpha);
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: d7a0d37aa7b09cb418a93251d226558a
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
{
"name": "_AVProVideo.Extensions.VideoPlayer",
"rootNamespace": "",
"references": [
"GUID:3ca842002c51d0a43b73e45298809a13",
"GUID:3bd657f68851a7f448c82186c6797ee0"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 367c3c6f75a457f40a6e4cc7207b4438
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 017104cd07f4a72439b9bb8ffd34b807
folderAsset: yes
timeCreated: 1587506896
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,152 @@
// You need to define AVPRO_PACKAGE_VFXGRAPH manually to use this script
// We could set up the asmdef to reference the package, but the package doesn't
// existing in Unity 2017 etc, and it throws an error due to missing reference
//#define AVPRO_PACKAGE_VFXGRAPH
#if (UNITY_2018_3_OR_NEWER && AVPRO_PACKAGE_VFXGRAPH)
using UnityEngine;
using UnityEngine.VFX;
using RenderHeads.Media.AVProVideo;
//-----------------------------------------------------------------------------
// Copyright 2019-2021 RenderHeads Ltd. All rights reserved.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo
{
/// <summary>
/// Sets the texture from the MediaPlayer to a texture parameter in a VFX Graph
/// </summary>
[AddComponentMenu("AVPro Video/Apply To VFX Graph", 300)]
[HelpURL("http://renderheads.com/products/avpro-video/")]
public class ApplyToVfxGraph : MonoBehaviour
{
[Header("Media Source")]
[SerializeField] MediaPlayer _mediaPlayer = null;
[Tooltip("Default texture to display when the video texture is preparing")]
[SerializeField] Texture2D _defaultTexture = null;
[Space(8f)]
[Header("VFX Target")]
[SerializeField] VisualEffect _visualEffect = null;
[SerializeField] string _texturePropertyName = string.Empty;
public Texture2D DefaultTexture
{
get { return _defaultTexture; }
set { if (_defaultTexture != value) { _defaultTexture = value; _isDirty = true; } }
}
public VisualEffect VisualEffect
{
get { return _visualEffect; }
set { _visualEffect = value; _isDirty = true; }
}
public string TexturePropertyName
{
get { return _texturePropertyName; }
set { _texturePropertyName = value; _textureProp = Shader.PropertyToID(_texturePropertyName); _isDirty = true; }
}
public MediaPlayer MediaPlayer
{
get { return _mediaPlayer; }
set { ChangeMediaPlayer(value); }
}
private bool _isDirty = true;
private int _textureProp = 0;
void OnEnable()
{
// Force evaluations
TexturePropertyName = _texturePropertyName;
if (_mediaPlayer != null)
{
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
}
}
#if UNITY_EDITOR
void OnValidate()
{
_isDirty = true;
}
#endif
void OnDisable()
{
if (_mediaPlayer != null)
{
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
}
}
// Callback function to handle events
private void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
{
switch (et)
{
case MediaPlayerEvent.EventType.FirstFrameReady:
case MediaPlayerEvent.EventType.PropertiesChanged:
ForceUpdate();
break;
case MediaPlayerEvent.EventType.Closing:
_isDirty = true; // Allow the update to happen on the next frame, as the video is still closing
break;
}
}
private void ChangeMediaPlayer(MediaPlayer player)
{
if (_mediaPlayer != player)
{
if (_mediaPlayer != null)
{
_mediaPlayer.Events.RemoveListener(OnMediaPlayerEvent);
}
_mediaPlayer = player;
if (_mediaPlayer != null)
{
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
}
_isDirty = true;
}
}
public void ForceUpdate()
{
_isDirty = true;
LateUpdate();
}
void LateUpdate()
{
if (_isDirty)
{
ApplyMapping();
}
}
private void ApplyMapping()
{
if (_visualEffect != null && !string.IsNullOrEmpty(_texturePropertyName))
{
if (_mediaPlayer != null && _mediaPlayer.TextureProducer != null && _mediaPlayer.TextureProducer.GetTexture() != null)
{
_visualEffect.SetTexture(_textureProp, _mediaPlayer.TextureProducer.GetTexture());
_isDirty = false;
}
else if (_defaultTexture != null)
{
_visualEffect.SetTexture(_textureProp, _defaultTexture);
_isDirty = false;
}
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 876043e54db05b045a4c75425318e3f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,9 @@
{
"name": "AVProVideo.Extensions.VisualEffectGraph",
"references": [
"AVProVideo.Runtime"
],
"optionalUnityReferences": [],
"includePlatforms": [],
"excludePlatforms": []
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 00c900f8a139a2540ab354c9ce09ac0e
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: