You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1393 lines
43 KiB
1393 lines
43 KiB
2 years ago
|
#if UNITY_5 && !UNITY_5_0 && !UNITY_5_1 && !UNITY_5_2 && !UNITY_5_3_0
|
||
|
#define AVPRO_UNITY_PLATFORM_TVOS
|
||
|
#endif
|
||
|
#if UNITY_5 && !UNITY_5_0 && !UNITY_5_1 && !UNITY_5_2_0
|
||
|
#define AVPRO_UNITY_IOS_ALLOWHTTPDOWNLOAD
|
||
|
#endif
|
||
|
using UnityEngine;
|
||
|
using UnityEditor;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Copyright 2015-2016 RenderHeads Ltd. All rights reserverd.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
|
||
|
namespace RenderHeads.Media.AVProVideo.Editor
|
||
|
{
|
||
|
[InitializeOnLoad]
|
||
|
[CanEditMultipleObjects]
|
||
|
[CustomEditor(typeof(MediaPlayer))]
|
||
|
public class MediaPlayerEditor : UnityEditor.Editor
|
||
|
{
|
||
|
private static Texture2D _icon;
|
||
|
private static int _platformIndex = 0;
|
||
|
private static bool _expandPlatformOverrides = false;
|
||
|
private static bool _expandMediaProperties = false;
|
||
|
private static bool _expandGlobalSettings = false;
|
||
|
private static bool _expandEvents = false;
|
||
|
private static bool _expandPreview = false;
|
||
|
private static bool _expandAbout = false;
|
||
|
private static List<string> _recentFiles = new List<string>(16);
|
||
|
|
||
|
private const string SettingsPrefix = "AVProVideo-MediaPlayerEditor-";
|
||
|
private const int MaxRecentFiles = 16;
|
||
|
|
||
|
private const string LinkPluginWebsite = "http://renderheads.com/product/avpro-video/";
|
||
|
private const string LinkForumPage = "http://forum.unity3d.com/threads/released-avpro-video-complete-video-playback-solution.385611/";
|
||
|
private const string LinkAssetStorePage = "https://www.assetstore.unity3d.com/#!/content/56355";
|
||
|
private const string LinkEmailSupport = "mailto:unitysupport@renderheads.com";
|
||
|
private const string LinkUserManual = "http://downloads.renderheads.com/docs/UnityAVProVideo.pdf";
|
||
|
private const string LinkScriptingClassReference = "http://downloads.renderheads.com/docs/AVProVideoClassReference/";
|
||
|
|
||
|
private const string SupportMessage = "If you are reporting a bug, please include any relevant files and details so that we may remedy the problem as fast as possible.\n\n" +
|
||
|
"Essential details:\n" +
|
||
|
"+ Error message\n" +
|
||
|
" + The exact error message\n" +
|
||
|
" + The console/output log if possible\n" +
|
||
|
"+ Hardware\n" +
|
||
|
" + Phone / tablet / device type and OS version\n" +
|
||
|
"+ Development environment\n" +
|
||
|
" + Unity version\n" +
|
||
|
" + Development OS version\n" +
|
||
|
" + AVPro Video plugin version\n" +
|
||
|
" + Video details\n" +
|
||
|
" + Resolution\n" +
|
||
|
" + Codec\n" +
|
||
|
" + Frame Rate\n" +
|
||
|
" + Better still, include a link to the video file\n";
|
||
|
|
||
|
private bool _showAlpha = false;
|
||
|
|
||
|
[MenuItem("GameObject/AVPro Video/Media Player", false, 0)]
|
||
|
public static void CreateMediaPlayerEditor()
|
||
|
{
|
||
|
GameObject go = new GameObject("MediaPlayer");
|
||
|
go.AddComponent<MediaPlayer>();
|
||
|
Selection.activeGameObject = go;
|
||
|
}
|
||
|
|
||
|
private static void LoadSettings()
|
||
|
{
|
||
|
_expandPlatformOverrides = EditorPrefs.GetBool(SettingsPrefix + "ExpandPlatformOverrides", false);
|
||
|
_expandMediaProperties = EditorPrefs.GetBool(SettingsPrefix + "ExpandMediaProperties", false);
|
||
|
_expandGlobalSettings = EditorPrefs.GetBool(SettingsPrefix + "ExpandGlobalSettings", false);
|
||
|
_expandEvents = EditorPrefs.GetBool(SettingsPrefix + "ExpandEvents", false);
|
||
|
_expandPreview = EditorPrefs.GetBool(SettingsPrefix + "ExpandPreview", false);
|
||
|
_platformIndex = EditorPrefs.GetInt(SettingsPrefix + "PlatformIndex", 0);
|
||
|
|
||
|
string recentFilesString = EditorPrefs.GetString(SettingsPrefix + "RecentFiles", string.Empty);
|
||
|
_recentFiles = new List<string>(recentFilesString.Split(new string[] { ";" }, System.StringSplitOptions.RemoveEmptyEntries));
|
||
|
}
|
||
|
|
||
|
private static void SaveSettings()
|
||
|
{
|
||
|
EditorPrefs.SetBool(SettingsPrefix + "ExpandPlatformOverrides", _expandPlatformOverrides);
|
||
|
EditorPrefs.SetBool(SettingsPrefix + "ExpandMediaProperties", _expandMediaProperties);
|
||
|
EditorPrefs.SetBool(SettingsPrefix + "ExpandGlobalSettings", _expandGlobalSettings);
|
||
|
EditorPrefs.SetBool(SettingsPrefix + "ExpandEvents", _expandEvents);
|
||
|
EditorPrefs.SetBool(SettingsPrefix + "ExpandPreview", _expandPreview);
|
||
|
EditorPrefs.SetInt(SettingsPrefix + "PlatformIndex", _platformIndex);
|
||
|
|
||
|
string recentFilesString = string.Empty;
|
||
|
if (_recentFiles.Count > 0)
|
||
|
{
|
||
|
recentFilesString = string.Join(";", _recentFiles.ToArray());
|
||
|
}
|
||
|
EditorPrefs.SetString(SettingsPrefix + "RecentFiles", recentFilesString);
|
||
|
}
|
||
|
|
||
|
void OnEnable()
|
||
|
{
|
||
|
LoadSettings();
|
||
|
}
|
||
|
|
||
|
void OnDisable()
|
||
|
{
|
||
|
SaveSettings();
|
||
|
}
|
||
|
|
||
|
private static bool IsPathWithin(string fullPath, string targetPath)
|
||
|
{
|
||
|
return fullPath.StartsWith(targetPath);
|
||
|
}
|
||
|
|
||
|
private static string GetPathRelativeTo(string root, string fullPath)
|
||
|
{
|
||
|
string result = fullPath.Remove(0, root.Length);
|
||
|
if (result.StartsWith(System.IO.Path.DirectorySeparatorChar.ToString()) || result.StartsWith(System.IO.Path.AltDirectorySeparatorChar.ToString()))
|
||
|
{
|
||
|
result = result.Remove(0, 1);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
public override bool RequiresConstantRepaint()
|
||
|
{
|
||
|
MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
return (Application.isPlaying && media != null && media.Control != null && _expandPreview);
|
||
|
}
|
||
|
|
||
|
public override void OnInspectorGUI()
|
||
|
{
|
||
|
MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
|
||
|
//DrawDefaultInspector();
|
||
|
|
||
|
serializedObject.Update();
|
||
|
|
||
|
GUILayout.Space(6f);
|
||
|
|
||
|
/////////////////// FILE PATH
|
||
|
|
||
|
EditorGUILayout.BeginVertical("box");
|
||
|
|
||
|
EditorGUILayout.LabelField("File", EditorStyles.boldLabel);
|
||
|
|
||
|
SerializedProperty propLocation = serializedObject.FindProperty("m_VideoLocation");
|
||
|
EditorGUILayout.PropertyField(propLocation);
|
||
|
|
||
|
SerializedProperty propPath = serializedObject.FindProperty("m_VideoPath");
|
||
|
EditorGUILayout.PropertyField(propPath);
|
||
|
|
||
|
//if (!Application.isPlaying)
|
||
|
{
|
||
|
GUILayout.BeginHorizontal();
|
||
|
OnInspectorGUI_RecentButton(propPath, propLocation);
|
||
|
GUI.color = Color.green;
|
||
|
if (GUILayout.Button("BROWSE"))
|
||
|
{
|
||
|
string startFolder = GetStartFolder(propPath.stringValue, (MediaPlayer.FileLocation)propLocation.enumValueIndex);
|
||
|
string videoPath = media.m_VideoPath;
|
||
|
string fullPath = string.Empty;
|
||
|
MediaPlayer.FileLocation fileLocation = media.m_VideoLocation;
|
||
|
if (Browse(startFolder, ref videoPath, ref fileLocation, ref fullPath))
|
||
|
{
|
||
|
propPath.stringValue = videoPath;
|
||
|
propLocation.enumValueIndex = (int)fileLocation;
|
||
|
EditorUtility.SetDirty(target);
|
||
|
|
||
|
AddToRecentFiles(fullPath);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GUILayout.EndHorizontal();
|
||
|
|
||
|
ShowFileWarningMessages(propPath.stringValue, (MediaPlayer.FileLocation)propLocation.enumValueIndex, media.m_AutoOpen, Platform.Unknown);
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
|
||
|
if (Application.isPlaying)
|
||
|
{
|
||
|
if (GUILayout.Button("Load"))
|
||
|
{
|
||
|
media.OpenVideoFromFile(media.m_VideoLocation, media.m_VideoPath, media.m_AutoStart);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
OnInspectorGUI_CopyableFilename(media.m_VideoPath);
|
||
|
|
||
|
EditorGUILayout.EndVertical();
|
||
|
|
||
|
/////////////////// STARTUP FIELDS
|
||
|
|
||
|
EditorGUILayout.BeginVertical("box");
|
||
|
GUILayout.Label("Startup", EditorStyles.boldLabel);
|
||
|
|
||
|
SerializedProperty propAutoOpen = serializedObject.FindProperty("m_AutoOpen");
|
||
|
EditorGUILayout.PropertyField(propAutoOpen);
|
||
|
|
||
|
SerializedProperty propAutoStart = serializedObject.FindProperty("m_AutoStart");
|
||
|
EditorGUILayout.PropertyField(propAutoStart);
|
||
|
EditorGUILayout.EndVertical();
|
||
|
|
||
|
/////////////////// PLAYBACK FIELDS
|
||
|
|
||
|
EditorGUILayout.BeginVertical("box");
|
||
|
GUILayout.Label("Playback", EditorStyles.boldLabel);
|
||
|
|
||
|
if (!Application.isPlaying)
|
||
|
{
|
||
|
SerializedProperty propLoop = serializedObject.FindProperty("m_Loop");
|
||
|
EditorGUILayout.PropertyField(propLoop);
|
||
|
|
||
|
SerializedProperty propRate = serializedObject.FindProperty("m_PlaybackRate");
|
||
|
EditorGUILayout.PropertyField(propRate);
|
||
|
|
||
|
SerializedProperty propVolume = serializedObject.FindProperty("m_Volume");
|
||
|
EditorGUILayout.PropertyField(propVolume);
|
||
|
|
||
|
SerializedProperty propMuted = serializedObject.FindProperty("m_Muted");
|
||
|
EditorGUILayout.PropertyField(propMuted);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (media.Control != null)
|
||
|
{
|
||
|
media.m_Loop = media.Control.IsLooping();
|
||
|
bool newLooping = EditorGUILayout.Toggle("Loop", media.m_Loop);
|
||
|
if (newLooping != media.m_Loop)
|
||
|
{
|
||
|
media.Control.SetLooping(newLooping);
|
||
|
}
|
||
|
|
||
|
media.m_PlaybackRate = media.Control.GetPlaybackRate();
|
||
|
float newPlaybackRate = EditorGUILayout.Slider("Rate", media.m_PlaybackRate, -4f, 4f);
|
||
|
if (newPlaybackRate != media.m_PlaybackRate)
|
||
|
{
|
||
|
media.Control.SetPlaybackRate(newPlaybackRate);
|
||
|
}
|
||
|
|
||
|
media.m_Volume = media.Control.GetVolume();
|
||
|
float newVolume = EditorGUILayout.Slider("Volume", media.m_Volume, 0f, 1f);
|
||
|
if (newVolume != media.m_Volume)
|
||
|
{
|
||
|
media.Control.SetVolume(newVolume);
|
||
|
}
|
||
|
|
||
|
media.m_Muted = media.Control.IsMuted();
|
||
|
bool newMuted = EditorGUILayout.Toggle("Muted", media.m_Muted);
|
||
|
if (newMuted != media.m_Muted)
|
||
|
{
|
||
|
media.Control.MuteAudio(newMuted);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EditorGUILayout.EndVertical();
|
||
|
|
||
|
|
||
|
EditorGUILayout.BeginVertical("box");
|
||
|
GUILayout.Label("Other", EditorStyles.boldLabel);
|
||
|
|
||
|
SerializedProperty propPersistent = serializedObject.FindProperty("m_Persistent");
|
||
|
EditorGUILayout.PropertyField(propPersistent, new GUIContent("Persistent", "Use DontDestroyOnLoad so this object isn't destroyed between level loads"));
|
||
|
|
||
|
SerializedProperty propDebugGui = serializedObject.FindProperty("m_DebugGui");
|
||
|
EditorGUILayout.PropertyField(propDebugGui);
|
||
|
|
||
|
EditorGUILayout.EndVertical();
|
||
|
|
||
|
|
||
|
/////////////////// MEDIA PROPERTIES
|
||
|
|
||
|
//if (!Application.isPlaying)
|
||
|
{
|
||
|
OnInspectorGUI_MediaProperties();
|
||
|
OnInspectorGUI_GlobalSettings();
|
||
|
}
|
||
|
|
||
|
//////////////////// PREVIEW
|
||
|
|
||
|
OnInspectorGUI_Preview();
|
||
|
|
||
|
/////////////////// EVENTS
|
||
|
|
||
|
OnInspectorGUI_Events();
|
||
|
|
||
|
/////////////////// PLATFORM OVERRIDES
|
||
|
|
||
|
if (!Application.isPlaying)
|
||
|
{
|
||
|
OnInspectorGUI_PlatformOverrides();
|
||
|
}
|
||
|
|
||
|
if (serializedObject.ApplyModifiedProperties())
|
||
|
{
|
||
|
EditorUtility.SetDirty(target);
|
||
|
}
|
||
|
|
||
|
if (!Application.isPlaying)
|
||
|
{
|
||
|
OnInspectorGUI_About();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct RecentFileData
|
||
|
{
|
||
|
public RecentFileData(string path, SerializedProperty propPath, SerializedProperty propLocation, Object target)
|
||
|
{
|
||
|
this.path = path;
|
||
|
this.propPath = propPath;
|
||
|
this.propLocation = propLocation;
|
||
|
this.target = target;
|
||
|
}
|
||
|
|
||
|
public string path;
|
||
|
public SerializedProperty propPath;
|
||
|
public SerializedProperty propLocation;
|
||
|
public Object target;
|
||
|
}
|
||
|
|
||
|
private static void AddToRecentFiles(string path)
|
||
|
{
|
||
|
if (!_recentFiles.Contains(path))
|
||
|
{
|
||
|
_recentFiles.Insert(0, path);
|
||
|
if (_recentFiles.Count > MaxRecentFiles)
|
||
|
{
|
||
|
// Remove the oldest item from the list
|
||
|
_recentFiles.RemoveAt(_recentFiles.Count - 1);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// If it already contains the item, then move it to the top
|
||
|
_recentFiles.Remove(path);
|
||
|
_recentFiles.Insert(0, path);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void RecentMenuCallback_Select(object obj)
|
||
|
{
|
||
|
RecentFileData data = (RecentFileData)obj;
|
||
|
|
||
|
string videoPath = string.Empty;
|
||
|
MediaPlayer.FileLocation fileLocation = MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder;
|
||
|
GetRelativeLocationFromPath(data.path, ref videoPath, ref fileLocation);
|
||
|
|
||
|
// Move it to the top of the list
|
||
|
AddToRecentFiles(data.path);
|
||
|
|
||
|
data.propPath.stringValue = videoPath;
|
||
|
data.propLocation.enumValueIndex = (int)fileLocation;
|
||
|
|
||
|
serializedObject.ApplyModifiedProperties();
|
||
|
EditorUtility.SetDirty(data.target);
|
||
|
}
|
||
|
|
||
|
private void RecentMenuCallback_Clear()
|
||
|
{
|
||
|
_recentFiles.Clear();
|
||
|
}
|
||
|
|
||
|
private void RecentMenuCallback_ClearMissing()
|
||
|
{
|
||
|
if (_recentFiles != null && _recentFiles.Count > 0)
|
||
|
{
|
||
|
List<string> newList = new List<string>(_recentFiles.Count);
|
||
|
for (int i = 0; i < _recentFiles.Count; i++)
|
||
|
{
|
||
|
string path = _recentFiles[i];
|
||
|
if (System.IO.File.Exists(path))
|
||
|
{
|
||
|
newList.Add(path);
|
||
|
}
|
||
|
}
|
||
|
_recentFiles = newList;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void RecentMenuCallback_Add()
|
||
|
{
|
||
|
// TODO: implement me
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_CopyableFilename(string path)
|
||
|
{
|
||
|
// Display the file name so it's easy to read and copy to the clipboard
|
||
|
if (!string.IsNullOrEmpty(path))
|
||
|
{
|
||
|
// Some GUI hacks here because SelectableLabel wants to be double height and it doesn't want to be centered because it's an EditorGUILayout function...
|
||
|
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 0.1f);
|
||
|
if (EditorGUIUtility.isProSkin)
|
||
|
{
|
||
|
GUI.backgroundColor = Color.black;
|
||
|
GUI.color = Color.cyan;
|
||
|
}
|
||
|
GUILayout.BeginHorizontal("box");
|
||
|
GUILayout.FlexibleSpace();
|
||
|
string text = System.IO.Path.GetFileName(path);
|
||
|
Vector2 textSize = EditorStyles.boldLabel.CalcSize(new GUIContent(text));
|
||
|
EditorGUILayout.SelectableLabel(text, EditorStyles.boldLabel, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x));
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUILayout.EndHorizontal();
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_RecentButton(SerializedProperty propPath, SerializedProperty propLocation)
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
|
||
|
if (GUILayout.Button("RECENT", GUILayout.Width(64f)))
|
||
|
{
|
||
|
GenericMenu toolsMenu = new GenericMenu();
|
||
|
toolsMenu.AddDisabledItem(new GUIContent("Recent Files"));
|
||
|
|
||
|
// TODO: allow current path to be added. Perhaps add it automatically when file is loaded?
|
||
|
/*if (!string.IsNullOrEmpty(propPath.stringValue))
|
||
|
{
|
||
|
string path = propPath.stringValue.Replace("/", ">").Replace("\\", ">");
|
||
|
toolsMenu.AddItem(new GUIContent("Add Current: " + path), false, RecentMenuCallback_Add);
|
||
|
}*/
|
||
|
toolsMenu.AddSeparator("");
|
||
|
|
||
|
int missingCount = 0;
|
||
|
for (int i = 0; i < _recentFiles.Count; i++)
|
||
|
{
|
||
|
string path = _recentFiles[i];
|
||
|
string itemName = path.Replace("/", ">").Replace("\\", ">");
|
||
|
if (System.IO.File.Exists(path))
|
||
|
{
|
||
|
toolsMenu.AddItem(new GUIContent(itemName), false, RecentMenuCallback_Select, new RecentFileData(path, propPath, propLocation, target));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
toolsMenu.AddDisabledItem(new GUIContent(itemName));
|
||
|
missingCount++;
|
||
|
}
|
||
|
}
|
||
|
if (_recentFiles.Count > 0)
|
||
|
{
|
||
|
toolsMenu.AddSeparator("");
|
||
|
toolsMenu.AddItem(new GUIContent("Clear"), false, RecentMenuCallback_Clear);
|
||
|
if (missingCount > 0)
|
||
|
{
|
||
|
toolsMenu.AddItem(new GUIContent("Clear Missing (" + missingCount + ")"), false, RecentMenuCallback_ClearMissing);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
toolsMenu.ShowAsContext();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static void ShowFileWarningMessages(string filePath, MediaPlayer.FileLocation fileLocation, bool isAutoOpen, Platform platform)
|
||
|
{
|
||
|
string finalPath = MediaPlayer.GetFilePath(filePath, fileLocation);
|
||
|
|
||
|
if (string.IsNullOrEmpty(filePath))
|
||
|
{
|
||
|
if (isAutoOpen)
|
||
|
{
|
||
|
GUI.color = Color.red;
|
||
|
GUILayout.TextArea("Error: No file specfied");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: No file specfied");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (finalPath.Contains("://"))
|
||
|
{
|
||
|
if (fileLocation != MediaPlayer.FileLocation.AbsolutePathOrURL)
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: URL detected, change location to URL?");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
#if AVPRO_UNITY_IOS_ALLOWHTTPDOWNLOAD
|
||
|
// Display warning to iOS users if they're trying to use HTTP url without setting the permission
|
||
|
bool isPlatformIOS = (platform == Platform.iOS) || (platform == Platform.Unknown && BuildTargetGroup.iOS == UnityEditor.EditorUserBuildSettings.selectedBuildTargetGroup);
|
||
|
#if AVPRO_UNITY_PLATFORM_TVOS
|
||
|
isPlatformIOS |= (platform == Platform.tvOS) || (platform == Platform.Unknown && BuildTargetGroup.tvOS == UnityEditor.EditorUserBuildSettings.selectedBuildTargetGroup);
|
||
|
#endif
|
||
|
|
||
|
if (isPlatformIOS)
|
||
|
{
|
||
|
if (filePath.StartsWith("http://") && !PlayerSettings.iOS.allowHTTPDownload)
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: Starting with iOS 9 'allow HTTP downloads' must be enabled for HTTP connections (see Player Settings)");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
// Display warning for Android users if they're trying to use a URL without setting permission
|
||
|
if (platform == Platform.Android || (platform == Platform.Unknown && BuildTargetGroup.Android == UnityEditor.EditorUserBuildSettings.selectedBuildTargetGroup))
|
||
|
{
|
||
|
if (!PlayerSettings.Android.forceInternetPermission)
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: You may need to set 'Internet Access' to 'require' in your Player Settings for Android builds when using URLs");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Display warning for Android users if they're trying to use absolute file path without permission
|
||
|
if (platform == Platform.Android || (platform == Platform.Unknown && BuildTargetGroup.Android == UnityEditor.EditorUserBuildSettings.selectedBuildTargetGroup))
|
||
|
{
|
||
|
if (!PlayerSettings.Android.forceSDCardPermission)
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: You may need to access the local file system you may need to set 'Write Access' to 'External(SDCard)' in your Player Settings for Android");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (platform == Platform.Unknown || platform == MediaPlayer.GetPlatform())
|
||
|
{
|
||
|
if (!System.IO.File.Exists(finalPath))
|
||
|
{
|
||
|
GUI.color = Color.red;
|
||
|
GUILayout.TextArea("Error: File not found");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (fileLocation == MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder)
|
||
|
{
|
||
|
if (!System.IO.Directory.Exists(Application.streamingAssetsPath))
|
||
|
{
|
||
|
GUILayout.Space(10f);
|
||
|
GUILayout.BeginHorizontal();
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: No StreamingAssets folder found");
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
if (GUILayout.Button("Create Folder"))
|
||
|
{
|
||
|
System.IO.Directory.CreateDirectory(Application.streamingAssetsPath);
|
||
|
AssetDatabase.Refresh();
|
||
|
}
|
||
|
GUILayout.EndHorizontal();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bool checkAndroidFileSize = false;
|
||
|
#if UNITY_ANDROID
|
||
|
if (platform == Platform.Unknown)
|
||
|
{
|
||
|
checkAndroidFileSize = true;
|
||
|
}
|
||
|
#endif
|
||
|
if (platform == Platform.Android)
|
||
|
{
|
||
|
checkAndroidFileSize = true;
|
||
|
}
|
||
|
|
||
|
if (checkAndroidFileSize)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
System.IO.FileInfo info = new System.IO.FileInfo(finalPath);
|
||
|
if (info != null && info.Length > (1024 * 1024 * 512))
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: Using this very large file inside StreamingAssets folder on Android isn't recommended. Deployments will be slow and mapping the file from the StreamingAssets JAR may cause storage and memory issues. We recommend loading from another folder on the device.");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
catch (System.Exception)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_VideoPreview(MediaPlayer media, IMediaProducer textureSource)
|
||
|
{
|
||
|
Texture texture = null;
|
||
|
if (textureSource != null)
|
||
|
{
|
||
|
texture = textureSource.GetTexture();
|
||
|
}
|
||
|
if (texture == null)
|
||
|
{
|
||
|
texture = EditorGUIUtility.whiteTexture;
|
||
|
}
|
||
|
|
||
|
float ratio = (float)texture.width / (float)texture.height;
|
||
|
|
||
|
// Reserve rectangle for texture
|
||
|
GUILayout.BeginHorizontal();
|
||
|
GUILayout.FlexibleSpace();
|
||
|
Rect textureRect;
|
||
|
if (texture != EditorGUIUtility.whiteTexture)
|
||
|
{
|
||
|
textureRect = GUILayoutUtility.GetRect(Screen.width / 2, Screen.width / 2, (Screen.width / 2) / ratio, (Screen.width / 2) / ratio);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
textureRect = GUILayoutUtility.GetRect(1920f / 40, 1080f / 40);
|
||
|
}
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUILayout.EndHorizontal();
|
||
|
|
||
|
// Dimensions
|
||
|
string dimensionText = string.Format("{0}x{1}", 0, 0);
|
||
|
if (texture != EditorGUIUtility.whiteTexture)
|
||
|
{
|
||
|
dimensionText = string.Format("{0}x{1}", texture.width, texture.height);
|
||
|
}
|
||
|
|
||
|
GUILayout.BeginHorizontal();
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUILayout.Label(dimensionText);
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUILayout.EndHorizontal();
|
||
|
|
||
|
// Show alpha toggle
|
||
|
GUILayout.BeginHorizontal();
|
||
|
GUILayout.FlexibleSpace();
|
||
|
_showAlpha = GUILayout.Toggle(_showAlpha, "Show Alpha Channel");
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUILayout.EndHorizontal();
|
||
|
|
||
|
// Draw the texture
|
||
|
Matrix4x4 prevMatrix = GUI.matrix;
|
||
|
if (textureSource != null && textureSource.RequiresVerticalFlip())
|
||
|
{
|
||
|
GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0, textureRect.y + (textureRect.height / 2)));
|
||
|
}
|
||
|
if (!_showAlpha)
|
||
|
{
|
||
|
if (!GUI.enabled)
|
||
|
{
|
||
|
GUI.color = Color.grey;
|
||
|
}
|
||
|
GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleToFit, true);
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
EditorGUI.DrawTextureAlpha(textureRect, texture, ScaleMode.ScaleToFit);
|
||
|
}
|
||
|
GUI.matrix = prevMatrix;
|
||
|
|
||
|
// Select texture button
|
||
|
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
|
||
|
GUILayout.FlexibleSpace();
|
||
|
if (GUILayout.Button("Select Texture", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
Selection.activeObject = texture;
|
||
|
}
|
||
|
if (GUILayout.Button("Save PNG", GUILayout.ExpandWidth(true)))
|
||
|
{
|
||
|
media.SaveFrameToPng();
|
||
|
}
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUILayout.EndHorizontal();
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_PlayControls(IMediaControl control, IMediaInfo info)
|
||
|
{
|
||
|
GUILayout.Space(8.0f);
|
||
|
|
||
|
// Slider
|
||
|
EditorGUILayout.BeginHorizontal();
|
||
|
bool isPlaying = false;
|
||
|
if (control != null)
|
||
|
{
|
||
|
isPlaying = control.IsPlaying();
|
||
|
}
|
||
|
float currentTime = 0f;
|
||
|
if (control != null)
|
||
|
{
|
||
|
currentTime = control.GetCurrentTimeMs();
|
||
|
}
|
||
|
|
||
|
float durationTime = 0f;
|
||
|
if (info != null)
|
||
|
{
|
||
|
durationTime = info.GetDurationMs();
|
||
|
if (float.IsNaN(durationTime))
|
||
|
{
|
||
|
durationTime = 0f;
|
||
|
}
|
||
|
}
|
||
|
string timeUsed = Helper.GetTimeString(currentTime / 1000f);
|
||
|
GUILayout.Label(timeUsed, GUILayout.ExpandWidth(false));
|
||
|
|
||
|
float newTime = GUILayout.HorizontalSlider(currentTime, 0f, durationTime, GUILayout.ExpandWidth(true));
|
||
|
if (newTime != currentTime)
|
||
|
{
|
||
|
control.Seek(newTime);
|
||
|
}
|
||
|
|
||
|
string timeTotal = "Infinity";
|
||
|
if (!float.IsInfinity(durationTime))
|
||
|
{
|
||
|
timeTotal = Helper.GetTimeString(durationTime / 1000f);
|
||
|
}
|
||
|
|
||
|
GUILayout.Label(timeTotal, GUILayout.ExpandWidth(false));
|
||
|
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
|
||
|
// Buttons
|
||
|
EditorGUILayout.BeginHorizontal();
|
||
|
if (GUILayout.Button("Rewind", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
control.Rewind();
|
||
|
}
|
||
|
|
||
|
if (!isPlaying)
|
||
|
{
|
||
|
GUI.color = Color.green;
|
||
|
if (GUILayout.Button("Play", GUILayout.ExpandWidth(true)))
|
||
|
{
|
||
|
control.Play();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
if (GUILayout.Button("Pause", GUILayout.ExpandWidth(true)))
|
||
|
{
|
||
|
control.Pause();
|
||
|
}
|
||
|
}
|
||
|
GUI.color = Color.white;
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
}
|
||
|
|
||
|
private struct Native
|
||
|
{
|
||
|
#if UNITY_EDITOR_WIN
|
||
|
[System.Runtime.InteropServices.DllImport("AVProVideo")]
|
||
|
public static extern System.IntPtr GetPluginVersion();
|
||
|
#elif UNITY_EDITOR_OSX
|
||
|
[System.Runtime.InteropServices.DllImport("AVProVideo")]
|
||
|
public static extern string AVPGetVersion();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_About()
|
||
|
{
|
||
|
//GUILayout.Space(8f);
|
||
|
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = Color.clear;
|
||
|
if (_expandAbout)
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 0.1f);
|
||
|
if (EditorGUIUtility.isProSkin)
|
||
|
{
|
||
|
GUI.backgroundColor = Color.black;
|
||
|
}
|
||
|
}
|
||
|
GUILayout.BeginVertical("box");
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
if (GUILayout.Button("About", EditorStyles.toolbarButton))
|
||
|
{
|
||
|
_expandAbout = !_expandAbout;
|
||
|
}
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
if (_expandAbout)
|
||
|
{
|
||
|
string version = "Unknown";
|
||
|
#if UNITY_EDITOR_WIN
|
||
|
version = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(Native.GetPluginVersion());
|
||
|
#elif UNITY_EDITOR_OSX
|
||
|
version = Native.AVPGetVersion();
|
||
|
#endif
|
||
|
|
||
|
EditorGUILayout.BeginHorizontal();
|
||
|
GUILayout.FlexibleSpace();
|
||
|
if (_icon == null)
|
||
|
{
|
||
|
_icon = Resources.Load<Texture2D>("AVProVideoIcon");
|
||
|
}
|
||
|
if (_icon != null)
|
||
|
{
|
||
|
GUILayout.Label(new GUIContent(_icon));
|
||
|
}
|
||
|
GUILayout.FlexibleSpace();
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
|
||
|
EditorGUILayout.BeginHorizontal();
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.Label("AVPro Video by RenderHeads Ltd", EditorStyles.boldLabel);
|
||
|
GUI.color = Color.white;
|
||
|
GUILayout.FlexibleSpace();
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
|
||
|
EditorGUILayout.BeginHorizontal();
|
||
|
GUILayout.FlexibleSpace();
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.Label("version " + version + " (scripts v" + Helper.ScriptVersion + ")");
|
||
|
GUI.color = Color.white;
|
||
|
GUILayout.FlexibleSpace();
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
|
||
|
|
||
|
|
||
|
GUILayout.Space(32f);
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
|
||
|
EditorGUILayout.LabelField("AVPro Video Links", EditorStyles.boldLabel);
|
||
|
|
||
|
GUILayout.Space(8f);
|
||
|
|
||
|
EditorGUILayout.LabelField("Documentation");
|
||
|
if (GUILayout.Button("User Manual", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
Application.OpenURL(LinkUserManual);
|
||
|
}
|
||
|
if (GUILayout.Button("Scripting Class Reference", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
Application.OpenURL(LinkScriptingClassReference);
|
||
|
}
|
||
|
|
||
|
GUILayout.Space(16f);
|
||
|
|
||
|
GUILayout.Label("Rate and Review (★★★★☆)", GUILayout.ExpandWidth(false));
|
||
|
if (GUILayout.Button("Unity Asset Store Page", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
Application.OpenURL(LinkAssetStorePage);
|
||
|
}
|
||
|
|
||
|
GUILayout.Space(16f);
|
||
|
|
||
|
GUILayout.Label("Community");
|
||
|
if (GUILayout.Button("Unity Forum Page", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
Application.OpenURL(LinkForumPage);
|
||
|
}
|
||
|
|
||
|
GUILayout.Space(16f);
|
||
|
|
||
|
GUILayout.Label("Homepage", GUILayout.ExpandWidth(false));
|
||
|
if (GUILayout.Button("AVPro Video Website", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
Application.OpenURL(LinkPluginWebsite);
|
||
|
}
|
||
|
|
||
|
GUILayout.Space(16f);
|
||
|
|
||
|
GUILayout.Label("Bugs and Support");
|
||
|
EditorGUILayout.BeginHorizontal();
|
||
|
if (GUILayout.Button("Email unitysupport@renderheads.com", GUILayout.ExpandWidth(false)))
|
||
|
{
|
||
|
Application.OpenURL(LinkEmailSupport);
|
||
|
}
|
||
|
EditorGUILayout.EndHorizontal();
|
||
|
|
||
|
GUILayout.Space(32f);
|
||
|
|
||
|
EditorGUILayout.LabelField("Bug Reporting Notes", EditorStyles.boldLabel);
|
||
|
|
||
|
EditorGUILayout.SelectableLabel(SupportMessage, EditorStyles.wordWrappedLabel, GUILayout.Height(300f));
|
||
|
}
|
||
|
|
||
|
EditorGUILayout.EndVertical();
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_Events()
|
||
|
{
|
||
|
//GUILayout.Space(8f);
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = Color.clear;
|
||
|
if (_expandEvents)
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 0.1f);
|
||
|
if (EditorGUIUtility.isProSkin)
|
||
|
{
|
||
|
GUI.backgroundColor = Color.black;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GUILayout.BeginVertical("box");
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
|
||
|
if (GUILayout.Button("Events", EditorStyles.toolbarButton))
|
||
|
{
|
||
|
_expandEvents = !_expandEvents;
|
||
|
}
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
if (_expandEvents)
|
||
|
{
|
||
|
SerializedProperty propEvents = serializedObject.FindProperty("m_events");
|
||
|
EditorGUILayout.PropertyField(propEvents);
|
||
|
}
|
||
|
|
||
|
GUILayout.EndVertical();
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_MediaProperties()
|
||
|
{
|
||
|
//GUILayout.Space(8f);
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = Color.clear;
|
||
|
if (_expandMediaProperties)
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 0.1f);
|
||
|
if (EditorGUIUtility.isProSkin)
|
||
|
{
|
||
|
GUI.backgroundColor = Color.black;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GUILayout.BeginVertical("box");
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
|
||
|
if (GUILayout.Button("Media Properties", EditorStyles.toolbarButton))
|
||
|
{
|
||
|
_expandMediaProperties = !_expandMediaProperties;
|
||
|
}
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
if (_expandMediaProperties)
|
||
|
{
|
||
|
MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
|
||
|
EditorGUILayout.BeginVertical();
|
||
|
GUILayout.Label("Texture", EditorStyles.boldLabel);
|
||
|
|
||
|
SerializedProperty propFilter = serializedObject.FindProperty("m_FilterMode");
|
||
|
EditorGUILayout.PropertyField(propFilter, new GUIContent("Filter"));
|
||
|
|
||
|
SerializedProperty propWrap = serializedObject.FindProperty("m_WrapMode");
|
||
|
EditorGUILayout.PropertyField(propWrap, new GUIContent("Wrap"));
|
||
|
|
||
|
SerializedProperty propAniso = serializedObject.FindProperty("m_AnisoLevel");
|
||
|
EditorGUILayout.PropertyField(propAniso, new GUIContent("Aniso"));
|
||
|
|
||
|
if (propWrap.enumValueIndex != (int)media.m_WrapMode ||
|
||
|
propFilter.enumValueIndex != (int)media.m_FilterMode ||
|
||
|
propAniso.intValue != media.m_AnisoLevel)
|
||
|
{
|
||
|
if (media.Control != null)
|
||
|
{
|
||
|
media.Control.SetTextureProperties((FilterMode)propFilter.enumValueIndex, (TextureWrapMode)propWrap.enumValueIndex, propAniso.intValue);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EditorGUILayout.EndVertical();
|
||
|
|
||
|
|
||
|
EditorGUILayout.BeginVertical();
|
||
|
GUILayout.Label("Stereo", EditorStyles.boldLabel);
|
||
|
|
||
|
SerializedProperty propStereoPacking = serializedObject.FindProperty("m_StereoPacking");
|
||
|
EditorGUILayout.PropertyField(propStereoPacking, new GUIContent("Packing"));
|
||
|
|
||
|
SerializedProperty propDisplayStereoTint = serializedObject.FindProperty("m_DisplayDebugStereoColorTint");
|
||
|
EditorGUILayout.PropertyField(propDisplayStereoTint, new GUIContent("Debug Eye Tint", "Tints the left eye green and the right eye red so you can confirm stereo is working"));
|
||
|
|
||
|
EditorGUILayout.EndVertical();
|
||
|
}
|
||
|
|
||
|
GUILayout.EndVertical();
|
||
|
}
|
||
|
|
||
|
|
||
|
private void OnInspectorGUI_GlobalSettings()
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = Color.clear;
|
||
|
if (_expandGlobalSettings)
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 0.1f);
|
||
|
if (EditorGUIUtility.isProSkin)
|
||
|
{
|
||
|
GUI.backgroundColor = Color.black;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GUILayout.BeginVertical("box");
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
|
||
|
if (GUILayout.Button("Global Settings", EditorStyles.toolbarButton))
|
||
|
{
|
||
|
_expandGlobalSettings = !_expandGlobalSettings;
|
||
|
}
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
if (_expandGlobalSettings)
|
||
|
{
|
||
|
EditorGUILayout.LabelField("Current Platform", EditorUserBuildSettings.selectedBuildTargetGroup.ToString());
|
||
|
|
||
|
const string TimeScaleDefine = "AVPROVIDEO_BETA_SUPPORT_TIMESCALE";
|
||
|
|
||
|
string defines = PlayerSettings.GetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup);
|
||
|
bool supportsTimeScale = defines.Contains(TimeScaleDefine);
|
||
|
bool supportsTimeScaleNew = EditorGUILayout.Toggle("TimeScale Support", supportsTimeScale);
|
||
|
if (supportsTimeScale != supportsTimeScaleNew)
|
||
|
{
|
||
|
if (supportsTimeScaleNew)
|
||
|
{
|
||
|
defines += ";" + TimeScaleDefine + ";";
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
defines = defines.Replace(TimeScaleDefine, "");
|
||
|
}
|
||
|
|
||
|
PlayerSettings.SetScriptingDefineSymbolsForGroup(EditorUserBuildSettings.selectedBuildTargetGroup, defines);
|
||
|
}
|
||
|
|
||
|
if (supportsTimeScaleNew)
|
||
|
{
|
||
|
GUI.color = Color.yellow;
|
||
|
GUILayout.TextArea("Warning: This will affect performance if you change Time.timeScale or Time.captureFramerate. This feature is useful for supporting video capture system that adjust time scale during capturing.");
|
||
|
GUI.color = Color.white;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GUILayout.EndVertical();
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_PlatformOverrides()
|
||
|
{
|
||
|
//GUILayout.Space(8f);
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = Color.clear;
|
||
|
if (_expandPlatformOverrides)
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 0.1f);
|
||
|
if (EditorGUIUtility.isProSkin)
|
||
|
{
|
||
|
GUI.backgroundColor = Color.black;
|
||
|
}
|
||
|
}
|
||
|
GUILayout.BeginVertical("box");
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
|
||
|
if (GUILayout.Button("Platform Overrides", EditorStyles.toolbarButton))
|
||
|
{
|
||
|
_expandPlatformOverrides = !_expandPlatformOverrides;
|
||
|
}
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
if (_expandPlatformOverrides)
|
||
|
{
|
||
|
int platformIndex = GUILayout.SelectionGrid(_platformIndex, Helper.GetPlatformNames(), 3);
|
||
|
//int platformIndex = GUILayout.Toolbar(_platformIndex, Helper.GetPlatformNames());
|
||
|
|
||
|
if (platformIndex != _platformIndex)
|
||
|
{
|
||
|
_platformIndex = platformIndex;
|
||
|
|
||
|
// We do this to clear the focus, otherwise a focused text field will not change when the Toolbar index changes
|
||
|
EditorGUI.FocusTextInControl("ClearFocus");
|
||
|
}
|
||
|
|
||
|
OnInspectorGUI_PathOverrides();
|
||
|
switch ((Platform)_platformIndex)
|
||
|
{
|
||
|
case Platform.Windows:
|
||
|
OnInspectorGUI_Override_Windows();
|
||
|
break;
|
||
|
case Platform.MacOSX:
|
||
|
OnInspectorGUI_Override_MacOSX();
|
||
|
break;
|
||
|
case Platform.iOS:
|
||
|
OnInspectorGUI_Override_iOS();
|
||
|
break;
|
||
|
case Platform.tvOS:
|
||
|
OnInspectorGUI_Override_tvOS();
|
||
|
break;
|
||
|
case Platform.Android:
|
||
|
OnInspectorGUI_Override_Android();
|
||
|
break;
|
||
|
case Platform.WindowsPhone:
|
||
|
OnInspectorGUI_Override_WindowsPhone();
|
||
|
break;
|
||
|
case Platform.WindowsUWP:
|
||
|
OnInspectorGUI_Override_WindowsUWP();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
GUILayout.EndVertical();
|
||
|
}
|
||
|
|
||
|
void OnInspectorGUI_Preview()
|
||
|
{
|
||
|
MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
|
||
|
//GUILayout.Space(8f);
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = Color.clear;
|
||
|
|
||
|
if (_expandPreview)
|
||
|
{
|
||
|
GUI.color = Color.white;
|
||
|
GUI.backgroundColor = new Color(0.8f, 0.8f, 0.8f, 0.1f);
|
||
|
if (EditorGUIUtility.isProSkin)
|
||
|
{
|
||
|
GUI.backgroundColor = Color.black;
|
||
|
}
|
||
|
}
|
||
|
GUILayout.BeginVertical("box");
|
||
|
GUI.backgroundColor = Color.white;
|
||
|
|
||
|
if (GUILayout.Button("Preview", EditorStyles.toolbarButton))
|
||
|
{
|
||
|
_expandPreview = !_expandPreview;
|
||
|
}
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
if (_expandPreview)
|
||
|
{
|
||
|
GUI.enabled = (media.TextureProducer != null && media.Info.HasVideo());
|
||
|
OnInspectorGUI_VideoPreview(media, media.TextureProducer);
|
||
|
GUI.enabled = true;
|
||
|
|
||
|
GUI.enabled = (media.Control != null && media.Control.CanPlay() && media.isActiveAndEnabled && !EditorApplication.isPaused);
|
||
|
OnInspectorGUI_PlayControls(media.Control, media.Info);
|
||
|
GUI.enabled = true;
|
||
|
}
|
||
|
|
||
|
GUILayout.EndVertical();
|
||
|
}
|
||
|
|
||
|
private static string GetStartFolder(string path, MediaPlayer.FileLocation fileLocation)
|
||
|
{
|
||
|
// Try to resolve based on file path + file location
|
||
|
string result = MediaPlayer.GetFilePath(path, fileLocation);
|
||
|
if (!string.IsNullOrEmpty(result))
|
||
|
{
|
||
|
if (System.IO.File.Exists(result))
|
||
|
{
|
||
|
result = System.IO.Path.GetDirectoryName(result);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!System.IO.Directory.Exists(result))
|
||
|
{
|
||
|
// Just resolve on file location
|
||
|
result = MediaPlayer.GetPath(fileLocation);
|
||
|
}
|
||
|
if (string.IsNullOrEmpty(result))
|
||
|
{
|
||
|
// Fallback
|
||
|
result = Application.streamingAssetsPath;
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
private void GUI_OverridePath(int platformIndex, MediaPlayer.PlatformOptions options)
|
||
|
{
|
||
|
string optionsVarName = MediaPlayer.GetPlatformOptionsVariable((Platform)platformIndex);
|
||
|
|
||
|
SerializedProperty propLocation = serializedObject.FindProperty(optionsVarName + ".pathLocation");
|
||
|
if (propLocation != null)
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(propLocation, new GUIContent("Location"));
|
||
|
}
|
||
|
SerializedProperty propPath = serializedObject.FindProperty(optionsVarName + ".path");
|
||
|
if (propPath != null)
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(propPath, new GUIContent("Video Path"));
|
||
|
}
|
||
|
|
||
|
GUILayout.BeginHorizontal();
|
||
|
OnInspectorGUI_RecentButton(propPath, propLocation);
|
||
|
GUI.color = Color.green;
|
||
|
if (GUILayout.Button("BROWSE"))
|
||
|
{
|
||
|
string result = string.Empty;
|
||
|
MediaPlayer.FileLocation fileLocation = MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder;
|
||
|
string startFolder = GetStartFolder(propPath.stringValue, (MediaPlayer.FileLocation)propLocation.enumValueIndex);
|
||
|
string fullPath = string.Empty;
|
||
|
if (Browse(startFolder, ref result, ref fileLocation, ref fullPath))
|
||
|
{
|
||
|
propPath.stringValue = result;
|
||
|
propLocation.enumValueIndex = (int)fileLocation;
|
||
|
EditorUtility.SetDirty(target); // TODO: not sure if we need this any more. Was put here to help prefabs save values I think
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GUILayout.EndHorizontal();
|
||
|
|
||
|
GUI.color = Color.white;
|
||
|
|
||
|
// Display the file name so it's easy to read and copy to the clipboard
|
||
|
OnInspectorGUI_CopyableFilename(propPath.stringValue);
|
||
|
|
||
|
if (GUI.enabled)
|
||
|
{
|
||
|
ShowFileWarningMessages(propPath.stringValue, (MediaPlayer.FileLocation)propLocation.enumValueIndex, false, (Platform)platformIndex);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_PathOverrides()
|
||
|
{
|
||
|
MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
|
||
|
MediaPlayer.PlatformOptions options = media.GetPlatformOptions((Platform)_platformIndex);
|
||
|
if (options != null)
|
||
|
{
|
||
|
// TODO: remove these
|
||
|
//media.m_platformVideoPathOverride = Helper.EnsureArraySize(media.m_platformVideoPathOverride, false, (int)Platform.Count);
|
||
|
//media.m_platformVideoPath = Helper.EnsureArraySize(media.m_platformVideoPath, string.Empty, (int)Platform.Count);
|
||
|
//media.m_platformVideoLocation = Helper.EnsureArraySize(media.m_platformVideoLocation, MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder, (int)Platform.Count);
|
||
|
|
||
|
string optionsVarName = MediaPlayer.GetPlatformOptionsVariable((Platform)_platformIndex);
|
||
|
SerializedProperty propOverridePath = serializedObject.FindProperty(optionsVarName + ".overridePath");
|
||
|
if (propOverridePath != null)
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(propOverridePath, new GUIContent("Override Path"));
|
||
|
}
|
||
|
|
||
|
if (propOverridePath.boolValue)
|
||
|
{
|
||
|
//GUI.enabled = propOverridePath.boolValue;
|
||
|
GUI_OverridePath(_platformIndex, options);
|
||
|
//GUI.enabled = true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
private void OnInspectorGUI_PathOverrides()
|
||
|
{
|
||
|
MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
|
||
|
media.m_platformVideoPathOverride = Helper.EnsureArraySize(media.m_platformVideoPathOverride, false, (int)Platform.Count);
|
||
|
media.m_platformVideoPath = Helper.EnsureArraySize(media.m_platformVideoPath, string.Empty, (int)Platform.Count);
|
||
|
media.m_platformVideoLocation = Helper.EnsureArraySize(media.m_platformVideoLocation, MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder, (int)Platform.Count);
|
||
|
|
||
|
bool newOverride = EditorGUILayout.Toggle("Override Path", media.m_platformVideoPathOverride[_platformIndex]);
|
||
|
|
||
|
if (newOverride != media.m_platformVideoPathOverride[_platformIndex])
|
||
|
{
|
||
|
media.m_platformVideoPathOverride[_platformIndex] = newOverride;
|
||
|
EditorUtility.SetDirty(target);
|
||
|
}
|
||
|
|
||
|
GUI.enabled = media.m_platformVideoPathOverride[_platformIndex];
|
||
|
GUI_OverridePath(_platformIndex);
|
||
|
GUI.enabled = true;
|
||
|
}*/
|
||
|
|
||
|
private void OnInspectorGUI_Override_Windows()
|
||
|
{
|
||
|
//MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
//MediaPlayer.OptionsWindows options = media._optionsWindows;
|
||
|
|
||
|
GUILayout.Space(8f);
|
||
|
|
||
|
string optionsVarName = MediaPlayer.GetPlatformOptionsVariable((Platform)_platformIndex);
|
||
|
SerializedProperty propForceDirectShow = serializedObject.FindProperty(optionsVarName + ".forceDirectShowApi");
|
||
|
if (propForceDirectShow != null)
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(propForceDirectShow, new GUIContent("Force DirectShow", "Only use DirectShow API and ignore Media Foundation API"));
|
||
|
}
|
||
|
|
||
|
if (propForceDirectShow.boolValue)
|
||
|
{
|
||
|
SerializedProperty propForceAudioOutputDeviceName = serializedObject.FindProperty(optionsVarName + ".forceAudioOutputDeviceName");
|
||
|
if (propForceAudioOutputDeviceName != null)
|
||
|
{
|
||
|
EditorGUILayout.PropertyField(propForceAudioOutputDeviceName, new GUIContent("Force Audio Output Device Name", "Useful for VR when you need to output to the VR audio device"));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_Override_MacOSX()
|
||
|
{
|
||
|
//MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
//MediaPlayer.OptionsMacOSX options = media._optionsMacOSX;
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_Override_iOS()
|
||
|
{
|
||
|
//MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
//MediaPlayer.OptionsIOS options = media._optionsIOS;
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_Override_tvOS()
|
||
|
{
|
||
|
//MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
//MediaPlayer.OptionsTVOS options = media._optionsTVOS;
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_Override_Android()
|
||
|
{
|
||
|
//MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
//MediaPlayer.OptionsAndroid options = media._optionsAndroid;
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_Override_WindowsPhone()
|
||
|
{
|
||
|
//MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
//MediaPlayer.OptionsWindowsPhone options = media._optionsWindowsPhone;
|
||
|
}
|
||
|
|
||
|
private void OnInspectorGUI_Override_WindowsUWP()
|
||
|
{
|
||
|
//MediaPlayer media = (this.target) as MediaPlayer;
|
||
|
//MediaPlayer.OptionsWindowsUWP options = media._optionsWindowsUWP;
|
||
|
}
|
||
|
|
||
|
private static bool Browse(string startPath, ref string filePath, ref MediaPlayer.FileLocation fileLocation, ref string fullPath)
|
||
|
{
|
||
|
bool result = false;
|
||
|
#if UNITY_EDITOR_OSX
|
||
|
string extensions = "mp4,m4v,mov,avi";
|
||
|
extensions += ",mp3,m4a,aac,ac3,au,aiff,wav";
|
||
|
#else
|
||
|
string extensions = "Media Files;*.mp4;*.mov;*.m4v;*.avi;*.mkv;*.ts;*.webm;*.flv;*.vob;*.ogg;*.ogv;*.mpg;*.wmv;*.3gp";
|
||
|
extensions += ";Audio Files;*wav;*.mp3;*.mp2;*.m4a;*.wma;*.aac;*.au;*.flac";
|
||
|
#endif
|
||
|
string path = UnityEditor.EditorUtility.OpenFilePanel("Browse Video File", startPath, extensions);
|
||
|
if (!string.IsNullOrEmpty(path) && !path.EndsWith(".meta"))
|
||
|
{
|
||
|
fullPath = path;
|
||
|
GetRelativeLocationFromPath(path, ref filePath, ref fileLocation);
|
||
|
result = true;
|
||
|
}
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
private static void GetRelativeLocationFromPath(string path, ref string filePath, ref MediaPlayer.FileLocation fileLocation)
|
||
|
{
|
||
|
string projectRoot = System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath, ".."));
|
||
|
projectRoot = projectRoot.Replace('\\', '/');
|
||
|
|
||
|
if (path.StartsWith(projectRoot))
|
||
|
{
|
||
|
if (path.StartsWith(Application.streamingAssetsPath))
|
||
|
{
|
||
|
// Must be StreamingAssets relative path
|
||
|
filePath = GetPathRelativeTo(Application.streamingAssetsPath, path);
|
||
|
fileLocation = MediaPlayer.FileLocation.RelativeToStreamingAssetsFolder;
|
||
|
}
|
||
|
else if (path.StartsWith(Application.dataPath))
|
||
|
{
|
||
|
// Must be Assets relative path
|
||
|
filePath = GetPathRelativeTo(Application.dataPath, path);
|
||
|
fileLocation = MediaPlayer.FileLocation.RelativeToDataFolder;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Must be project relative path
|
||
|
filePath = GetPathRelativeTo(projectRoot, path);
|
||
|
fileLocation = MediaPlayer.FileLocation.RelativeToProjectFolder;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Must be persistant data
|
||
|
if (path.StartsWith(Application.persistentDataPath))
|
||
|
{
|
||
|
filePath = GetPathRelativeTo(Application.persistentDataPath, path);
|
||
|
fileLocation = MediaPlayer.FileLocation.RelativeToPeristentDataFolder;
|
||
|
}
|
||
|
|
||
|
// Must be absolute path
|
||
|
filePath = path;
|
||
|
fileLocation = MediaPlayer.FileLocation.AbsolutePathOrURL;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|