UP-Viagg-io/Viagg-io/Assets/Packages/AVProVideo/Editor/Scripts/MediaReferenceEditor.cs

388 lines
12 KiB
C#
Raw Normal View History

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;
}
}
}