MediaPlayerEditor_Player.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. using UnityEngine;
  2. using UnityEditor;
  3. //-----------------------------------------------------------------------------
  4. // Copyright 2015-2021 RenderHeads Ltd. All rights reserved.
  5. //-----------------------------------------------------------------------------
  6. namespace RenderHeads.Media.AVProVideo.Editor
  7. {
  8. /// <summary>
  9. /// Editor for the MediaPlayer component
  10. /// </summary>
  11. public partial class MediaPlayerEditor : UnityEditor.Editor
  12. {
  13. private static GUIContent FilePathSplitEllipses = new GUIContent("-");
  14. private static GUIContent _iconPlayButton;
  15. private static GUIContent _iconPauseButton;
  16. private static GUIContent _iconSceneViewAudio;
  17. private static GUIContent _iconProject;
  18. private static GUIContent _iconRotateTool;
  19. private static bool _showAlpha = false;
  20. private static bool _showPreview = false;
  21. private static Material _materialResolve;
  22. private static Material _materialIMGUI;
  23. private static RenderTexture _previewTexture;
  24. private static float _lastTextureRatio = -1f;
  25. private static int _previewTextureFrameCount = -1;
  26. private MediaReference _queuedLoadMediaRef = null;
  27. private bool _queuedToggleShowPreview = false;
  28. private void OnInspectorGUI_MediaInfo()
  29. {
  30. MediaPlayer media = (this.target) as MediaPlayer;
  31. IMediaInfo info = media.Info;
  32. IMediaControl control = media.Control;
  33. ITextTracks textTracks = media.TextTracks;
  34. IAudioTracks audioTracks = media.AudioTracks;
  35. IVideoTracks videoTracks = media.VideoTracks;
  36. if (info != null)
  37. {
  38. if (!info.HasVideo() && !info.HasAudio())// && !info.HasText())
  39. {
  40. GUILayout.Label("No media loaded");
  41. }
  42. else
  43. {
  44. if (info.HasVideo())
  45. {
  46. GUILayout.BeginHorizontal();
  47. {
  48. string dimensionText = string.Format("{0}x{1}@{2:0.##}", info.GetVideoWidth(), info.GetVideoHeight(), info.GetVideoFrameRate());
  49. GUILayout.Label(dimensionText);
  50. GUILayout.FlexibleSpace();
  51. string rateText = "0.00";
  52. if (media.Info != null)
  53. {
  54. rateText = media.Info.GetVideoDisplayRate().ToString("F2");
  55. }
  56. GUILayout.Label(rateText + "FPS");
  57. }
  58. GUILayout.EndHorizontal();
  59. EditorGUILayout.Space();
  60. }
  61. if (info.HasVideo())
  62. {
  63. VideoTracks tracks = videoTracks.GetVideoTracks();
  64. if (tracks.Count > 0)
  65. {
  66. GUILayout.Label("Video Tracks: " + tracks.Count);
  67. foreach (VideoTrack track in tracks)
  68. {
  69. bool isActiveTrack = (track == videoTracks.GetActiveVideoTrack());
  70. GUI.color = isActiveTrack?Color.green:Color.white;
  71. {
  72. if (GUILayout.Button(track.DisplayName))
  73. {
  74. if (isActiveTrack)
  75. {
  76. videoTracks.SetActiveVideoTrack(null);
  77. }
  78. else
  79. {
  80. videoTracks.SetActiveVideoTrack(track);
  81. }
  82. }
  83. }
  84. }
  85. GUI.color = Color.white;
  86. EditorGUILayout.Space();
  87. }
  88. }
  89. if (info.HasAudio())
  90. {
  91. AudioTracks tracks = audioTracks.GetAudioTracks();
  92. if (tracks.Count > 0)
  93. {
  94. GUILayout.Label("Audio Tracks: " + tracks.Count);
  95. foreach (AudioTrack track in tracks)
  96. {
  97. bool isActiveTrack = (track == audioTracks.GetActiveAudioTrack());
  98. GUI.color = isActiveTrack?Color.green:Color.white;
  99. {
  100. if (GUILayout.Button(track.DisplayName))
  101. {
  102. if (isActiveTrack)
  103. {
  104. audioTracks.SetActiveAudioTrack(null);
  105. }
  106. else
  107. {
  108. audioTracks.SetActiveAudioTrack(track);
  109. }
  110. }
  111. }
  112. }
  113. GUI.color = Color.white;
  114. /*int channelCount = control.GetAudioChannelCount();
  115. if (channelCount > 0)
  116. {
  117. GUILayout.Label("Audio Channels: " + channelCount);
  118. AudioChannelMaskFlags audioChannels = control.GetAudioChannelMask();
  119. GUILayout.Label("(" + audioChannels + ")", EditorHelper.IMGUI.GetWordWrappedTextAreaStyle());
  120. }*/
  121. EditorGUILayout.Space();
  122. }
  123. }
  124. {
  125. TextTracks tracks = textTracks.GetTextTracks();
  126. if (tracks.Count > 0)
  127. {
  128. GUILayout.Label("Text Tracks: " + tracks.Count);
  129. foreach (TextTrack track in tracks)
  130. {
  131. bool isActiveTrack = (track == textTracks.GetActiveTextTrack());
  132. GUI.color = isActiveTrack?Color.green:Color.white;
  133. {
  134. if (GUILayout.Button(track.DisplayName))
  135. {
  136. if (isActiveTrack)
  137. {
  138. textTracks.SetActiveTextTrack(null);
  139. }
  140. else
  141. {
  142. textTracks.SetActiveTextTrack(track);
  143. }
  144. }
  145. }
  146. }
  147. GUI.color = Color.white;
  148. if (textTracks.GetActiveTextTrack() != null)
  149. {
  150. string text = string.Empty;
  151. if (textTracks.GetCurrentTextCue() != null)
  152. {
  153. text = textTracks.GetCurrentTextCue().Text;
  154. // Clip the text if it is too long
  155. if (text.Length >= 96)
  156. {
  157. text = string.Format("{0}...({1} chars)", text.Substring(0, 96), text.Length);
  158. }
  159. }
  160. GUILayout.Label(text, EditorHelper.IMGUI.GetWordWrappedTextAreaStyle(), GUILayout.Height(48f));
  161. }
  162. EditorGUILayout.Space();
  163. }
  164. }
  165. }
  166. }
  167. else
  168. {
  169. GUILayout.Label("No media loaded");
  170. }
  171. }
  172. private void ClosePreview()
  173. {
  174. if (_materialResolve)
  175. {
  176. DestroyImmediate(_materialResolve); _materialResolve = null;
  177. }
  178. if (_materialIMGUI)
  179. {
  180. DestroyImmediate(_materialIMGUI); _materialIMGUI = null;
  181. }
  182. if (_previewTexture)
  183. {
  184. RenderTexture.ReleaseTemporary(_previewTexture); _previewTexture = null;
  185. }
  186. }
  187. private void RenderPreview(MediaPlayer media)
  188. {
  189. int textureFrameCount = media.TextureProducer.GetTextureFrameCount();
  190. if (textureFrameCount != _previewTextureFrameCount)
  191. {
  192. _previewTextureFrameCount = textureFrameCount;
  193. if (!_materialResolve)
  194. {
  195. _materialResolve = VideoRender.CreateResolveMaterial( false );
  196. VideoRender.SetupResolveMaterial(_materialResolve, VideoResolveOptions.Create());
  197. }
  198. if (!_materialIMGUI)
  199. {
  200. _materialIMGUI = VideoRender.CreateIMGUIMaterial();
  201. }
  202. VideoRender.SetupMaterialForMedia(_materialResolve, media, -1);
  203. VideoRender.ResolveFlags resolveFlags = (VideoRender.ResolveFlags.ColorspaceSRGB | VideoRender.ResolveFlags.Mipmaps | VideoRender.ResolveFlags.PackedAlpha | VideoRender.ResolveFlags.StereoLeft);
  204. _previewTexture = VideoRender.ResolveVideoToRenderTexture(_materialResolve, _previewTexture, media.TextureProducer, resolveFlags);
  205. }
  206. }
  207. private void DrawCenterCroppedLabel(Rect rect, string text)
  208. {
  209. if (Event.current.type != EventType.Repaint) return;
  210. GUIContent textContent = new GUIContent(text);
  211. Vector2 textSize = GUI.skin.label.CalcSize(textContent);
  212. if (textSize.x > rect.width)
  213. {
  214. float ellipseWidth = GUI.skin.label.CalcSize(FilePathSplitEllipses).x;
  215. // Left
  216. Rect rleft = rect;
  217. rleft.xMax -= (rleft.width / 2f);
  218. rleft.xMax -= (ellipseWidth / 2f);
  219. GUI.Label(rleft, textContent);
  220. // Right
  221. Rect rRight = rect;
  222. rRight.xMin += (rRight.width / 2f);
  223. rRight.xMin += (ellipseWidth / 2f);
  224. GUI.Label(rRight, textContent, EditorHelper.IMGUI.GetRightAlignedLabelStyle());
  225. // Center
  226. Rect rCenter = rect;
  227. rCenter.xMin += (rect.width / 2f) - (ellipseWidth / 2f);
  228. rCenter.xMax -= (rect.width / 2f) - (ellipseWidth / 2f);
  229. GUI.Label(rCenter, FilePathSplitEllipses, EditorHelper.IMGUI.GetCenterAlignedLabelStyle());
  230. }
  231. else
  232. {
  233. GUI.Label(rect, textContent, EditorHelper.IMGUI.GetCenterAlignedLabelStyle());
  234. }
  235. }
  236. private void OnInspectorGUI_Player(MediaPlayer mediaPlayer, ITextureProducer textureSource)
  237. {
  238. EditorGUILayout.BeginVertical(GUI.skin.box);
  239. Rect titleRect = Rect.zero;
  240. // Display filename as title of preview
  241. {
  242. string mediaFileName = string.Empty;
  243. if ((MediaSource)_propMediaSource.enumValueIndex == MediaSource.Path)
  244. {
  245. mediaFileName = mediaPlayer.MediaPath.Path;
  246. }
  247. else if ((MediaSource)_propMediaSource.enumValueIndex == MediaSource.Reference)
  248. {
  249. if (_propMediaReference.objectReferenceValue != null)
  250. {
  251. mediaFileName = ((MediaReference)_propMediaReference.objectReferenceValue).GetCurrentPlatformMediaReference().MediaPath.Path;
  252. }
  253. }
  254. // Display the file name, cropping if necessary
  255. if (!string.IsNullOrEmpty(mediaFileName) &&
  256. (0 > mediaFileName.IndexOfAny(System.IO.Path.GetInvalidPathChars())))
  257. {
  258. string text = System.IO.Path.GetFileName(mediaFileName);
  259. titleRect = GUILayoutUtility.GetRect(GUIContent.none, GUI.skin.label);
  260. // Draw background
  261. GUI.Box(titleRect, GUIContent.none, EditorStyles.toolbarButton);
  262. DrawCenterCroppedLabel(titleRect, text);
  263. }
  264. }
  265. // Toggle preview
  266. if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && Event.current.isMouse)
  267. {
  268. if (titleRect.Contains(Event.current.mousePosition))
  269. {
  270. _queuedToggleShowPreview = true;
  271. }
  272. }
  273. if (_showPreview)
  274. {
  275. Texture texture = EditorGUIUtility.whiteTexture;
  276. float textureRatio = 16f / 9f;
  277. if (_lastTextureRatio > 0f)
  278. {
  279. textureRatio = _lastTextureRatio;
  280. }
  281. if (textureSource != null && textureSource.GetTexture() != null)
  282. {
  283. texture = textureSource.GetTexture();
  284. if (_previewTexture)
  285. {
  286. texture = _previewTexture;
  287. }
  288. _lastTextureRatio = textureRatio = (((float)texture.width / (float)texture.height) * textureSource.GetTexturePixelAspectRatio());
  289. }
  290. // Reserve rectangle for texture
  291. //GUILayout.BeginHorizontal(GUILayout.MaxHeight(Screen.height / 2f), GUILayout.ExpandHeight(true));
  292. //GUILayout.FlexibleSpace();
  293. Rect textureRect;
  294. //textureRect = GUILayoutUtility.GetRect(256f, 256f);
  295. if (texture != EditorGUIUtility.whiteTexture)
  296. {
  297. if (_showAlpha)
  298. {
  299. float rectRatio = textureRatio * 2f;
  300. rectRatio = Mathf.Max(1f, rectRatio);
  301. textureRect = GUILayoutUtility.GetAspectRect(rectRatio, GUILayout.ExpandWidth(true));
  302. }
  303. else
  304. {
  305. //textureRatio *= 2f;
  306. float rectRatio = Mathf.Max(1f, textureRatio);
  307. textureRect = GUILayoutUtility.GetAspectRect(rectRatio, GUILayout.ExpandWidth(true), GUILayout.Height(256f));
  308. /*GUIStyle style = new GUIStyle(GUI.skin.box);
  309. style.stretchHeight = true;
  310. style.stretchWidth = true;
  311. style.fixedWidth = 0;
  312. style.fixedHeight = 0;
  313. textureRect = GUILayoutUtility.GetRect(Screen.width, Screen.width, 128f, Screen.height / 1.2f, style);*/
  314. }
  315. }
  316. else
  317. {
  318. float rectRatio = Mathf.Max(1f, textureRatio);
  319. textureRect = GUILayoutUtility.GetAspectRect(rectRatio, GUILayout.ExpandWidth(true), GUILayout.Height(256f));
  320. }
  321. if (textureRect.height > (Screen.height / 2f))
  322. {
  323. //textureRect.height = Screen.height / 2f;
  324. }
  325. //Debug.Log(textureRect.height + " " + Screen.height);
  326. //GUILayout.FlexibleSpace();
  327. //GUILayout.EndHorizontal();
  328. // Pause / Play toggle on mouse click
  329. if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && Event.current.isMouse)
  330. {
  331. if (textureRect.Contains(Event.current.mousePosition))
  332. {
  333. if (mediaPlayer.Control != null)
  334. {
  335. if (mediaPlayer.Control.IsPaused())
  336. {
  337. mediaPlayer.Play();
  338. }
  339. else
  340. {
  341. mediaPlayer.Pause();
  342. }
  343. }
  344. }
  345. }
  346. if (Event.current.type == EventType.Repaint)
  347. {
  348. GUI.color = Color.gray;
  349. EditorGUI.DrawTextureTransparent(textureRect, Texture2D.blackTexture, ScaleMode.StretchToFill);
  350. GUI.color = Color.white;
  351. //EditorGUI.DrawTextureAlpha(textureRect, Texture2D.whiteTexture, ScaleMode.ScaleToFit);
  352. //GUI.color = Color.black;
  353. //GUI.DrawTexture(textureRect, texture, ScaleMode.StretchToFill, false);
  354. //GUI.color = Color.white;
  355. // Draw the texture
  356. if (textureSource != null && textureSource.RequiresVerticalFlip())
  357. {
  358. // GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0f, textureRect.y + (textureRect.height / 2f)));
  359. }
  360. if (!GUI.enabled)
  361. {
  362. //GUI.color = Color.black;
  363. //GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleToFit, false);
  364. //GUI.color = Color.white;
  365. }
  366. else
  367. {
  368. if (_showPreview && texture != EditorGUIUtility.whiteTexture)
  369. {
  370. RenderPreview(mediaPlayer);
  371. }
  372. if (!_showAlpha)
  373. {
  374. if (texture != EditorGUIUtility.whiteTexture)
  375. {
  376. // TODO: In Linear mode, this displays the texture too bright, but GUI.DrawTexture displays it correctly
  377. //GL.sRGBWrite = true;
  378. //GUI.DrawTexture(textureRect, rt, ScaleMode.ScaleToFit, false);
  379. if (_previewTexture)
  380. {
  381. EditorGUI.DrawPreviewTexture(textureRect, _previewTexture, _materialIMGUI, ScaleMode.ScaleToFit, textureRatio);
  382. }
  383. //EditorGUI.DrawTextureTransparent(textureRect, rt, ScaleMode.ScaleToFit);
  384. //VideoRender.DrawTexture(textureRect, rt, ScaleMode.ScaleToFit, AlphaPacking.None, _materialPreview);
  385. //GL.sRGBWrite = false;
  386. }
  387. else
  388. {
  389. // Fill with black
  390. //GUI.color = Color.black;
  391. //GUI.DrawTexture(textureRect, texture, ScaleMode.StretchToFill, false);
  392. //GUI.color = Color.white;
  393. }
  394. }
  395. else
  396. {
  397. textureRect.width /= 2f;
  398. //GUI.DrawTexture(textureRect, rt, ScaleMode.ScaleToFit, false);
  399. //GL.sRGBWrite = true;
  400. //VideoRender.DrawTexture(textureRect, rt, ScaleMode.ScaleToFit, AlphaPacking.None, _materialIMGUI);
  401. //GL.sRGBWrite = false;
  402. textureRect.x += textureRect.width;
  403. //EditorGUI.DrawTextureAlpha(textureRect, texture, ScaleMode.ScaleToFit);
  404. }
  405. }
  406. }
  407. }
  408. IMediaInfo info = mediaPlayer.Info;
  409. IMediaControl control = mediaPlayer.Control;
  410. bool showBrowseMenu = false;
  411. if (true)
  412. {
  413. bool isPlaying = false;
  414. if (control != null)
  415. {
  416. isPlaying = control.IsPlaying();
  417. }
  418. // Slider layout
  419. EditorGUILayout.BeginHorizontal(GUILayout.Height(EditorGUIUtility.singleLineHeight/2f));
  420. Rect sliderRect = GUILayoutUtility.GetRect(GUIContent.none, GUI.skin.horizontalSlider, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
  421. EditorGUILayout.EndHorizontal();
  422. float currentTime = 0f;
  423. float durationTime = 0.001f;
  424. if (control != null)
  425. {
  426. currentTime = (float)control.GetCurrentTime();
  427. durationTime = (float)info.GetDuration();
  428. if (float.IsNaN(durationTime))
  429. {
  430. durationTime = 0f;
  431. }
  432. }
  433. TimeRange timelineRange = new TimeRange(0.0, 0.001); // A tiny default duration to prevent divide by zero's
  434. if (info != null)
  435. {
  436. timelineRange = Helper.GetTimelineRange(info.GetDuration(), control.GetSeekableTimes());
  437. }
  438. // Slider
  439. {
  440. // Draw buffering
  441. if (control != null && timelineRange.Duration > 0.0 && Event.current.type == EventType.Repaint)
  442. {
  443. GUI.color = new Color(0f, 1f, 0f, 0.25f);
  444. TimeRanges times = control.GetBufferedTimes();
  445. if (timelineRange.Duration > 0.0)
  446. {
  447. for (int i = 0; i < times.Count; i++)
  448. {
  449. Rect bufferedRect = sliderRect;
  450. float startT = Mathf.Clamp01((float)((times[i].StartTime - timelineRange.StartTime) / timelineRange.Duration));
  451. float endT = Mathf.Clamp01((float)((times[i].EndTime - timelineRange.StartTime) / timelineRange.Duration));
  452. bufferedRect.xMin = sliderRect.xMin + sliderRect.width * startT;
  453. bufferedRect.xMax = sliderRect.xMin + sliderRect.width * endT;
  454. bufferedRect.yMin += sliderRect.height * 0.5f;
  455. GUI.DrawTexture(bufferedRect, Texture2D.whiteTexture);
  456. }
  457. }
  458. GUI.color = Color.white;
  459. }
  460. // Timeline slider
  461. {
  462. float newTime = GUI.HorizontalSlider(sliderRect, currentTime, (float)timelineRange.StartTime, (float)timelineRange.EndTime);
  463. if (newTime != currentTime)
  464. {
  465. if (control != null)
  466. {
  467. // NOTE: For unknown reasons the seeks here behave differently to the MediaPlayerUI demo
  468. // When scrubbing (especially with NotchLC) while the video is playing, the frames will not update and a Stalled state will be shown,
  469. // but using the MediaPlayerUI the same scrubbing will updates the frames. Perhaps it's just an execution order issue
  470. control.Seek(newTime);
  471. }
  472. }
  473. }
  474. }
  475. EditorGUILayout.BeginHorizontal();
  476. string timeTotal = "∞";
  477. if (!float.IsInfinity(durationTime))
  478. {
  479. timeTotal = Helper.GetTimeString(durationTime, false);
  480. }
  481. string timeUsed = Helper.GetTimeString(currentTime - (float)timelineRange.StartTime, false);
  482. GUILayout.Label(timeUsed, GUILayout.ExpandWidth(false));
  483. //GUILayout.Label("/", GUILayout.ExpandWidth(false));
  484. GUILayout.FlexibleSpace();
  485. GUILayout.Label(timeTotal, GUILayout.ExpandWidth(false));
  486. EditorGUILayout.EndHorizontal();
  487. // In non-pro we need to make these 3 icon content black as the buttons are light
  488. // and the icons are white by default
  489. if (!EditorGUIUtility.isProSkin)
  490. {
  491. GUI.contentColor = Color.black;
  492. }
  493. EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
  494. // Play/Pause
  495. {
  496. float maxHeight = GUI.skin.button.CalcHeight(_iconSceneViewAudio, 0f);
  497. if (!isPlaying)
  498. {
  499. GUI.color = Color.green;
  500. if (GUILayout.Button(_iconPlayButton, GUILayout.ExpandWidth(false), GUILayout.Height(maxHeight)))
  501. {
  502. if (control != null)
  503. {
  504. control.Play();
  505. }
  506. else
  507. {
  508. if (mediaPlayer.MediaSource == MediaSource.Path)
  509. {
  510. mediaPlayer.OpenMedia(mediaPlayer.MediaPath.PathType, mediaPlayer.MediaPath.Path, true);
  511. }
  512. else if (mediaPlayer.MediaSource == MediaSource.Reference)
  513. {
  514. mediaPlayer.OpenMedia(mediaPlayer.MediaReference, true);
  515. }
  516. }
  517. }
  518. }
  519. else
  520. {
  521. GUI.color = Color.yellow;
  522. if (GUILayout.Button(_iconPauseButton, GUILayout.ExpandWidth(false), GUILayout.Height(maxHeight)))
  523. {
  524. if (control != null)
  525. {
  526. control.Pause();
  527. }
  528. }
  529. }
  530. GUI.color = Color.white;
  531. }
  532. // Looping
  533. {
  534. if (!_propLoop.boolValue)
  535. {
  536. GUI.color = Color.grey;
  537. }
  538. float maxHeight = GUI.skin.button.CalcHeight(_iconSceneViewAudio, 0f);
  539. //GUIContent icon = new GUIContent("∞");
  540. if (GUILayout.Button(_iconRotateTool, GUILayout.Height(maxHeight)))
  541. {
  542. if (control != null)
  543. {
  544. control.SetLooping(!_propLoop.boolValue);
  545. }
  546. _propLoop.boolValue = !_propLoop.boolValue;
  547. }
  548. GUI.color = Color.white;
  549. }
  550. // Mute & Volume
  551. EditorGUI.BeginDisabledGroup(UnityEditor.EditorUtility.audioMasterMute);
  552. {
  553. if (_propMuted.boolValue)
  554. {
  555. GUI.color = Color.gray;
  556. }
  557. float maxWidth = _iconPlayButton.image.width;
  558. //if (GUILayout.Button("Muted", GUILayout.ExpandWidth(false), GUILayout.Height(EditorGUIUtility.singleLineHeight)))
  559. //string iconName = "d_AudioListener Icon"; // Unity 2019+
  560. if (GUILayout.Button(_iconSceneViewAudio))//, GUILayout.Width(maxWidth), GUILayout.Height(EditorGUIUtility.singleLineHeight), GUILayout.ExpandHeight(false)))
  561. {
  562. if (control != null)
  563. {
  564. control.MuteAudio(!_propMuted.boolValue);
  565. }
  566. _propMuted.boolValue = !_propMuted.boolValue;
  567. }
  568. GUI.color = Color.white;
  569. }
  570. if (!_propMuted.boolValue)
  571. {
  572. EditorGUI.BeginChangeCheck();
  573. float newVolume = GUILayout.HorizontalSlider(_propVolume.floatValue, 0f, 1f, GUILayout.ExpandWidth(true), GUILayout.MinWidth(64f));
  574. if (EditorGUI.EndChangeCheck())
  575. {
  576. if (control != null)
  577. {
  578. control.SetVolume(newVolume);
  579. }
  580. _propVolume.floatValue = newVolume;
  581. }
  582. }
  583. EditorGUI.EndDisabledGroup();
  584. GUI.contentColor = Color.white;
  585. GUILayout.FlexibleSpace();
  586. if (Event.current.commandName == "ObjectSelectorClosed" &&
  587. EditorGUIUtility.GetObjectPickerControlID() == 200)
  588. {
  589. _queuedLoadMediaRef = (MediaReference)EditorGUIUtility.GetObjectPickerObject();
  590. }
  591. if (GUILayout.Button(_iconProject, GUILayout.ExpandWidth(false)))
  592. {
  593. showBrowseMenu = true;
  594. }
  595. EditorGUILayout.EndHorizontal();
  596. }
  597. EditorGUILayout.EndVertical();
  598. if (showBrowseMenu)
  599. {
  600. RecentMenu.Create(_propMediaPath, _propMediaSource, MediaFileExtensions, true, 200);
  601. }
  602. if (_queuedLoadMediaRef && Event.current.type == EventType.Repaint)
  603. {
  604. //MediaPlayer mediaPlayer = (MediaPlayer)_propMediaPath.serializedObject.targetObject;
  605. if (mediaPlayer)
  606. {
  607. mediaPlayer.OpenMedia(_queuedLoadMediaRef, true);
  608. _queuedLoadMediaRef = null;
  609. }
  610. }
  611. if (_queuedToggleShowPreview)
  612. {
  613. _showPreview = !_showPreview;
  614. _queuedToggleShowPreview = false;
  615. this.Repaint();
  616. }
  617. }
  618. private void OnInspectorGUI_VideoPreview(MediaPlayer media, ITextureProducer textureSource)
  619. {
  620. EditorGUILayout.LabelField("* Inspector preview affects playback performance");
  621. Texture texture = null;
  622. if (textureSource != null)
  623. {
  624. texture = textureSource.GetTexture();
  625. }
  626. if (texture == null)
  627. {
  628. texture = EditorGUIUtility.whiteTexture;
  629. }
  630. float ratio = (float)texture.width / (float)texture.height;
  631. // Reserve rectangle for texture
  632. GUILayout.BeginHorizontal();
  633. GUILayout.FlexibleSpace();
  634. Rect textureRect;
  635. if (texture != EditorGUIUtility.whiteTexture)
  636. {
  637. if (_showAlpha)
  638. {
  639. ratio *= 2f;
  640. textureRect = GUILayoutUtility.GetRect(Screen.width / 2, Screen.width / 2, (Screen.width / 2) / ratio, (Screen.width / 2) / ratio);
  641. }
  642. else
  643. {
  644. textureRect = GUILayoutUtility.GetRect(Screen.width / 2, Screen.width / 2, (Screen.width / 2) / ratio, (Screen.width / 2) / ratio);
  645. }
  646. }
  647. else
  648. {
  649. textureRect = GUILayoutUtility.GetRect(1920f / 40f, 1080f / 40f, GUILayout.ExpandWidth(true));
  650. }
  651. GUILayout.FlexibleSpace();
  652. GUILayout.EndHorizontal();
  653. // Dimensions
  654. string dimensionText = string.Format("{0}x{1}@{2:0.##}", 0, 0, 0.0f);
  655. if (texture != EditorGUIUtility.whiteTexture && media.Info != null)
  656. {
  657. dimensionText = string.Format("{0}x{1}@{2:0.##}", texture.width, texture.height, media.Info.GetVideoFrameRate());
  658. }
  659. EditorHelper.IMGUI.CentreLabel(dimensionText);
  660. string rateText = "0";
  661. string playerText = string.Empty;
  662. if (media.Info != null)
  663. {
  664. rateText = media.Info.GetVideoDisplayRate().ToString("F2");
  665. playerText = media.Info.GetPlayerDescription();
  666. }
  667. EditorGUILayout.LabelField("Display Rate", rateText);
  668. EditorGUILayout.LabelField("Using", playerText);
  669. _showAlpha = EditorGUILayout.Toggle("Show Alpha", _showAlpha);
  670. // Draw the texture
  671. Matrix4x4 prevMatrix = GUI.matrix;
  672. if (textureSource != null && textureSource.RequiresVerticalFlip())
  673. {
  674. GUIUtility.ScaleAroundPivot(new Vector2(1f, -1f), new Vector2(0, textureRect.y + (textureRect.height / 2)));
  675. }
  676. if (!GUI.enabled)
  677. {
  678. GUI.color = Color.grey;
  679. GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleToFit, false);
  680. GUI.color = Color.white;
  681. }
  682. else
  683. {
  684. if (!_showAlpha)
  685. {
  686. // TODO: In Linear mode, this displays the texture too bright, but GUI.DrawTexture displays it correctly
  687. EditorGUI.DrawTextureTransparent(textureRect, texture, ScaleMode.ScaleToFit);
  688. }
  689. else
  690. {
  691. textureRect.width /= 2f;
  692. GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleToFit, false);
  693. textureRect.x += textureRect.width;
  694. EditorGUI.DrawTextureAlpha(textureRect, texture, ScaleMode.ScaleToFit);
  695. }
  696. }
  697. GUI.matrix = prevMatrix;
  698. // Select texture button
  699. /*if (texture != null && texture != EditorGUIUtility.whiteTexture)
  700. {
  701. GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true));
  702. GUILayout.FlexibleSpace();
  703. for (int i = 0; i < textureSource.GetTextureCount(); i++)
  704. {
  705. Texture textures = textureSource.GetTexture(i);
  706. if (GUILayout.Button("Select Texture", GUILayout.ExpandWidth(false)))
  707. {
  708. Selection.activeObject = textures;
  709. }
  710. }
  711. if (GUILayout.Button("Save PNG", GUILayout.ExpandWidth(true)))
  712. {
  713. media.SaveFrameToPng();
  714. }
  715. GUILayout.FlexibleSpace();
  716. GUILayout.EndHorizontal();
  717. }*/
  718. }
  719. private void OnInspectorGUI_PlayControls(IMediaControl control, IMediaInfo info)
  720. {
  721. GUILayout.Space(8.0f);
  722. // Slider
  723. EditorGUILayout.BeginHorizontal();
  724. bool isPlaying = false;
  725. if (control != null)
  726. {
  727. isPlaying = control.IsPlaying();
  728. }
  729. float currentTime = 0f;
  730. if (control != null)
  731. {
  732. currentTime = (float)control.GetCurrentTime();
  733. }
  734. float durationTime = 0f;
  735. if (info != null)
  736. {
  737. durationTime = (float)info.GetDuration();
  738. if (float.IsNaN(durationTime))
  739. {
  740. durationTime = 0f;
  741. }
  742. }
  743. string timeUsed = Helper.GetTimeString(currentTime, true);
  744. GUILayout.Label(timeUsed, GUILayout.ExpandWidth(false));
  745. float newTime = GUILayout.HorizontalSlider(currentTime, 0f, durationTime, GUILayout.ExpandWidth(true));
  746. if (newTime != currentTime)
  747. {
  748. control.Seek(newTime);
  749. }
  750. string timeTotal = "Infinity";
  751. if (!float.IsInfinity(durationTime))
  752. {
  753. timeTotal = Helper.GetTimeString(durationTime, true);
  754. }
  755. GUILayout.Label(timeTotal, GUILayout.ExpandWidth(false));
  756. EditorGUILayout.EndHorizontal();
  757. // Buttons
  758. EditorGUILayout.BeginHorizontal();
  759. if (GUILayout.Button("Rewind", GUILayout.ExpandWidth(false)))
  760. {
  761. control.Rewind();
  762. }
  763. if (!isPlaying)
  764. {
  765. GUI.color = Color.green;
  766. if (GUILayout.Button("Play", GUILayout.ExpandWidth(true)))
  767. {
  768. control.Play();
  769. }
  770. }
  771. else
  772. {
  773. GUI.color = Color.yellow;
  774. if (GUILayout.Button("Pause", GUILayout.ExpandWidth(true)))
  775. {
  776. control.Pause();
  777. }
  778. }
  779. GUI.color = Color.white;
  780. EditorGUILayout.EndHorizontal();
  781. }
  782. void OnInspectorGUI_Preview()
  783. {
  784. MediaPlayer media = (this.target) as MediaPlayer;
  785. EditorGUI.BeginDisabledGroup(!(media.TextureProducer != null && media.Info.HasVideo()));
  786. OnInspectorGUI_VideoPreview(media, media.TextureProducer);
  787. EditorGUI.EndDisabledGroup();
  788. EditorGUI.BeginDisabledGroup(!(media.Control != null && media.Control.CanPlay() && media.isActiveAndEnabled && !EditorApplication.isPaused));
  789. OnInspectorGUI_PlayControls(media.Control, media.Info);
  790. EditorGUI.EndDisabledGroup();
  791. }
  792. }
  793. }