MediaPlayerEditor.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. #define AVPROVIDEO_SUPPORT_LIVEEDITMODE
  2. using UnityEngine;
  3. using UnityEditor;
  4. using System.Collections.Generic;
  5. //-----------------------------------------------------------------------------
  6. // Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. namespace RenderHeads.Media.AVProVideo.Editor
  9. {
  10. /// <summary>
  11. /// Editor for the MediaPlayer component
  12. /// </summary>
  13. [CanEditMultipleObjects]
  14. [CustomEditor(typeof(MediaPlayer))]
  15. public partial class MediaPlayerEditor : UnityEditor.Editor
  16. {
  17. internal const string SettingsPrefix = "AVProVideo-MediaPlayerEditor-";
  18. private SerializedProperty _propAutoOpen;
  19. private SerializedProperty _propAutoStart;
  20. private SerializedProperty _propLoop;
  21. private SerializedProperty _propRate;
  22. private SerializedProperty _propPersistent;
  23. private SerializedProperty _propFilter;
  24. private SerializedProperty _propWrap;
  25. private SerializedProperty _propAniso;
  26. #if AVPRO_FEATURE_VIDEORESOLVE
  27. private SerializedProperty _propUseVideoResolve;
  28. private SerializedProperty _propVideoResolve;
  29. private SerializedProperty _propVideoResolveOptions;
  30. #endif
  31. private SerializedProperty _propResample;
  32. private SerializedProperty _propResampleMode;
  33. private SerializedProperty _propResampleBufferSize;
  34. private SerializedProperty _propVideoMapping;
  35. private SerializedProperty _propForceFileFormat;
  36. private SerializedProperty _propFallbackMediaHints;
  37. private static Texture2D _icon;
  38. private static bool _isTrialVersion = false;
  39. private static GUIStyle _styleSectionBox = null;
  40. private AnimCollapseSection _sectionMediaInfo;
  41. private AnimCollapseSection _sectionDebug;
  42. private AnimCollapseSection _sectionSettings;
  43. private AnimCollapseSection _sectionAboutHelp;
  44. private List<AnimCollapseSection> _settingSections = new List<AnimCollapseSection>(16);
  45. private List<AnimCollapseSection> _platformSections = new List<AnimCollapseSection>(8);
  46. [MenuItem("GameObject/Video/AVPro Video - Media Player", false, 100)]
  47. public static void CreateMediaPlayerEditor()
  48. {
  49. GameObject go = new GameObject("MediaPlayer");
  50. go.AddComponent<MediaPlayer>();
  51. Selection.activeGameObject = go;
  52. }
  53. [MenuItem("GameObject/Video/AVPro Video - Media Player with Unity Audio", false, 101)]
  54. public static void CreateMediaPlayerWithUnityAudioEditor()
  55. {
  56. GameObject go = new GameObject("MediaPlayer");
  57. go.AddComponent<MediaPlayer>();
  58. go.AddComponent<AudioSource>();
  59. AudioOutput ao = go.AddComponent<AudioOutput>();
  60. // Move the AudioOutput component above the AudioSource so that it acts as the audio generator
  61. UnityEditorInternal.ComponentUtility.MoveComponentUp(ao);
  62. Selection.activeGameObject = go;
  63. }
  64. private static void LoadSettings()
  65. {
  66. _platformIndex = EditorPrefs.GetInt(SettingsPrefix + "PlatformIndex", -1);
  67. _showAlpha = EditorPrefs.GetBool(SettingsPrefix + "ShowAlphaChannel", false);
  68. _showPreview = EditorPrefs.GetBool(SettingsPrefix + "ShowPreview", true);
  69. _allowDeveloperMode = EditorPrefs.GetBool(SettingsPrefix + "AllowDeveloperMode", false);
  70. _HTTPHeadersToggle = EditorPrefs.GetBool(SettingsPrefix + "HTTPHeadersToggle", false);
  71. RecentItems.Load();
  72. }
  73. private void SaveSettings()
  74. {
  75. _sectionMediaInfo.Save();
  76. _sectionDebug.Save();
  77. _sectionSettings.Save();
  78. _sectionAboutHelp.Save();
  79. foreach (AnimCollapseSection section in _settingSections)
  80. {
  81. section.Save();
  82. }
  83. foreach (AnimCollapseSection section in _platformSections)
  84. {
  85. section.Save();
  86. }
  87. _sectionDevModeState.Save();
  88. _sectionDevModeTexture.Save();
  89. _sectionDevModePlaybackQuality.Save();
  90. _sectionDevModeHapNotchLCDecoder.Save();
  91. _sectionDevModeBufferedFrames.Save();
  92. EditorPrefs.SetInt(SettingsPrefix + "PlatformIndex", _platformIndex);
  93. EditorPrefs.SetBool(SettingsPrefix + "ShowAlphaChannel", _showAlpha);
  94. EditorPrefs.SetBool(SettingsPrefix + "ShowPreview", _showPreview);
  95. EditorPrefs.SetBool(SettingsPrefix + "AllowDeveloperMode", _allowDeveloperMode);
  96. EditorPrefs.SetBool(SettingsPrefix + "HTTPHeadersToggle", _HTTPHeadersToggle);
  97. RecentItems.Save();
  98. }
  99. //[MenuItem("RenderHeads/AVPro Video/Reset Settings", false, 101)]
  100. internal static void DeleteSettings()
  101. {
  102. EditorPrefs.DeleteKey(SettingsPrefix + "PlatformIndex");
  103. EditorPrefs.DeleteKey(SettingsPrefix + "ShowAlphaChannel");
  104. EditorPrefs.DeleteKey(SettingsPrefix + "AllowDeveloperMode");
  105. EditorPrefs.DeleteKey(SettingsPrefix + "HTTPHeadersToggle");
  106. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Media"));
  107. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Debug"));
  108. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Settings"));
  109. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("About / Help"));
  110. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Source"));
  111. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Main"));
  112. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Audio"));
  113. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Visual"));
  114. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Network"));
  115. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Media"));
  116. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Subtitles"));
  117. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Events"));
  118. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Platform Specific"));
  119. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName("Global"));
  120. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName(GetPlatformButtonContent(Platform.Windows).text));
  121. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName(GetPlatformButtonContent(Platform.MacOSX).text));
  122. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName(GetPlatformButtonContent(Platform.Android).text));
  123. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName(GetPlatformButtonContent(Platform.iOS).text));
  124. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName(GetPlatformButtonContent(Platform.tvOS).text));
  125. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName(GetPlatformButtonContent(Platform.WindowsUWP).text));
  126. EditorPrefs.DeleteKey(AnimCollapseSection.GetPrefName(GetPlatformButtonContent(Platform.WebGL).text));
  127. }
  128. private void CreateSections()
  129. {
  130. const float colorSaturation = 0.66f;
  131. Color mediaInfoColor = Color.HSVToRGB(0.55f, colorSaturation, 1f);
  132. Color sourceColor = Color.HSVToRGB(0.4f, colorSaturation, 1f);
  133. Color platformSpecificColor = Color.HSVToRGB(0.85f, colorSaturation, 1f);
  134. Color platformColor = platformSpecificColor;
  135. if (EditorGUIUtility.isProSkin)
  136. {
  137. platformColor *= 0.66f;
  138. }
  139. _sectionMediaInfo = new AnimCollapseSection("Media Info", false, false, OnInspectorGUI_MediaInfo, this, mediaInfoColor);
  140. _sectionDebug = new AnimCollapseSection("Debug", false, true, OnInspectorGUI_Debug, this, Color.white);
  141. _sectionSettings = new AnimCollapseSection("Settings", false, true, OnInspectorGUI_Settings, this, Color.white);
  142. _sectionAboutHelp = new AnimCollapseSection("About / Help", false, false, OnInspectorGUI_About, this, Color.white);
  143. _settingSections.Clear();
  144. _settingSections.Add(new AnimCollapseSection("Source", false, true, OnInspectorGUI_Source, this, sourceColor));
  145. _settingSections.Add(new AnimCollapseSection("Main", false, false, OnInspectorGUI_Main, this, Color.white));
  146. _settingSections.Add(new AnimCollapseSection("Audio", false, false, OnInspectorGUI_Audio, this, Color.white));
  147. _settingSections.Add(new AnimCollapseSection("Visual", true, false, OnInspectorGUI_Visual, this, Color.white));
  148. //_settingSections.Add(new AnimCollapseSection("Network", true, false, OnInspectorGUI_Network, this, Color.white));
  149. _settingSections.Add(new AnimCollapseSection("Subtitles", true, false, OnInspectorGUI_Subtitles, this, Color.white));
  150. _settingSections.Add(new AnimCollapseSection("Events", true, false, OnInspectorGUI_Events, this, Color.white));
  151. _settingSections.Add(new AnimCollapseSection("Platform Specific", true, false, OnInspectorGUI_PlatformOverrides, this, platformSpecificColor));
  152. _settingSections.Add(new AnimCollapseSection("Global", true, false, OnInspectorGUI_GlobalSettings, this, Color.white));
  153. _platformSections.Clear();
  154. _platformSections.Add(new AnimCollapseSection(GetPlatformButtonContent(Platform.Windows), true, false, OnInspectorGUI_Override_Windows, this, platformColor, _platformSections));
  155. _platformSections.Add(new AnimCollapseSection(GetPlatformButtonContent(Platform.MacOSX), true, false, OnInspectorGUI_Override_MacOSX, this, platformColor, _platformSections));
  156. _platformSections.Add(new AnimCollapseSection(GetPlatformButtonContent(Platform.Android), true, false, OnInspectorGUI_Override_Android, this, platformColor, _platformSections));
  157. _platformSections.Add(new AnimCollapseSection(GetPlatformButtonContent(Platform.iOS), true, false, OnInspectorGUI_Override_iOS, this, platformColor, _platformSections));
  158. _platformSections.Add(new AnimCollapseSection(GetPlatformButtonContent(Platform.tvOS), true, false, OnInspectorGUI_Override_tvOS, this, platformColor, _platformSections));
  159. _platformSections.Add(new AnimCollapseSection(GetPlatformButtonContent(Platform.WindowsUWP), true, false, OnInspectorGUI_Override_WindowsUWP, this, platformColor, _platformSections));
  160. _platformSections.Add(new AnimCollapseSection(GetPlatformButtonContent(Platform.WebGL), true, false, OnInspectorGUI_Override_WebGL, this, platformColor, _platformSections));
  161. _sectionDevModeState = new AnimCollapseSection("State", false, false, OnInspectorGUI_DevMode_State, this, Color.white);
  162. _sectionDevModeTexture = new AnimCollapseSection("Texture", false, false, OnInspectorGUI_DevMode_Texture, this, Color.white);
  163. _sectionDevModePlaybackQuality = new AnimCollapseSection("Presentation Quality", false, false, OnInspectorGUI_DevMode_PresentationQuality, this, Color.white);
  164. _sectionDevModeHapNotchLCDecoder = new AnimCollapseSection("Hap/NotchLC Decoder", false, false, OnInspectorGUI_DevMode_HapNotchLCDecoder, this, Color.white);
  165. _sectionDevModeBufferedFrames = new AnimCollapseSection("Buffers", false, false, OnInspectorGUI_DevMode_BufferedFrames, this, Color.white);
  166. }
  167. private void ResolveProperties()
  168. {
  169. _propMediaSource = this.CheckFindProperty("_mediaSource");
  170. _propMediaReference = this.CheckFindProperty("_mediaReference");
  171. _propMediaPath = this.CheckFindProperty("_mediaPath");
  172. _propAutoOpen = this.CheckFindProperty("_autoOpen");
  173. _propAutoStart = this.CheckFindProperty("_autoPlayOnStart");
  174. _propLoop = this.CheckFindProperty("_loop");
  175. _propRate = this.CheckFindProperty("_playbackRate");
  176. _propVolume = this.CheckFindProperty("_audioVolume");
  177. _propBalance = this.CheckFindProperty("_audioBalance");
  178. _propMuted = this.CheckFindProperty("_audioMuted");
  179. _propPersistent = this.CheckFindProperty("_persistent");
  180. _propEvents = this.CheckFindProperty("_events");
  181. _propEventMask = this.CheckFindProperty("_eventMask");
  182. _propPauseMediaOnAppPause = this.CheckFindProperty("_pauseMediaOnAppPause");
  183. _propPlayMediaOnAppUnpause = this.CheckFindProperty("_playMediaOnAppUnpause");
  184. _propFilter = this.CheckFindProperty("_textureFilterMode");
  185. _propWrap = this.CheckFindProperty("_textureWrapMode");
  186. _propAniso = this.CheckFindProperty("_textureAnisoLevel");
  187. #if AVPRO_FEATURE_VIDEORESOLVE
  188. _propUseVideoResolve = this.CheckFindProperty("_useVideoResolve");
  189. _propVideoResolve = this.CheckFindProperty("_videoResolve");
  190. _propVideoResolveOptions = this.CheckFindProperty("_videoResolveOptions");
  191. #endif
  192. _propVideoMapping = this.CheckFindProperty("_videoMapping");
  193. _propForceFileFormat = this.CheckFindProperty("_forceFileFormat");
  194. _propFallbackMediaHints = this.CheckFindProperty("_fallbackMediaHints");
  195. _propSubtitles = this.CheckFindProperty("_sideloadSubtitles");
  196. _propSubtitlePath = this.CheckFindProperty("_subtitlePath");
  197. _propResample = this.CheckFindProperty("_useResampler");
  198. _propResampleMode = this.CheckFindProperty("_resampleMode");
  199. _propResampleBufferSize = this.CheckFindProperty("_resampleBufferSize");
  200. _propAudioHeadTransform = this.CheckFindProperty("_audioHeadTransform");
  201. _propAudioEnableFocus = this.CheckFindProperty("_audioFocusEnabled");
  202. _propAudioFocusOffLevelDB = this.CheckFindProperty("_audioFocusOffLevelDB");
  203. _propAudioFocusWidthDegrees = this.CheckFindProperty("_audioFocusWidthDegrees");
  204. _propAudioFocusTransform = this.CheckFindProperty("_audioFocusTransform");
  205. }
  206. private static Texture GetPlatformIcon(Platform platform)
  207. {
  208. string iconName = string.Empty;
  209. switch (platform)
  210. {
  211. case Platform.Windows:
  212. case Platform.MacOSX:
  213. iconName = "BuildSettings.Standalone.Small";
  214. break;
  215. case Platform.Android:
  216. iconName = "BuildSettings.Android.Small";
  217. break;
  218. case Platform.iOS:
  219. iconName = "BuildSettings.iPhone.Small";
  220. break;
  221. case Platform.tvOS:
  222. iconName = "BuildSettings.tvOS.Small";
  223. break;
  224. case Platform.WindowsUWP:
  225. iconName = "BuildSettings.Metro.Small";
  226. break;
  227. case Platform.WebGL:
  228. iconName = "BuildSettings.WebGL.Small";
  229. break;
  230. }
  231. Texture iconTexture = null;
  232. if (!string.IsNullOrEmpty(iconName))
  233. {
  234. iconTexture = EditorGUIUtility.IconContent(iconName).image;
  235. }
  236. return iconTexture;
  237. }
  238. private static GUIContent GetPlatformButtonContent(Platform platform)
  239. {
  240. return new GUIContent(Helper.GetPlatformName(platform), GetPlatformIcon(platform));
  241. }
  242. private void FixRogueEditorBug()
  243. {
  244. // NOTE: There seems to be a bug in Unity where the editor script will call OnEnable and OnDisable twice.
  245. // This is resolved by setting the Window Layout mode to Default.
  246. // It causes a problem (at least in Unity 2020.1.11) where the System.Action invocations (usd by AnimCollapseSection)
  247. // seem to be in a different 'this' context and so their pointers to serializedObject is not the same, resulting in
  248. // properties modified not marking the serialisedObject as dirty. To get around this issue we use this static bool
  249. // so that OnEnable can only be called once.
  250. // https://answers.unity.com/questions/1216599/custom-editor-gets-created-multiple-times-and-rece.html
  251. var remainingBuggedEditors = FindObjectsOfType<MediaPlayerEditor>();
  252. foreach(var editor in remainingBuggedEditors)
  253. {
  254. if (editor == this)
  255. {
  256. continue;
  257. }
  258. DestroyImmediate(editor);
  259. }
  260. }
  261. private void OnEnable()
  262. {
  263. FixRogueEditorBug();
  264. CreateSections();
  265. LoadSettings();
  266. _isTrialVersion = IsTrialVersion();
  267. if (_platformNames == null)
  268. {
  269. _platformNames = new GUIContent[]
  270. {
  271. GetPlatformButtonContent(Platform.Windows),
  272. GetPlatformButtonContent(Platform.MacOSX),
  273. GetPlatformButtonContent(Platform.iOS),
  274. GetPlatformButtonContent(Platform.tvOS),
  275. GetPlatformButtonContent(Platform.Android),
  276. GetPlatformButtonContent(Platform.WindowsUWP),
  277. GetPlatformButtonContent(Platform.WebGL)
  278. };
  279. }
  280. ResolveProperties();
  281. }
  282. private void OnDisable()
  283. {
  284. ClosePreview();
  285. SaveSettings();
  286. if (!Application.isPlaying)
  287. {
  288. // NOTE: For some reason when transitioning into Play mode, Dispose() is not called in the MediaPlayer if
  289. // it was playing before the transition because all members are reset to null. So we must force this
  290. // dispose of all resources to handle this case.
  291. // Sadly it means we can't keep persistent playback in the inspector when it loses focus, but
  292. // hopefully we can find a way to achieve this in the future
  293. /*if (EditorApplication.isPlayingOrWillChangePlaymode)
  294. {
  295. // NOTE: This seems to work for the above issue, but
  296. // we'd need to move it to the global event for when the play state changes
  297. MediaPlayer.EditorAllPlayersDispose();
  298. }*/
  299. foreach (MediaPlayer player in this.targets)
  300. {
  301. player.ForceDispose();
  302. }
  303. }
  304. }
  305. private void CreateStyles()
  306. {
  307. if (_styleSectionBox == null)
  308. {
  309. _styleSectionBox = new GUIStyle(GUI.skin.box);
  310. if (!EditorGUIUtility.isProSkin)
  311. {
  312. _styleSectionBox = new GUIStyle(GUI.skin.box);
  313. //_styleSectionBox.normal.background = Texture2D.redTexture;
  314. }
  315. }
  316. _iconPlayButton = EditorGUIUtility.IconContent("d_PlayButton");
  317. _iconPauseButton = EditorGUIUtility.IconContent("d_PauseButton");
  318. _iconSceneViewAudio = EditorGUIUtility.IconContent("d_SceneViewAudio");
  319. _iconProject = EditorGUIUtility.IconContent("d_Project");
  320. _iconRotateTool = EditorGUIUtility.IconContent("d_RotateTool");
  321. AnimCollapseSection.CreateStyles();
  322. }
  323. public override void OnInspectorGUI()
  324. {
  325. MediaPlayer media = (this.target) as MediaPlayer;
  326. // NOTE: It is important that serializedObject.Update() is called before media.EditorUpdate()
  327. // as otherwise the serializedPropertys are not correctly detected as modified
  328. serializedObject.Update();
  329. #if AVPROVIDEO_SUPPORT_LIVEEDITMODE
  330. bool isPlayingInEditor = false;
  331. // Update only during the layout event so that nothing updates for the render event
  332. if (!Application.isPlaying && Event.current.type == EventType.Layout)
  333. {
  334. isPlayingInEditor = media.EditorUpdate();
  335. }
  336. #endif
  337. if (media == null || _propMediaPath == null)
  338. {
  339. return;
  340. }
  341. CreateStyles();
  342. _icon = GetIcon(_icon);
  343. ShowImportantMessages();
  344. if (media != null)
  345. {
  346. OnInspectorGUI_Player(media, media.TextureProducer);
  347. }
  348. AnimCollapseSection.Show(_sectionMediaInfo);
  349. if (_allowDeveloperMode)
  350. {
  351. AnimCollapseSection.Show(_sectionDebug);
  352. }
  353. AnimCollapseSection.Show(_sectionSettings);
  354. if (serializedObject.ApplyModifiedProperties())
  355. {
  356. EditorUtility.SetDirty(target);
  357. }
  358. AnimCollapseSection.Show(_sectionAboutHelp);
  359. #if AVPROVIDEO_SUPPORT_LIVEEDITMODE
  360. if (isPlayingInEditor)
  361. {
  362. GL.InvalidateState();
  363. // NOTE: there seems to be a bug in Unity (2019.3.13) where if you don't have
  364. // GL.sRGBWrite = true and then call RepaintAllViews() it makes the current Inspector
  365. // background turn black. This only happens when using D3D12
  366. // UPDATE: this is happening in Unity 2019.4.15 as well, and in D3D11 mode. It only
  367. // happens when loading a video via the Recent Menu.
  368. bool originalSRGBWrite = GL.sRGBWrite;
  369. GL.sRGBWrite = true;
  370. //this.Repaint();
  371. UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
  372. GL.sRGBWrite = originalSRGBWrite;
  373. }
  374. // TODO: OnDisable - stop the video if it's playing (and unload it?)
  375. #endif
  376. }
  377. private void OnInspectorGUI_Settings()
  378. {
  379. foreach (AnimCollapseSection section in _settingSections)
  380. {
  381. AnimCollapseSection.Show(section, indentLevel:1);
  382. }
  383. }
  384. private void ShowSupportWindowButton()
  385. {
  386. //GUI.backgroundColor = new Color(0.96f, 0.25f, 0.47f);
  387. //if (GUILayout.Button("◄ AVPro Video ►\nHelp & Support"))
  388. if (GUILayout.Button("Click here for \nHelp & Support"))
  389. {
  390. SupportWindow.Init();
  391. }
  392. //GUI.backgroundColor = Color.white;
  393. }
  394. private void ShowImportantMessages()
  395. {
  396. // Describe the watermark for trial version
  397. if (_isTrialVersion)
  398. {
  399. string message = string.Empty;
  400. if (Application.isPlaying)
  401. {
  402. #if UNITY_EDITOR_WIN
  403. MediaPlayer media = (this.target) as MediaPlayer;
  404. message = "The watermark is the horizontal bar that moves vertically and the small 'AVPRO TRIAL' text.";
  405. if (media.Info != null && media.Info.GetPlayerDescription().Contains("MF-MediaEngine-Hardware"))
  406. {
  407. message = "The watermark is the RenderHeads logo that moves around the image.";
  408. }
  409. #elif UNITY_EDITOR_OSX
  410. message = "The RenderHeads logo is the watermark.";
  411. #endif
  412. }
  413. EditorHelper.IMGUI.BeginWarningTextBox("AVPRO VIDEO - TRIAL WATERMARK", message, Color.yellow, Color.yellow, Color.white);
  414. if (GUILayout.Button("Purchase"))
  415. {
  416. Application.OpenURL(LinkPurchase);
  417. }
  418. EditorHelper.IMGUI.EndWarningTextBox();
  419. }
  420. // Warning about not using multi-threaded rendering
  421. {
  422. bool showWarningMT = false;
  423. if (/*EditorUserBuildSettings.selectedBuildTargetGroup == BuildTargetGroup.iOS ||
  424. EditorUserBuildSettings.selectedBuildTargetGroup == BuildTargetGroup.tvOS ||*/
  425. EditorUserBuildSettings.selectedBuildTargetGroup == BuildTargetGroup.Android)
  426. {
  427. #if UNITY_2017_2_OR_NEWER
  428. showWarningMT = !UnityEditor.PlayerSettings.GetMobileMTRendering(BuildTargetGroup.Android);
  429. #else
  430. showWarningMT = !UnityEditor.PlayerSettings.mobileMTRendering;
  431. #endif
  432. }
  433. /*if (EditorUserBuildSettings.selectedBuildTargetGroup == BuildTargetGroup.WSA)
  434. {
  435. }*/
  436. if (showWarningMT)
  437. {
  438. EditorHelper.IMGUI.WarningTextBox("Performance Warning", "Deploying to Android with multi-threaded rendering disabled is not recommended. Enable multi-threaded rendering in the Player Settings > Other Settings panel.", Color.yellow, Color.yellow, Color.white);
  439. }
  440. }
  441. #if !UNITY_2019_3_OR_NEWER
  442. if (SystemInfo.graphicsDeviceType == UnityEngine.Rendering.GraphicsDeviceType.Direct3D12)
  443. {
  444. EditorHelper.IMGUI.WarningTextBox("Compatibility Warning", "Direct3D 12 is not supported until Unity 2019.3", Color.yellow, Color.yellow, Color.white);
  445. }
  446. #endif
  447. // Warn about using Vulkan graphics API
  448. #if UNITY_2018_1_OR_NEWER
  449. {
  450. if (EditorUserBuildSettings.selectedBuildTargetGroup == BuildTargetGroup.Android)
  451. {
  452. bool showWarningVulkan = false;
  453. if (!UnityEditor.PlayerSettings.GetUseDefaultGraphicsAPIs(BuildTarget.Android))
  454. {
  455. UnityEngine.Rendering.GraphicsDeviceType[] devices = UnityEditor.PlayerSettings.GetGraphicsAPIs(BuildTarget.Android);
  456. foreach (UnityEngine.Rendering.GraphicsDeviceType device in devices)
  457. {
  458. if (device == UnityEngine.Rendering.GraphicsDeviceType.Vulkan)
  459. {
  460. showWarningVulkan = true;
  461. break;
  462. }
  463. }
  464. }
  465. if (showWarningVulkan)
  466. {
  467. EditorHelper.IMGUI.WarningTextBox("Compatibility Warning", "Vulkan graphics API is not supported. Please go to Player Settings > Android > Auto Graphics API and remove Vulkan from the list. Only OpenGL 2.0 and 3.0 are supported on Android.", Color.yellow, Color.yellow, Color.white);
  468. }
  469. }
  470. }
  471. #endif
  472. }
  473. private void OnInspectorGUI_Main()
  474. {
  475. /////////////////// STARTUP FIELDS
  476. EditorGUILayout.BeginVertical(_styleSectionBox);
  477. GUILayout.Label("Startup", EditorStyles.boldLabel);
  478. EditorGUILayout.PropertyField(_propAutoOpen);
  479. EditorGUILayout.PropertyField(_propAutoStart, new GUIContent("Auto Play"));
  480. EditorGUILayout.EndVertical();
  481. /////////////////// PLAYBACK FIELDS
  482. EditorGUILayout.BeginVertical(GUI.skin.box);
  483. GUILayout.Label("Playback", EditorStyles.boldLabel);
  484. EditorGUI.BeginChangeCheck();
  485. EditorGUILayout.PropertyField(_propLoop);
  486. if (EditorGUI.EndChangeCheck())
  487. {
  488. Undo.RecordObject(target, "Loop");
  489. foreach (MediaPlayer player in this.targets)
  490. {
  491. player.Loop = _propLoop.boolValue;
  492. }
  493. }
  494. EditorGUI.BeginChangeCheck();
  495. EditorGUILayout.PropertyField(_propRate);
  496. if (EditorGUI.EndChangeCheck())
  497. {
  498. Undo.RecordObject(target, "PlaybackRate");
  499. foreach (MediaPlayer player in this.targets)
  500. {
  501. player.PlaybackRate = _propRate.floatValue;
  502. }
  503. }
  504. EditorGUILayout.EndVertical();
  505. EditorGUILayout.BeginVertical(GUI.skin.box);
  506. GUILayout.Label("Other", EditorStyles.boldLabel);
  507. EditorGUILayout.PropertyField(_propPersistent, new GUIContent("Persistent", "Use DontDestroyOnLoad so this object isn't destroyed between level loads"));
  508. if (_propForceFileFormat != null)
  509. {
  510. GUIContent label = new GUIContent("Force File Format", "Override automatic format detection when using non-standard file extensions");
  511. _propForceFileFormat.enumValueIndex = EditorGUILayout.Popup(label, _propForceFileFormat.enumValueIndex, _fileFormatGuiNames);
  512. }
  513. EditorGUILayout.EndVertical();
  514. }
  515. private void OnInspectorGUI_Visual()
  516. {
  517. #if AVPRO_FEATURE_VIDEORESOLVE
  518. {
  519. EditorGUILayout.BeginVertical(GUI.skin.box);
  520. GUILayout.Label("Resolve", EditorStyles.boldLabel);
  521. EditorGUI.BeginChangeCheck();
  522. EditorGUILayout.PropertyField(_propUseVideoResolve);
  523. if (EditorGUI.EndChangeCheck())
  524. {
  525. Undo.RecordObject(target, "UseVideoResolve");
  526. foreach (MediaPlayer player in this.targets)
  527. {
  528. player.UseVideoResolve = _propUseVideoResolve.boolValue;
  529. }
  530. }
  531. if (_propUseVideoResolve.boolValue)
  532. {
  533. EditorGUILayout.PropertyField(_propVideoResolve);
  534. /*EditorGUI.indentLevel++;
  535. EditorGUILayout.PropertyField(_propVideoResolveOptions, true);
  536. EditorGUI.indentLevel--;*/
  537. }
  538. GUILayout.EndVertical();
  539. }
  540. #endif
  541. EditorGUILayout.BeginVertical(GUI.skin.box);
  542. GUILayout.Label("Texture", EditorStyles.boldLabel);
  543. EditorGUI.BeginChangeCheck();
  544. EditorGUILayout.PropertyField(_propFilter, new GUIContent("Filter"));
  545. if (EditorGUI.EndChangeCheck())
  546. {
  547. Undo.RecordObject(target, "TextureFilterMode");
  548. foreach (MediaPlayer player in this.targets)
  549. {
  550. player.TextureFilterMode = (FilterMode)_propFilter.enumValueIndex;
  551. }
  552. }
  553. EditorGUI.BeginChangeCheck();
  554. EditorGUILayout.PropertyField(_propWrap, new GUIContent("Wrap"));
  555. if (EditorGUI.EndChangeCheck())
  556. {
  557. Undo.RecordObject(target, "TextureWrapMode");
  558. foreach (MediaPlayer player in this.targets)
  559. {
  560. player.TextureWrapMode = (TextureWrapMode)_propWrap.enumValueIndex;
  561. }
  562. }
  563. EditorGUI.BeginChangeCheck();
  564. EditorGUILayout.PropertyField(_propAniso, new GUIContent("Aniso"));
  565. if (EditorGUI.EndChangeCheck())
  566. {
  567. Undo.RecordObject(target, "TextureAnisoLevel");
  568. foreach (MediaPlayer player in this.targets)
  569. {
  570. player.TextureAnisoLevel = _propAniso.intValue;
  571. }
  572. }
  573. EditorGUILayout.EndVertical();
  574. EditorGUILayout.BeginVertical(GUI.skin.box);
  575. GUILayout.Label("Layout Mapping", EditorStyles.boldLabel);
  576. EditorGUILayout.PropertyField(_propVideoMapping);
  577. EditorGUILayout.EndVertical();
  578. {
  579. EditorGUILayout.BeginVertical(GUI.skin.box);
  580. GUILayout.Label("Resampler (BETA)", EditorStyles.boldLabel);
  581. EditorGUILayout.PropertyField(_propResample);
  582. EditorGUI.BeginDisabledGroup(!_propResample.boolValue);
  583. EditorGUILayout.PropertyField(_propResampleMode);
  584. EditorGUILayout.PropertyField(_propResampleBufferSize);
  585. EditorGUI.EndDisabledGroup();
  586. EditorGUILayout.EndVertical();
  587. }
  588. }
  589. private static bool IsTrialVersion()
  590. {
  591. string version = GetPluginVersion();
  592. return version.Contains("-trial");
  593. }
  594. //private int _updateFrameCount = -1;
  595. public override bool RequiresConstantRepaint()
  596. {
  597. MediaPlayer media = (this.target) as MediaPlayer;
  598. if (media != null && media.Control != null && media.isActiveAndEnabled && media.Info.GetDuration() > 0.0)
  599. {
  600. if (!media.Info.HasVideo())
  601. {
  602. if (media.Info.HasAudio())
  603. {
  604. return true;
  605. }
  606. }
  607. else if (media.TextureProducer.GetTexture() != null)
  608. {
  609. //int frameCount = media.TextureProducer.GetTextureFrameCount();
  610. //if (_updateFrameCount != frameCount)
  611. {
  612. //_updateFrameCount = frameCount;
  613. return true;
  614. }
  615. }
  616. }
  617. return false;
  618. }
  619. }
  620. }