| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 | using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEditor;namespace RenderHeads.Media.AVProVideo.Editor{	[CanEditMultipleObjects()]	[CustomEditor(typeof(MediaReference))]	public class MediaReferenceEditor : UnityEditor.Editor	{		internal const string SettingsPrefix = "AVProVideo-MediaReferenceEditor-";		private SerializedProperty _propMediaPath;		private SerializedProperty _propHints;		private SerializedProperty _propPlatformMacOS;		private SerializedProperty _propPlatformWindows;		private SerializedProperty _propPlatformAndroid;		private SerializedProperty _propPlatformIOS;		private SerializedProperty _propPlatformTvOS;		private SerializedProperty _propPlatformWindowsUWP;		private SerializedProperty _propPlatformWebGL;		//private SerializedProperty _propAlias;		void OnEnable()		{			_propMediaPath = this.CheckFindProperty("_mediaPath");			_propHints = this.CheckFindProperty("_hints");			_propPlatformMacOS = this.CheckFindProperty("_macOS");			_propPlatformWindows = this.CheckFindProperty("_windows");			_propPlatformAndroid = this.CheckFindProperty("_android");			_propPlatformIOS = this.CheckFindProperty("_iOS");			_propPlatformTvOS = this.CheckFindProperty("_tvOS");			_propPlatformWindowsUWP = this.CheckFindProperty("_windowsUWP");			_propPlatformWebGL = this.CheckFindProperty("_webGL");			//_propAlias = CheckFindProperty("_alias");			_zoomToFill = EditorPrefs.GetBool(SettingsPrefix + "ZoomToFill", _zoomToFill);			_thumbnailTime = EditorPrefs.GetFloat(SettingsPrefix + "ThumbnailTime", _thumbnailTime);		}		void OnDisable()		{			EndGenerateThumbnails(false);			RemoveProgress();			EditorPrefs.SetBool(SettingsPrefix + "ZoomToFill", _zoomToFill);			EditorPrefs.SetFloat(SettingsPrefix + "ThumbnailTime", _thumbnailTime);		}		public override void OnInspectorGUI()		{			//MediaPlayer media = (this.target) as MediaPlayer;			//this.DrawDefaultInspector();			serializedObject.Update();			GUILayout.Label("Media Reference");			EditorGUILayout.Space();			//EditorGUILayout.PropertyField(_propAlias);			//EditorGUILayout.Space();			{				string mediaName = _propMediaPath.FindPropertyRelative("_path").stringValue;					GUILayout.BeginVertical(GUI.skin.box);				MediaPlayerEditor.OnInspectorGUI_CopyableFilename(mediaName);				GUILayout.EndVertical();			}			EditorGUILayout.PropertyField(_propMediaPath);			MediaPathDrawer.ShowBrowseButton(_propMediaPath);			EditorGUILayout.Space();			//GUILayout.Label("Media Hints", EditorStyles.boldLabel);			EditorGUILayout.PropertyField(_propHints);			EditorGUILayout.PropertyField(_propPlatformMacOS, new GUIContent("macOS"));			EditorGUILayout.PropertyField(_propPlatformWindows, new GUIContent("Windows"));			EditorGUILayout.PropertyField(_propPlatformAndroid, new GUIContent("Android"));			EditorGUILayout.PropertyField(_propPlatformIOS, new GUIContent("iOS"));			EditorGUILayout.PropertyField(_propPlatformTvOS, new GUIContent("tvOS"));			EditorGUILayout.PropertyField(_propPlatformWindowsUWP, new GUIContent("UWP"));			EditorGUILayout.PropertyField(_propPlatformWebGL, new GUIContent("WebGL"));			EditorGUILayout.Space();			EditorGUILayout.Space();						serializedObject.ApplyModifiedProperties();			bool beginGenerateThumbnails = false;						GUILayout.FlexibleSpace();			EditorGUI.BeginDisabledGroup(IsGeneratingThumbnails());			GUILayout.BeginHorizontal();			_thumbnailTime = GUILayout.HorizontalSlider(_thumbnailTime, 0f, 1f, GUILayout.ExpandWidth(true));			_zoomToFill = GUILayout.Toggle(_zoomToFill, "Zoom And Crop", GUI.skin.button, GUILayout.ExpandWidth(false));			GUILayout.EndHorizontal();			if (GUILayout.Button("Generate Thumbnail"))			{				beginGenerateThumbnails = true;			}			EditorGUI.EndDisabledGroup();			if (beginGenerateThumbnails)			{				BeginGenerateThumbnails();			}			if (IsGeneratingThumbnails())			{				ShowProgress();			}			if (!IsGeneratingThumbnails())			{				RemoveProgress();			}		}		private void ShowProgress()		{			// Show cancellable progress			float t = (float)_targetIndex / (float)this.targets.Length;			t = 0.25f + t * 0.75f;			MediaReference media = (this.targets[_targetIndex]) as MediaReference;						#if UNITY_2020_1_OR_NEWER			if (_progressId < 0)			{				//Progress.RegisterCancelCallback(_progressId...)				_progressId = Progress.Start("[AVProVideo] Generating Thumbnails...", null, Progress.Options.Managed);			}			Progress.Report(_progressId, t, media.MediaPath.Path);			#else			if (EditorUtility.DisplayCancelableProgressBar("[AVProVideo] Generating Thumbnails...", media.MediaPath.Path, t))			{				EndGenerateThumbnails(false);			}			#endif		}		private void RemoveProgress()		{			#if UNITY_2020_1_OR_NEWER			if (_progressId >= 0)			{				Progress.Remove(_progressId);				_progressId = -1;			}			#else			EditorUtility.ClearProgressBar();			#endif		}		#if UNITY_2020_1_OR_NEWER		private int _progressId = -1;		#endif		private float _thumbnailTime;		private bool _zoomToFill = false;		private int _lastFrame;		private BaseMediaPlayer _thumbnailPlayer;		private int _mediaFrame = -1;		private int _targetIndex = 0;		private float _timeoutTimer = 0f;		private bool IsGeneratingThumbnails()		{			return (_thumbnailPlayer != null);		}		private void BeginGenerateThumbnails()		{			EditorApplication.update -= UpdateGenerateThumbnail;			Debug.Assert(_thumbnailPlayer == null);			#if UNITY_EDITOR_WIN			if (WindowsMediaPlayer.InitialisePlatform())			{				MediaPlayer.OptionsWindows options = new MediaPlayer.OptionsWindows();				_thumbnailPlayer = new WindowsMediaPlayer(options);			}			#elif UNITY_EDITOR_OSX			{				MediaPlayer.OptionsApple options = new MediaPlayer.OptionsApple(MediaPlayer.OptionsApple.TextureFormat.BGRA, MediaPlayer.OptionsApple.Flags.None);				_thumbnailPlayer = new PlatformMediaPlayer(options);			}			#endif			if (_thumbnailPlayer != null)			{				_targetIndex = 0;				BeginNextThumbnail(0);			}			else			{				EndGenerateThumbnails(false);			}		}		private void BeginNextThumbnail(int index)		{			EditorApplication.update -= UpdateGenerateThumbnail;			_mediaFrame = -1;			_timeoutTimer = 0f;			if (_thumbnailPlayer != null)			{				if (index < this.targets.Length)				{					_targetIndex = index;					MediaReference media = (this.targets[_targetIndex]) as MediaReference;					string path = media.MediaPath.GetResolvedFullPath();					bool openedMedia = false;					if (!string.IsNullOrEmpty(path))					{						if (_thumbnailPlayer.OpenMedia(path, 0, string.Empty, media.Hints, 0, false))						{							openedMedia = true;							EditorApplication.update += UpdateGenerateThumbnail;						}					}					if (!openedMedia)					{						// If the media failed to open, continue to the next one						BeginNextThumbnail(_targetIndex + 1);					}				}				else				{					EndGenerateThumbnails(true);				}			}		}		private void EndGenerateThumbnails(bool updateAssets)		{			EditorApplication.update -= UpdateGenerateThumbnail;			if (_thumbnailPlayer != null)			{				_thumbnailPlayer.CloseMedia();				_thumbnailPlayer.Dispose();				_thumbnailPlayer = null;			}			_mediaFrame = -1;			if (updateAssets)			{				// This forces the static preview to refresh				foreach (Object o in this.targets)				{					EditorUtility.SetDirty(o);					AssetPreview.GetAssetPreview(o);				}				AssetDatabase.SaveAssets();			}		}		private void UpdateGenerateThumbnail()		{			if (Time.renderedFrameCount == _lastFrame)			{				// In at least Unity 5.6 we have to force refresh of the UI otherwise the render thread doesn't run to update the textures				this.Repaint();				UnityEditorInternal.InternalEditorUtility.RepaintAllViews();				return;			}			// Wait for a frame to be rendered			Debug.Assert(_thumbnailPlayer != null);			if (_thumbnailPlayer != null)			{				_timeoutTimer += Time.unscaledDeltaTime;				bool nextVideo = false;				_thumbnailPlayer.Update();				_thumbnailPlayer.Render();				if (_mediaFrame < 0 && _thumbnailPlayer.CanPlay())				{					_thumbnailPlayer.MuteAudio(true);					_thumbnailPlayer.Play();					_thumbnailPlayer.Seek(_thumbnailPlayer.GetDuration() * _thumbnailTime);					_mediaFrame = _thumbnailPlayer.GetTextureFrameCount();				}				if (_thumbnailPlayer.GetTexture() != null)				{					if (_mediaFrame != _thumbnailPlayer.GetTextureFrameCount() && _thumbnailPlayer.GetTextureFrameCount() > 3)					{						bool prevSRGB = GL.sRGBWrite;						GL.sRGBWrite = false;						RenderTexture rt2 = null;						// TODO: move this all into VideoRender as a resolve method						{							Material materialResolve = new Material(Shader.Find(VideoRender.Shader_Resolve));							VideoRender.SetupVerticalFlipMaterial(materialResolve, _thumbnailPlayer.RequiresVerticalFlip());							VideoRender.SetupAlphaPackedMaterial(materialResolve, _thumbnailPlayer.GetTextureAlphaPacking());							VideoRender.SetupGammaMaterial(materialResolve, !_thumbnailPlayer.PlayerSupportsLinearColorSpace());							RenderTexture prev = RenderTexture.active;							// Scale to fit and downsample							rt2 = RenderTexture.GetTemporary(128, 128, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB);							RenderTexture.active = rt2;							GL.Clear(false, true, new Color(0f, 0f, 0f, 0f));							ScaleMode scaleMode = ScaleMode.ScaleToFit;							if (_zoomToFill)							{								scaleMode = ScaleMode.ScaleAndCrop;							}							VideoRender.DrawTexture(new Rect(0f, 0f, 128f, 128f), _thumbnailPlayer.GetTexture(), scaleMode, _thumbnailPlayer.GetTextureAlphaPacking(), _thumbnailPlayer.GetTexturePixelAspectRatio(), materialResolve);							RenderTexture.active = prev;							Material.DestroyImmediate(materialResolve); materialResolve = null;						}										Texture2D readTexture = new Texture2D(128, 128, TextureFormat.RGBA32, true, false);						Helper.GetReadableTexture(rt2, readTexture);						MediaReference mediaRef = (this.targets[_targetIndex]) as MediaReference;						mediaRef.GeneratePreview(readTexture);						DestroyImmediate(readTexture); readTexture = null;						RenderTexture.ReleaseTemporary(rt2);						GL.sRGBWrite = prevSRGB;						nextVideo = true;						Debug.Log("Thumbnail Written");					}				}				if (!nextVideo)				{					// If there is an error or it times out, then skip this media					if (_timeoutTimer > 10f || _thumbnailPlayer.GetLastError() != ErrorCode.None)					{						MediaReference mediaRef = (this.targets[_targetIndex]) as MediaReference;						mediaRef.GeneratePreview(null);						nextVideo = true;					}				}				if (nextVideo)				{					BeginNextThumbnail(_targetIndex + 1);				}			}			_lastFrame = Time.renderedFrameCount;		}		public override bool HasPreviewGUI()		{			return true;		}		public override void OnPreviewGUI(Rect r, GUIStyle background)		{			Texture texture = RenderStaticPreview(string.Empty, null, 128, 128);			if (texture)			{				GUI.DrawTexture(r, texture, ScaleMode.ScaleToFit, true);			}		}		public override Texture2D RenderStaticPreview(string assetPath, Object[] subAssets, int width, int height)		{			MediaReference media = this.target as MediaReference;			if (media)			{				bool isLinear = false;				#if !UNITY_2018_1_OR_NEWER				// NOTE: These older versions of Unity don't handle sRGB in the editor correctly so a workaround is to create texture as linear				isLinear = true;				#endif				Texture2D result = new Texture2D(width, height, TextureFormat.RGBA32, true, isLinear);				if (!media.GetPreview(result))				{					DestroyImmediate(result); result = null;				}				return result;			}			return null;		}	}}
 |