CaptureEditorWindow.cs 64 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848
  1. #if UNITY_EDITOR
  2. #if UNITY_5_4_OR_NEWER || (UNITY_5 && !UNITY_5_0)
  3. #define AVPRO_MOVIECAPTURE_WINDOWTITLE_51
  4. #define AVPRO_MOVIECAPTURE_GRAPHICSDEVICETYPE_51
  5. #endif
  6. #if UNITY_5_4_OR_NEWER || (UNITY_5 && !UNITY_5_0 && !UNITY_5_1 && !UNITY_5_2)
  7. #define AVPRO_MOVIECAPTURE_SCENEMANAGER_53
  8. #endif
  9. #if UNITY_5_4_OR_NEWER || UNITY_5
  10. #define AVPRO_MOVIECAPTURE_DEFERREDSHADING
  11. #endif
  12. using UnityEngine;
  13. using UnityEditor;
  14. //-----------------------------------------------------------------------------
  15. // Copyright 2012-2017 RenderHeads Ltd. All rights reserved.
  16. //-----------------------------------------------------------------------------
  17. namespace RenderHeads.Media.AVProMovieCapture.Editor
  18. {
  19. /// <summary>
  20. /// Creates a dockable window in Unity that can be used for handy in-editor capturing
  21. /// </summary>
  22. public class CaptureEditorWindow : EditorWindow
  23. {
  24. private const string TempGameObjectName = "Temp_MovieCapture";
  25. private const string SettingsPrefix = "AVProMovieCapture.EditorWindow.";
  26. private static bool _isTrialVersion = false;
  27. private CaptureBase _capture;
  28. private CaptureFromScreen _captureScreen;
  29. private CaptureFromCamera _captureCamera;
  30. private CaptureFromCamera360 _captureCamera360;
  31. private CaptureFromCamera360ODS _captureCamera360ODS;
  32. private static bool _isCreated = false;
  33. private static bool _isInit = false;
  34. private static bool _isFailedInit = false;
  35. private static bool _showAlpha = false;
  36. private static string[] _videoCodecNames = new string[0];
  37. private static string[] _audioCodecNames = new string[0];
  38. private static string[] _audioDeviceNames = new string[0];
  39. private static bool[] _videoCodecConfigurable = new bool[0];
  40. private static bool[] _audioCodecConfigurable = new bool[0];
  41. private readonly string[] _downScales = { "Original", "Half", "Quarter", "Eighth", "Sixteenth", "Custom" };
  42. private readonly string[] _captureModes = { "Realtime Capture", "Offline Render" };
  43. private readonly string[] _outputFolders = { "Project Folder", "Persistent Data Folder", "Absolute Folder" };
  44. private readonly string[] _sourceNames = { "Screen", "Camera", "Camera 360 (fast Stereo)", "Camera 360 (accurate ODS Stereo)" };
  45. private enum SourceType
  46. {
  47. Screen,
  48. Camera,
  49. Camera360,
  50. Camera360ODS,
  51. }
  52. [SerializeField]
  53. private SourceType _sourceType = SourceType.Screen;
  54. private bool _startPaused = false;
  55. private Camera _cameraNode;
  56. private string _cameraName;
  57. private int _captureModeIndex;
  58. private int _outputFolderIndex;
  59. [SerializeField]
  60. private CaptureBase.OutputType _outputType = CaptureBase.OutputType.VideoFile;
  61. private bool _autoFilenamePrefixFromSceneName = true;
  62. private string _autoFilenamePrefix = "capture";
  63. private string _autoFilenameExtension = "avi";
  64. private string _outputFolderRelative = string.Empty;
  65. private string _outputFolderAbsolute = string.Empty;
  66. private bool _appendTimestamp = true;
  67. [SerializeField]
  68. private string _namedPipePath = @"\\.\pipe\pipename";
  69. private int _downScaleIndex;
  70. private int _downscaleX;
  71. private int _downscaleY;
  72. private bool _captureMouseCursor = false;
  73. private Texture2D _mouseCursorTexture = null;
  74. [SerializeField]
  75. private CaptureBase.Resolution _renderResolution = CaptureBase.Resolution.Original;
  76. private Vector2 _renderSize;
  77. [SerializeField]
  78. private int _renderAntiAliasing;
  79. [SerializeField]
  80. private bool _useContributingCameras = true;
  81. [SerializeField]
  82. private CaptureBase.FrameRate _frameRate = CaptureBase.FrameRate.Thirty;
  83. private bool _supportAlpha = false;
  84. private bool _useMediaFoundationH264 = false;
  85. private int _videoCodecIndex;
  86. private bool _captureAudio;
  87. private int _audioCodecIndex;
  88. private int _audioDeviceIndex;
  89. private Vector2 _scroll = Vector2.zero;
  90. private bool _queueStart;
  91. private int _queueConfigureVideoCodec = -1;
  92. private int _queueConfigureAudioCodec = -1;
  93. private bool _useMotionBlur = false;
  94. private int _motionBlurSampleCount = 16;
  95. private int _cubemapResolution = 2048;
  96. private int _cubemapDepth = 24;
  97. private int _cubemapStereoPacking = 0;
  98. private float _cubemapStereoIPD = 0.064f;
  99. [SerializeField]
  100. private StopMode _stopMode = StopMode.None;
  101. private int _stopFrames = 300;
  102. private float _stopSeconds = 10f;
  103. private SerializedProperty _propSourceType;
  104. private SerializedProperty _propOutputType;
  105. private SerializedProperty _propNamedPipePath;
  106. private SerializedProperty _propFrameRate;
  107. private SerializedProperty _propStopMode;
  108. private SerializedProperty _propRenderResolution;
  109. private SerializedProperty _propUseContributingCameras;
  110. private SerializedProperty _propStereoIPD;
  111. private SerializedProperty _propRenderAntiAliasing;
  112. private SerializedProperty _propOdsCamera;
  113. private SerializedProperty _propOdsIPD;
  114. private SerializedProperty _propOdsPixelSliceSize;
  115. private SerializedProperty _propOdsPaddingSize;
  116. private SerializedProperty _propOdsCameraClearMode;
  117. private SerializedProperty _propOdsCameraClearColor;
  118. [SerializeField]
  119. private CaptureFromCamera360ODS.Settings _odsSettings = new CaptureFromCamera360ODS.Settings();
  120. // TODO: we should actually be saving these parameters per-scene...
  121. private long _lastFileSize;
  122. private uint _lastEncodedMinutes;
  123. private uint _lastEncodedSeconds;
  124. private uint _lastEncodedFrame;
  125. private int _selectedTool;
  126. private int _selectedConfigTool;
  127. private bool _expandSectionTrial = true;
  128. private static Texture2D _icon;
  129. private string _pluginVersionWarningText = string.Empty;
  130. private SerializedObject _so;
  131. private const string LinkPluginWebsite = "http://renderheads.com/product/av-pro-movie-capture/";
  132. private const string LinkForumPage = "http://forum.unity3d.com/threads/released-avpro-movie-capture.120717/";
  133. private const string LinkAssetStorePage = "https://www.assetstore.unity3d.com/#!/content/2670";
  134. private const string LinkFreeAssetStorePage = "https://www.assetstore.unity3d.com/#!/content/97562";
  135. private const string LinkEmailSupport = "mailto:unitysupport@renderheads.com";
  136. private const string LinkUserManual = "http://downloads.renderheads.com/docs/UnityAVProMovieCapture.pdf";
  137. 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" +
  138. "Essential details:\n" +
  139. "+ Error message\n" +
  140. " + The exact error message\n" +
  141. " + The console/output log if possible\n" +
  142. "+ Development environment\n" +
  143. " + Unity version\n" +
  144. " + Development OS version\n" +
  145. " + AVPro Movie Capture plugin version\n";
  146. [MenuItem("Window/Open AVPro Movie Capture..")]
  147. public static void Init()
  148. {
  149. if (_isInit || _isCreated)
  150. {
  151. CaptureEditorWindow window = (CaptureEditorWindow)EditorWindow.GetWindow(typeof(CaptureEditorWindow));
  152. window.Close();
  153. return;
  154. }
  155. _isCreated = true;
  156. // Get existing open window or if none, make a new one:
  157. CaptureEditorWindow window2 = (CaptureEditorWindow)EditorWindow.GetWindow(typeof(CaptureEditorWindow));
  158. if (window2 != null)
  159. {
  160. window2.SetupWindow();
  161. }
  162. }
  163. public void SetupWindow()
  164. {
  165. _isCreated = true;
  166. if (Application.platform == RuntimePlatform.WindowsEditor)
  167. {
  168. this.minSize = new Vector2(200f, 48f);
  169. this.maxSize = new Vector2(340f, 620f);
  170. #if AVPRO_MOVIECAPTURE_WINDOWTITLE_51
  171. if (_icon != null)
  172. {
  173. this.titleContent = new GUIContent("Movie Capture", _icon, "AVPro Movie Capture");
  174. }
  175. else
  176. {
  177. this.titleContent = new GUIContent("Movie Capture", "AVPro Movie Capture");
  178. }
  179. #else
  180. this.title = "Movie Capture";
  181. #endif
  182. this.CreateGUI();
  183. this.LoadSettings();
  184. _so = new SerializedObject(this);
  185. if (_so == null)
  186. {
  187. Debug.LogError("[AVProMovieCapture] SO is null");
  188. }
  189. _propSourceType = _so.FindProperty("_sourceType");
  190. _propOutputType = _so.FindProperty("_outputType");
  191. _propNamedPipePath = _so.FindProperty("_namedPipePath");
  192. _propRenderResolution = _so.FindProperty("_renderResolution");
  193. _propUseContributingCameras = _so.FindProperty("_useContributingCameras");
  194. _propFrameRate = _so.FindProperty("_frameRate");
  195. _propStopMode = _so.FindProperty("_stopMode");
  196. _propRenderAntiAliasing = _so.FindProperty("_renderAntiAliasing");
  197. _propOdsIPD = _so.FindProperty("_odsSettings.ipd");
  198. _propOdsPixelSliceSize = _so.FindProperty("_odsSettings.pixelSliceSize");
  199. _propOdsPaddingSize = _so.FindProperty("_odsSettings.paddingSize");
  200. _propOdsCameraClearMode = _so.FindProperty("_odsSettings.cameraClearMode");
  201. _propOdsCameraClearColor = _so.FindProperty("_odsSettings.cameraClearColor");
  202. this.Repaint();
  203. }
  204. }
  205. private void LoadSettings()
  206. {
  207. _sourceType = (SourceType)EditorPrefs.GetInt(SettingsPrefix + "SourceType", (int)_sourceType);
  208. _cameraName = EditorPrefs.GetString(SettingsPrefix + "CameraName", string.Empty);
  209. _captureModeIndex = EditorPrefs.GetInt(SettingsPrefix + "CaptureModeIndex", 0);
  210. _startPaused = EditorPrefs.GetBool(SettingsPrefix + "StartPaused", false);
  211. _captureMouseCursor = EditorPrefs.GetBool(SettingsPrefix + "CaptureMouseCursor", false);
  212. string mouseCursorGuid = EditorPrefs.GetString(SettingsPrefix + "CaptureMouseTexture", string.Empty);
  213. if (!string.IsNullOrEmpty(mouseCursorGuid))
  214. {
  215. string mouseCursorPath = AssetDatabase.GUIDToAssetPath(mouseCursorGuid);
  216. if (!string.IsNullOrEmpty(mouseCursorPath))
  217. {
  218. _mouseCursorTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(mouseCursorPath, typeof(Texture2D));
  219. }
  220. }
  221. _outputType = (CaptureBase.OutputType)EditorPrefs.GetInt(SettingsPrefix + "OutputType", (int)_outputType);
  222. _namedPipePath = EditorPrefs.GetString(SettingsPrefix + "NamedPipePath", _namedPipePath);
  223. _autoFilenamePrefixFromSceneName = EditorPrefs.GetBool(SettingsPrefix + "AutoFilenamePrefixFromScenename", _autoFilenamePrefixFromSceneName);
  224. _autoFilenamePrefix = EditorPrefs.GetString(SettingsPrefix + "AutoFilenamePrefix", "capture");
  225. _autoFilenameExtension = EditorPrefs.GetString(SettingsPrefix + "AutoFilenameExtension", "avi");
  226. _appendTimestamp = EditorPrefs.GetBool(SettingsPrefix + "AppendTimestamp", true);
  227. _outputFolderIndex = EditorPrefs.GetInt(SettingsPrefix + "OutputFolderIndex", 0);
  228. _outputFolderRelative = EditorPrefs.GetString(SettingsPrefix + "OutputFolderRelative", string.Empty);
  229. _outputFolderAbsolute = EditorPrefs.GetString(SettingsPrefix + "OutputFolderAbsolute", string.Empty);
  230. _downScaleIndex = EditorPrefs.GetInt(SettingsPrefix + "DownScaleIndex", 0);
  231. _downscaleX = EditorPrefs.GetInt(SettingsPrefix + "DownScaleX", 1);
  232. _downscaleY = EditorPrefs.GetInt(SettingsPrefix + "DownScaleY", 1);
  233. _frameRate = (CaptureBase.FrameRate)System.Enum.Parse(typeof(CaptureBase.FrameRate), EditorPrefs.GetString(SettingsPrefix + "FrameRate", "Thirty"));
  234. _supportAlpha = EditorPrefs.GetBool(SettingsPrefix + "SupportAlpha", false);
  235. _useMediaFoundationH264 = EditorPrefs.GetBool(SettingsPrefix + "UseMediaFoundationH264", false);
  236. _videoCodecIndex = EditorPrefs.GetInt(SettingsPrefix + "VideoCodecIndex", 0);
  237. _renderResolution = (CaptureBase.Resolution)EditorPrefs.GetInt(SettingsPrefix + "RenderResolution", (int)_renderResolution);
  238. _renderSize.x = EditorPrefs.GetInt(SettingsPrefix + "RenderWidth", 0);
  239. _renderSize.y = EditorPrefs.GetInt(SettingsPrefix + "RenderHeight", 0);
  240. _renderAntiAliasing = EditorPrefs.GetInt(SettingsPrefix + "RenderAntiAliasing", 0);
  241. _useContributingCameras = EditorPrefs.GetBool(SettingsPrefix + "UseContributingCameras", true);
  242. _captureAudio = EditorPrefs.GetBool(SettingsPrefix + "CaptureAudio", false);
  243. _audioCodecIndex = EditorPrefs.GetInt(SettingsPrefix + "AudioCodecIndex", 0);
  244. _audioDeviceIndex = EditorPrefs.GetInt(SettingsPrefix + "AudioDeviceIndex", 0);
  245. _useMotionBlur = EditorPrefs.GetBool(SettingsPrefix + "UseMotionBlur", false);
  246. _motionBlurSampleCount = EditorPrefs.GetInt(SettingsPrefix + "MotionBlurSampleCount", 16);
  247. _cubemapResolution = EditorPrefs.GetInt(SettingsPrefix + "CubemapResolution", 2048);
  248. _cubemapDepth = EditorPrefs.GetInt(SettingsPrefix + "CubemapDepth", 24);
  249. _cubemapStereoPacking = EditorPrefs.GetInt(SettingsPrefix + "CubemapStereoPacking", 0);
  250. _cubemapStereoIPD = EditorPrefs.GetFloat(SettingsPrefix + "CubemapStereoIPD", 0.064f);
  251. _stopMode = (StopMode)EditorPrefs.GetInt(SettingsPrefix + "StopMode", (int)_stopMode);
  252. _stopFrames = EditorPrefs.GetInt(SettingsPrefix + "StopFrames", _stopFrames);
  253. _stopSeconds = EditorPrefs.GetFloat(SettingsPrefix + "StopSeconds", _stopSeconds);
  254. if (!string.IsNullOrEmpty(_cameraName))
  255. {
  256. Camera[] cameras = (Camera[])GameObject.FindObjectsOfType(typeof(Camera));
  257. foreach (Camera cam in cameras)
  258. {
  259. if (cam.name == _cameraName)
  260. {
  261. _cameraNode = cam;
  262. break;
  263. }
  264. }
  265. }
  266. // Check ranges
  267. if (_videoCodecIndex >= _videoCodecNames.Length)
  268. {
  269. _videoCodecIndex = 0;
  270. }
  271. if (_audioDeviceIndex >= _audioDeviceNames.Length)
  272. {
  273. _audioDeviceIndex = 0;
  274. _captureAudio = false;
  275. }
  276. if (_audioCodecIndex >= _audioCodecNames.Length)
  277. {
  278. _audioCodecIndex = 0;
  279. _captureAudio = false;
  280. }
  281. _showAlpha = EditorPrefs.GetBool(SettingsPrefix + "ShowAlphaChannel", false);
  282. }
  283. private void SaveSettings()
  284. {
  285. EditorPrefs.SetInt(SettingsPrefix + "SourceType", (int)_sourceType);
  286. EditorPrefs.SetString(SettingsPrefix + "CameraName", _cameraName);
  287. EditorPrefs.SetInt(SettingsPrefix + "CaptureModeIndex", _captureModeIndex);
  288. EditorPrefs.SetBool(SettingsPrefix + "CaptureMouseCursor", _captureMouseCursor);
  289. EditorPrefs.SetBool(SettingsPrefix + "StartPaused", _startPaused);
  290. string mouseCursorGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_mouseCursorTexture));
  291. EditorPrefs.SetString(SettingsPrefix + "CaptureMouseTexture", mouseCursorGuid);
  292. EditorPrefs.SetInt(SettingsPrefix + "OutputType", (int)_outputType);
  293. EditorPrefs.SetString(SettingsPrefix + "NamedPipePath", _namedPipePath);
  294. EditorPrefs.SetBool(SettingsPrefix + "AutoFilenamePrefixFromScenename", _autoFilenamePrefixFromSceneName);
  295. EditorPrefs.SetString(SettingsPrefix + "AutoFilenamePrefix", _autoFilenamePrefix);
  296. EditorPrefs.SetString(SettingsPrefix + "AutoFilenameExtension", _autoFilenameExtension);
  297. EditorPrefs.SetBool(SettingsPrefix + "AppendTimestamp", _appendTimestamp);
  298. EditorPrefs.SetInt(SettingsPrefix + "OutputFolderIndex", _outputFolderIndex);
  299. EditorPrefs.SetString(SettingsPrefix + "OutputFolderRelative", _outputFolderRelative);
  300. EditorPrefs.SetString(SettingsPrefix + "OutputFolderAbsolute", _outputFolderAbsolute);
  301. EditorPrefs.SetInt(SettingsPrefix + "DownScaleIndex", _downScaleIndex);
  302. EditorPrefs.SetInt(SettingsPrefix + "DownScaleX", _downscaleX);
  303. EditorPrefs.SetInt(SettingsPrefix + "DownScaleY", _downscaleY);
  304. EditorPrefs.SetBool(SettingsPrefix + "SupportAlpha", _supportAlpha);
  305. EditorPrefs.SetBool(SettingsPrefix + "UseMediaFoundationH264", _useMediaFoundationH264);
  306. EditorPrefs.SetString(SettingsPrefix + "FrameRate", _frameRate.ToString());
  307. EditorPrefs.SetInt(SettingsPrefix + "VideoCodecIndex", _videoCodecIndex);
  308. EditorPrefs.SetInt(SettingsPrefix + "RenderResolution", (int)_renderResolution);
  309. EditorPrefs.SetInt(SettingsPrefix + "RenderWidth", (int)_renderSize.x);
  310. EditorPrefs.SetInt(SettingsPrefix + "RenderHeight", (int)_renderSize.y);
  311. EditorPrefs.SetInt(SettingsPrefix + "RenderAntiAliasing", _renderAntiAliasing);
  312. EditorPrefs.SetBool(SettingsPrefix + "UseContributingCameras", _useContributingCameras);
  313. EditorPrefs.SetBool(SettingsPrefix + "CaptureAudio", _captureAudio);
  314. EditorPrefs.SetInt(SettingsPrefix + "AudioCodecIndex", _audioCodecIndex);
  315. EditorPrefs.SetInt(SettingsPrefix + "AudioDeviceIndex", _audioDeviceIndex);
  316. EditorPrefs.SetBool(SettingsPrefix + "UseMotionBlur", _useMotionBlur);
  317. EditorPrefs.SetInt(SettingsPrefix + "MotionBlurSampleCount", _motionBlurSampleCount);
  318. EditorPrefs.SetInt(SettingsPrefix + "CubemapResolution", _cubemapResolution);
  319. EditorPrefs.SetInt(SettingsPrefix + "CubemapDepth", _cubemapDepth);
  320. EditorPrefs.SetInt(SettingsPrefix + "CubemapStereoPacking", _cubemapStereoPacking);
  321. EditorPrefs.SetFloat(SettingsPrefix + "CubemapStereoIPD", _cubemapStereoIPD);
  322. EditorPrefs.SetInt(SettingsPrefix + "StopMode", (int)_stopMode);
  323. EditorPrefs.SetInt(SettingsPrefix + "StopFrames", _stopFrames);
  324. EditorPrefs.SetFloat(SettingsPrefix + "StopSeconds", _stopSeconds);
  325. EditorPrefs.SetBool(SettingsPrefix + "ShowAlphaChannel", _showAlpha);
  326. }
  327. private void ResetSettings()
  328. {
  329. _sourceType = SourceType.Screen;
  330. _cameraNode = null;
  331. _cameraName = string.Empty;
  332. _captureModeIndex = 0;
  333. _startPaused = false;
  334. _captureMouseCursor = false;
  335. _mouseCursorTexture = null;
  336. _outputType = CaptureBase.OutputType.VideoFile;
  337. _namedPipePath = @"\\.\pipe\pipename";
  338. _autoFilenamePrefixFromSceneName = true;
  339. _autoFilenamePrefix = "capture";
  340. _autoFilenameExtension = "avi";
  341. _outputFolderIndex = 0;
  342. _outputFolderRelative = string.Empty;
  343. _outputFolderAbsolute = string.Empty;
  344. _appendTimestamp = true;
  345. _downScaleIndex = 0;
  346. _downscaleX = 1;
  347. _downscaleY = 1;
  348. _frameRate = CaptureBase.FrameRate.Thirty;
  349. _supportAlpha = false;
  350. _useMediaFoundationH264 = false;
  351. _videoCodecIndex = 0;
  352. _renderResolution = CaptureBase.Resolution.Original;
  353. _renderSize = Vector2.one;
  354. _renderAntiAliasing = 0;
  355. _useContributingCameras = true;
  356. _captureAudio = false;
  357. _audioCodecIndex = 0;
  358. _audioDeviceIndex = 0;
  359. _useMotionBlur = false;
  360. _motionBlurSampleCount = 16;
  361. _cubemapResolution = 2048;
  362. _cubemapDepth = 24;
  363. _cubemapStereoPacking = 0;
  364. _stopMode = StopMode.None;
  365. _cubemapStereoIPD = 0.064f;
  366. _stopFrames = 300;
  367. _stopSeconds = 10f;
  368. }
  369. private static CaptureBase.DownScale GetDownScaleFromIndex(int index)
  370. {
  371. CaptureBase.DownScale result = CaptureBase.DownScale.Original;
  372. switch (index)
  373. {
  374. case 0:
  375. result = CaptureBase.DownScale.Original;
  376. break;
  377. case 1:
  378. result = CaptureBase.DownScale.Half;
  379. break;
  380. case 2:
  381. result = CaptureBase.DownScale.Quarter;
  382. break;
  383. case 3:
  384. result = CaptureBase.DownScale.Eighth;
  385. break;
  386. case 4:
  387. result = CaptureBase.DownScale.Sixteenth;
  388. break;
  389. case 5:
  390. result = CaptureBase.DownScale.Custom;
  391. break;
  392. }
  393. return result;
  394. }
  395. private void Configure(CaptureBase capture)
  396. {
  397. capture._videoCodecPriority = null;
  398. capture._audioCodecPriority = null;
  399. capture._captureOnStart = false;
  400. capture._listVideoCodecsOnStart = false;
  401. capture._frameRate = _frameRate;
  402. capture._supportAlpha = _supportAlpha;
  403. capture._downScale = GetDownScaleFromIndex(_downScaleIndex);
  404. if (capture._downScale == CaptureBase.DownScale.Custom)
  405. {
  406. capture._maxVideoSize.x = _downscaleX;
  407. capture._maxVideoSize.y = _downscaleY;
  408. }
  409. capture._stopMode = _stopMode;
  410. capture._stopFrames = _stopFrames;
  411. capture._stopSeconds = _stopSeconds;
  412. capture._isRealTime = (_captureModeIndex == 0);
  413. capture._startPaused = _startPaused;
  414. capture._outputType = _outputType;
  415. if (_outputType == CaptureBase.OutputType.VideoFile)
  416. {
  417. capture._autoGenerateFilename = _appendTimestamp;
  418. capture._autoFilenamePrefix = _autoFilenamePrefix;
  419. capture._autoFilenameExtension = _autoFilenameExtension;
  420. if (!capture._autoGenerateFilename)
  421. {
  422. capture._forceFilename = _autoFilenamePrefix + "." + _autoFilenameExtension;
  423. }
  424. }
  425. else
  426. {
  427. capture._forceFilename = _namedPipePath;
  428. }
  429. capture._outputFolderType = CaptureBase.OutputPath.RelativeToProject;
  430. capture._outputFolderPath = _outputFolderRelative;
  431. if (_outputFolderIndex == 1)
  432. {
  433. capture._outputFolderType = CaptureBase.OutputPath.RelativeToPeristentData;
  434. capture._outputFolderPath = _outputFolderAbsolute;
  435. }
  436. if (_outputFolderIndex == 2)
  437. {
  438. capture._outputFolderType = CaptureBase.OutputPath.Absolute;
  439. capture._outputFolderPath = _outputFolderAbsolute;
  440. }
  441. capture._forceVideoCodecIndex = capture._codecIndex = Mathf.Max(-1, (_videoCodecIndex - 4));
  442. capture._useMediaFoundationH264 = (_videoCodecIndex == 2);
  443. capture._noAudio = !_captureAudio;
  444. capture._forceAudioCodecIndex = capture._audioCodecIndex = Mathf.Max(-1, (_audioCodecIndex - 2));
  445. capture._forceAudioDeviceIndex = capture._audioDeviceIndex = Mathf.Max(-1, (_audioDeviceIndex - 2));
  446. if (_useMotionBlur && !capture._isRealTime && Camera.main != null)
  447. {
  448. capture._useMotionBlur = _useMotionBlur;
  449. capture._motionBlurSamples = _motionBlurSampleCount;
  450. capture._motionBlurCameras = new Camera[1];
  451. capture._motionBlurCameras[0] = Camera.main;
  452. }
  453. else
  454. {
  455. capture._useMotionBlur = false;
  456. }
  457. if (_captureMouseCursor)
  458. {
  459. capture._captureMouseCursor = true;
  460. if (capture._mouseCursor == null)
  461. {
  462. capture._mouseCursor = capture.gameObject.AddComponent<MouseCursor>();
  463. }
  464. if (capture._mouseCursor != null)
  465. {
  466. capture._mouseCursor.SetTexture(_mouseCursorTexture);
  467. }
  468. }
  469. else
  470. {
  471. capture._captureMouseCursor = false;
  472. if (capture._mouseCursor != null)
  473. {
  474. capture._mouseCursor.enabled = false;
  475. }
  476. }
  477. }
  478. private void CreateComponents()
  479. {
  480. switch (_sourceType)
  481. {
  482. case SourceType.Screen:
  483. _captureScreen = (CaptureFromScreen)GameObject.FindObjectOfType(typeof(CaptureFromScreen));
  484. if (_captureScreen == null)
  485. {
  486. GameObject go = new GameObject(TempGameObjectName);
  487. _captureScreen = go.AddComponent<CaptureFromScreen>();
  488. }
  489. _capture = _captureScreen;
  490. break;
  491. case SourceType.Camera:
  492. _captureCamera = _cameraNode.gameObject.GetComponent<CaptureFromCamera>();
  493. if (_captureCamera == null)
  494. {
  495. _captureCamera = _cameraNode.gameObject.AddComponent<CaptureFromCamera>();
  496. }
  497. _captureCamera.SetCamera(_cameraNode, _useContributingCameras);
  498. _capture = _captureCamera;
  499. _capture._renderResolution = _renderResolution;
  500. _capture._renderSize = _renderSize;
  501. _capture._renderAntiAliasing = _renderAntiAliasing;
  502. break;
  503. case SourceType.Camera360:
  504. _captureCamera360 = _cameraNode.gameObject.GetComponent<CaptureFromCamera360>();
  505. if (_captureCamera360 == null)
  506. {
  507. _captureCamera360 = _cameraNode.gameObject.AddComponent<CaptureFromCamera360>();
  508. }
  509. _capture = _captureCamera360;
  510. _capture._renderResolution = _renderResolution;
  511. _capture._renderSize = _renderSize;
  512. _capture._renderAntiAliasing = _renderAntiAliasing;
  513. _captureCamera360._cubemapResolution = _cubemapResolution;
  514. _captureCamera360._cubemapDepth = _cubemapDepth;
  515. _captureCamera360._stereoRendering = (StereoPacking)_cubemapStereoPacking;
  516. _captureCamera360._ipd = _cubemapStereoIPD;
  517. break;
  518. case SourceType.Camera360ODS:
  519. _captureCamera360ODS = _cameraNode.gameObject.GetComponent<CaptureFromCamera360ODS>();
  520. if (_captureCamera360ODS == null)
  521. {
  522. _captureCamera360ODS = _cameraNode.gameObject.AddComponent<CaptureFromCamera360ODS>();
  523. }
  524. _capture = _captureCamera360ODS;
  525. _capture._renderResolution = _renderResolution;
  526. _capture._renderSize = _renderSize;
  527. _capture._renderAntiAliasing = _renderAntiAliasing;
  528. _captureCamera360ODS.Setup.camera = _cameraNode;
  529. _captureCamera360ODS.Setup.ipd = _odsSettings.ipd;
  530. _captureCamera360ODS.Setup.pixelSliceSize = _odsSettings.pixelSliceSize;
  531. _captureCamera360ODS.Setup.paddingSize = _odsSettings.paddingSize;
  532. _captureCamera360ODS.Setup.cameraClearMode = _odsSettings.cameraClearMode;
  533. _captureCamera360ODS.Setup.cameraClearColor= _odsSettings.cameraClearColor;
  534. break;
  535. }
  536. // TODO: Remove old components from previous captures if the mode or gameObject has changed
  537. }
  538. private void CreateGUI()
  539. {
  540. try
  541. {
  542. if (!NativePlugin.Init())
  543. {
  544. Debug.LogError("[AVProMovieCapture] Failed to initialise");
  545. return;
  546. }
  547. }
  548. catch (System.DllNotFoundException e)
  549. {
  550. _isFailedInit = true;
  551. string missingDllMessage = string.Empty;
  552. #if (UNITY_5 || UNITY_5_4_OR_NEWER)
  553. missingDllMessage = "Unity couldn't find the plugin DLL. Please select the native plugin files in 'Plugins/RenderHeads/AVProMovieCapture/Plugins' folder and select the correct platform in the Inspector.";
  554. #else
  555. missingDllMessage = "Unity couldn't find the plugin DLL, Unity 4.x requires the 'Plugins' folder to be at the root of your project. Please move the contents of the 'Plugins' folder (in Plugins/RenderHeads/AVProMovieCapture/Plugins) to the 'Plugins' folder in the root of your project.";
  556. #endif
  557. Debug.LogError("[AVProMovieCapture] " + missingDllMessage);
  558. #if UNITY_EDITOR
  559. UnityEditor.EditorUtility.DisplayDialog("Plugin files not found", missingDllMessage, "Ok");
  560. #endif
  561. throw e;
  562. }
  563. // Video codec enumeration
  564. {
  565. int numVideoCodecs = Mathf.Max(0, NativePlugin.GetNumAVIVideoCodecs());
  566. _videoCodecNames = new string[numVideoCodecs + 4];
  567. _videoCodecNames[0] = "Uncompressed";
  568. _videoCodecNames[1] = string.Empty;
  569. _videoCodecNames[2] = "Media Foundation H.264 (MP4)";
  570. _videoCodecNames[3] = string.Empty;
  571. _videoCodecConfigurable = new bool[numVideoCodecs + 4];
  572. _videoCodecConfigurable[0] = false;
  573. _videoCodecConfigurable[1] = false;
  574. _videoCodecConfigurable[2] = false;
  575. _videoCodecConfigurable[3] = false;
  576. for (int i = 0; i < numVideoCodecs; i++)
  577. {
  578. _videoCodecNames[i + 4] = i.ToString("D2") + ") " + NativePlugin.GetAVIVideoCodecName(i).Replace("/", "_");
  579. _videoCodecConfigurable[i + 4] = NativePlugin.IsConfigureVideoCodecSupported(i);
  580. }
  581. }
  582. // Audio device enumeration
  583. {
  584. int numAudioDevices = Mathf.Max(0, NativePlugin.GetNumAVIAudioInputDevices());
  585. _audioDeviceNames = new string[numAudioDevices + 2];
  586. _audioDeviceNames[0] = "Unity";
  587. _audioDeviceNames[1] = string.Empty;
  588. for (int i = 0; i < numAudioDevices; i++)
  589. {
  590. _audioDeviceNames[i + 2] = i.ToString("D2") + ") " + NativePlugin.GetAVIAudioInputDeviceName(i).Replace("/", "_");
  591. }
  592. }
  593. // Audio codec enumeration
  594. {
  595. int numAudioCodecs = Mathf.Max(0, NativePlugin.GetNumAVIAudioCodecs());
  596. _audioCodecNames = new string[numAudioCodecs + 2];
  597. _audioCodecNames[0] = "Uncompressed";
  598. _audioCodecNames[1] = string.Empty;
  599. _audioCodecConfigurable = new bool[numAudioCodecs + 2];
  600. _audioCodecConfigurable[0] = false;
  601. _audioCodecConfigurable[1] = false;
  602. for (int i = 0; i < numAudioCodecs; i++)
  603. {
  604. _audioCodecNames[i + 2] = i.ToString("D2") + ") " + NativePlugin.GetAVIAudioCodecName(i).Replace("/", "_");
  605. _audioCodecConfigurable[i + 2] = NativePlugin.IsConfigureAudioCodecSupported(i);
  606. }
  607. }
  608. _isInit = true;
  609. }
  610. private void OnEnable()
  611. {
  612. if (_icon == null)
  613. {
  614. _icon = Resources.Load<Texture2D>("AVProMovieCaptureIcon");
  615. }
  616. if (!_isCreated)
  617. {
  618. SetupWindow();
  619. }
  620. _isTrialVersion = IsTrialVersion();
  621. // Check that the plugin version number is not too old
  622. {
  623. float pluginVersion = NativePlugin.GetPluginVersion();
  624. string pluginVersionString = pluginVersion.ToString("F2");
  625. if (_isTrialVersion)
  626. {
  627. pluginVersionString += "t";
  628. }
  629. _pluginVersionWarningText = string.Empty;
  630. if (pluginVersion.ToString("F2") != NativePlugin.ExpectedPluginVersion)
  631. {
  632. _pluginVersionWarningText = "Warning: Plugin version number " + pluginVersionString + " doesn't match the expected version number " + NativePlugin.ExpectedPluginVersion + ". It looks like the plugin didn't upgrade correctly. To resolve this please restart Unity and try to upgrade the package again.";
  633. }
  634. }
  635. }
  636. private void OnDisable()
  637. {
  638. SaveSettings();
  639. StopCapture();
  640. _isInit = false;
  641. _isCreated = false;
  642. Repaint();
  643. }
  644. private void StartCapture()
  645. {
  646. _lastFileSize = 0;
  647. _lastEncodedSeconds = 0;
  648. _lastEncodedMinutes = 0;
  649. _lastEncodedFrame = 0;
  650. CreateComponents();
  651. if (_capture != null)
  652. {
  653. Configure(_capture);
  654. _capture.SelectCodec(false);
  655. if (!_capture._noAudio)
  656. {
  657. _capture.SelectAudioCodec(false);
  658. _capture.SelectAudioDevice(false);
  659. }
  660. _capture.QueueStartCapture();
  661. }
  662. }
  663. private void StopCapture(bool cancelCapture = false)
  664. {
  665. if (_capture != null)
  666. {
  667. if (_capture.IsCapturing())
  668. {
  669. if (!cancelCapture)
  670. {
  671. _capture.StopCapture();
  672. }
  673. else
  674. {
  675. _capture.CancelCapture();
  676. }
  677. }
  678. _capture = null;
  679. _captureScreen = null;
  680. _captureCamera = null;
  681. }
  682. }
  683. // Updates 10 times/second
  684. void OnInspectorUpdate()
  685. {
  686. if (_capture != null)
  687. {
  688. if (Application.isPlaying)
  689. {
  690. _lastFileSize = _capture.GetCaptureFileSize();
  691. if (!_capture._isRealTime)
  692. {
  693. _lastEncodedSeconds = (uint)Mathf.FloorToInt((float)_capture.NumEncodedFrames / (float)_capture._frameRate);
  694. }
  695. else
  696. {
  697. _lastEncodedSeconds = _capture.TotalEncodedSeconds;
  698. }
  699. _lastEncodedMinutes = _lastEncodedSeconds / 60;
  700. _lastEncodedSeconds = _lastEncodedSeconds % 60;
  701. _lastEncodedFrame = _capture.NumEncodedFrames % (uint)_capture._frameRate;
  702. // If the capture has stopped automatically, we need to update the UI
  703. if (_capture._stopMode != StopMode.None && _capture.NumEncodedFrames > 0 && !_capture.IsCapturing())
  704. {
  705. StopCapture();
  706. }
  707. }
  708. else
  709. {
  710. StopCapture();
  711. }
  712. }
  713. else
  714. {
  715. if (_queueConfigureVideoCodec >= 0)
  716. {
  717. int configureVideoCodec = _queueConfigureVideoCodec;
  718. _queueConfigureVideoCodec = -1;
  719. NativePlugin.Init();
  720. NativePlugin.ConfigureVideoCodec(configureVideoCodec);
  721. }
  722. if (_queueConfigureAudioCodec >= 0)
  723. {
  724. int configureAudioCodec = _queueConfigureAudioCodec;
  725. _queueConfigureAudioCodec = -1;
  726. NativePlugin.Init();
  727. NativePlugin.ConfigureAudioCodec(configureAudioCodec);
  728. }
  729. if (_queueStart && Application.isPlaying)
  730. {
  731. _queueStart = false;
  732. StartCapture();
  733. }
  734. }
  735. Repaint();
  736. }
  737. private static bool ShowConfigList(string title, string[] items, bool[] isConfigurable, ref int itemIndex, bool showConfig = true, bool listEnabled = true)
  738. {
  739. bool result = false;
  740. if (itemIndex < 0 || items == null)
  741. return result;
  742. if (!string.IsNullOrEmpty(title))
  743. {
  744. EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
  745. }
  746. EditorGUI.BeginDisabledGroup(!listEnabled);
  747. EditorGUILayout.BeginHorizontal();
  748. itemIndex = EditorGUILayout.Popup(itemIndex, items);
  749. if (showConfig && isConfigurable != null && itemIndex < isConfigurable.Length)
  750. {
  751. EditorGUI.BeginDisabledGroup(itemIndex == 0 || !isConfigurable[itemIndex]);
  752. if (GUILayout.Button("Configure"))
  753. {
  754. result = true;
  755. }
  756. EditorGUI.EndDisabledGroup();
  757. }
  758. EditorGUILayout.EndHorizontal();
  759. EditorGUI.EndDisabledGroup();
  760. return result;
  761. }
  762. void OnGUI()
  763. {
  764. if (Application.platform != RuntimePlatform.WindowsEditor)
  765. {
  766. EditorGUILayout.LabelField("AVPro Movie Capture only works on the Windows platform.");
  767. return;
  768. }
  769. if (!_isInit)
  770. {
  771. if (_isFailedInit)
  772. {
  773. GUILayout.Label("Error", EditorStyles.boldLabel);
  774. GUI.enabled = false;
  775. string missingDllMessage = string.Empty;
  776. #if (UNITY_5 || UNITY_5_4_OR_NEWER)
  777. missingDllMessage = "Unity couldn't find the plugin DLL. Please select the native plugin files in 'Plugins/RenderHeads/AVProMovieCapture/Plugins' folder and select the correct platform in the Inspector.";
  778. #else
  779. missingDllMessage = "Unity couldn't find the plugin DLL, Unity 4.x requires the 'Plugins' folder to be at the root of your project. Please move the contents of the 'Plugins' folder (in Plugins/RenderHeads/AVProMovieCapture/Plugins) to the 'Plugins' folder in the root of your project.";
  780. #endif
  781. GUILayout.TextArea(missingDllMessage);
  782. GUI.enabled = true;
  783. return;
  784. }
  785. else
  786. {
  787. EditorGUILayout.LabelField("Initialising...");
  788. return;
  789. }
  790. }
  791. if (!string.IsNullOrEmpty(_pluginVersionWarningText))
  792. {
  793. GUI.color = Color.yellow;
  794. GUILayout.TextArea(_pluginVersionWarningText);
  795. GUI.color = Color.white;
  796. }
  797. if (_so == null)
  798. {
  799. return;
  800. }
  801. _so.Update();
  802. #if AVPRO_MOVIECAPTURE_GRAPHICSDEVICETYPE_51
  803. if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.Direct3D11)
  804. {
  805. GUI.color = Color.yellow;
  806. GUILayout.TextArea("Consider switching to Direct3D11 for best capture results. You may need to change your Build platform to Windows.");
  807. GUI.color = Color.white;
  808. }
  809. #endif
  810. if (_isTrialVersion)
  811. {
  812. EditorUtils.DrawSectionColored("- AVPRO MOVIE CAPTURE - FREE TRIAL VERSION", ref _expandSectionTrial, DrawTrialMessage, Color.yellow, Color.yellow, Color.yellow);
  813. //EditorGUILayout.Space();
  814. }
  815. DrawControlButtonsGUI();
  816. EditorGUILayout.Space();
  817. // Live Capture Stats
  818. if (Application.isPlaying && _capture != null && _capture.IsCapturing())
  819. {
  820. if (_propStopMode.enumValueIndex != (int)StopMode.None)
  821. {
  822. Rect r = GUILayoutUtility.GetRect(128f, EditorStyles.label.CalcHeight(GUIContent.none, 32f), GUILayout.ExpandWidth(true));
  823. float progress = _capture.GetProgress();
  824. EditorGUI.ProgressBar(r, progress, (progress * 100f).ToString("F1") + "%");
  825. }
  826. _scroll = EditorGUILayout.BeginScrollView(_scroll);
  827. DrawBaseCapturingGUI(_capture);
  828. DrawMoreCapturingGUI();
  829. EditorGUILayout.EndScrollView();
  830. }
  831. // Configuration
  832. else if (_capture == null)
  833. {
  834. string[] _toolNames = { "Settings", "About" };
  835. _selectedTool = GUILayout.Toolbar(_selectedTool, _toolNames);
  836. switch (_selectedTool)
  837. {
  838. case 0:
  839. DrawConfigGUI_Toolbar();
  840. _scroll = EditorGUILayout.BeginScrollView(_scroll);
  841. DrawConfigGUI();
  842. EditorGUILayout.EndScrollView();
  843. break;
  844. case 1:
  845. _scroll = EditorGUILayout.BeginScrollView(_scroll);
  846. DrawConfigGUI_About();
  847. EditorGUILayout.EndScrollView();
  848. break;
  849. }
  850. }
  851. if (_so.ApplyModifiedProperties())
  852. {
  853. EditorUtility.SetDirty(this);
  854. }
  855. }
  856. private void DrawTrialMessage()
  857. {
  858. string message = "The free trial version is limited to 10 seconds of capture time. UPGRADE to the full package for unlimited use.";
  859. //GUI.backgroundColor = Color.yellow;
  860. //EditorGUILayout.BeginVertical(GUI.skin.box);
  861. //GUI.color = Color.yellow;
  862. //GUILayout.Label("AVPRO MOVIE CAPTURE - FREE TRIAL VERSION", EditorStyles.boldLabel);
  863. GUI.color = Color.white;
  864. GUILayout.Label(message, EditorStyles.wordWrappedLabel);
  865. if (GUILayout.Button("Upgrade Now"))
  866. {
  867. Application.OpenURL("https://www.assetstore.unity3d.com/en/#!/content/2670");
  868. }
  869. //EditorGUILayout.EndVertical();
  870. GUI.backgroundColor = Color.white;
  871. GUI.color = Color.white;
  872. }
  873. private void DrawControlButtonsGUI()
  874. {
  875. EditorGUILayout.BeginHorizontal();
  876. if (_capture == null)
  877. {
  878. GUI.backgroundColor = Color.green;
  879. string startString = "Start Capture";
  880. if (_captureModeIndex == 1)
  881. {
  882. startString = "Start Render";
  883. }
  884. if (GUILayout.Button(startString, GUILayout.Height(32f)))
  885. {
  886. bool isReady = true;
  887. if (_sourceType == SourceType.Camera && _cameraNode == null)
  888. {
  889. Debug.LogError("[AVProMovieCapture] Please select a Camera to capture from, or select to capture from Screen.");
  890. isReady = false;
  891. }
  892. if (isReady)
  893. {
  894. if (!Application.isPlaying)
  895. {
  896. EditorApplication.isPlaying = true;
  897. _queueStart = true;
  898. }
  899. else
  900. {
  901. StartCapture();
  902. Repaint();
  903. }
  904. }
  905. }
  906. }
  907. else
  908. {
  909. GUI.backgroundColor = Color.cyan;
  910. if (GUILayout.Button("Cancel", GUILayout.Height(32f)))
  911. {
  912. StopCapture(true);
  913. Repaint();
  914. }
  915. GUI.backgroundColor = Color.red;
  916. if (GUILayout.Button("Stop", GUILayout.Height(32f)))
  917. {
  918. StopCapture(false);
  919. Repaint();
  920. }
  921. if (_capture != null)
  922. {
  923. if (_capture.IsPaused())
  924. {
  925. GUI.backgroundColor = Color.green;
  926. if (GUILayout.Button("Resume", GUILayout.Height(32f)))
  927. {
  928. _capture.ResumeCapture();
  929. Repaint();
  930. }
  931. }
  932. else
  933. {
  934. GUI.backgroundColor = Color.yellow;
  935. if (GUILayout.Button("Pause", GUILayout.Height(32f)))
  936. {
  937. _capture.PauseCapture();
  938. Repaint();
  939. }
  940. }
  941. }
  942. }
  943. EditorGUILayout.EndHorizontal();
  944. GUI.backgroundColor = Color.white;
  945. GUILayout.BeginHorizontal();
  946. if (GUILayout.Button("Browse"))
  947. {
  948. if (!string.IsNullOrEmpty(CaptureBase.LastFileSaved))
  949. {
  950. Utils.ShowInExplorer(CaptureBase.LastFileSaved);
  951. }
  952. }
  953. if (GUILayout.Button("View Last Capture"))
  954. {
  955. if (!string.IsNullOrEmpty(CaptureBase.LastFileSaved))
  956. {
  957. Utils.OpenInDefaultApp(CaptureBase.LastFileSaved);
  958. }
  959. }
  960. GUILayout.EndHorizontal();
  961. }
  962. public static void DrawBaseCapturingGUI(CaptureBase capture)
  963. {
  964. GUILayout.Space(8.0f);
  965. Texture texture = capture.GetPreviewTexture();
  966. if (texture != null)
  967. {
  968. float width = Screen.width - (Screen.width / 8f);
  969. width = (Screen.width / 2f) - (Screen.width / 16f);
  970. float aspect = (float)texture.width / (float)texture.height;
  971. GUILayout.BeginHorizontal();
  972. GUILayout.FlexibleSpace();
  973. if (_showAlpha)
  974. {
  975. width = (Screen.width / 2f) - (Screen.width / 16f);
  976. Rect textureRect = GUILayoutUtility.GetRect(width, width / aspect, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
  977. EditorGUI.DrawPreviewTexture(textureRect, texture, null, ScaleMode.ScaleToFit);
  978. //textureRect = GUILayoutUtility.GetRect(width, width / aspect);
  979. textureRect = GUILayoutUtility.GetRect(width, width / aspect, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false)); ;
  980. EditorGUI.DrawTextureAlpha(textureRect, texture, ScaleMode.ScaleToFit);
  981. }
  982. else
  983. {
  984. Rect textureRect = GUILayoutUtility.GetRect(width, width / aspect, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
  985. EditorGUI.DrawPreviewTexture(textureRect, texture, null, ScaleMode.ScaleToFit);
  986. }
  987. GUILayout.FlexibleSpace();
  988. GUILayout.EndHorizontal();
  989. GUILayout.BeginHorizontal();
  990. GUILayout.FlexibleSpace();
  991. _showAlpha = GUILayout.Toggle(_showAlpha, "Show Alpha", GUILayout.ExpandWidth(false));
  992. GUILayout.FlexibleSpace();
  993. GUILayout.EndHorizontal();
  994. GUILayout.Space(8.0f);
  995. }
  996. GUILayout.Label("Output", EditorStyles.boldLabel);
  997. EditorGUILayout.BeginVertical("box");
  998. EditorGUI.indentLevel++;
  999. GUILayout.Label("Recording to: " + System.IO.Path.GetFileName(capture.LastFilePath), EditorStyles.wordWrappedLabel);
  1000. GUILayout.Space(8.0f);
  1001. GUILayout.Label("Video");
  1002. EditorGUILayout.LabelField("Dimensions", capture.GetRecordingWidth() + "x" + capture.GetRecordingHeight() + " @ " + ((int)capture._frameRate).ToString() + "hz");
  1003. if (!capture._useMediaFoundationH264)
  1004. {
  1005. EditorGUILayout.LabelField("Codec", capture._codecName);
  1006. }
  1007. else
  1008. {
  1009. EditorGUILayout.LabelField("Codec", "Media Foundation H.264");
  1010. }
  1011. if (!capture._noAudio && capture._isRealTime)
  1012. {
  1013. GUILayout.Label("Audio");
  1014. EditorGUILayout.LabelField("Source", capture._audioDeviceName);
  1015. EditorGUILayout.LabelField("Codec", capture._audioCodecName);
  1016. if (capture._audioDeviceName == "Unity")
  1017. {
  1018. EditorGUILayout.LabelField("Sample Rate", capture._unityAudioSampleRate.ToString() + "hz");
  1019. EditorGUILayout.LabelField("Channels", capture._unityAudioChannelCount.ToString());
  1020. }
  1021. }
  1022. EditorGUI.indentLevel--;
  1023. EditorGUILayout.EndVertical();
  1024. GUILayout.Space(8.0f);
  1025. GUILayout.Label("Stats", EditorStyles.boldLabel);
  1026. EditorGUILayout.BeginVertical("box");
  1027. EditorGUI.indentLevel++;
  1028. if (capture.FPS > 0f)
  1029. {
  1030. Color originalColor = GUI.color;
  1031. if (capture._isRealTime)
  1032. {
  1033. float fpsDelta = (capture.FPS - (int)capture._frameRate);
  1034. GUI.color = Color.red;
  1035. if (fpsDelta > -10)
  1036. {
  1037. GUI.color = Color.yellow;
  1038. }
  1039. if (fpsDelta > -2)
  1040. {
  1041. GUI.color = Color.green;
  1042. }
  1043. }
  1044. EditorGUILayout.LabelField("Capture Rate", string.Format("{0:0.##} / {1} FPS", capture.FPS, (int)capture._frameRate));
  1045. GUI.color = originalColor;
  1046. }
  1047. else
  1048. {
  1049. EditorGUILayout.LabelField("Capture Rate", string.Format(".. / {0} FPS", (int)capture._frameRate));
  1050. }
  1051. EditorGUILayout.LabelField("Encoded Frames", capture.NumEncodedFrames.ToString());
  1052. EditorGUI.indentLevel--;
  1053. EditorGUILayout.EndVertical();
  1054. }
  1055. public void DrawMoreCapturingGUI()
  1056. {
  1057. GUILayout.Label("More Stats", EditorStyles.boldLabel);
  1058. EditorGUILayout.BeginVertical("box");
  1059. EditorGUI.indentLevel++;
  1060. EditorGUILayout.LabelField("File Size", ((float)_lastFileSize / (1024f * 1024f)).ToString("F1") + "MB");
  1061. EditorGUILayout.LabelField("Video Length", _lastEncodedMinutes.ToString("00") + ":" + _lastEncodedSeconds.ToString("00") + "." + _lastEncodedFrame.ToString("000"));
  1062. GUILayout.Label("Dropped Frames");
  1063. EditorGUILayout.LabelField("In Unity", _capture.NumDroppedFrames.ToString());
  1064. EditorGUILayout.LabelField("In Encoder", _capture.NumDroppedEncoderFrames.ToString());
  1065. if (!_capture._noAudio && _capture._isRealTime)
  1066. {
  1067. if (_capture._audioCapture && _capture._audioDeviceName == "Unity")
  1068. {
  1069. EditorGUILayout.LabelField("Audio Overflows", _capture._audioCapture.OverflowCount.ToString());
  1070. }
  1071. }
  1072. EditorGUI.indentLevel--;
  1073. EditorGUILayout.EndVertical();
  1074. }
  1075. private void DrawConfigGUI_Toolbar()
  1076. {
  1077. string[] _toolNames = { "General", "Visual", "Audio", "Output" };
  1078. _selectedConfigTool = GUILayout.Toolbar(_selectedConfigTool, _toolNames);
  1079. }
  1080. private void DrawConfigGUI()
  1081. {
  1082. switch (_selectedConfigTool)
  1083. {
  1084. case 0:
  1085. DrawConfigGUI_General();
  1086. break;
  1087. case 1:
  1088. DrawConfigGUI_Visual();
  1089. break;
  1090. case 2:
  1091. DrawConfigGUI_Audio();
  1092. break;
  1093. case 3:
  1094. DrawConfigGUI_Output();
  1095. break;
  1096. }
  1097. GUILayout.FlexibleSpace();
  1098. }
  1099. public static void DrawConfigGUI_About()
  1100. {
  1101. string version = NativePlugin.GetPluginVersion().ToString("F2");
  1102. EditorGUILayout.BeginHorizontal();
  1103. GUILayout.FlexibleSpace();
  1104. if (_icon == null)
  1105. {
  1106. _icon = Resources.Load<Texture2D>("AVProMovieCaptureIcon");
  1107. }
  1108. if (_icon != null)
  1109. {
  1110. GUILayout.Label(new GUIContent(_icon));
  1111. }
  1112. GUILayout.FlexibleSpace();
  1113. EditorGUILayout.EndHorizontal();
  1114. EditorGUILayout.BeginHorizontal();
  1115. GUILayout.FlexibleSpace();
  1116. GUI.color = Color.yellow;
  1117. GUILayout.Label("AVPro Movie Capture by RenderHeads Ltd", EditorStyles.boldLabel);
  1118. GUI.color = Color.white;
  1119. GUILayout.FlexibleSpace();
  1120. EditorGUILayout.EndHorizontal();
  1121. EditorGUILayout.BeginHorizontal();
  1122. GUILayout.FlexibleSpace();
  1123. GUI.color = Color.yellow;
  1124. GUILayout.Label("version " + version + " (scripts v" + NativePlugin.ScriptVersion + ")");
  1125. GUI.color = Color.white;
  1126. GUILayout.FlexibleSpace();
  1127. EditorGUILayout.EndHorizontal();
  1128. // Links
  1129. {
  1130. GUILayout.Space(32f);
  1131. GUI.backgroundColor = Color.white;
  1132. EditorGUILayout.LabelField("AVPro Movie Capture Links", EditorStyles.boldLabel);
  1133. GUILayout.Space(8f);
  1134. EditorGUILayout.LabelField("Documentation");
  1135. EditorGUILayout.BeginHorizontal();
  1136. if (GUILayout.Button("User Manual", GUILayout.ExpandWidth(false)))
  1137. {
  1138. Application.OpenURL(LinkUserManual);
  1139. }
  1140. EditorGUILayout.EndHorizontal();
  1141. GUILayout.Space(16f);
  1142. GUILayout.Label("Rate and Review (★★★★☆)", GUILayout.ExpandWidth(false));
  1143. if (GUILayout.Button("Unity Asset Store Page", GUILayout.ExpandWidth(false)))
  1144. {
  1145. if (!_isTrialVersion)
  1146. {
  1147. Application.OpenURL(LinkAssetStorePage);
  1148. }
  1149. else
  1150. {
  1151. Application.OpenURL(LinkFreeAssetStorePage);
  1152. }
  1153. }
  1154. GUILayout.Space(16f);
  1155. GUILayout.Label("Community");
  1156. if (GUILayout.Button("Unity Forum Page", GUILayout.ExpandWidth(false)))
  1157. {
  1158. Application.OpenURL(LinkForumPage);
  1159. }
  1160. GUILayout.Space(16f);
  1161. GUILayout.Label("Homepage", GUILayout.ExpandWidth(false));
  1162. if (GUILayout.Button("AVPro Movie Capture Website", GUILayout.ExpandWidth(false)))
  1163. {
  1164. Application.OpenURL(LinkPluginWebsite);
  1165. }
  1166. GUILayout.Space(16f);
  1167. GUILayout.Label("Bugs and Support");
  1168. EditorGUILayout.BeginHorizontal();
  1169. if (GUILayout.Button("Email unitysupport@renderheads.com", GUILayout.ExpandWidth(false)))
  1170. {
  1171. Application.OpenURL(LinkEmailSupport);
  1172. }
  1173. EditorGUILayout.EndHorizontal();
  1174. }
  1175. // Credits
  1176. {
  1177. GUILayout.Space(32f);
  1178. EditorGUILayout.LabelField("Credits", EditorStyles.boldLabel);
  1179. GUILayout.Space(8f);
  1180. EditorUtils.CentreLabel("Programming", EditorStyles.boldLabel);
  1181. EditorUtils.CentreLabel("Andrew Griffiths");
  1182. EditorUtils.CentreLabel("Sunrise Wang");
  1183. GUILayout.Space(8f);
  1184. EditorUtils.CentreLabel("Graphics", EditorStyles.boldLabel);
  1185. EditorUtils.CentreLabel("Jeff Rusch");
  1186. EditorUtils.CentreLabel("Luke Godward");
  1187. }
  1188. // Bug reporting
  1189. {
  1190. GUILayout.Space(32f);
  1191. EditorGUILayout.LabelField("Bug Reporting Notes", EditorStyles.boldLabel);
  1192. EditorGUILayout.SelectableLabel(SupportMessage, EditorStyles.wordWrappedLabel, GUILayout.Height(180f));
  1193. }
  1194. }
  1195. private void DrawConfigGUI_General()
  1196. {
  1197. //GUILayout.Label("General", EditorStyles.boldLabel);
  1198. EditorGUILayout.BeginVertical("box");
  1199. //EditorGUI.indentLevel++;
  1200. // Time
  1201. {
  1202. GUILayout.Space(8f);
  1203. EditorGUILayout.LabelField("Time", EditorStyles.boldLabel);
  1204. EditorGUI.indentLevel++;
  1205. _captureModeIndex = EditorGUILayout.Popup("Capture Mode", _captureModeIndex, _captureModes);
  1206. EditorUtils.EnumAsDropdown("Frame Rate", _propFrameRate, new string[] { "1", "10", "15", "24", "25", "30", "50", "60", "75", "90", "120" });
  1207. //_frameRate = (CaptureBase.FrameRate)EditorGUILayout.EnumPopup("Frame Rate", _frameRate);
  1208. EditorGUI.indentLevel--;
  1209. }
  1210. // Source
  1211. GUILayout.Space(8f);
  1212. EditorGUILayout.LabelField("Source", EditorStyles.boldLabel);
  1213. EditorGUI.indentLevel++;
  1214. EditorUtils.EnumAsDropdown("Source", _propSourceType, _sourceNames);
  1215. if (_sourceType == SourceType.Camera360ODS && _captureModeIndex == 0)
  1216. {
  1217. GUI.color = Color.yellow;
  1218. GUILayout.TextArea("Warning: This source type is very slow and not suitable for 'Realtime Capture'. Consider changing the capture mode to 'Offline Render'.");
  1219. GUI.color = Color.white;
  1220. }
  1221. //_sourceType = (SourceType)EditorGUILayout.EnumPopup("Type", _sourceType);
  1222. if (_sourceType == SourceType.Camera || _sourceType == SourceType.Camera360 || _sourceType == SourceType.Camera360ODS)
  1223. {
  1224. if (_cameraNode == null)
  1225. {
  1226. _cameraNode = Utils.GetUltimateRenderCamera();
  1227. }
  1228. _cameraNode = (Camera)EditorGUILayout.ObjectField("Camera", _cameraNode, typeof(Camera), true);
  1229. if (_sourceType == SourceType.Camera && _cameraNode != null)
  1230. {
  1231. EditorGUILayout.PropertyField(_propUseContributingCameras, new GUIContent("Contributing Cameras"));
  1232. }
  1233. }
  1234. EditorGUI.indentLevel--;
  1235. // Screen options
  1236. if (_sourceType == SourceType.Screen)
  1237. {
  1238. GUILayout.Space(8f);
  1239. EditorGUILayout.LabelField("Cursor", EditorStyles.boldLabel);
  1240. EditorGUI.indentLevel++;
  1241. _captureMouseCursor = EditorGUILayout.Toggle("Capture Mouse Cursor", _captureMouseCursor);
  1242. _mouseCursorTexture = (Texture2D)EditorGUILayout.ObjectField("Mouse Cursor Texture", _mouseCursorTexture, typeof(Texture2D), false);
  1243. EditorGUI.indentLevel--;
  1244. }
  1245. // Camera overrides
  1246. if (_sourceType == SourceType.Camera || _sourceType == SourceType.Camera360 || _sourceType == SourceType.Camera360ODS)
  1247. {
  1248. GUILayout.Space(8f);
  1249. EditorGUILayout.LabelField("Camera Overrides", EditorStyles.boldLabel);
  1250. EditorGUI.indentLevel++;
  1251. {
  1252. EditorUtils.EnumAsDropdown("Resolution", _propRenderResolution, CaptureBaseEditor.ResolutionStrings);
  1253. }
  1254. if (_renderResolution == CaptureBase.Resolution.Custom)
  1255. {
  1256. _renderSize = EditorGUILayout.Vector2Field("Size", _renderSize);
  1257. _renderSize = new Vector2(Mathf.Clamp((int)_renderSize.x, 1, NativePlugin.MaxRenderWidth), Mathf.Clamp((int)_renderSize.y, 1, NativePlugin.MaxRenderHeight));
  1258. }
  1259. {
  1260. string currentAA = "None";
  1261. if (QualitySettings.antiAliasing > 1)
  1262. {
  1263. currentAA = QualitySettings.antiAliasing.ToString() + "x";
  1264. }
  1265. EditorUtils.IntAsDropdown("Anti-aliasing", _propRenderAntiAliasing, new string[] { "Current (" + currentAA + ")", "None", "2x", "4x", "8x" }, new int[] { -1, 1, 2, 4, 8 });
  1266. }
  1267. if (_cameraNode != null)
  1268. {
  1269. if (_cameraNode.actualRenderingPath == RenderingPath.DeferredLighting
  1270. #if AVPRO_MOVIECAPTURE_DEFERREDSHADING
  1271. || _cameraNode.actualRenderingPath == RenderingPath.DeferredShading
  1272. #endif
  1273. )
  1274. {
  1275. GUI.color = Color.yellow;
  1276. GUILayout.TextArea("Warning: Antialiasing by MSAA is not supported as camera is using deferred rendering path");
  1277. GUI.color = Color.white;
  1278. _renderAntiAliasing = -1;
  1279. }
  1280. if (_cameraNode.clearFlags == CameraClearFlags.Nothing || _cameraNode.clearFlags == CameraClearFlags.Depth)
  1281. {
  1282. if (_renderResolution != CaptureBase.Resolution.Original || _renderAntiAliasing != -1)
  1283. {
  1284. GUI.color = Color.yellow;
  1285. GUILayout.TextArea("Warning: Overriding camera resolution or anti-aliasing when clear flag is set to " + _cameraNode.clearFlags + " may result in incorrect captures");
  1286. GUI.color = Color.white;
  1287. }
  1288. }
  1289. }
  1290. EditorGUI.indentLevel--;
  1291. }
  1292. // 360 Cubemap
  1293. if (_sourceType == SourceType.Camera360)
  1294. {
  1295. GUILayout.Space(8f);
  1296. EditorGUILayout.LabelField("360 Camera", EditorStyles.boldLabel);
  1297. EditorGUI.indentLevel++;
  1298. {
  1299. CaptureBase.CubemapResolution cubemapEnum = (CaptureBase.CubemapResolution)_cubemapResolution;
  1300. _cubemapResolution = (int)((CaptureBase.CubemapResolution)EditorGUILayout.EnumPopup("Resolution", cubemapEnum));
  1301. }
  1302. {
  1303. CaptureBase.CubemapDepth depthEnum = (CaptureBase.CubemapDepth)_cubemapDepth;
  1304. _cubemapDepth = (int)((CaptureBase.CubemapDepth)EditorGUILayout.EnumPopup("Depth", depthEnum));
  1305. }
  1306. {
  1307. StereoPacking stereoEnum = (StereoPacking)_cubemapStereoPacking;
  1308. _cubemapStereoPacking = (int)((StereoPacking)EditorGUILayout.EnumPopup("Stereo Mode", stereoEnum));
  1309. }
  1310. if (_cubemapStereoPacking != (int)StereoPacking.None)
  1311. {
  1312. _cubemapStereoIPD = EditorGUILayout.FloatField("Interpupillary distance", _cubemapStereoIPD);
  1313. }
  1314. EditorGUI.indentLevel--;
  1315. }
  1316. // 360 Cubemap ODS
  1317. if (_sourceType == SourceType.Camera360ODS)
  1318. {
  1319. GUILayout.Space(8f);
  1320. EditorGUI.indentLevel++;
  1321. EditorGUILayout.LabelField("Source Options", EditorStyles.boldLabel);
  1322. EditorGUI.indentLevel++;
  1323. {
  1324. EditorGUILayout.PropertyField(_propOdsIPD, new GUIContent("Interpupillary distance"));
  1325. EditorGUILayout.PropertyField(_propOdsPixelSliceSize);
  1326. EditorGUILayout.PropertyField(_propOdsPaddingSize);
  1327. EditorGUILayout.PropertyField(_propOdsCameraClearMode);
  1328. EditorGUILayout.PropertyField(_propOdsCameraClearColor);
  1329. }
  1330. EditorGUI.indentLevel--;
  1331. EditorGUI.indentLevel--;
  1332. }
  1333. // Start / Stop
  1334. {
  1335. GUILayout.Space(8f);
  1336. EditorGUILayout.LabelField("Start / Stop", EditorStyles.boldLabel);
  1337. EditorGUI.indentLevel++;
  1338. _startPaused = EditorGUILayout.Toggle("Start Paused", _startPaused);
  1339. _stopMode = (StopMode)EditorGUILayout.EnumPopup("Stop Mode", _stopMode);
  1340. if (_stopMode == StopMode.FramesEncoded)
  1341. {
  1342. _stopFrames = EditorGUILayout.IntField("Frames", _stopFrames);
  1343. }
  1344. else if (_stopMode == StopMode.SecondsElapsed || _stopMode == StopMode.SecondsEncoded)
  1345. {
  1346. _stopSeconds = EditorGUILayout.FloatField("Seconds", _stopSeconds);
  1347. }
  1348. EditorGUI.indentLevel--;
  1349. }
  1350. GUILayout.Space(8f);
  1351. if (GUILayout.Button("Reset All Settings"))
  1352. {
  1353. ResetSettings();
  1354. }
  1355. GUILayout.Space(4f);
  1356. //EditorGUI.indentLevel--;
  1357. EditorGUILayout.EndVertical();
  1358. }
  1359. private void DrawConfigGUI_Output()
  1360. {
  1361. //GUILayout.Label("Target", EditorStyles.boldLabel);
  1362. EditorGUILayout.BeginVertical("box");
  1363. //EditorGUI.indentLevel++;
  1364. EditorUtils.EnumAsDropdown("Output Type", _propOutputType, new string[] { "Video File", "Named Pipe" });
  1365. GUILayout.Space(8f);
  1366. if (_propOutputType.enumValueIndex == (int)CaptureBase.OutputType.VideoFile)
  1367. {
  1368. // File path
  1369. EditorGUILayout.LabelField("File Path", EditorStyles.boldLabel);
  1370. EditorGUI.indentLevel++;
  1371. _outputFolderIndex = EditorGUILayout.Popup("Relative to", _outputFolderIndex, _outputFolders);
  1372. if (_outputFolderIndex == 0 || _outputFolderIndex == 1)
  1373. {
  1374. _outputFolderRelative = EditorGUILayout.TextField("SubFolder(s)", _outputFolderRelative);
  1375. }
  1376. else
  1377. {
  1378. EditorGUILayout.BeginHorizontal();
  1379. _outputFolderAbsolute = EditorGUILayout.TextField("Path", _outputFolderAbsolute);
  1380. if (GUILayout.Button(">", GUILayout.Width(22)))
  1381. {
  1382. _outputFolderAbsolute = EditorUtility.SaveFolderPanel("Select Folder To Store Video Captures", System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath, "../")), "");
  1383. EditorUtility.SetDirty(this);
  1384. }
  1385. EditorGUILayout.EndHorizontal();
  1386. }
  1387. EditorGUI.indentLevel--;
  1388. GUILayout.Space(8f);
  1389. // File name
  1390. EditorGUILayout.LabelField("File Name", EditorStyles.boldLabel);
  1391. EditorGUI.indentLevel++;
  1392. _autoFilenamePrefixFromSceneName = EditorGUILayout.Toggle("From Scene Name", _autoFilenamePrefixFromSceneName);
  1393. if (_autoFilenamePrefixFromSceneName)
  1394. {
  1395. #if AVPRO_MOVIECAPTURE_SCENEMANAGER_53
  1396. string currentScenePath = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().path;
  1397. #else
  1398. string currentScenePath = EditorApplication.currentScene;
  1399. #endif
  1400. _autoFilenamePrefix = System.IO.Path.GetFileNameWithoutExtension(currentScenePath);
  1401. if (string.IsNullOrEmpty(_autoFilenamePrefix))
  1402. {
  1403. _autoFilenamePrefix = "capture";
  1404. }
  1405. }
  1406. EditorGUI.BeginDisabledGroup(_autoFilenamePrefixFromSceneName);
  1407. _autoFilenamePrefix = EditorGUILayout.TextField("Prefix", _autoFilenamePrefix);
  1408. EditorGUI.EndDisabledGroup();
  1409. _autoFilenameExtension = EditorGUILayout.TextField("Extension", _autoFilenameExtension);
  1410. _appendTimestamp = EditorGUILayout.Toggle("Append Timestamp", _appendTimestamp);
  1411. EditorGUI.indentLevel--;
  1412. }
  1413. else if (_propOutputType.enumValueIndex == (int)CaptureBase.OutputType.NamedPipe)
  1414. {
  1415. EditorGUILayout.PropertyField(_propNamedPipePath);
  1416. }
  1417. //EditorGUI.indentLevel--;
  1418. EditorGUILayout.EndVertical();
  1419. }
  1420. private void DrawConfigGUI_Visual()
  1421. {
  1422. //GUILayout.Label("Video", EditorStyles.boldLabel);
  1423. EditorGUILayout.BeginVertical("box");
  1424. //EditorGUI.indentLevel++;
  1425. {
  1426. Vector2 outSize = Vector2.zero;
  1427. if (_sourceType == SourceType.Screen)
  1428. {
  1429. // We can't just use Screen.width and Screen.height because Unity returns the size of this window
  1430. // So instead we look for a camera with no texture target and a valid viewport
  1431. int inWidth = 1;
  1432. int inHeight = 1;
  1433. foreach (Camera cam in Camera.allCameras)
  1434. {
  1435. if (cam.targetTexture == null)
  1436. {
  1437. float rectWidth = Mathf.Clamp01(cam.rect.width + cam.rect.x) - Mathf.Clamp01(cam.rect.x);
  1438. float rectHeight = Mathf.Clamp01(cam.rect.height + cam.rect.y) - Mathf.Clamp01(cam.rect.y);
  1439. if (rectWidth > 0.0f && rectHeight > 0.0f)
  1440. {
  1441. inWidth = Mathf.FloorToInt(cam.pixelWidth / rectWidth);
  1442. inHeight = Mathf.FloorToInt(cam.pixelHeight / rectHeight);
  1443. //Debug.Log (rectWidth + " " + (cam.rect.height - cam.rect.y) + " " + cam.pixelHeight + " = " + inWidth + "x" + inHeight);
  1444. break;
  1445. }
  1446. }
  1447. }
  1448. outSize = CaptureBase.GetRecordingResolution(inWidth, inHeight, GetDownScaleFromIndex(_downScaleIndex), new Vector2(_downscaleX, _downscaleY));
  1449. }
  1450. else
  1451. {
  1452. if (_cameraNode != null)
  1453. {
  1454. int inWidth = Mathf.FloorToInt(_cameraNode.pixelRect.width);
  1455. int inHeight = Mathf.FloorToInt(_cameraNode.pixelRect.height);
  1456. if (_renderResolution != CaptureBase.Resolution.Original)
  1457. {
  1458. float rectWidth = Mathf.Clamp01(_cameraNode.rect.width + _cameraNode.rect.x) - Mathf.Clamp01(_cameraNode.rect.x);
  1459. float rectHeight = Mathf.Clamp01(_cameraNode.rect.height + _cameraNode.rect.y) - Mathf.Clamp01(_cameraNode.rect.y);
  1460. if (_renderResolution == CaptureBase.Resolution.Custom)
  1461. {
  1462. inWidth = (int)_renderSize.x;
  1463. inHeight = (int)_renderSize.y;
  1464. }
  1465. else
  1466. {
  1467. CaptureBase.GetResolution(_renderResolution, ref inWidth, ref inHeight);
  1468. inWidth = Mathf.FloorToInt(inWidth * rectWidth);
  1469. inHeight = Mathf.FloorToInt(inHeight * rectHeight);
  1470. }
  1471. }
  1472. outSize = CaptureBase.GetRecordingResolution(inWidth, inHeight, GetDownScaleFromIndex(_downScaleIndex), new Vector2(_downscaleX, _downscaleY));
  1473. }
  1474. }
  1475. GUILayout.Space(8f);
  1476. GUILayout.BeginHorizontal();
  1477. GUILayout.FlexibleSpace();
  1478. GUI.color = Color.cyan;
  1479. GUILayout.TextArea("Output: " + (int)outSize.x + " x " + (int)outSize.y + " @ " + (int)_frameRate);
  1480. GUILayout.FlexibleSpace();
  1481. GUILayout.EndHorizontal();
  1482. GUILayout.Space(8f);
  1483. GUI.color = Color.white;
  1484. }
  1485. _downScaleIndex = EditorGUILayout.Popup("Down Scale", _downScaleIndex, _downScales);
  1486. if (_downScaleIndex == 5)
  1487. {
  1488. Vector2 maxVideoSize = new Vector2(_downscaleX, _downscaleY);
  1489. maxVideoSize = EditorGUILayout.Vector2Field("Size", maxVideoSize);
  1490. _downscaleX = Mathf.Clamp((int)maxVideoSize.x, 1, NativePlugin.MaxRenderWidth);
  1491. _downscaleY = Mathf.Clamp((int)maxVideoSize.y, 1, NativePlugin.MaxRenderHeight);
  1492. }
  1493. _supportAlpha = EditorGUILayout.Toggle("Support Alpha", _supportAlpha);
  1494. GUILayout.Space(8f);
  1495. //EditorGUILayout.LabelField("Codec", EditorStyles.boldLabel);
  1496. if (_outputType == CaptureBase.OutputType.VideoFile)
  1497. {
  1498. if (ShowConfigList("Codec", _videoCodecNames, _videoCodecConfigurable, ref _videoCodecIndex, true, true))
  1499. {
  1500. _queueConfigureVideoCodec = Mathf.Max(-1, _videoCodecIndex - 4);
  1501. }
  1502. _useMediaFoundationH264 = (_videoCodecIndex == 2);
  1503. if (_useMediaFoundationH264)
  1504. {
  1505. GUI.color = Color.yellow;
  1506. GUILayout.TextArea("Warning: Make sure to set the file extension to .mp4");
  1507. GUI.color = Color.white;
  1508. }
  1509. else
  1510. {
  1511. if (_videoCodecIndex > 0 && (
  1512. _videoCodecNames[_videoCodecIndex].EndsWith("Cinepak Codec by Radius")
  1513. || _videoCodecNames[_videoCodecIndex].EndsWith("DV Video Encoder")
  1514. || _videoCodecNames[_videoCodecIndex].EndsWith("Microsoft Video 1")
  1515. || _videoCodecNames[_videoCodecIndex].EndsWith("Microsoft RLE")
  1516. || _videoCodecNames[_videoCodecIndex].EndsWith("Logitech Video (I420)")
  1517. || _videoCodecNames[_videoCodecIndex].EndsWith("Intel IYUV codec")
  1518. ))
  1519. {
  1520. GUI.color = Color.yellow;
  1521. GUILayout.TextArea("Warning: Legacy codec, not recommended");
  1522. GUI.color = Color.white;
  1523. }
  1524. if (_videoCodecIndex >= 0 &&
  1525. (_videoCodecNames[_videoCodecIndex].Contains("Decoder") || _videoCodecNames[_videoCodecIndex].Contains("Decompressor")))
  1526. {
  1527. GUI.color = Color.yellow;
  1528. GUILayout.TextArea("Warning: Codec may contain decompressor only");
  1529. GUI.color = Color.white;
  1530. }
  1531. if (_videoCodecIndex >= 0 && _videoCodecNames[_videoCodecIndex].EndsWith("Uncompressed"))
  1532. {
  1533. GUI.color = Color.yellow;
  1534. GUILayout.TextArea("Warning: Uncompressed may result in very large files");
  1535. GUI.color = Color.white;
  1536. }
  1537. if (_videoCodecNames.Length < 8)
  1538. {
  1539. GUI.color = Color.cyan;
  1540. EditorGUILayout.TextArea("Low number of codecs, consider installing more");
  1541. GUI.color = Color.white;
  1542. }
  1543. }
  1544. }
  1545. else
  1546. {
  1547. GUI.color = Color.yellow;
  1548. EditorGUILayout.TextArea("Codec selection not available when using named pipe output");
  1549. GUI.color = Color.white;
  1550. }
  1551. DrawConfigGUI_MotionBlur();
  1552. //EditorGUI.indentLevel--;
  1553. EditorGUILayout.EndVertical();
  1554. }
  1555. private void DrawConfigGUI_MotionBlur()
  1556. {
  1557. EditorGUI.BeginDisabledGroup(_captureModeIndex == 0);
  1558. //EditorGUILayout.BeginVertical("box");
  1559. //EditorGUI.indentLevel++;
  1560. GUILayout.Space(8f);
  1561. GUILayout.Label("Motion Blur (beta)", EditorStyles.boldLabel);
  1562. //EditorGUILayout.BeginVertical("box");
  1563. //EditorGUI.indentLevel++;
  1564. if (_captureModeIndex == 0)
  1565. {
  1566. GUI.color = Color.yellow;
  1567. EditorGUILayout.TextArea("Motion Blur only available in Offline Render mode");
  1568. GUI.color = Color.white;
  1569. }
  1570. _useMotionBlur = EditorGUILayout.Toggle("Use Motion Blur", _useMotionBlur);
  1571. EditorGUI.BeginDisabledGroup(!_useMotionBlur);
  1572. EditorGUILayout.PrefixLabel("Samples");
  1573. EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(false));
  1574. //EditorGUILayout.LabelField("moo", GUILayout.ExpandWidth(false));
  1575. _motionBlurSampleCount = EditorGUILayout.IntSlider(_motionBlurSampleCount, 0, 64);
  1576. EditorGUILayout.EndHorizontal();
  1577. EditorGUI.EndDisabledGroup();
  1578. //EditorGUI.indentLevel--;
  1579. //EditorGUILayout.EndVertical();
  1580. EditorGUI.EndDisabledGroup();
  1581. }
  1582. private void DrawConfigGUI_Audio()
  1583. {
  1584. EditorGUI.BeginDisabledGroup(_captureModeIndex != 0 || _outputType != CaptureBase.OutputType.VideoFile);
  1585. //GUILayout.Label("Audio", EditorStyles.boldLabel);
  1586. EditorGUILayout.BeginVertical("box");
  1587. //EditorGUI.indentLevel++;
  1588. if (_captureModeIndex != 0)
  1589. {
  1590. GUI.color = Color.yellow;
  1591. EditorGUILayout.TextArea("Audio capture not available in Offline Render mode");
  1592. GUI.color = Color.white;
  1593. }
  1594. if (_outputType == CaptureBase.OutputType.NamedPipe)
  1595. {
  1596. GUI.color = Color.yellow;
  1597. EditorGUILayout.TextArea("Audio capture not available when using named pipe output");
  1598. GUI.color = Color.white;
  1599. }
  1600. _captureAudio = EditorGUILayout.Toggle("Capture Audio", _captureAudio);
  1601. GUILayout.Space(8f);
  1602. EditorGUI.BeginDisabledGroup(!_captureAudio);
  1603. if (ShowConfigList("Source", _audioDeviceNames, null, ref _audioDeviceIndex, false))
  1604. {
  1605. }
  1606. GUILayout.Space(8f);
  1607. if (ShowConfigList("Codec", _audioCodecNames, _audioCodecConfigurable, ref _audioCodecIndex))
  1608. {
  1609. _queueConfigureAudioCodec = Mathf.Max(-1, _audioCodecIndex - 2);
  1610. }
  1611. if (_audioCodecIndex > 0 && (_audioCodecNames[_audioCodecIndex].EndsWith("MPEG Layer-3")))
  1612. {
  1613. GUI.color = Color.yellow;
  1614. GUILayout.TextArea("Warning: We have had reports that this codec doesn't work. Consider using a different codec");
  1615. GUI.color = Color.white;
  1616. }
  1617. EditorGUI.EndDisabledGroup();
  1618. //EditorGUI.indentLevel--;
  1619. EditorGUILayout.EndVertical();
  1620. EditorGUI.EndDisabledGroup();
  1621. }
  1622. private static bool IsTrialVersion()
  1623. {
  1624. return NativePlugin.IsTrialVersion();
  1625. }
  1626. }
  1627. }
  1628. #endif