CaptureEditorWindow.cs 107 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910
  1. #if UNITY_EDITOR
  2. #if UNITY_2017_3_OR_NEWER
  3. #define AVPRO_MOVIECAPTURE_OFFLINE_AUDIOCAPTURE
  4. #endif
  5. #if UNITY_5_4_OR_NEWER || (UNITY_5 && !UNITY_5_0)
  6. #define AVPRO_MOVIECAPTURE_WINDOWTITLE_51
  7. #define AVPRO_MOVIECAPTURE_GRAPHICSDEVICETYPE_51
  8. #endif
  9. #if UNITY_5_4_OR_NEWER || (UNITY_5 && !UNITY_5_0 && !UNITY_5_1 && !UNITY_5_2)
  10. #define AVPRO_MOVIECAPTURE_SCENEMANAGER_53
  11. #endif
  12. #if UNITY_5_4_OR_NEWER || UNITY_5
  13. #define AVPRO_MOVIECAPTURE_DEFERREDSHADING
  14. #endif
  15. #if UNITY_2017_1_OR_NEWER
  16. #define AVPRO_MOVIECAPTURE_PLAYABLES_SUPPORT
  17. #endif
  18. #if UNITY_2018_1_OR_NEWER
  19. // Unity 2018.1 introduces stereo cubemap render methods
  20. #define AVPRO_MOVIECAPTURE_UNITY_STEREOCUBEMAP_RENDER
  21. #endif
  22. #if !UNITY_2018_3_OR_NEWER
  23. #define SUPPORT_SCENE_VIEW_GIZMOS_CAPTURE
  24. #endif
  25. using UnityEngine;
  26. using UnityEditor;
  27. //-----------------------------------------------------------------------------
  28. // Copyright 2012-2022 RenderHeads Ltd. All rights reserved.
  29. //-----------------------------------------------------------------------------
  30. namespace RenderHeads.Media.AVProMovieCapture.Editor
  31. {
  32. /// <summary>
  33. /// Creates a dockable window in Unity that can be used for handy in-editor capturing
  34. /// </summary>
  35. public class CaptureEditorWindow : EditorWindow
  36. {
  37. private const string TempGameObjectName = "Temp97435_MovieCapture";
  38. private const string SettingsPrefix = "AVProMovieCapture.EditorWindow.";
  39. private const string SelectorPrefix = SettingsPrefix + "CameraSelector.";
  40. private GameObject _gameObject;
  41. private CaptureBase _capture;
  42. private CaptureFromScreen _captureScreen;
  43. private CaptureFromCamera _captureCamera;
  44. private CaptureFromCamera360 _captureCamera360;
  45. private CaptureFromCamera360ODS _captureCamera360ODS;
  46. private CameraSelector _cameraSelector;
  47. #if AVPRO_MOVIECAPTURE_PLAYABLES_SUPPORT
  48. private TimelineController _timelineController;
  49. #endif
  50. private static bool _isTrialVersion = false;
  51. private static bool _isCreated = false;
  52. private static bool _isInit = false;
  53. private static bool _isFailedInit = false;
  54. private static bool _showAlpha = false;
  55. private static int _superSizeIndex = 0;
  56. [SerializeField] string _screenshotFolder = "Captures/Shots/";
  57. [SerializeField] EditorScreenshot.Options _screenshotOptions = new EditorScreenshot.Options();
  58. private static string[] _fileExtensions = new string[0];
  59. private static string[] _audioDeviceNames = new string[0];
  60. private readonly string[] _downScales = { "Original", "Half", "Quarter", "Eighth", "Sixteenth", "Custom" };
  61. private readonly string[] _captureModes = { "Realtime Capture", "Offline Render" };
  62. private readonly string[] _outputFolders = { "Project Folder", "Persistent Data Folder", "Absolute Folder", "Desktop", "Pictures", "Videos" }; // NOTE: PhotoLibrary is not included as Unity Editor doesn't have permission to use it anyway
  63. private readonly string[] _sourceNames = { "Screen", "Camera", "Camera 360 (Mono+Stereo)", "Camera 360 (experimental ODS Stereo)" };
  64. private readonly string[] _tabNames = { "Capture", "Visual", "Audio", "Encoding" };
  65. private readonly static GUIContent _guiBlankSpace = new GUIContent(" ");
  66. private readonly static GUIContent _guiCameraSelectorTag = new GUIContent("Tag");
  67. private readonly static GUIContent _guiCameraSelectorName = new GUIContent("Name");
  68. private readonly static GUIContent _guiContributingCameras = new GUIContent("Contributing Cameras");
  69. private readonly static GUIContent _guiCaptureWorldSpaceUI= new GUIContent("Capture Worldspace UI");
  70. private readonly static GUIContent _guiCameraRotation = new GUIContent("Camera Rotation");
  71. private readonly static GUIContent _guiInterpupillaryDistance = new GUIContent("Interpupillary distance");
  72. private readonly static GUIContent _guiStartDelay = new GUIContent("Start Delay");
  73. private readonly static GUIContent _guiSeconds = new GUIContent("Seconds");
  74. private readonly static GUIContent _guiStartFrame = new GUIContent("Start Frame");
  75. private readonly static GUIContent _guiZeroDigits = new GUIContent("Zero Digits");
  76. private readonly static GUIContent _guiStereoPacking = new GUIContent("Stereo Packing");
  77. private readonly static GUIContent _guiSphericalLayout = new GUIContent("Spherical Layout");
  78. private enum SourceType
  79. {
  80. Screen,
  81. Camera,
  82. Camera360,
  83. Camera360ODS,
  84. }
  85. private enum ConfigTabs
  86. {
  87. Capture = 0,
  88. Visual = 1,
  89. Audio = 2,
  90. Encoding = 3,
  91. }
  92. [SerializeField] SourceType _sourceType = SourceType.Screen;
  93. private Camera _cameraNode;
  94. private string _cameraName;
  95. private int _captureModeIndex;
  96. private int _outputFolderIndex;
  97. [SerializeField] OutputTarget _outputTarget = OutputTarget.VideoFile;
  98. [SerializeField] ImageSequenceFormat _imageSequenceFormat = ImageSequenceFormat.PNG;
  99. private bool _filenamePrefixFromSceneName = true;
  100. private string _filenamePrefix = "capture";
  101. private string _filenameExtension = "mp4";
  102. private int _fileContainerIndex = 0;
  103. [SerializeField] int _imageSequenceStartFrame = 0;
  104. [SerializeField, Range(2, 12)] int _imageSequenceZeroDigits = 6;
  105. private string _outputFolderRelative = "Captures";
  106. private string _outputFolderAbsolute = string.Empty;
  107. private bool _appendTimestamp = true;
  108. [SerializeField] string _namedPipePath = @"\\.\pipe\pipename";
  109. private int _downScaleIndex;
  110. private int _downscaleX;
  111. private int _downscaleY;
  112. private bool _captureMouseCursor = false;
  113. private Texture2D _mouseCursorTexture = null;
  114. [SerializeField] CaptureBase.Resolution _renderResolution = CaptureBase.Resolution.Original;
  115. private Vector2 _renderSize;
  116. [SerializeField] int _renderAntiAliasing;
  117. [SerializeField] bool _useContributingCameras = true;
  118. [SerializeField] float _frameRate = 30f;
  119. [SerializeField] int _timelapseScale = 1;
  120. private AudioCaptureSource _audioCaptureSource = AudioCaptureSource.None;
  121. [SerializeField, Range(8000, 96000)] int _manualAudioSampleRate = 48000;
  122. [SerializeField, Range(1, 8)] int _manualAudioChannelCount = 2;
  123. private Vector2 _scroll = Vector2.zero;
  124. private bool _queueStart;
  125. private Codec _queueConfigureVideoCodec = null;
  126. private Codec _queueConfigureAudioCodec = null;
  127. private bool _useMotionBlur = false;
  128. private int _motionBlurSampleCount = 16;
  129. private int _cubemapResolution = 2048;
  130. private int _cubemapDepth = 24;
  131. [SerializeField] bool _render180Degrees = false;
  132. [SerializeField] bool _captureWorldSpaceGUI = false;
  133. [SerializeField] bool _supportCameraRotation = false;
  134. [SerializeField] bool _onlyLeftRightRotation = false;
  135. private int _cubemapStereoPacking = 0;
  136. private float _cubemapStereoIPD = 0.064f;
  137. [SerializeField] StartDelayMode _startDelay = StartDelayMode.None;
  138. [SerializeField] float _startDelaySeconds = 0f;
  139. [SerializeField] StopMode _stopMode = StopMode.None;
  140. private int _stopFrames = 300;
  141. private float _stopSeconds = 10f;
  142. [SerializeField] CameraSelector.SelectByMode _selectBy = CameraSelector.SelectByMode.HighestDepthCamera;
  143. [SerializeField] CameraSelector.ScanFrequencyMode _scanFrequency = CameraSelector.ScanFrequencyMode.SceneLoad;
  144. [SerializeField] bool _scanHiddenCameras = false;
  145. [SerializeField] string _selectCameraTag = "MainCamera";
  146. [SerializeField] string _selectCameraName = "Main Camera";
  147. private SerializedProperty _propCameraSelectorSelectBy;
  148. private SerializedProperty _propCameraSelectorScanFrequency;
  149. private SerializedProperty _propCameraSelectorScanHiddenCameras;
  150. private SerializedProperty _propCameraSelectorTag;
  151. private SerializedProperty _propCameraSelectorName;
  152. private SerializedProperty _propSourceType;
  153. private SerializedProperty _propOutputTarget;
  154. private SerializedProperty _propImageSequenceFormat;
  155. private SerializedProperty _propImageSequenceStartFrame;
  156. private SerializedProperty _propImageSequenceZeroDigits;
  157. private SerializedProperty _propNamedPipePath;
  158. private SerializedProperty _propFrameRate;
  159. [Tooltip("Timelapse scale makes the frame capture run at a fraction of the target frame rate. Default value is 1")]
  160. private SerializedProperty _propTimelapseScale;
  161. private SerializedProperty _propStartDelay;
  162. private SerializedProperty _propStartDelaySeconds;
  163. private SerializedProperty _propStopMode;
  164. private SerializedProperty _propRenderResolution;
  165. private SerializedProperty _propUseContributingCameras;
  166. private SerializedProperty _propRender180Degrees;
  167. private SerializedProperty _propCaptureWorldSpaceGUI;
  168. private SerializedProperty _propSupportCameraRotation;
  169. private SerializedProperty _propOnlyLeftRightRotation;
  170. private SerializedProperty _propManualAudioSampleRate;
  171. private SerializedProperty _propManualAudioChannelCount;
  172. private SerializedProperty _propRenderAntiAliasing;
  173. private SerializedProperty _propOdsRender180Degrees;
  174. private SerializedProperty _propOdsCamera;
  175. private SerializedProperty _propOdsIPD;
  176. private SerializedProperty _propOdsPixelSliceSize;
  177. private SerializedProperty _propOdsPaddingSize;
  178. private SerializedProperty _propOdsCameraClearMode;
  179. private SerializedProperty _propOdsCameraClearColor;
  180. [SerializeField] CaptureFromCamera360ODS.Settings _odsSettings = new CaptureFromCamera360ODS.Settings();
  181. private SerializedProperty _propVideoHintsAverageBitrate;
  182. #if UNITY_EDITOR_WIN
  183. private SerializedProperty _propVideoHintsMaximumBitrate;
  184. #endif
  185. private SerializedProperty _propVideoHintsQuality;
  186. private SerializedProperty _propVideoHintsKeyframeInterval;
  187. private SerializedProperty _propVideoHintsAllowFastStart;
  188. private SerializedProperty _propVideoHintsTransparency;
  189. #if UNITY_EDITOR_WIN
  190. private SerializedProperty _propVideoHintsUseHardwareEncoding;
  191. #elif UNITY_EDITOR_OSX
  192. private SerializedProperty _propVideoHintsEnableFragmentedWriting;
  193. private SerializedProperty _propVideoHintsMovieFragmentInterval;
  194. #endif
  195. private SerializedProperty _propVideoHintsInjectStereoPacking;
  196. private SerializedProperty _propVideoHintsStereoPacking;
  197. private SerializedProperty _propVideoHintsInjectSphericalVideoLayout;
  198. private SerializedProperty _propVideoHintsSphericalVideoLayout;
  199. #if UNITY_EDITOR_OSX
  200. private SerializedProperty _propImageHintsQuality;
  201. #endif
  202. private SerializedProperty _propImageHintsTransparency;
  203. private SerializedProperty _propScreenshotFolder;
  204. private SerializedProperty _propScreenshotOptions;
  205. [SerializeField] EncoderHints _encoderHints = new EncoderHints();
  206. // TODO: we should actually be saving these parameters per-scene...
  207. private Codec _videoCodec = null;
  208. private Codec _audioCodec = null;
  209. private Device _audioInputDevice = null;
  210. private long _lastFileSize;
  211. private uint _lastEncodedMinutes;
  212. private uint _lastEncodedSeconds;
  213. private uint _lastEncodedFrame;
  214. private int _selectedTool;
  215. private int _selectedConfigTab;
  216. private bool _expandSectionTrial = true;
  217. private static Texture2D _icon;
  218. private string _pluginVersionWarningText = string.Empty;
  219. private SerializedObject _so;
  220. private const string LinkPluginWebsite = "http://renderheads.com/products/avpro-movie-capture/";
  221. private const string LinkForumPage = "http://forum.unity3d.com/threads/released-avpro-movie-capture.120717/";
  222. private const string LinkAssetStorePage = "https://assetstore.unity.com/packages/tools/video/avpro-movie-capture-151061?aid=1101lcNgx";
  223. private const string LinkSupport = "https://github.com/RenderHeads/UnityPlugin-AVProMovieCapture/issues";
  224. private const string LinkUserManual = "https://www.renderheads.com/content/docs/AVProMovieCapture/articles/download.html";
  225. 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" +
  226. "Essential details:\n" +
  227. "+ Error message\n" +
  228. " + The exact error message\n" +
  229. " + The console/output log if possible\n" +
  230. "+ Development environment\n" +
  231. " + Unity version\n" +
  232. " + Development OS version\n" +
  233. " + AVPro Movie Capture plugin version\n";
  234. [MenuItem("Window/Open AVPro Movie Capture..")]
  235. public static void Init()
  236. {
  237. if (_isInit || _isCreated)
  238. {
  239. CaptureEditorWindow window = (CaptureEditorWindow)EditorWindow.GetWindow(typeof(CaptureEditorWindow));
  240. window.Close();
  241. return;
  242. }
  243. _isCreated = true;
  244. // Get existing open window or if none, make a new one:
  245. CaptureEditorWindow window2 = (CaptureEditorWindow)EditorWindow.GetWindow(typeof(CaptureEditorWindow));
  246. if (window2 != null)
  247. {
  248. window2.SetupWindow();
  249. }
  250. }
  251. public void SetupWindow()
  252. {
  253. _isCreated = true;
  254. if ((Application.platform == RuntimePlatform.WindowsEditor)
  255. || (Application.platform == RuntimePlatform.OSXEditor))
  256. {
  257. this.minSize = new Vector2(200f, 48f);
  258. this.maxSize = new Vector2(340f, 620f);
  259. #if AVPRO_MOVIECAPTURE_WINDOWTITLE_51
  260. if (_icon != null)
  261. {
  262. this.titleContent = new GUIContent("Movie Capture", _icon, "AVPro Movie Capture");
  263. }
  264. else
  265. {
  266. this.titleContent = new GUIContent("Movie Capture", "AVPro Movie Capture");
  267. }
  268. #else
  269. this.title = "Movie Capture";
  270. #endif
  271. this.CreateGUI();
  272. this.LoadSettings();
  273. _so = new SerializedObject(this);
  274. if (_so == null)
  275. {
  276. Debug.LogError("[AVProMovieCapture] SerializedObject is null");
  277. }
  278. _propSourceType = _so.AssertFindProperty("_sourceType");
  279. _propOutputTarget = _so.AssertFindProperty("_outputTarget");
  280. _propImageSequenceFormat = _so.AssertFindProperty("_imageSequenceFormat");
  281. _propImageSequenceStartFrame = _so.AssertFindProperty("_imageSequenceStartFrame");
  282. _propImageSequenceZeroDigits = _so.AssertFindProperty("_imageSequenceZeroDigits");
  283. _propNamedPipePath = _so.AssertFindProperty("_namedPipePath");
  284. _propRenderResolution = _so.AssertFindProperty("_renderResolution");
  285. _propUseContributingCameras = _so.AssertFindProperty("_useContributingCameras");
  286. _propRender180Degrees = _so.AssertFindProperty("_render180Degrees");
  287. _propCaptureWorldSpaceGUI = _so.AssertFindProperty("_captureWorldSpaceGUI");
  288. _propSupportCameraRotation = _so.AssertFindProperty("_supportCameraRotation");
  289. _propOnlyLeftRightRotation = _so.AssertFindProperty("_onlyLeftRightRotation");
  290. // Audio
  291. _propManualAudioSampleRate = _so.AssertFindProperty("_manualAudioSampleRate");
  292. _propManualAudioChannelCount = _so.AssertFindProperty("_manualAudioChannelCount");
  293. // Time
  294. _propFrameRate = _so.AssertFindProperty("_frameRate");
  295. _propTimelapseScale = _so.AssertFindProperty("_timelapseScale");
  296. // Start/Stop
  297. _propStopMode = _so.AssertFindProperty("_stopMode");
  298. _propStartDelay = _so.AssertFindProperty("_startDelay");
  299. _propStartDelaySeconds = _so.AssertFindProperty("_startDelaySeconds");
  300. // Camera Selector
  301. _propCameraSelectorSelectBy = _so.AssertFindProperty("_selectBy");
  302. _propCameraSelectorScanFrequency = _so.AssertFindProperty("_scanFrequency");
  303. _propCameraSelectorScanHiddenCameras = _so.AssertFindProperty("_scanHiddenCameras");
  304. _propCameraSelectorTag = _so.AssertFindProperty("_selectCameraTag");
  305. _propCameraSelectorName = _so.AssertFindProperty("_selectCameraName");
  306. _propRenderAntiAliasing = _so.AssertFindProperty("_renderAntiAliasing");
  307. _propOdsIPD = _so.AssertFindProperty("_odsSettings.ipd");
  308. _propOdsRender180Degrees = _so.AssertFindProperty("_odsSettings.render180Degrees");
  309. _propOdsPixelSliceSize = _so.AssertFindProperty("_odsSettings.pixelSliceSize");
  310. _propOdsPaddingSize = _so.AssertFindProperty("_odsSettings.paddingSize");
  311. _propOdsCameraClearMode = _so.AssertFindProperty("_odsSettings.cameraClearMode");
  312. _propOdsCameraClearColor = _so.AssertFindProperty("_odsSettings.cameraClearColor");
  313. _propVideoHintsAverageBitrate = _so.AssertFindProperty("_encoderHints.videoHints.averageBitrate");
  314. #if UNITY_EDITOR_WIN
  315. _propVideoHintsMaximumBitrate = _so.AssertFindProperty("_encoderHints.videoHints.maximumBitrate");
  316. #endif
  317. _propVideoHintsQuality = _so.AssertFindProperty("_encoderHints.videoHints.quality");
  318. _propVideoHintsKeyframeInterval = _so.AssertFindProperty("_encoderHints.videoHints.keyframeInterval");
  319. _propVideoHintsAllowFastStart = _so.AssertFindProperty("_encoderHints.videoHints.allowFastStartStreamingPostProcess");
  320. _propVideoHintsTransparency = _so.AssertFindProperty("_encoderHints.videoHints.transparency");
  321. #if UNITY_EDITOR_WIN
  322. _propVideoHintsUseHardwareEncoding = _so.AssertFindProperty("_encoderHints.videoHints.useHardwareEncoding");
  323. #elif UNITY_EDITOR_OSX
  324. _propVideoHintsEnableFragmentedWriting = _so.AssertFindProperty("_encoderHints.videoHints.enableFragmentedWriting");
  325. _propVideoHintsMovieFragmentInterval = _so.AssertFindProperty("_encoderHints.videoHints.movieFragmentInterval");
  326. #endif
  327. _propVideoHintsInjectStereoPacking = _so.AssertFindProperty("_encoderHints.videoHints.injectStereoPacking");
  328. _propVideoHintsStereoPacking = _so.AssertFindProperty("_encoderHints.videoHints.stereoPacking");
  329. _propVideoHintsInjectSphericalVideoLayout = _so.AssertFindProperty("_encoderHints.videoHints.injectSphericalVideoLayout");
  330. _propVideoHintsSphericalVideoLayout = _so.AssertFindProperty("_encoderHints.videoHints.sphericalVideoLayout");
  331. #if UNITY_EDITOR_OSX
  332. _propImageHintsQuality = _so.AssertFindProperty("_encoderHints.imageHints.quality");
  333. #endif
  334. _propImageHintsTransparency = _so.AssertFindProperty("_encoderHints.imageHints.transparency");
  335. _propScreenshotOptions = _so.AssertFindProperty("_screenshotOptions");
  336. _propScreenshotFolder = _so.AssertFindProperty("_screenshotFolder");
  337. this.Repaint();
  338. }
  339. }
  340. private void LoadSettings()
  341. {
  342. _sourceType = (SourceType)EditorPrefs.GetInt(SettingsPrefix + "SourceType", (int)_sourceType);
  343. _cameraName = EditorPrefs.GetString(SettingsPrefix + "CameraName", string.Empty);
  344. _captureModeIndex = EditorPrefs.GetInt(SettingsPrefix + "CaptureModeIndex", 0);
  345. _captureMouseCursor = EditorPrefs.GetBool(SettingsPrefix + "CaptureMouseCursor", false);
  346. string mouseCursorGuid = EditorPrefs.GetString(SettingsPrefix + "CaptureMouseTexture", string.Empty);
  347. if (!string.IsNullOrEmpty(mouseCursorGuid))
  348. {
  349. string mouseCursorPath = AssetDatabase.GUIDToAssetPath(mouseCursorGuid);
  350. if (!string.IsNullOrEmpty(mouseCursorPath))
  351. {
  352. _mouseCursorTexture = (Texture2D)AssetDatabase.LoadAssetAtPath(mouseCursorPath, typeof(Texture2D));
  353. }
  354. }
  355. _outputTarget = (OutputTarget)EditorPrefs.GetInt(SettingsPrefix + "OutputTarget", (int)_outputTarget);
  356. _imageSequenceFormat = (ImageSequenceFormat)EditorPrefs.GetInt(SettingsPrefix + "ImageSequenceFormat", (int)_imageSequenceFormat);
  357. _namedPipePath = EditorPrefs.GetString(SettingsPrefix + "NamedPipePath", _namedPipePath);
  358. _filenamePrefixFromSceneName = EditorPrefs.GetBool(SettingsPrefix + "FilenamePrefixFromScenename", _filenamePrefixFromSceneName);
  359. _filenamePrefix = EditorPrefs.GetString(SettingsPrefix + "FilenamePrefix", "capture");
  360. _filenameExtension = EditorPrefs.GetString(SettingsPrefix + "FilenameExtension", _filenameExtension);
  361. _fileContainerIndex = EditorPrefs.GetInt(SettingsPrefix + "FileContainerIndex", _fileContainerIndex);
  362. _appendTimestamp = EditorPrefs.GetBool(SettingsPrefix + "AppendTimestamp", true);
  363. _imageSequenceStartFrame = EditorPrefs.GetInt(SettingsPrefix + "ImageSequenceStartFrame", 0);
  364. _imageSequenceZeroDigits = EditorPrefs.GetInt(SettingsPrefix + "ImageSequenceZeroDigits", 6);
  365. _outputFolderIndex = EditorPrefs.GetInt(SettingsPrefix + "OutputFolderIndex", (int)CaptureBase.OutputPath.RelativeToProject);
  366. _outputFolderRelative = EditorPrefs.GetString(SettingsPrefix + "OutputFolderRelative", "Captures");
  367. _outputFolderAbsolute = EditorPrefs.GetString(SettingsPrefix + "OutputFolderAbsolute", string.Empty);
  368. _downScaleIndex = EditorPrefs.GetInt(SettingsPrefix + "DownScaleIndex", 0);
  369. _downscaleX = EditorPrefs.GetInt(SettingsPrefix + "DownScaleX", 1);
  370. _downscaleY = EditorPrefs.GetInt(SettingsPrefix + "DownScaleY", 1);
  371. _frameRate = EditorPrefs.GetFloat(SettingsPrefix + "FrameRate", _frameRate);
  372. _timelapseScale = EditorPrefs.GetInt(SettingsPrefix + "TimelapseScale", 1);
  373. _renderResolution = (CaptureBase.Resolution)EditorPrefs.GetInt(SettingsPrefix + "RenderResolution", (int)_renderResolution);
  374. _renderSize.x = EditorPrefs.GetInt(SettingsPrefix + "RenderWidth", 0);
  375. _renderSize.y = EditorPrefs.GetInt(SettingsPrefix + "RenderHeight", 0);
  376. _renderAntiAliasing = EditorPrefs.GetInt(SettingsPrefix + "RenderAntiAliasing", 0);
  377. _useContributingCameras = EditorPrefs.GetBool(SettingsPrefix + "UseContributingCameras", true);
  378. _audioCaptureSource = (AudioCaptureSource)EditorPrefs.GetInt(SettingsPrefix + "AudioCaptureSource", (int)_audioCaptureSource);
  379. _audioInputDevice = DeviceManager.AudioInputDevices.FindDevice(EditorPrefs.GetString(SettingsPrefix + "AudioInputDeviceName", ""));
  380. _manualAudioChannelCount = Mathf.Clamp(EditorPrefs.GetInt(SettingsPrefix + "ManualAudioChannelCount", (int)_manualAudioChannelCount), 1, 8);
  381. _manualAudioSampleRate = Mathf.Clamp(EditorPrefs.GetInt(SettingsPrefix + "ManualAudioSampleRate", (int)_manualAudioSampleRate), 8000, 96000);
  382. _useMotionBlur = EditorPrefs.GetBool(SettingsPrefix + "UseMotionBlur", false);
  383. _motionBlurSampleCount = EditorPrefs.GetInt(SettingsPrefix + "MotionBlurSampleCount", 16);
  384. _render180Degrees = EditorPrefs.GetBool(SettingsPrefix + "Render180Degrees", false);
  385. _captureWorldSpaceGUI = EditorPrefs.GetBool(SettingsPrefix + "CaptureWorldSpaceGUI", false);
  386. _supportCameraRotation = EditorPrefs.GetBool(SettingsPrefix + "SupportCameraRotation", false);
  387. _onlyLeftRightRotation = EditorPrefs.GetBool(SettingsPrefix + "OnlyLeftRightRotation", false);
  388. _cubemapResolution = EditorPrefs.GetInt(SettingsPrefix + "CubemapResolution", 2048);
  389. _cubemapDepth = EditorPrefs.GetInt(SettingsPrefix + "CubemapDepth", 24);
  390. _cubemapStereoPacking = EditorPrefs.GetInt(SettingsPrefix + "CubemapStereoPacking", 0);
  391. _cubemapStereoIPD = EditorPrefs.GetFloat(SettingsPrefix + "CubemapStereoIPD", 0.064f);
  392. _startDelay = (StartDelayMode)EditorPrefs.GetInt(SettingsPrefix + "StartDelay", (int)_startDelay);
  393. _startDelaySeconds = EditorPrefs.GetFloat(SettingsPrefix + "StartDelaySeconds", _startDelaySeconds);
  394. _stopMode = (StopMode)EditorPrefs.GetInt(SettingsPrefix + "StopMode", (int)_stopMode);
  395. _stopFrames = EditorPrefs.GetInt(SettingsPrefix + "StopFrames", _stopFrames);
  396. _stopSeconds = EditorPrefs.GetFloat(SettingsPrefix + "StopSeconds", _stopSeconds);
  397. _encoderHints.videoHints.averageBitrate = (uint)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.AverageBitrate", (int)_encoderHints.videoHints.averageBitrate);
  398. _encoderHints.videoHints.maximumBitrate = (uint)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.MaximumBitrate", (int)_encoderHints.videoHints.maximumBitrate);
  399. _encoderHints.videoHints.quality = EditorPrefs.GetFloat(SettingsPrefix + "EncoderHints.VideoHints.Quality", _encoderHints.videoHints.quality);
  400. _encoderHints.videoHints.keyframeInterval = (uint)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.KeyframeInterval", (int)_encoderHints.videoHints.keyframeInterval);
  401. _encoderHints.videoHints.allowFastStartStreamingPostProcess = EditorPrefs.GetBool(SettingsPrefix + "EncoderHints.VideoHints.AllowFastStart", _encoderHints.videoHints.allowFastStartStreamingPostProcess);
  402. _encoderHints.videoHints.transparency = (Transparency)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.Transparency", (int)_encoderHints.videoHints.transparency);
  403. _encoderHints.videoHints.useHardwareEncoding = EditorPrefs.GetBool(SettingsPrefix + "EncoderHints.VideoHints.UseHardwareEncoding", _encoderHints.videoHints.useHardwareEncoding);
  404. _encoderHints.videoHints.enableFragmentedWriting = EditorPrefs.GetBool(SettingsPrefix + "EncoderHints.VideoHints.EnableFragmentedWriting", _encoderHints.videoHints.enableFragmentedWriting);
  405. _encoderHints.videoHints.movieFragmentInterval = (double)EditorPrefs.GetFloat(SettingsPrefix + "EncoderHints.VideoHints.MovieFragmentInterval", (float)_encoderHints.videoHints.movieFragmentInterval);
  406. _encoderHints.videoHints.injectStereoPacking = (NoneAutoCustom)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.InjectStereoPacking", (int)_encoderHints.videoHints.injectStereoPacking);
  407. _encoderHints.videoHints.stereoPacking = (StereoPacking)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.StereoPacking", (int)_encoderHints.videoHints.stereoPacking);
  408. _encoderHints.videoHints.injectSphericalVideoLayout = (NoneAutoCustom)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.InjectSphericalVideoLayout", (int)_encoderHints.videoHints.injectSphericalVideoLayout);
  409. _encoderHints.videoHints.sphericalVideoLayout = (SphericalVideoLayout)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.VideoHints.SphericalVideoLayout", (int)_encoderHints.videoHints.sphericalVideoLayout);
  410. _encoderHints.imageHints.quality = EditorPrefs.GetFloat(SettingsPrefix + "EncoderHints.ImageHints.Quality", _encoderHints.imageHints.quality);
  411. _encoderHints.imageHints.transparency = (Transparency)EditorPrefs.GetInt(SettingsPrefix + "EncoderHints.ImageHints.Transparency", (int)_encoderHints.imageHints.transparency);
  412. if (!string.IsNullOrEmpty(_cameraName))
  413. {
  414. Camera[] cameras = (Camera[])GameObject.FindObjectsOfType(typeof(Camera));
  415. foreach (Camera cam in cameras)
  416. {
  417. if (cam.name == _cameraName)
  418. {
  419. _cameraNode = cam;
  420. break;
  421. }
  422. }
  423. }
  424. _showAlpha = EditorPrefs.GetBool(SettingsPrefix + "ShowAlphaChannel", false);
  425. _superSizeIndex = EditorPrefs.GetInt(SettingsPrefix + "SuperSizeIndex", 0);
  426. _screenshotFolder = EditorPrefs.GetString(SettingsPrefix + "ScreenshotFolder", _screenshotFolder);
  427. _screenshotOptions.exrPrecision = (EditorScreenshot.ExrPrecision)EditorPrefs.GetInt(SettingsPrefix + "ScreenshotOptions.ExrPrecision", (int)_screenshotOptions.exrPrecision);
  428. _screenshotOptions.exrCompression = (EditorScreenshot.ExrCompression)EditorPrefs.GetInt(SettingsPrefix + "ScreenshotOptions.ExrCompression", (int)_screenshotOptions.exrCompression);
  429. _screenshotOptions.jpgQuality = EditorPrefs.GetInt(SettingsPrefix + "ScreenshotOptions.JpgQuality", (int)_screenshotOptions.jpgQuality);
  430. // Codecs
  431. _videoCodec = CodecManager.VideoCodecs.FindCodec(EditorPrefs.GetString(SettingsPrefix + "VideoCodecName", ""));
  432. _audioCodec = CodecManager.AudioCodecs.FindCodec(EditorPrefs.GetString(SettingsPrefix + "AudioCodecName", ""));
  433. UpdateSelectedCodec();
  434. // Camera selector
  435. _selectBy = (CameraSelector.SelectByMode)EditorPrefs.GetInt(SelectorPrefix + "SelectBy", (int)_selectBy);
  436. _scanFrequency = (CameraSelector.ScanFrequencyMode)EditorPrefs.GetInt(SelectorPrefix + "ScanFrequency", (int)_scanFrequency);
  437. _scanHiddenCameras = EditorPrefs.GetBool(SelectorPrefix + "ScanHiddenCameras", _scanHiddenCameras);
  438. _selectCameraTag = EditorPrefs.GetString(SelectorPrefix + "Tag", _selectCameraTag);
  439. _selectCameraName = EditorPrefs.GetString(SelectorPrefix + "Name", _selectCameraName);
  440. }
  441. private void SaveSettings()
  442. {
  443. EditorPrefs.SetInt(SettingsPrefix + "SourceType", (int)_sourceType);
  444. EditorPrefs.SetString(SettingsPrefix + "CameraName", _cameraName);
  445. EditorPrefs.SetInt(SettingsPrefix + "CaptureModeIndex", _captureModeIndex);
  446. EditorPrefs.SetBool(SettingsPrefix + "CaptureMouseCursor", _captureMouseCursor);
  447. string mouseCursorGuid = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_mouseCursorTexture));
  448. EditorPrefs.SetString(SettingsPrefix + "CaptureMouseTexture", mouseCursorGuid);
  449. EditorPrefs.SetInt(SettingsPrefix + "OutputTarget", (int)_outputTarget);
  450. EditorPrefs.SetInt(SettingsPrefix + "ImageSequenceFormat", (int)_imageSequenceFormat);
  451. EditorPrefs.SetString(SettingsPrefix + "NamedPipePath", _namedPipePath);
  452. EditorPrefs.SetBool(SettingsPrefix + "FilenamePrefixFromScenename", _filenamePrefixFromSceneName);
  453. EditorPrefs.SetString(SettingsPrefix + "FilenamePrefix", _filenamePrefix);
  454. EditorPrefs.SetString(SettingsPrefix + "FilenameExtension", _filenameExtension);
  455. EditorPrefs.SetInt(SettingsPrefix + "FileContainerIndex", _fileContainerIndex);
  456. EditorPrefs.SetBool(SettingsPrefix + "AppendTimestamp", _appendTimestamp);
  457. EditorPrefs.SetInt(SettingsPrefix + "ImageSequenceStartFrame", _imageSequenceStartFrame);
  458. EditorPrefs.SetInt(SettingsPrefix + "ImageSequenceZeroDigits", _imageSequenceZeroDigits);
  459. EditorPrefs.SetInt(SettingsPrefix + "OutputFolderIndex", _outputFolderIndex);
  460. EditorPrefs.SetString(SettingsPrefix + "OutputFolderRelative", _outputFolderRelative);
  461. EditorPrefs.SetString(SettingsPrefix + "OutputFolderAbsolute", _outputFolderAbsolute);
  462. EditorPrefs.SetInt(SettingsPrefix + "DownScaleIndex", _downScaleIndex);
  463. EditorPrefs.SetInt(SettingsPrefix + "DownScaleX", _downscaleX);
  464. EditorPrefs.SetInt(SettingsPrefix + "DownScaleY", _downscaleY);
  465. EditorPrefs.SetFloat(SettingsPrefix + "FrameRate", _frameRate);
  466. EditorPrefs.SetInt(SettingsPrefix + "TimelapseScale", _timelapseScale);
  467. EditorPrefs.SetInt(SettingsPrefix + "RenderResolution", (int)_renderResolution);
  468. EditorPrefs.SetInt(SettingsPrefix + "RenderWidth", (int)_renderSize.x);
  469. EditorPrefs.SetInt(SettingsPrefix + "RenderHeight", (int)_renderSize.y);
  470. EditorPrefs.SetInt(SettingsPrefix + "RenderAntiAliasing", _renderAntiAliasing);
  471. EditorPrefs.SetBool(SettingsPrefix + "UseContributingCameras", _useContributingCameras);
  472. EditorPrefs.SetString(SettingsPrefix + "VideoCodecName", (_videoCodec != null)?_videoCodec.Name:string.Empty);
  473. EditorPrefs.SetString(SettingsPrefix + "AudioCodecName", (_audioCodec != null)?_audioCodec.Name:string.Empty);
  474. EditorPrefs.SetInt(SettingsPrefix + "AudioCaptureSource", (int)_audioCaptureSource);
  475. EditorPrefs.SetString(SettingsPrefix + "AudioInputDeviceName", (_audioInputDevice != null)?_audioInputDevice.Name:string.Empty);
  476. EditorPrefs.SetInt(SettingsPrefix + "ManualAudioChannelCount", _manualAudioChannelCount);
  477. EditorPrefs.SetInt(SettingsPrefix + "ManualAudioSampleRate", _manualAudioSampleRate);
  478. EditorPrefs.SetBool(SettingsPrefix + "UseMotionBlur", _useMotionBlur);
  479. EditorPrefs.SetInt(SettingsPrefix + "MotionBlurSampleCount", _motionBlurSampleCount);
  480. EditorPrefs.SetBool(SettingsPrefix + "Render180Degrees", _render180Degrees);
  481. EditorPrefs.SetBool(SettingsPrefix + "CaptureWorldSpaceGUI", _captureWorldSpaceGUI);
  482. EditorPrefs.SetBool(SettingsPrefix + "SupportCameraRotation", _supportCameraRotation);
  483. EditorPrefs.SetBool(SettingsPrefix + "OnlyLeftRightRotation", _onlyLeftRightRotation);
  484. EditorPrefs.SetInt(SettingsPrefix + "CubemapResolution", _cubemapResolution);
  485. EditorPrefs.SetInt(SettingsPrefix + "CubemapDepth", _cubemapDepth);
  486. EditorPrefs.SetInt(SettingsPrefix + "CubemapStereoPacking", _cubemapStereoPacking);
  487. EditorPrefs.SetFloat(SettingsPrefix + "CubemapStereoIPD", _cubemapStereoIPD);
  488. EditorPrefs.SetInt(SettingsPrefix + "StartDelay", (int)_startDelay);
  489. EditorPrefs.SetFloat(SettingsPrefix + "StartDelaySeconds", _startDelaySeconds);
  490. EditorPrefs.SetInt(SettingsPrefix + "StopMode", (int)_stopMode);
  491. EditorPrefs.SetInt(SettingsPrefix + "StopFrames", _stopFrames);
  492. EditorPrefs.SetFloat(SettingsPrefix + "StopSeconds", _stopSeconds);
  493. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.AverageBitrate", (int)_encoderHints.videoHints.averageBitrate);
  494. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.MaximumBitrate", (int)_encoderHints.videoHints.maximumBitrate);
  495. EditorPrefs.SetFloat(SettingsPrefix + "EncoderHints.VideoHints.Quality", _encoderHints.videoHints.quality);
  496. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.KeyframeInterval", (int)_encoderHints.videoHints.keyframeInterval);
  497. EditorPrefs.SetBool(SettingsPrefix + "EncoderHints.VideoHints.AllowFastStart", _encoderHints.videoHints.allowFastStartStreamingPostProcess);
  498. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.Transparency", (int)_encoderHints.videoHints.transparency);
  499. EditorPrefs.SetBool(SettingsPrefix + "EncoderHints.VideoHints.UseHardwareEncoding", _encoderHints.videoHints.useHardwareEncoding);
  500. EditorPrefs.SetBool(SettingsPrefix + "EncoderHints.VideoHints.EnableFragmentedWriting", _encoderHints.videoHints.enableFragmentedWriting);
  501. EditorPrefs.SetFloat(SettingsPrefix + "EncoderHints.VideoHints.MovieFragmentInterval", (float)_encoderHints.videoHints.movieFragmentInterval);
  502. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.InjectStereoPacking", (int)_encoderHints.videoHints.injectStereoPacking);
  503. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.StereoPacking", (int)_encoderHints.videoHints.stereoPacking);
  504. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.InjectSphericalVideoLayout", (int)_encoderHints.videoHints.injectSphericalVideoLayout);
  505. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.VideoHints.SphericalVideoLayout", (int)_encoderHints.videoHints.sphericalVideoLayout);
  506. EditorPrefs.SetFloat(SettingsPrefix + "EncoderHints.ImageHints.Quality", _encoderHints.imageHints.quality);
  507. EditorPrefs.SetInt(SettingsPrefix + "EncoderHints.ImageHints.Transparency", (int)_encoderHints.imageHints.transparency);
  508. EditorPrefs.SetBool(SettingsPrefix + "ShowAlphaChannel", _showAlpha);
  509. EditorPrefs.SetInt(SettingsPrefix + "SuperSizeIndex", _superSizeIndex);
  510. EditorPrefs.SetString(SettingsPrefix + "ScreenshotFolder", _screenshotFolder);
  511. EditorPrefs.SetInt(SettingsPrefix + "ScreenshotOptions.ExrPrecision", (int)_screenshotOptions.exrPrecision);
  512. EditorPrefs.SetInt(SettingsPrefix + "ScreenshotOptions.ExrCompression", (int)_screenshotOptions.exrCompression);
  513. EditorPrefs.SetInt(SettingsPrefix + "ScreenshotOptions.JpgQuality", _screenshotOptions.jpgQuality);
  514. // Camera selector
  515. EditorPrefs.SetInt(SelectorPrefix + "SelectBy", (int)_selectBy);
  516. EditorPrefs.SetInt(SelectorPrefix + "ScanFrequency", (int)_scanFrequency);
  517. EditorPrefs.SetBool(SelectorPrefix + "ScanHiddenCameras", _scanHiddenCameras);
  518. EditorPrefs.SetString(SelectorPrefix + "Tag", _selectCameraTag);
  519. EditorPrefs.SetString(SelectorPrefix + "Name", _selectCameraName);
  520. }
  521. private void ResetSettings()
  522. {
  523. _sourceType = SourceType.Screen;
  524. _cameraNode = null;
  525. _cameraName = string.Empty;
  526. _captureModeIndex = 0;
  527. _captureMouseCursor = false;
  528. _mouseCursorTexture = null;
  529. _outputTarget = OutputTarget.VideoFile;
  530. _imageSequenceFormat = ImageSequenceFormat.PNG;
  531. _namedPipePath = @"\\.\pipe\test_pipe";
  532. _filenamePrefixFromSceneName = true;
  533. _filenamePrefix = "capture";
  534. _filenameExtension = "mp4";
  535. _imageSequenceStartFrame = 0;
  536. _imageSequenceZeroDigits = 6;
  537. _outputFolderIndex = (int)CaptureBase.OutputPath.RelativeToProject;
  538. _outputFolderRelative = "Captures";
  539. _outputFolderAbsolute = string.Empty;
  540. _appendTimestamp = true;
  541. _downScaleIndex = 0;
  542. _downscaleX = 1;
  543. _downscaleY = 1;
  544. _frameRate = 30f;
  545. _timelapseScale = 1;
  546. _videoCodec = null;
  547. _audioCodec = null;
  548. _renderResolution = CaptureBase.Resolution.Original;
  549. _renderSize = Vector2.one;
  550. _renderAntiAliasing = 0;
  551. _useContributingCameras = true;
  552. _audioCaptureSource = AudioCaptureSource.None;
  553. _audioInputDevice = null;
  554. _manualAudioChannelCount = 2;
  555. _manualAudioSampleRate = 48000;
  556. _useMotionBlur = false;
  557. _motionBlurSampleCount = 16;
  558. _render180Degrees = false;
  559. _captureWorldSpaceGUI = false;
  560. _supportCameraRotation = false;
  561. _onlyLeftRightRotation = false;
  562. _cubemapResolution = 2048;
  563. _cubemapDepth = 24;
  564. _cubemapStereoPacking = 0;
  565. _startDelay = StartDelayMode.None;
  566. _startDelaySeconds = 0f;
  567. _stopMode = StopMode.None;
  568. _cubemapStereoIPD = 0.064f;
  569. _stopFrames = 300;
  570. _stopSeconds = 10f;
  571. _encoderHints = new EncoderHints();
  572. _odsSettings = new CaptureFromCamera360ODS.Settings();
  573. UpdateSelectedCodec();
  574. // Camera selector
  575. _selectBy = CameraSelector.SelectByMode.HighestDepthCamera;
  576. _scanFrequency = CameraSelector.ScanFrequencyMode.SceneLoad;
  577. _scanHiddenCameras = false;
  578. _selectCameraTag = "MainCamera";
  579. _selectCameraName = "Main Camera";
  580. }
  581. private void Configure(CaptureBase capture)
  582. {
  583. capture.VideoCodecPriorityWindows = new string[0];
  584. capture.VideoCodecPriorityMacOS = new string[0];
  585. capture.AudioCodecPriorityWindows = new string[0];
  586. capture.AudioCodecPriorityMacOS = new string[0];
  587. capture.FrameRate = _frameRate;
  588. capture.TimelapseScale = _timelapseScale;
  589. capture.ResolutionDownScale = GetDownScaleFromIndex(_downScaleIndex);
  590. if (capture.ResolutionDownScale == CaptureBase.DownScale.Custom)
  591. {
  592. capture.ResolutionDownscaleCustom = new Vector2(_downscaleX, _downscaleY);
  593. }
  594. capture.StartDelay = _startDelay;
  595. capture.StartDelaySeconds = _startDelaySeconds;
  596. capture.StopMode = _stopMode;
  597. capture.StopAfterFramesElapsed = _stopFrames;
  598. capture.StopAfterSecondsElapsed = _stopSeconds;
  599. capture.SetEncoderHints(_encoderHints);
  600. capture.IsRealTime = IsCaptureRealTime();
  601. capture.OutputTarget = _outputTarget;
  602. if (_outputTarget == OutputTarget.VideoFile)
  603. {
  604. capture.FilenamePrefix = _filenamePrefix;
  605. capture.AppendFilenameTimestamp = _appendTimestamp;
  606. capture.AllowManualFileExtension = true;
  607. capture.FilenameExtension = _filenameExtension;
  608. }
  609. else if (_outputTarget == OutputTarget.NamedPipe)
  610. {
  611. capture.NamedPipePath = _namedPipePath;
  612. }
  613. else if (_outputTarget == OutputTarget.ImageSequence)
  614. {
  615. capture.NativeImageSequenceFormat = _imageSequenceFormat;
  616. capture.ImageSequenceStartFrame = _imageSequenceStartFrame;
  617. capture.ImageSequenceZeroDigits = _imageSequenceZeroDigits;
  618. capture.FilenamePrefix = _filenamePrefix;
  619. }
  620. if (_outputFolderIndex == (int)CaptureBase.OutputPath.RelativeToPeristentData)
  621. {
  622. capture.OutputFolder = CaptureBase.OutputPath.RelativeToPeristentData;
  623. capture.OutputFolderPath = _outputFolderRelative;
  624. }
  625. else if (_outputFolderIndex == (int)CaptureBase.OutputPath.Absolute)
  626. {
  627. capture.OutputFolder = CaptureBase.OutputPath.Absolute;
  628. capture.OutputFolderPath = _outputFolderAbsolute;
  629. }
  630. else if (_outputFolderIndex == (int)CaptureBase.OutputPath.RelativeToDesktop)
  631. {
  632. capture.OutputFolder = CaptureBase.OutputPath.RelativeToDesktop;
  633. capture.OutputFolderPath = _outputFolderRelative;
  634. }
  635. else if (_outputFolderIndex == (int)CaptureBase.OutputPath.RelativeToPictures)
  636. {
  637. capture.OutputFolder = CaptureBase.OutputPath.RelativeToPictures;
  638. capture.OutputFolderPath = _outputFolderRelative;
  639. }
  640. else if (_outputFolderIndex == (int)CaptureBase.OutputPath.RelativeToVideos)
  641. {
  642. capture.OutputFolder = CaptureBase.OutputPath.RelativeToVideos;
  643. capture.OutputFolderPath = _outputFolderRelative;
  644. }
  645. else if (_outputFolderIndex == (int)CaptureBase.OutputPath.PhotoLibrary)
  646. {
  647. capture.OutputFolder = CaptureBase.OutputPath.PhotoLibrary;
  648. capture.OutputFolderPath = _outputFolderRelative;
  649. }
  650. else
  651. {
  652. capture.OutputFolder = CaptureBase.OutputPath.RelativeToProject;
  653. capture.OutputFolderPath = _outputFolderRelative;
  654. }
  655. capture.NativeForceVideoCodecIndex = (_videoCodec != null)?_videoCodec.Index:-1;
  656. capture.AudioCaptureSource = IsAudioCaptured()?_audioCaptureSource:AudioCaptureSource.None;
  657. if (capture.AudioCaptureSource != AudioCaptureSource.None)
  658. {
  659. capture.NativeForceAudioCodecIndex = (_audioCodec != null)?_audioCodec.Index:-1;
  660. if (capture.AudioCaptureSource == AudioCaptureSource.Microphone)
  661. {
  662. capture.ForceAudioInputDeviceIndex = (_audioInputDevice != null)?_audioInputDevice.Index:-1;
  663. }
  664. else if (capture.AudioCaptureSource == AudioCaptureSource.Manual)
  665. {
  666. capture.ManualAudioChannelCount = _manualAudioChannelCount;
  667. capture.ManualAudioSampleRate = _manualAudioSampleRate;
  668. }
  669. }
  670. if (_useMotionBlur && !capture.IsRealTime && Camera.main != null)
  671. {
  672. capture.UseMotionBlur = _useMotionBlur;
  673. capture.MotionBlurSamples = _motionBlurSampleCount;
  674. capture.MotionBlurCameras = new Camera[1];
  675. capture.MotionBlurCameras[0] = Camera.main;
  676. }
  677. else
  678. {
  679. capture.UseMotionBlur = false;
  680. }
  681. if (_captureScreen != null)
  682. {
  683. // Toggle mouse cursor
  684. if (_captureMouseCursor)
  685. {
  686. _captureScreen.CaptureMouseCursor = true;
  687. if (_captureScreen.MouseCursor == null)
  688. {
  689. _captureScreen.MouseCursor = capture.gameObject.AddComponent<MouseCursor>();
  690. }
  691. if (_captureScreen.MouseCursor != null)
  692. {
  693. _captureScreen.MouseCursor.SetTexture(_mouseCursorTexture);
  694. }
  695. }
  696. else
  697. {
  698. _captureScreen.CaptureMouseCursor = false;
  699. if (_captureScreen.MouseCursor != null)
  700. {
  701. _captureScreen.MouseCursor.enabled = false;
  702. }
  703. }
  704. }
  705. }
  706. private void CreateComponents()
  707. {
  708. // Create hidden gameobject
  709. if (_gameObject == null)
  710. {
  711. _gameObject = GameObject.Find(TempGameObjectName);
  712. if (_gameObject == null)
  713. {
  714. _gameObject = new GameObject(TempGameObjectName);
  715. _gameObject.hideFlags = HideFlags.HideAndDontSave;
  716. #if UNITY_5 || UNITY_5_4_OR_NEWER
  717. _gameObject.hideFlags |= HideFlags.DontSaveInBuild|HideFlags.DontSaveInEditor|HideFlags.DontUnloadUnusedAsset;
  718. #endif
  719. Object.DontDestroyOnLoad(_gameObject);
  720. }
  721. }
  722. // Remove old capture component if different
  723. if (_captureScreen != null && _sourceType != SourceType.Screen)
  724. {
  725. Destroy(_captureScreen);
  726. _captureScreen = null;
  727. }
  728. if (_captureCamera != null && _sourceType != SourceType.Camera)
  729. {
  730. Destroy(_captureCamera);
  731. _captureCamera = null;
  732. }
  733. if (_captureCamera360 != null && _sourceType != SourceType.Camera360)
  734. {
  735. Destroy(_captureCamera360);
  736. _captureCamera360 = null;
  737. }
  738. if (_captureCamera360ODS != null && _sourceType != SourceType.Camera360ODS)
  739. {
  740. Destroy(_captureCamera360ODS);
  741. _captureCamera360ODS = null;
  742. }
  743. if (_cameraSelector != null && _sourceType == SourceType.Screen)
  744. {
  745. Destroy(_cameraSelector);
  746. _cameraSelector = null;
  747. }
  748. #if AVPRO_MOVIECAPTURE_PLAYABLES_SUPPORT
  749. // Remove timelineController for realtime captures
  750. if (IsCaptureRealTime())
  751. {
  752. if (_timelineController != null)
  753. {
  754. Destroy(_timelineController);
  755. _timelineController = null;
  756. }
  757. }
  758. // Add timelineController for non-realtime captures
  759. else
  760. {
  761. if (_timelineController == null)
  762. {
  763. _timelineController = _gameObject.AddComponent<TimelineController>();
  764. }
  765. }
  766. #endif
  767. switch (_sourceType)
  768. {
  769. case SourceType.Screen:
  770. if (_captureScreen == null)
  771. {
  772. _captureScreen = _gameObject.AddComponent<CaptureFromScreen>();
  773. }
  774. _capture = _captureScreen;
  775. break;
  776. case SourceType.Camera:
  777. if (_captureCamera == null)
  778. {
  779. _captureCamera = _gameObject.AddComponent<CaptureFromCamera>();
  780. }
  781. if (_cameraSelector == null)
  782. {
  783. _cameraSelector = _gameObject.AddComponent<CameraSelector>();
  784. }
  785. SetupCameraSelector();
  786. _captureCamera.SetCamera(_cameraNode, _useContributingCameras);
  787. _captureCamera.CameraSelector = _cameraSelector;
  788. _capture = _captureCamera;
  789. _capture.CameraRenderResolution = _renderResolution;
  790. _capture.CameraRenderCustomResolution = _renderSize;
  791. _capture.CameraRenderAntiAliasing = _renderAntiAliasing;
  792. break;
  793. case SourceType.Camera360:
  794. if (_captureCamera360 == null)
  795. {
  796. _captureCamera360 = _gameObject.AddComponent<CaptureFromCamera360>();
  797. }
  798. if (_cameraSelector == null)
  799. {
  800. _cameraSelector = _gameObject.AddComponent<CameraSelector>();
  801. }
  802. SetupCameraSelector();
  803. _capture = _captureCamera360;
  804. _capture.CameraRenderResolution = _renderResolution;
  805. _capture.CameraRenderCustomResolution = _renderSize;
  806. _capture.CameraRenderAntiAliasing = _renderAntiAliasing;
  807. _captureCamera360.SetCamera(_cameraNode);
  808. _captureCamera360.CameraSelector = _cameraSelector;
  809. _captureCamera360.Render180Degrees = _render180Degrees;
  810. _captureCamera360.SupportCameraRotation = _supportCameraRotation;
  811. _captureCamera360.OnlyLeftRightRotation = _onlyLeftRightRotation;
  812. _captureCamera360.SupportGUI = _captureWorldSpaceGUI;
  813. _captureCamera360.CubemapFaceResolution = (CaptureBase.CubemapResolution)_cubemapResolution;
  814. _captureCamera360.CubemapDepthResolution = (CaptureBase.CubemapDepth)_cubemapDepth;
  815. _captureCamera360.StereoRendering = (StereoPacking)_cubemapStereoPacking;
  816. _captureCamera360.IPD = _cubemapStereoIPD;
  817. break;
  818. case SourceType.Camera360ODS:
  819. if (_captureCamera360ODS == null)
  820. {
  821. _captureCamera360ODS = _gameObject.AddComponent<CaptureFromCamera360ODS>();
  822. }
  823. if (_cameraSelector == null)
  824. {
  825. _cameraSelector = _gameObject.AddComponent<CameraSelector>();
  826. }
  827. SetupCameraSelector();
  828. _capture = _captureCamera360ODS;
  829. _capture.CameraRenderResolution = _renderResolution;
  830. _capture.CameraRenderCustomResolution = _renderSize;
  831. _capture.CameraRenderAntiAliasing = _renderAntiAliasing;
  832. _captureCamera360ODS.Setup.camera = _cameraNode;
  833. _captureCamera360ODS.Setup.cameraSelector = _cameraSelector;
  834. _captureCamera360ODS.Setup.render180Degrees = _odsSettings.render180Degrees;
  835. _captureCamera360ODS.Setup.ipd = _odsSettings.ipd;
  836. _captureCamera360ODS.Setup.pixelSliceSize = _odsSettings.pixelSliceSize;
  837. _captureCamera360ODS.Setup.paddingSize = _odsSettings.paddingSize;
  838. _captureCamera360ODS.Setup.cameraClearMode = _odsSettings.cameraClearMode;
  839. _captureCamera360ODS.Setup.cameraClearColor= _odsSettings.cameraClearColor;
  840. break;
  841. }
  842. #if AVPRO_MOVIECAPTURE_PLAYABLES_SUPPORT
  843. if (_capture != null)
  844. {
  845. _capture.TimelineController = _timelineController;
  846. }
  847. #endif
  848. }
  849. private void SetupCameraSelector()
  850. {
  851. if (_cameraSelector == null) return;
  852. _cameraSelector.SelectBy = _selectBy;
  853. _cameraSelector.ScanFrequency = _scanFrequency;
  854. _cameraSelector.ScanHiddenCameras = _scanHiddenCameras;
  855. if (_selectBy == CameraSelector.SelectByMode.Tag)
  856. {
  857. _cameraSelector.SelectTag = _selectCameraTag;
  858. }
  859. else if (_selectBy == CameraSelector.SelectByMode.Name)
  860. {
  861. _cameraSelector.SelectName = _selectCameraName;
  862. }
  863. else if (_selectBy == CameraSelector.SelectByMode.Manual)
  864. {
  865. _cameraSelector.Camera = _cameraNode;
  866. }
  867. }
  868. private void CreateGUI()
  869. {
  870. try
  871. {
  872. if (!NativePlugin.Init())
  873. {
  874. Debug.LogError("[AVProMovieCapture] Failed to initialise");
  875. return;
  876. }
  877. }
  878. catch (System.DllNotFoundException e)
  879. {
  880. _isFailedInit = true;
  881. string missingDllMessage = string.Empty;
  882. #if (UNITY_5 || UNITY_5_4_OR_NEWER)
  883. 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.";
  884. #else
  885. 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.";
  886. #endif
  887. Debug.LogError("[AVProMovieCapture] " + missingDllMessage);
  888. #if UNITY_EDITOR
  889. UnityEditor.EditorUtility.DisplayDialog("Plugin files not found", missingDllMessage, "Ok");
  890. #endif
  891. throw e;
  892. }
  893. // Audio device enumeration
  894. {
  895. int numAudioDevices = Mathf.Max(0, NativePlugin.GetAudioInputDeviceCount());
  896. _audioDeviceNames = new string[numAudioDevices];
  897. for (int i = 0; i < numAudioDevices; i++)
  898. {
  899. _audioDeviceNames[i] = i.ToString("D2") + ") " + NativePlugin.GetAudioInputDeviceName(i).Replace("/", "_");
  900. }
  901. }
  902. _isInit = true;
  903. }
  904. private void OnEnable()
  905. {
  906. if (_icon == null)
  907. {
  908. _icon = Resources.Load<Texture2D>("AVProMovieCaptureIcon");
  909. }
  910. if (!_isCreated)
  911. {
  912. SetupWindow();
  913. }
  914. _isTrialVersion = IsTrialVersion();
  915. // Check that the plugin version number is not too old
  916. {
  917. string pluginVersionString = NativePlugin.GetPluginVersionString();
  918. _pluginVersionWarningText = string.Empty;
  919. if (!pluginVersionString.StartsWith(NativePlugin.ExpectedPluginVersion))
  920. {
  921. _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.";
  922. }
  923. }
  924. }
  925. private void OnDisable()
  926. {
  927. SaveSettings();
  928. StopCapture();
  929. if (_gameObject != null)
  930. {
  931. DestroyImmediate(_gameObject);
  932. _gameObject = null;
  933. _capture = null;
  934. _captureScreen = null;
  935. _captureCamera = null;
  936. _captureCamera360 = null;
  937. _captureCamera360ODS = null;
  938. _cameraSelector = null;
  939. #if AVPRO_MOVIECAPTURE_PLAYABLES_SUPPORT
  940. _timelineController = null;
  941. #endif
  942. }
  943. _isInit = false;
  944. _isCreated = false;
  945. Repaint();
  946. }
  947. private void StartCapture()
  948. {
  949. _lastFileSize = 0;
  950. _lastEncodedSeconds = 0;
  951. _lastEncodedMinutes = 0;
  952. _lastEncodedFrame = 0;
  953. CreateComponents();
  954. if (_capture != null)
  955. {
  956. Configure(_capture);
  957. _capture.SelectVideoCodec();
  958. if (_capture.AudioCaptureSource != AudioCaptureSource.None)
  959. {
  960. _capture.SelectAudioCodec();
  961. _capture.SelectAudioInputDevice();
  962. }
  963. _capture.QueueStartCapture();
  964. }
  965. }
  966. private void StopCapture(bool cancelCapture = false)
  967. {
  968. if (_capture != null)
  969. {
  970. if (_capture.IsCapturing())
  971. {
  972. if (!cancelCapture)
  973. {
  974. _capture.StopCapture();
  975. }
  976. else
  977. {
  978. _capture.CancelCapture();
  979. }
  980. }
  981. _capture = null;
  982. }
  983. }
  984. // Updates 10 times/second
  985. void OnInspectorUpdate()
  986. {
  987. if (_capture != null)
  988. {
  989. if (Application.isPlaying)
  990. {
  991. if (_capture.IsCapturing())
  992. {
  993. _lastFileSize = _capture.GetCaptureFileSize();
  994. }
  995. if (!_capture.IsRealTime)
  996. {
  997. _lastEncodedSeconds = (uint)Mathf.FloorToInt((float)_capture.CaptureStats.NumEncodedFrames / _capture.FrameRate);
  998. }
  999. else
  1000. {
  1001. _lastEncodedSeconds = _capture.CaptureStats.TotalEncodedSeconds;
  1002. }
  1003. _lastEncodedMinutes = _lastEncodedSeconds / 60;
  1004. _lastEncodedSeconds = _lastEncodedSeconds % 60;
  1005. _lastEncodedFrame = _capture.CaptureStats.NumEncodedFrames % (uint)_capture.FrameRate;
  1006. // If the capture has stopped automatically, we need to update the UI
  1007. if (!_capture.IsPrepared() || (_capture.StopMode != StopMode.None && _capture.CaptureStats.NumEncodedFrames > 0 && !_capture.IsCapturing() && !_capture.IsStartCaptureQueued()))
  1008. {
  1009. StopCapture();
  1010. }
  1011. }
  1012. else
  1013. {
  1014. StopCapture();
  1015. }
  1016. }
  1017. else
  1018. {
  1019. if (_queueConfigureVideoCodec != null)
  1020. {
  1021. Codec tempCodec = _queueConfigureVideoCodec;
  1022. _queueConfigureVideoCodec = null;
  1023. tempCodec.ShowConfigWindow();
  1024. }
  1025. if (_queueConfigureAudioCodec != null)
  1026. {
  1027. Codec tempCodec = _queueConfigureAudioCodec;
  1028. _queueConfigureAudioCodec = null;
  1029. tempCodec.ShowConfigWindow();
  1030. }
  1031. if (_queueStart && Application.isPlaying)
  1032. {
  1033. _queueStart = false;
  1034. StartCapture();
  1035. }
  1036. }
  1037. Repaint();
  1038. }
  1039. private struct MediaApiItemMenuData
  1040. {
  1041. public MediaApiItemMenuData(IMediaApiItem item)
  1042. {
  1043. this.item = item;
  1044. }
  1045. public IMediaApiItem item;
  1046. }
  1047. private void MediaApiItemMenuCallback_Select(object obj)
  1048. {
  1049. if (((MediaApiItemMenuData)obj).item is Codec)
  1050. {
  1051. Codec codec = (Codec)((MediaApiItemMenuData)obj).item;
  1052. if (codec.CodecType == CodecType.Video)
  1053. {
  1054. _videoCodec = codec;
  1055. }
  1056. else if (codec.CodecType == CodecType.Audio)
  1057. {
  1058. _audioCodec = codec;
  1059. }
  1060. }
  1061. else if (((MediaApiItemMenuData)obj).item is Device)
  1062. {
  1063. Device device = (Device)((MediaApiItemMenuData)obj).item;
  1064. if (device.DeviceType == DeviceType.AudioInput)
  1065. {
  1066. _audioInputDevice = device;
  1067. }
  1068. }
  1069. UpdateSelectedCodec();
  1070. }
  1071. private GenericMenu CreateMediaItemMenu(System.Collections.IEnumerable items, IMediaApiItem selectedItem, IMediaApiItem matchMediaType)
  1072. {
  1073. GenericMenu menu = new GenericMenu();
  1074. #if UNITY_EDITOR_WIN
  1075. MediaApi lastApi = MediaApi.Unknown;
  1076. #endif
  1077. foreach (IMediaApiItem item in items)
  1078. {
  1079. bool isEnabled = (matchMediaType == null || matchMediaType.MediaApi == item.MediaApi);
  1080. #if UNITY_EDITOR_WIN
  1081. if (isEnabled && item.MediaApi != lastApi)
  1082. {
  1083. string title = string.Empty;
  1084. switch (item.MediaApi)
  1085. {
  1086. case MediaApi.DirectShow:
  1087. title = "DirectShow Legacy API:";
  1088. break;
  1089. case MediaApi.MediaFoundation:
  1090. title = "Media Foundation API:";
  1091. break;
  1092. }
  1093. menu.AddSeparator("");
  1094. menu.AddDisabledItem(new GUIContent(title));
  1095. lastApi = item.MediaApi;
  1096. }
  1097. #endif
  1098. if (isEnabled)
  1099. {
  1100. // Have to replace '/' as Unity context menu uses to this indicate a sub-menu
  1101. string displayName = item.Name.Replace("/", "⁄");
  1102. menu.AddItem(new GUIContent(displayName), item == selectedItem, MediaApiItemMenuCallback_Select, new MediaApiItemMenuData(item));
  1103. }
  1104. else
  1105. {
  1106. //menu.AddDisabledItem(new GUIContent(item.Name));
  1107. }
  1108. }
  1109. return menu;
  1110. }
  1111. private bool ShowMediaItemList(string title, System.Collections.IEnumerable itemList, IMediaApiItem selectedItem, IMediaApiItem matchMediaType = null)
  1112. {
  1113. bool result = false;
  1114. if (itemList == null || selectedItem == null)
  1115. {
  1116. return result;
  1117. }
  1118. if (!string.IsNullOrEmpty(title))
  1119. {
  1120. EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
  1121. }
  1122. EditorGUILayout.BeginHorizontal();
  1123. var rect = EditorGUILayout.GetControlRect(false);
  1124. if (EditorGUI.DropdownButton(rect, new GUIContent(selectedItem.Name), FocusType.Keyboard))
  1125. {
  1126. CreateMediaItemMenu(itemList, selectedItem, matchMediaType).DropDown(rect);
  1127. }
  1128. #if UNITY_EDITOR_WIN
  1129. if (selectedItem is Codec)
  1130. {
  1131. EditorGUI.BeginDisabledGroup(!((Codec)selectedItem).HasConfigwindow);
  1132. if (GUILayout.Button("Configure"))
  1133. {
  1134. result = true;
  1135. }
  1136. EditorGUI.EndDisabledGroup();
  1137. }
  1138. #endif
  1139. EditorGUILayout.EndHorizontal();
  1140. return result;
  1141. }
  1142. private static bool ShowConfigList(string title, string[] items, bool[] isConfigurable, ref Codec codec, ref int itemIndex, ref bool itemChanged, bool showConfig = true, bool listEnabled = true)
  1143. {
  1144. bool result = false;
  1145. if (itemIndex < 0 || items == null)
  1146. return result;
  1147. if (!string.IsNullOrEmpty(title))
  1148. {
  1149. EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
  1150. }
  1151. EditorGUI.BeginDisabledGroup(!listEnabled);
  1152. EditorGUILayout.BeginHorizontal();
  1153. int newItemIndex = EditorGUILayout.Popup(itemIndex, items);
  1154. itemChanged = (newItemIndex != itemIndex);
  1155. itemIndex = newItemIndex;
  1156. #if UNITY_EDITOR_WIN
  1157. if (showConfig && isConfigurable != null && itemIndex < isConfigurable.Length)
  1158. {
  1159. EditorGUI.BeginDisabledGroup(itemIndex == 0 || !isConfigurable[itemIndex]);
  1160. if (GUILayout.Button("Configure"))
  1161. {
  1162. result = true;
  1163. }
  1164. EditorGUI.EndDisabledGroup();
  1165. }
  1166. #endif
  1167. EditorGUILayout.EndHorizontal();
  1168. EditorGUI.EndDisabledGroup();
  1169. return result;
  1170. }
  1171. void OnGUI()
  1172. {
  1173. if ((Application.platform != RuntimePlatform.WindowsEditor)
  1174. && (Application.platform != RuntimePlatform.OSXEditor))
  1175. {
  1176. EditorGUILayout.LabelField("AVPro Movie Capture Window only works on the Windows and macOS platforms.");
  1177. return;
  1178. }
  1179. if (!_isInit)
  1180. {
  1181. if (_isFailedInit)
  1182. {
  1183. GUILayout.Label("Error", EditorStyles.boldLabel);
  1184. GUI.enabled = false;
  1185. string missingDllMessage = string.Empty;
  1186. #if (UNITY_5 || UNITY_5_4_OR_NEWER)
  1187. 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.";
  1188. #else
  1189. 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.";
  1190. #endif
  1191. GUILayout.TextArea(missingDllMessage);
  1192. GUI.enabled = true;
  1193. return;
  1194. }
  1195. else
  1196. {
  1197. EditorGUILayout.LabelField("Initialising...");
  1198. return;
  1199. }
  1200. }
  1201. if (!string.IsNullOrEmpty(_pluginVersionWarningText))
  1202. {
  1203. GUI.color = Color.yellow;
  1204. GUILayout.TextArea(_pluginVersionWarningText);
  1205. GUI.color = Color.white;
  1206. }
  1207. if (_so == null)
  1208. {
  1209. return;
  1210. }
  1211. _so.Update();
  1212. #if AVPRO_MOVIECAPTURE_GRAPHICSDEVICETYPE_51 && UNITY_EDITOR_WIN
  1213. if (SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.Direct3D11 &&
  1214. SystemInfo.graphicsDeviceType != UnityEngine.Rendering.GraphicsDeviceType.Direct3D12)
  1215. {
  1216. GUI.color = Color.yellow;
  1217. GUILayout.TextArea("Consider switching to D3D11 or D3D12 for best capture results. You may need to change your Build platform to Windows.");
  1218. GUI.color = Color.white;
  1219. }
  1220. #endif
  1221. if (_isTrialVersion)
  1222. {
  1223. EditorUtils.DrawSectionColored("- AVPRO MOVIE CAPTURE - TRIAL VERSION", ref _expandSectionTrial, DrawTrialMessage, Color.magenta, Color.magenta, Color.magenta);
  1224. //EditorGUILayout.Space();
  1225. }
  1226. DrawControlButtonsGUI();
  1227. EditorGUILayout.Space();
  1228. // Live Capture Stats
  1229. if (Application.isPlaying && _capture != null && (_capture.IsCapturing() || _capture.IsStartCaptureQueued()))
  1230. {
  1231. if (_propStopMode.enumValueIndex != (int)StopMode.None)
  1232. {
  1233. Rect r = GUILayoutUtility.GetRect(128f, EditorStyles.label.CalcHeight(GUIContent.none, 32f), GUILayout.ExpandWidth(true));
  1234. float progress = _capture.GetProgress();
  1235. EditorGUI.ProgressBar(r, progress, (progress * 100f).ToString("F1") + "%");
  1236. }
  1237. _scroll = EditorGUILayout.BeginScrollView(_scroll);
  1238. DrawBaseCapturingGUI(_capture);
  1239. DrawMoreCapturingGUI();
  1240. EditorGUILayout.EndScrollView();
  1241. }
  1242. // Configuration
  1243. else if (_capture == null)
  1244. {
  1245. string[] _toolNames = { "Settings", "Screenshot", "Help" };
  1246. _selectedTool = GUILayout.Toolbar(_selectedTool, _toolNames);
  1247. switch (_selectedTool)
  1248. {
  1249. case 0:
  1250. DrawConfigGUI_Toolbar();
  1251. _scroll = EditorGUILayout.BeginScrollView(_scroll);
  1252. DrawConfigGUI();
  1253. EditorGUILayout.EndScrollView();
  1254. break;
  1255. case 1:
  1256. _scroll = EditorGUILayout.BeginScrollView(_scroll);
  1257. DrawConfigGUI_Screenshot();
  1258. EditorGUILayout.EndScrollView();
  1259. break;
  1260. case 2:
  1261. _scroll = EditorGUILayout.BeginScrollView(_scroll);
  1262. DrawConfigGUI_About();
  1263. EditorGUILayout.EndScrollView();
  1264. break;
  1265. }
  1266. }
  1267. if (_so.ApplyModifiedProperties())
  1268. {
  1269. EditorUtility.SetDirty(this);
  1270. }
  1271. }
  1272. private void DrawTrialMessage()
  1273. {
  1274. string message = "The free trial version is watermarked. Upgrade to the full package to remove the watermark.";
  1275. //GUI.backgroundColor = Color.yellow;
  1276. //EditorGUILayout.BeginVertical(GUI.skin.box);
  1277. //GUI.color = Color.yellow;
  1278. //GUILayout.Label("AVPRO MOVIE CAPTURE - FREE TRIAL VERSION", EditorStyles.boldLabel);
  1279. GUI.color = Color.white;
  1280. GUILayout.Label(message, EditorStyles.wordWrappedLabel);
  1281. if (GUILayout.Button("Upgrade Now"))
  1282. {
  1283. Application.OpenURL(LinkAssetStorePage);
  1284. }
  1285. //EditorGUILayout.EndVertical();
  1286. GUI.backgroundColor = Color.white;
  1287. GUI.color = Color.white;
  1288. }
  1289. private void DrawControlButtonsGUI()
  1290. {
  1291. EditorGUILayout.BeginHorizontal();
  1292. if (_capture == null)
  1293. {
  1294. GUI.backgroundColor = Color.green;
  1295. string startString = "Start Capture";
  1296. if (!IsCaptureRealTime())
  1297. {
  1298. startString = "Start Render";
  1299. }
  1300. if (GUILayout.Button(startString, GUILayout.Height(32f)))
  1301. {
  1302. bool isReady = true;
  1303. if (_sourceType == SourceType.Camera &&
  1304. _cameraNode == null &&
  1305. _selectBy == CameraSelector.SelectByMode.Manual)
  1306. {
  1307. if ((ConfigTabs)_selectedConfigTab != ConfigTabs.Capture)
  1308. {
  1309. _cameraNode = Utils.GetUltimateRenderCamera();
  1310. }
  1311. if (_cameraNode == null)
  1312. {
  1313. Debug.LogError("[AVProMovieCapture] Please select a Camera to capture from, or select to capture from Screen.");
  1314. isReady = false;
  1315. }
  1316. }
  1317. if (isReady)
  1318. {
  1319. if (!Application.isPlaying)
  1320. {
  1321. EditorApplication.isPlaying = true;
  1322. _queueStart = true;
  1323. }
  1324. else
  1325. {
  1326. StartCapture();
  1327. Repaint();
  1328. }
  1329. }
  1330. }
  1331. }
  1332. else
  1333. {
  1334. GUI.backgroundColor = Color.cyan;
  1335. if (GUILayout.Button("Cancel", GUILayout.Height(32f)))
  1336. {
  1337. StopCapture(true);
  1338. Repaint();
  1339. }
  1340. GUI.backgroundColor = Color.red;
  1341. if (GUILayout.Button("Stop", GUILayout.Height(32f)))
  1342. {
  1343. StopCapture(false);
  1344. Repaint();
  1345. }
  1346. if (_capture != null)
  1347. {
  1348. if (_capture.IsPaused())
  1349. {
  1350. GUI.backgroundColor = Color.green;
  1351. if (GUILayout.Button("Resume", GUILayout.Height(32f)))
  1352. {
  1353. _capture.ResumeCapture();
  1354. Repaint();
  1355. }
  1356. }
  1357. else
  1358. {
  1359. GUI.backgroundColor = Color.yellow;
  1360. if (GUILayout.Button("Pause", GUILayout.Height(32f)))
  1361. {
  1362. _capture.PauseCapture();
  1363. Repaint();
  1364. }
  1365. }
  1366. }
  1367. }
  1368. EditorGUILayout.EndHorizontal();
  1369. GUI.backgroundColor = Color.white;
  1370. GUILayout.BeginHorizontal();
  1371. if (GUILayout.Button("Browse"))
  1372. {
  1373. if (!string.IsNullOrEmpty(CaptureBase.LastFileSaved))
  1374. {
  1375. Utils.ShowInExplorer(CaptureBase.LastFileSaved);
  1376. }
  1377. }
  1378. {
  1379. Color prevColor = GUI.color;
  1380. GUI.color = Color.cyan;
  1381. if (GUILayout.Button("View Last Capture"))
  1382. {
  1383. if (!string.IsNullOrEmpty(CaptureBase.LastFileSaved))
  1384. {
  1385. Utils.OpenInDefaultApp(CaptureBase.LastFileSaved);
  1386. }
  1387. }
  1388. GUI.color = prevColor;
  1389. }
  1390. GUILayout.EndHorizontal();
  1391. }
  1392. public static void DrawBaseCapturingGUI(CaptureBase capture)
  1393. {
  1394. GUILayout.Space(8.0f);
  1395. Texture texture = capture.GetPreviewTexture();
  1396. if (texture != null)
  1397. {
  1398. float aspect = (float)texture.width / (float)texture.height;
  1399. GUILayout.BeginHorizontal();
  1400. Transparency captureTransparency = capture.Transparency;
  1401. bool sideBySideTransparency = ( captureTransparency == Transparency.TopBottom || captureTransparency == Transparency.LeftRight );
  1402. //if (Event.current.type == EventType.Repaint)
  1403. {
  1404. if( _showAlpha && !sideBySideTransparency )
  1405. {
  1406. Rect textureRect = GUILayoutUtility.GetAspectRect(aspect);//(width, width / aspect, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(false));
  1407. EditorGUI.DrawPreviewTexture(textureRect, texture, null, ScaleMode.ScaleToFit);
  1408. textureRect = GUILayoutUtility.GetAspectRect(aspect);//width, width / aspect, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false)); ;
  1409. EditorGUI.DrawTextureAlpha(textureRect, texture, ScaleMode.ScaleToFit);
  1410. }
  1411. else
  1412. {
  1413. if( sideBySideTransparency )
  1414. {
  1415. Texture sideBySideTexture = capture.GetSideBySideTexture();
  1416. if( sideBySideTexture )
  1417. {
  1418. float sideBySideAspect = (float)sideBySideTexture.width / (float)sideBySideTexture.height;
  1419. Rect textureRect = GUILayoutUtility.GetAspectRect( sideBySideAspect/*, GUILayout.MaxHeight(256.0f)*/);
  1420. EditorGUI.DrawPreviewTexture(textureRect, sideBySideTexture, null, ScaleMode.StretchToFill);
  1421. }
  1422. }
  1423. else
  1424. {
  1425. Rect textureRect = GUILayoutUtility.GetAspectRect(aspect, GUILayout.MaxHeight(256f));//width, width / aspect, GUILayout.ExpandWidth(false), GUILayout.ExpandHeight(false));
  1426. EditorGUI.DrawPreviewTexture(textureRect, texture, null, ScaleMode.ScaleToFit);
  1427. }
  1428. }
  1429. }
  1430. GUILayout.EndHorizontal();
  1431. if( !sideBySideTransparency )
  1432. {
  1433. GUILayout.BeginHorizontal();
  1434. GUILayout.FlexibleSpace();
  1435. _showAlpha = GUILayout.Toggle(_showAlpha, "Show Alpha", GUILayout.ExpandWidth(false));
  1436. GUILayout.FlexibleSpace();
  1437. GUILayout.EndHorizontal();
  1438. GUILayout.Space(8.0f);
  1439. }
  1440. }
  1441. GUILayout.Label("Output", EditorStyles.boldLabel);
  1442. EditorGUILayout.BeginVertical(GUI.skin.box);
  1443. EditorGUI.indentLevel++;
  1444. GUILayout.Label("Recording to: " + System.IO.Path.GetFileName(capture.LastFilePath), EditorStyles.wordWrappedLabel);
  1445. GUILayout.Space(8.0f);
  1446. GUILayout.Label("Video");
  1447. EditorGUILayout.LabelField("Dimensions", capture.GetRecordingWidth() + "x" + capture.GetRecordingHeight() + " @ " + capture.FrameRate.ToString("F2") + "hz");
  1448. if (capture.OutputTarget == OutputTarget.VideoFile)
  1449. {
  1450. EditorGUILayout.LabelField("Codec", (capture.SelectedVideoCodec != null)?capture.SelectedVideoCodec.Name:"None");
  1451. }
  1452. else if (capture.OutputTarget == OutputTarget.ImageSequence)
  1453. {
  1454. EditorGUILayout.LabelField("Codec", capture.NativeImageSequenceFormat.ToString());
  1455. }
  1456. if (capture.AudioCaptureSource != AudioCaptureSource.None)
  1457. {
  1458. GUILayout.Label("Audio");
  1459. if (capture.AudioCaptureSource == AudioCaptureSource.Unity && capture.UnityAudioCapture != null)
  1460. {
  1461. EditorGUILayout.LabelField("Source", "Unity");
  1462. }
  1463. else if (capture.AudioCaptureSource == AudioCaptureSource.Microphone)
  1464. {
  1465. EditorGUILayout.LabelField("Source", (capture.SelectedAudioInputDevice != null)?capture.SelectedAudioInputDevice.Name:"None");
  1466. }
  1467. else if (capture.AudioCaptureSource == AudioCaptureSource.Wwise && capture.UnityAudioCapture != null)
  1468. {
  1469. EditorGUILayout.LabelField("Source", "Wwise");
  1470. }
  1471. EditorGUILayout.LabelField("Codec", (capture.SelectedAudioCodec!= null)?capture.SelectedAudioCodec.Name:"None");
  1472. if (capture.UnityAudioCapture != null && (capture.AudioCaptureSource == AudioCaptureSource.Unity || capture.AudioCaptureSource == AudioCaptureSource.Wwise))
  1473. {
  1474. EditorGUILayout.LabelField("Sample Rate", (capture.CaptureStats.UnityAudioSampleRate/1000f).ToString("F1") + "Khz");
  1475. EditorGUILayout.LabelField("Channels", capture.CaptureStats.UnityAudioChannelCount.ToString());
  1476. }
  1477. }
  1478. EditorGUI.indentLevel--;
  1479. EditorGUILayout.EndVertical();
  1480. GUILayout.Space(8.0f);
  1481. GUILayout.Label("Stats", EditorStyles.boldLabel);
  1482. EditorGUILayout.BeginVertical(GUI.skin.box);
  1483. EditorGUI.indentLevel++;
  1484. if (capture.CaptureStats.FPS > 0f)
  1485. {
  1486. Color originalColor = GUI.color;
  1487. if (capture.IsRealTime)
  1488. {
  1489. float fpsDelta = (capture.CaptureStats.FPS - capture.FrameRate);
  1490. GUI.color = Color.red;
  1491. if (fpsDelta > -10)
  1492. {
  1493. GUI.color = Color.yellow;
  1494. }
  1495. if (fpsDelta > -2)
  1496. {
  1497. GUI.color = Color.green;
  1498. }
  1499. }
  1500. EditorGUILayout.LabelField("Capture Rate", string.Format("{0:0.##} / {1:F2} FPS", capture.CaptureStats.FPS, capture.FrameRate));
  1501. GUI.color = originalColor;
  1502. }
  1503. else
  1504. {
  1505. EditorGUILayout.LabelField("Capture Rate", string.Format(".. / {0:F2} FPS", capture.FrameRate));
  1506. }
  1507. EditorGUILayout.LabelField("Encoded Frames", capture.CaptureStats.NumEncodedFrames.ToString());
  1508. EditorGUI.indentLevel--;
  1509. EditorGUILayout.EndVertical();
  1510. }
  1511. public void DrawMoreCapturingGUI()
  1512. {
  1513. GUILayout.Label("More Stats", EditorStyles.boldLabel);
  1514. EditorGUILayout.BeginVertical(GUI.skin.box);
  1515. EditorGUI.indentLevel++;
  1516. EditorGUILayout.LabelField("File Size", ((float)_lastFileSize / (1024f * 1024f)).ToString("F1") + "MB");
  1517. EditorGUILayout.LabelField("Video Length", _lastEncodedMinutes.ToString("00") + ":" + _lastEncodedSeconds.ToString("00") + "." + _lastEncodedFrame.ToString("000"));
  1518. EditorGUILayout.LabelField("Avg Bitrate", (8f * ((float)_lastFileSize / (1024f * 1024f)) / (float)((_lastEncodedMinutes * 60) + _lastEncodedSeconds)).ToString("F2") + "Mb/s");
  1519. EditorGUILayout.PrefixLabel("Dropped Frames");
  1520. EditorGUI.indentLevel++;
  1521. EditorGUILayout.LabelField("In Unity", _capture.CaptureStats.NumDroppedFrames.ToString());
  1522. EditorGUILayout.LabelField("In Encoder", _capture.CaptureStats.NumDroppedEncoderFrames.ToString());
  1523. EditorGUI.indentLevel--;
  1524. if (IsAudioCaptured())
  1525. {
  1526. if (_capture.AudioCaptureSource == AudioCaptureSource.Unity && _capture.UnityAudioCapture != null)
  1527. {
  1528. EditorGUILayout.LabelField("Audio Overflows", _capture.UnityAudioCapture.OverflowCount.ToString());
  1529. }
  1530. }
  1531. EditorGUI.indentLevel--;
  1532. EditorGUILayout.EndVertical();
  1533. }
  1534. private void DrawConfigGUI_Toolbar()
  1535. {
  1536. _selectedConfigTab = GUILayout.Toolbar(_selectedConfigTab, _tabNames);
  1537. }
  1538. private void DrawConfigGUI()
  1539. {
  1540. switch ((ConfigTabs)_selectedConfigTab)
  1541. {
  1542. case ConfigTabs.Encoding:
  1543. DrawConfigGUI_Encoding();
  1544. break;
  1545. case ConfigTabs.Capture:
  1546. DrawConfigGUI_Capture();
  1547. break;
  1548. case ConfigTabs.Visual:
  1549. DrawConfigGUI_Visual();
  1550. break;
  1551. case ConfigTabs.Audio:
  1552. DrawConfigGUI_Audio();
  1553. break;
  1554. }
  1555. GUILayout.FlexibleSpace();
  1556. }
  1557. public void DrawConfigGUI_Screenshot()
  1558. {
  1559. EditorGUILayout.PropertyField(_propScreenshotFolder, new GUIContent("Folder"));
  1560. EditorGUILayout.PropertyField(_propScreenshotOptions, new GUIContent("Format Options"));
  1561. EditorGUILayout.Space();
  1562. string folder = System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath, "../" + _screenshotFolder));
  1563. {
  1564. EditorGUILayout.BeginVertical(GUI.skin.box);
  1565. int superSize = 1;
  1566. switch (_superSizeIndex)
  1567. {
  1568. case 1:
  1569. superSize = 2;
  1570. break;
  1571. case 2:
  1572. superSize = 4;
  1573. break;
  1574. }
  1575. Vector2 captureSize = EditorScreenshot.GetGameViewSize() * superSize;
  1576. GUILayout.BeginHorizontal();
  1577. GUILayout.Label("GameView", EditorStyles.boldLabel, GUILayout.ExpandWidth(false));
  1578. GUILayout.Label(string.Format("({0}x{1})", (int)captureSize.x, (int)captureSize.y));
  1579. GUILayout.EndHorizontal();
  1580. EditorGUILayout.Space();
  1581. GUILayout.BeginHorizontal();
  1582. GUILayout.Label("Supersample");
  1583. _superSizeIndex = GUILayout.SelectionGrid(_superSizeIndex, new string[]{"1x", "2x", "4x"}, 4);
  1584. GUILayout.EndHorizontal();
  1585. GUILayout.BeginHorizontal();
  1586. if (GUILayout.Button("Capture PNG"))
  1587. {
  1588. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.PNG;
  1589. string filePath = EditorScreenshot.GenerateFilename("Screen", format, (int)captureSize.x, (int)captureSize.y);
  1590. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1591. EditorScreenshot.GameViewToPNG(filePath, superSize);
  1592. }
  1593. {
  1594. EditorGUI.BeginDisabledGroup(!EditorScreenshot.SupportsGameViewJPGTGAEXR());
  1595. if (GUILayout.Button("Capture JPG"))
  1596. {
  1597. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.JPG;
  1598. string filePath = EditorScreenshot.GenerateFilename("Screen", format, (int)captureSize.x, (int)captureSize.y);
  1599. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1600. EditorScreenshot.GameViewToFile(filePath, format, _screenshotOptions, superSize);
  1601. }
  1602. GUILayout.EndHorizontal();
  1603. GUILayout.BeginHorizontal();
  1604. {
  1605. EditorGUI.BeginDisabledGroup(!EditorScreenshot.SupportsTGA());
  1606. if (GUILayout.Button("Capture TGA"))
  1607. {
  1608. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.TGA;
  1609. string filePath = EditorScreenshot.GenerateFilename("Screen", format, (int)captureSize.x, (int)captureSize.y);
  1610. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1611. EditorScreenshot.GameViewToFile(filePath, format, _screenshotOptions, superSize);
  1612. }
  1613. EditorGUI.EndDisabledGroup();
  1614. }
  1615. {
  1616. EditorGUI.BeginDisabledGroup(!EditorScreenshot.SupportsGameViewEXR());
  1617. if (GUILayout.Button("Capture EXR"))
  1618. {
  1619. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.EXR;
  1620. string filePath = EditorScreenshot.GenerateFilename("Screen", format, (int)captureSize.x, (int)captureSize.y);
  1621. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1622. EditorScreenshot.GameViewToFile(filePath, format, _screenshotOptions, superSize);
  1623. }
  1624. EditorGUI.EndDisabledGroup();
  1625. }
  1626. EditorGUI.EndDisabledGroup();
  1627. }
  1628. GUILayout.EndHorizontal();
  1629. GUILayout.EndVertical();
  1630. }
  1631. EditorGUILayout.Space();
  1632. {
  1633. EditorGUILayout.BeginVertical(GUI.skin.box);
  1634. GUILayout.BeginHorizontal();
  1635. RenderTexture sceneViewTexture = EditorScreenshot.GetSceneViewTexture();
  1636. GUILayout.Label("Scene View", EditorStyles.boldLabel, GUILayout.ExpandWidth(false));
  1637. if (sceneViewTexture != null)
  1638. {
  1639. GUILayout.Label(string.Format("({0}x{1})", sceneViewTexture.width, sceneViewTexture.height));
  1640. }
  1641. else
  1642. {
  1643. GUI.color = Color.red;
  1644. GUILayout.Label("*Missing*", EditorStyles.boldLabel);
  1645. GUI.color = Color.white;
  1646. }
  1647. GUILayout.EndHorizontal();
  1648. GUILayout.BeginHorizontal();
  1649. if (GUILayout.Button("Capture PNG"))
  1650. {
  1651. EditorScreenshot.SceneViewToFile("Scene", folder, EditorScreenshot.ImageFormat.PNG, _screenshotOptions);
  1652. }
  1653. if (GUILayout.Button("Capture JPG"))
  1654. {
  1655. EditorScreenshot.SceneViewToFile("Scene", folder, EditorScreenshot.ImageFormat.JPG, _screenshotOptions);
  1656. }
  1657. GUILayout.EndHorizontal();
  1658. GUILayout.BeginHorizontal();
  1659. if (GUILayout.Button("Capture TGA"))
  1660. {
  1661. EditorScreenshot.SceneViewToFile("Scene", folder, EditorScreenshot.ImageFormat.TGA, _screenshotOptions);
  1662. }
  1663. if (GUILayout.Button("Capture EXR"))
  1664. {
  1665. EditorScreenshot.SceneViewToFile("Scene", folder, EditorScreenshot.ImageFormat.EXR, _screenshotOptions);
  1666. }
  1667. GUILayout.EndHorizontal();
  1668. GUILayout.EndVertical();
  1669. }
  1670. EditorGUILayout.Space();
  1671. {
  1672. GUILayout.BeginVertical(GUI.skin.box);
  1673. GUILayout.Label("Cameras", EditorStyles.boldLabel);
  1674. if (GUILayout.Button("Refresh"))
  1675. {
  1676. _cameras = Resources.FindObjectsOfTypeAll<Camera>();
  1677. }
  1678. if (_cameras != null && _cameras.Length > 0)
  1679. {
  1680. _cameraIndex = (int)GUILayout.HorizontalSlider(_cameraIndex, 0, _cameras.Length - 1, GUILayout.ExpandWidth(true));
  1681. EditorGUILayout.Space();
  1682. Camera camera = _cameras[_cameraIndex];
  1683. string desc = _cameraIndex + "/" + _cameras.Length + ": ";
  1684. Texture texture = Texture2D.blackTexture;
  1685. if (camera != null)
  1686. {
  1687. desc += camera.name;
  1688. if (camera.targetTexture != null)
  1689. {
  1690. desc += " " + camera.targetTexture.width + "x" + camera.targetTexture.height;
  1691. #if UNITY_2019_1_OR_NEWER
  1692. desc += " " + camera.targetTexture.graphicsFormat;
  1693. #endif
  1694. texture = camera.targetTexture;
  1695. }
  1696. }
  1697. GUILayout.Label(desc);
  1698. Rect textureRect = GUILayoutUtility.GetRect(256f, 256f);
  1699. GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleToFit);
  1700. }
  1701. if (_cameras != null && _cameras.Length > 0)
  1702. {
  1703. RenderTexture rt = _cameras[_cameraIndex].targetTexture;
  1704. if (rt != null)
  1705. {
  1706. GUILayout.BeginHorizontal();
  1707. if (GUILayout.Button("Capture PNG"))
  1708. {
  1709. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.PNG;
  1710. string filePath = EditorScreenshot.GenerateFilename("RT-" + rt.name, format, rt.width, rt.height);
  1711. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1712. EditorScreenshot.RenderTextureToFile(filePath, format, _screenshotOptions, rt);
  1713. }
  1714. if (GUILayout.Button("Capture EXR"))
  1715. {
  1716. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.EXR;
  1717. string filePath = EditorScreenshot.GenerateFilename("RT-" + rt.name, format, rt.width, rt.height);
  1718. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1719. EditorScreenshot.RenderTextureToFile(filePath, format, _screenshotOptions, rt);
  1720. }
  1721. GUILayout.EndHorizontal();
  1722. }
  1723. }
  1724. GUILayout.EndVertical();
  1725. }
  1726. EditorGUILayout.Space();
  1727. {
  1728. GUILayout.BeginVertical(GUI.skin.box);
  1729. GUILayout.Label("RenderTextures", EditorStyles.boldLabel);
  1730. if (GUILayout.Button("Refresh"))
  1731. {
  1732. _rts = Resources.FindObjectsOfTypeAll<RenderTexture>();
  1733. }
  1734. if (_rts != null && _rts.Length > 0)
  1735. {
  1736. _rtIndex = (int)GUILayout.HorizontalSlider(_rtIndex, 0, _rts.Length - 1, GUILayout.ExpandWidth(true));
  1737. EditorGUILayout.Space();
  1738. RenderTexture rt = _rts[_rtIndex];
  1739. string desc = _rtIndex + "/" + _rts.Length + ": ";
  1740. Texture texture = Texture2D.blackTexture;
  1741. if (rt != null)
  1742. {
  1743. desc += rt.name + " " + rt.width + "x" + rt.height;
  1744. #if UNITY_2019_1_OR_NEWER
  1745. desc += " " + rt.graphicsFormat;
  1746. #endif
  1747. texture = rt;
  1748. }
  1749. GUILayout.Label(desc);
  1750. Rect textureRect = GUILayoutUtility.GetRect(256f, 256f);
  1751. GUI.DrawTexture(textureRect, texture, ScaleMode.ScaleToFit);
  1752. }
  1753. if (_rts != null && _rts.Length > 0)
  1754. {
  1755. RenderTexture rt = _rts[_rtIndex];
  1756. if (rt != null)
  1757. {
  1758. GUILayout.BeginHorizontal();
  1759. if (GUILayout.Button("Capture PNG"))
  1760. {
  1761. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.PNG;
  1762. string filePath = EditorScreenshot.GenerateFilename("RT-" + rt.name, format, rt.width, rt.height);
  1763. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1764. EditorScreenshot.RenderTextureToFile(filePath, format, _screenshotOptions, rt);
  1765. }
  1766. if (GUILayout.Button("Capture EXR"))
  1767. {
  1768. EditorScreenshot.ImageFormat format = EditorScreenshot.ImageFormat.EXR;
  1769. string filePath = EditorScreenshot.GenerateFilename("RT-" + rt.name, format, rt.width, rt.height);
  1770. filePath = EditorScreenshot.GenerateFilePath(folder, filePath);
  1771. EditorScreenshot.RenderTextureToFile(filePath, format, _screenshotOptions, rt);
  1772. }
  1773. GUILayout.EndHorizontal();
  1774. }
  1775. }
  1776. GUILayout.EndVertical();
  1777. }
  1778. }
  1779. private static int _rtIndex;
  1780. private static int _cameraIndex;
  1781. private static RenderTexture[] _rts;
  1782. private static Camera[] _cameras;
  1783. public static void DrawConfigGUI_About()
  1784. {
  1785. string version = NativePlugin.GetPluginVersionString();
  1786. EditorGUILayout.BeginHorizontal();
  1787. GUILayout.FlexibleSpace();
  1788. if (_icon == null)
  1789. {
  1790. _icon = Resources.Load<Texture2D>("AVProMovieCaptureIcon");
  1791. }
  1792. if (_icon != null)
  1793. {
  1794. GUILayout.Label(new GUIContent(_icon));
  1795. }
  1796. GUILayout.FlexibleSpace();
  1797. EditorGUILayout.EndHorizontal();
  1798. EditorGUILayout.BeginHorizontal();
  1799. GUILayout.FlexibleSpace();
  1800. GUI.color = Color.yellow;
  1801. GUILayout.Label("AVPro Movie Capture by RenderHeads Ltd", EditorStyles.boldLabel);
  1802. GUI.color = Color.white;
  1803. GUILayout.FlexibleSpace();
  1804. EditorGUILayout.EndHorizontal();
  1805. EditorGUILayout.BeginHorizontal();
  1806. GUILayout.FlexibleSpace();
  1807. GUI.color = Color.yellow;
  1808. GUILayout.Label("version " + version + " (scripts v" + NativePlugin.ScriptVersion + ")");
  1809. GUI.color = Color.white;
  1810. GUILayout.FlexibleSpace();
  1811. EditorGUILayout.EndHorizontal();
  1812. // Links
  1813. {
  1814. GUILayout.Space(32f);
  1815. GUI.backgroundColor = Color.white;
  1816. EditorGUILayout.LabelField("AVPro Movie Capture Links", EditorStyles.boldLabel);
  1817. GUILayout.Space(8f);
  1818. EditorGUILayout.LabelField("Documentation");
  1819. if (GUILayout.Button("User Manual", GUILayout.ExpandWidth(false)))
  1820. {
  1821. Application.OpenURL(LinkUserManual);
  1822. }
  1823. GUILayout.Space(16f);
  1824. GUILayout.Label("Bugs and Support");
  1825. if (GUILayout.Button("GitHub Issues", GUILayout.ExpandWidth(false)))
  1826. {
  1827. Application.OpenURL(LinkSupport);
  1828. }
  1829. GUILayout.Space(16f);
  1830. GUILayout.Label("Rate and Review (★★★★☆)", GUILayout.ExpandWidth(false));
  1831. if (GUILayout.Button("Asset Store Page", GUILayout.ExpandWidth(false)))
  1832. {
  1833. Application.OpenURL(LinkAssetStorePage);
  1834. }
  1835. GUILayout.Space(16f);
  1836. GUILayout.Label("Community");
  1837. if (GUILayout.Button("Forum Thread", GUILayout.ExpandWidth(false)))
  1838. {
  1839. Application.OpenURL(LinkForumPage);
  1840. }
  1841. GUILayout.Space(16f);
  1842. GUILayout.Label("Website", GUILayout.ExpandWidth(false));
  1843. if (GUILayout.Button("Official Website", GUILayout.ExpandWidth(false)))
  1844. {
  1845. Application.OpenURL(LinkPluginWebsite);
  1846. }
  1847. }
  1848. // Credits
  1849. {
  1850. GUILayout.Space(32f);
  1851. EditorGUILayout.LabelField("Credits", EditorStyles.boldLabel);
  1852. GUILayout.Space(8f);
  1853. EditorUtils.CentreLabel("Programming", EditorStyles.boldLabel);
  1854. EditorUtils.CentreLabel("Andrew Griffiths");
  1855. EditorUtils.CentreLabel("Morris Butler");
  1856. EditorUtils.CentreLabel("Richard Turnbull");
  1857. EditorUtils.CentreLabel("Sunrise Wang");
  1858. GUILayout.Space(8f);
  1859. EditorUtils.CentreLabel("Graphics", EditorStyles.boldLabel);
  1860. EditorUtils.CentreLabel("Jeff Rusch");
  1861. EditorUtils.CentreLabel("Luke Godward");
  1862. }
  1863. // Bug reporting
  1864. {
  1865. GUILayout.Space(32f);
  1866. EditorGUILayout.LabelField("Bug Reporting Notes", EditorStyles.boldLabel);
  1867. EditorGUILayout.SelectableLabel(SupportMessage, EditorStyles.wordWrappedLabel, GUILayout.Height(180f));
  1868. }
  1869. }
  1870. private void DrawConfigGUI_Capture()
  1871. {
  1872. //GUILayout.Label("Capture", EditorStyles.boldLabel);
  1873. EditorGUILayout.BeginVertical(GUI.skin.box);
  1874. //EditorGUI.indentLevel++;
  1875. // Time
  1876. {
  1877. GUILayout.Space(8f);
  1878. EditorGUILayout.LabelField("Time", EditorStyles.boldLabel);
  1879. EditorGUI.indentLevel++;
  1880. _captureModeIndex = EditorGUILayout.Popup("Capture Mode", _captureModeIndex, _captureModes);
  1881. GUILayout.BeginHorizontal();
  1882. EditorGUILayout.PropertyField(_propFrameRate, GUILayout.ExpandWidth(false));
  1883. _propFrameRate.floatValue = Mathf.Clamp(_propFrameRate.floatValue, 0.01f, 240f);
  1884. EditorUtils.FloatAsPopup("▶", "Common Frame Rates", _so, _propFrameRate, EditorUtils.CommonFrameRateNames, EditorUtils.CommonFrameRateValues);
  1885. GUILayout.EndHorizontal();
  1886. if (IsCaptureRealTime())
  1887. {
  1888. EditorGUILayout.PropertyField(_propTimelapseScale);
  1889. _propTimelapseScale.intValue = Mathf.Max(1, _propTimelapseScale.intValue);
  1890. }
  1891. EditorGUI.indentLevel--;
  1892. }
  1893. // Source
  1894. GUILayout.Space(8f);
  1895. EditorGUILayout.LabelField("Source", EditorStyles.boldLabel);
  1896. EditorGUI.indentLevel++;
  1897. EditorUtils.EnumAsDropdown("Source", _propSourceType, _sourceNames);
  1898. if (_sourceType == SourceType.Camera360ODS && IsCaptureRealTime())
  1899. {
  1900. GUI.color = Color.yellow;
  1901. GUILayout.TextArea("Warning: This source type is very slow and not suitable for 'Realtime Capture'. Consider changing the capture mode to 'Offline Render'.");
  1902. GUI.color = Color.white;
  1903. }
  1904. EditorGUI.indentLevel--;
  1905. //_sourceType = (SourceType)EditorGUILayout.EnumPopup("Type", _sourceType);
  1906. if (_sourceType == SourceType.Camera || _sourceType == SourceType.Camera360 || _sourceType == SourceType.Camera360ODS)
  1907. {
  1908. GUILayout.Space(8f);
  1909. EditorGUILayout.LabelField("Camera Selector", EditorStyles.boldLabel);
  1910. EditorGUI.indentLevel++;
  1911. EditorGUILayout.PropertyField(_propCameraSelectorSelectBy);
  1912. if (_propCameraSelectorSelectBy.enumValueIndex == (int)CameraSelector.SelectByMode.Name)
  1913. {
  1914. EditorGUILayout.PropertyField(_propCameraSelectorName, _guiCameraSelectorName);
  1915. }
  1916. else if (_propCameraSelectorSelectBy.enumValueIndex == (int)CameraSelector.SelectByMode.Tag)
  1917. {
  1918. EditorGUILayout.PropertyField(_propCameraSelectorTag, _guiCameraSelectorTag);
  1919. }
  1920. else if (_propCameraSelectorSelectBy.enumValueIndex == (int)CameraSelector.SelectByMode.Manual)
  1921. {
  1922. if (_cameraNode == null)
  1923. {
  1924. _cameraNode = Utils.GetUltimateRenderCamera();
  1925. }
  1926. _cameraNode = (Camera)EditorGUILayout.ObjectField("Camera", _cameraNode, typeof(Camera), true);
  1927. }
  1928. #if !SUPPORT_SCENE_VIEW_GIZMOS_CAPTURE
  1929. else if (_propCameraSelectorSelectBy.enumValueIndex == (int)CameraSelector.SelectByMode.EditorSceneView)
  1930. {
  1931. GUI.color = Color.yellow;
  1932. GUILayout.TextArea("Warning: Scene View capture only currently supports gizmo capture up to Unity 2018.2.x");
  1933. GUI.color = Color.white;
  1934. }
  1935. #endif
  1936. if (_sourceType == SourceType.Camera && _cameraNode != null)
  1937. {
  1938. EditorGUILayout.PropertyField(_propUseContributingCameras, _guiContributingCameras);
  1939. }
  1940. EditorGUILayout.PropertyField(_propCameraSelectorScanFrequency);
  1941. EditorGUILayout.PropertyField(_propCameraSelectorScanHiddenCameras);
  1942. EditorGUI.indentLevel--;
  1943. }
  1944. // Screen options
  1945. if (_sourceType == SourceType.Screen)
  1946. {
  1947. GUILayout.Space(8f);
  1948. EditorGUILayout.LabelField("Cursor", EditorStyles.boldLabel);
  1949. EditorGUI.indentLevel++;
  1950. _captureMouseCursor = EditorGUILayout.Toggle("Capture Mouse Cursor", _captureMouseCursor);
  1951. _mouseCursorTexture = (Texture2D)EditorGUILayout.ObjectField("Mouse Cursor Texture", _mouseCursorTexture, typeof(Texture2D), false);
  1952. EditorGUI.indentLevel--;
  1953. }
  1954. // Camera overrides
  1955. if (_sourceType == SourceType.Camera || _sourceType == SourceType.Camera360 || _sourceType == SourceType.Camera360ODS)
  1956. {
  1957. GUILayout.Space(8f);
  1958. EditorGUILayout.LabelField("Camera Overrides", EditorStyles.boldLabel);
  1959. EditorGUI.indentLevel++;
  1960. {
  1961. EditorUtils.EnumAsDropdown("Resolution", _propRenderResolution, CaptureBaseEditor.ResolutionStrings);
  1962. }
  1963. if (_renderResolution == CaptureBase.Resolution.Custom)
  1964. {
  1965. _renderSize = EditorGUILayout.Vector2Field("Size", _renderSize);
  1966. _renderSize = new Vector2(Mathf.Clamp((int)_renderSize.x, 1, NativePlugin.MaxRenderWidth), Mathf.Clamp((int)_renderSize.y, 1, NativePlugin.MaxRenderHeight));
  1967. }
  1968. {
  1969. string currentAA = "None";
  1970. if (QualitySettings.antiAliasing > 1)
  1971. {
  1972. currentAA = QualitySettings.antiAliasing.ToString() + "x";
  1973. }
  1974. EditorUtils.IntAsDropdown("Anti-aliasing", _propRenderAntiAliasing, new string[] { "Current (" + currentAA + ")", "None", "2x", "4x", "8x" }, new int[] { -1, 1, 2, 4, 8 });
  1975. }
  1976. if (_cameraNode != null)
  1977. {
  1978. if (_cameraNode.actualRenderingPath == RenderingPath.DeferredLighting
  1979. #if AVPRO_MOVIECAPTURE_DEFERREDSHADING
  1980. || _cameraNode.actualRenderingPath == RenderingPath.DeferredShading
  1981. #endif
  1982. )
  1983. {
  1984. GUI.color = Color.yellow;
  1985. GUILayout.TextArea("Warning: Antialiasing by MSAA is not supported as camera is using deferred rendering path");
  1986. GUI.color = Color.white;
  1987. _renderAntiAliasing = -1;
  1988. }
  1989. if (_cameraNode.clearFlags == CameraClearFlags.Nothing || _cameraNode.clearFlags == CameraClearFlags.Depth)
  1990. {
  1991. if (_renderResolution != CaptureBase.Resolution.Original || _renderAntiAliasing != -1)
  1992. {
  1993. GUI.color = Color.yellow;
  1994. GUILayout.TextArea("Warning: Overriding camera resolution or anti-aliasing when clear flag is set to " + _cameraNode.clearFlags + " may result in incorrect captures");
  1995. GUI.color = Color.white;
  1996. }
  1997. }
  1998. }
  1999. EditorGUI.indentLevel--;
  2000. }
  2001. // 360 Cubemap
  2002. if (_sourceType == SourceType.Camera360)
  2003. {
  2004. GUILayout.Space(8f);
  2005. EditorGUILayout.LabelField("360 Camera", EditorStyles.boldLabel);
  2006. EditorGUI.indentLevel++;
  2007. EditorGUILayout.PropertyField(_propRender180Degrees);
  2008. {
  2009. CaptureBase.CubemapResolution cubemapEnum = (CaptureBase.CubemapResolution)_cubemapResolution;
  2010. _cubemapResolution = (int)((CaptureBase.CubemapResolution)EditorGUILayout.EnumPopup("Resolution", cubemapEnum));
  2011. }
  2012. {
  2013. CaptureBase.CubemapDepth depthEnum = (CaptureBase.CubemapDepth)_cubemapDepth;
  2014. _cubemapDepth = (int)((CaptureBase.CubemapDepth)EditorGUILayout.EnumPopup("Depth", depthEnum));
  2015. }
  2016. {
  2017. StereoPacking stereoEnum = (StereoPacking)_cubemapStereoPacking;
  2018. _cubemapStereoPacking = (int)((StereoPacking)EditorGUILayout.EnumPopup("Stereo Mode", stereoEnum));
  2019. }
  2020. if (_cubemapStereoPacking != (int)StereoPacking.None)
  2021. {
  2022. #if AVPRO_MOVIECAPTURE_UNITY_STEREOCUBEMAP_RENDER
  2023. if (!PlayerSettings.enable360StereoCapture)
  2024. {
  2025. GUI.color = Color.yellow;
  2026. GUILayout.TextArea("Warning: 360 Stereo Capture needs to be enabled in PlayerSettings");
  2027. GUI.color = Color.white;
  2028. if (GUILayout.Button("Enable 360 Stereo Capture"))
  2029. {
  2030. PlayerSettings.enable360StereoCapture = true;
  2031. }
  2032. }
  2033. #endif
  2034. _cubemapStereoIPD = EditorGUILayout.FloatField("Interpupillary distance", _cubemapStereoIPD);
  2035. }
  2036. EditorGUILayout.PropertyField(_propCaptureWorldSpaceGUI, _guiCaptureWorldSpaceUI);
  2037. EditorGUILayout.PropertyField(_propSupportCameraRotation, _guiCameraRotation);
  2038. if (_propSupportCameraRotation.boolValue)
  2039. {
  2040. EditorGUILayout.PropertyField(_propOnlyLeftRightRotation);
  2041. }
  2042. EditorGUI.indentLevel--;
  2043. }
  2044. // 360 Cubemap ODS
  2045. if (_sourceType == SourceType.Camera360ODS)
  2046. {
  2047. GUILayout.Space(8f);
  2048. EditorGUI.indentLevel++;
  2049. EditorGUILayout.LabelField("Source Options", EditorStyles.boldLabel);
  2050. EditorGUI.indentLevel++;
  2051. {
  2052. EditorGUILayout.PropertyField(_propOdsRender180Degrees);
  2053. EditorGUILayout.PropertyField(_propOdsIPD, _guiInterpupillaryDistance);
  2054. EditorGUILayout.PropertyField(_propOdsPixelSliceSize);
  2055. EditorGUILayout.PropertyField(_propOdsPaddingSize);
  2056. EditorGUILayout.PropertyField(_propOdsCameraClearMode);
  2057. EditorGUILayout.PropertyField(_propOdsCameraClearColor);
  2058. }
  2059. EditorGUI.indentLevel--;
  2060. EditorGUI.indentLevel--;
  2061. }
  2062. // Start / Stop
  2063. {
  2064. GUILayout.Space(8f);
  2065. EditorGUILayout.LabelField("Start / Stop", EditorStyles.boldLabel);
  2066. EditorGUI.indentLevel++;
  2067. EditorGUILayout.PropertyField(_propStartDelay, _guiStartDelay);
  2068. if ((StartDelayMode)_propStartDelay.enumValueIndex == StartDelayMode.RealSeconds ||
  2069. (StartDelayMode)_propStartDelay.enumValueIndex == StartDelayMode.GameSeconds)
  2070. {
  2071. EditorGUILayout.PropertyField(_propStartDelaySeconds, _guiSeconds);
  2072. }
  2073. EditorGUILayout.Separator();
  2074. _stopMode = (StopMode)EditorGUILayout.EnumPopup("Stop Mode", _stopMode);
  2075. if (_stopMode == StopMode.FramesEncoded)
  2076. {
  2077. _stopFrames = EditorGUILayout.IntField("Frames", _stopFrames);
  2078. }
  2079. else if (_stopMode == StopMode.SecondsElapsed || _stopMode == StopMode.SecondsEncoded)
  2080. {
  2081. _stopSeconds = EditorGUILayout.FloatField("Seconds", _stopSeconds);
  2082. }
  2083. EditorGUI.indentLevel--;
  2084. }
  2085. GUILayout.Space(8f);
  2086. if (GUILayout.Button("Reset All Settings"))
  2087. {
  2088. ResetSettings();
  2089. }
  2090. GUILayout.Space(4f);
  2091. //EditorGUI.indentLevel--;
  2092. EditorGUILayout.EndVertical();
  2093. }
  2094. private void DrawConfigGUI_Encoding()
  2095. {
  2096. //GUILayout.Label("Target", EditorStyles.boldLabel);
  2097. EditorGUILayout.BeginVertical(GUI.skin.box);
  2098. //EditorGUI.indentLevel++;
  2099. EditorUtils.EnumAsDropdown("Output Target", _propOutputTarget, EditorUtils.OutputTargetNames);
  2100. GUILayout.Space(8f);
  2101. if (_propOutputTarget.enumValueIndex == (int)OutputTarget.VideoFile ||
  2102. _propOutputTarget.enumValueIndex == (int)OutputTarget.ImageSequence)
  2103. {
  2104. bool isImageSequence = (_propOutputTarget.enumValueIndex == (int)OutputTarget.ImageSequence);
  2105. if (isImageSequence)
  2106. {
  2107. EditorUtils.EnumAsDropdown("Format", _propImageSequenceFormat, Utils.GetNativeImageSequenceFormatNames());
  2108. GUILayout.Space(8f);
  2109. }
  2110. // File path
  2111. EditorGUILayout.LabelField("File Path", EditorStyles.boldLabel);
  2112. EditorGUI.indentLevel++;
  2113. _outputFolderIndex = EditorGUILayout.Popup("Relative to", _outputFolderIndex, _outputFolders);
  2114. if (_outputFolderIndex != (int)CaptureBase.OutputPath.Absolute)
  2115. {
  2116. _outputFolderRelative = EditorGUILayout.TextField("SubFolder(s)", _outputFolderRelative);
  2117. }
  2118. else
  2119. {
  2120. EditorGUILayout.BeginHorizontal();
  2121. _outputFolderAbsolute = EditorGUILayout.TextField("Path", _outputFolderAbsolute);
  2122. if (GUILayout.Button(">", GUILayout.Width(22)))
  2123. {
  2124. _outputFolderAbsolute = EditorUtility.SaveFolderPanel("Select Folder To Store Video Captures", System.IO.Path.GetFullPath(System.IO.Path.Combine(Application.dataPath, "../")), "");
  2125. EditorUtility.SetDirty(this);
  2126. }
  2127. EditorGUILayout.EndHorizontal();
  2128. }
  2129. EditorGUI.indentLevel--;
  2130. GUILayout.Space(8f);
  2131. // File name
  2132. EditorGUILayout.LabelField("File Name", EditorStyles.boldLabel);
  2133. EditorGUI.indentLevel++;
  2134. _filenamePrefixFromSceneName = EditorGUILayout.Toggle("From Scene Name", _filenamePrefixFromSceneName);
  2135. if (_filenamePrefixFromSceneName)
  2136. {
  2137. #if AVPRO_MOVIECAPTURE_SCENEMANAGER_53
  2138. string currentScenePath = UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene().path;
  2139. #else
  2140. string currentScenePath = EditorApplication.currentScene;
  2141. #endif
  2142. _filenamePrefix = System.IO.Path.GetFileNameWithoutExtension(currentScenePath);
  2143. if (string.IsNullOrEmpty(_filenamePrefix))
  2144. {
  2145. _filenamePrefix = "capture";
  2146. }
  2147. }
  2148. EditorGUI.BeginDisabledGroup(_filenamePrefixFromSceneName);
  2149. _filenamePrefix = EditorGUILayout.TextField("Prefix", _filenamePrefix);
  2150. EditorGUI.EndDisabledGroup();
  2151. if (!isImageSequence)
  2152. {
  2153. _appendTimestamp = EditorGUILayout.Toggle("Append Timestamp", _appendTimestamp);
  2154. }
  2155. else
  2156. {
  2157. EditorGUILayout.PropertyField(_propImageSequenceStartFrame, _guiStartFrame);
  2158. EditorGUILayout.PropertyField(_propImageSequenceZeroDigits, _guiZeroDigits);
  2159. }
  2160. EditorGUI.indentLevel--;
  2161. GUILayout.Space(8f);
  2162. // File container
  2163. if (!isImageSequence)
  2164. {
  2165. EditorGUILayout.LabelField("File Container", EditorStyles.boldLabel);
  2166. EditorGUI.indentLevel++;
  2167. _fileContainerIndex = EditorGUILayout.Popup("Extension", _fileContainerIndex, _fileExtensions);
  2168. if (_fileContainerIndex >= 0 && _fileContainerIndex < _fileExtensions.Length)
  2169. {
  2170. _filenameExtension = _fileExtensions[_fileContainerIndex].ToLower();
  2171. }
  2172. EditorGUI.indentLevel--;
  2173. }
  2174. }
  2175. else if (_propOutputTarget.enumValueIndex == (int)OutputTarget.NamedPipe)
  2176. {
  2177. EditorGUILayout.PropertyField(_propNamedPipePath);
  2178. }
  2179. DrawVisualCodecList();
  2180. DrawAudioCodecList();
  2181. if (_propOutputTarget.enumValueIndex == (int)OutputTarget.VideoFile ||
  2182. _propOutputTarget.enumValueIndex == (int)OutputTarget.ImageSequence)
  2183. {
  2184. GUILayout.Space(8f);
  2185. EditorGUILayout.LabelField("Encoder Hints", EditorStyles.boldLabel);
  2186. EditorGUI.indentLevel++;
  2187. if (_propOutputTarget.enumValueIndex == (int)OutputTarget.VideoFile)
  2188. {
  2189. EditorUtils.BitrateField("Average Bitrate", _propVideoHintsAverageBitrate);
  2190. #if UNITY_EDITOR_WIN
  2191. EditorUtils.BitrateField("Maxiumum Bitrate", _propVideoHintsMaximumBitrate);
  2192. // Ensure that the maximum value is larger than the average value, or zero
  2193. if (_propVideoHintsMaximumBitrate.intValue != 0)
  2194. {
  2195. _propVideoHintsMaximumBitrate.intValue = Mathf.Max(_propVideoHintsMaximumBitrate.intValue, _propVideoHintsAverageBitrate.intValue);
  2196. }
  2197. #endif
  2198. EditorGUILayout.PropertyField(_propVideoHintsQuality);
  2199. EditorGUILayout.PropertyField(_propVideoHintsKeyframeInterval);
  2200. EditorGUILayout.PropertyField(_propVideoHintsTransparency);
  2201. #if UNITY_EDITOR_WIN
  2202. EditorGUILayout.PropertyField(_propVideoHintsUseHardwareEncoding, new GUIContent("Hardware Encoding"));
  2203. #elif UNITY_EDITOR_OSX
  2204. EditorGUILayout.PropertyField(_propVideoHintsEnableFragmentedWriting);
  2205. if (_propVideoHintsEnableFragmentedWriting.boolValue)
  2206. {
  2207. EditorGUILayout.PropertyField(_propVideoHintsMovieFragmentInterval);
  2208. }
  2209. #endif
  2210. }
  2211. else if (_propOutputTarget.enumValueIndex == (int)OutputTarget.ImageSequence)
  2212. {
  2213. #if UNITY_EDITOR_OSX
  2214. EditorGUILayout.PropertyField(_propImageHintsQuality);
  2215. #endif
  2216. EditorGUILayout.PropertyField(_propImageHintsTransparency);
  2217. }
  2218. EditorGUI.indentLevel--;
  2219. if (_propOutputTarget.enumValueIndex == (int)OutputTarget.VideoFile)
  2220. {
  2221. GUILayout.Space(8f);
  2222. EditorGUILayout.LabelField("Post Process", EditorStyles.boldLabel);
  2223. EditorGUI.indentLevel++;
  2224. EditorGUILayout.PropertyField(_propVideoHintsAllowFastStart);
  2225. EditorGUILayout.PropertyField(_propVideoHintsInjectStereoPacking, _guiStereoPacking);
  2226. if (_propVideoHintsInjectStereoPacking.enumValueIndex == (int)NoneAutoCustom.Custom)
  2227. {
  2228. EditorGUILayout.PropertyField(_propVideoHintsStereoPacking, _guiBlankSpace);
  2229. }
  2230. EditorGUILayout.PropertyField(_propVideoHintsInjectSphericalVideoLayout, _guiSphericalLayout);
  2231. if (_propVideoHintsInjectSphericalVideoLayout.enumValueIndex == (int)NoneAutoCustom.Custom)
  2232. {
  2233. EditorGUILayout.PropertyField(_propVideoHintsSphericalVideoLayout, _guiBlankSpace);
  2234. }
  2235. }
  2236. }
  2237. //EditorGUI.indentLevel--;
  2238. EditorGUILayout.EndVertical();
  2239. }
  2240. private void DrawConfigGUI_Visual()
  2241. {
  2242. //GUILayout.Label("Video", EditorStyles.boldLabel);
  2243. EditorGUILayout.BeginVertical(GUI.skin.box);
  2244. //EditorGUI.indentLevel++;
  2245. {
  2246. Vector2 outSize = Vector2.zero;
  2247. if (_sourceType == SourceType.Screen)
  2248. {
  2249. // We can't just use Screen.width and Screen.height because Unity returns the size of this window
  2250. // So instead we look for a camera with no texture target and a valid viewport
  2251. int inWidth = 1;
  2252. int inHeight = 1;
  2253. foreach (Camera cam in Camera.allCameras)
  2254. {
  2255. if (cam.targetTexture == null)
  2256. {
  2257. float rectWidth = Mathf.Clamp01(cam.rect.width + cam.rect.x) - Mathf.Clamp01(cam.rect.x);
  2258. float rectHeight = Mathf.Clamp01(cam.rect.height + cam.rect.y) - Mathf.Clamp01(cam.rect.y);
  2259. if (rectWidth > 0.0f && rectHeight > 0.0f)
  2260. {
  2261. inWidth = Mathf.FloorToInt(cam.pixelWidth / rectWidth);
  2262. inHeight = Mathf.FloorToInt(cam.pixelHeight / rectHeight);
  2263. //Debug.Log (rectWidth + " " + (cam.rect.height - cam.rect.y) + " " + cam.pixelHeight + " = " + inWidth + "x" + inHeight);
  2264. break;
  2265. }
  2266. }
  2267. }
  2268. outSize = CaptureBase.GetRecordingResolution(inWidth, inHeight, GetDownScaleFromIndex(_downScaleIndex), new Vector2(_downscaleX, _downscaleY));
  2269. }
  2270. else
  2271. {
  2272. if (_cameraNode != null)
  2273. {
  2274. int inWidth = Mathf.FloorToInt(_cameraNode.pixelRect.width);
  2275. int inHeight = Mathf.FloorToInt(_cameraNode.pixelRect.height);
  2276. if (_renderResolution != CaptureBase.Resolution.Original)
  2277. {
  2278. float rectWidth = Mathf.Clamp01(_cameraNode.rect.width + _cameraNode.rect.x) - Mathf.Clamp01(_cameraNode.rect.x);
  2279. float rectHeight = Mathf.Clamp01(_cameraNode.rect.height + _cameraNode.rect.y) - Mathf.Clamp01(_cameraNode.rect.y);
  2280. if (_renderResolution == CaptureBase.Resolution.Custom)
  2281. {
  2282. inWidth = (int)_renderSize.x;
  2283. inHeight = (int)_renderSize.y;
  2284. }
  2285. else
  2286. {
  2287. CaptureBase.GetResolution(_renderResolution, ref inWidth, ref inHeight);
  2288. inWidth = Mathf.FloorToInt(inWidth * rectWidth);
  2289. inHeight = Mathf.FloorToInt(inHeight * rectHeight);
  2290. }
  2291. }
  2292. outSize = CaptureBase.GetRecordingResolution(inWidth, inHeight, GetDownScaleFromIndex(_downScaleIndex), new Vector2(_downscaleX, _downscaleY));
  2293. }
  2294. }
  2295. GUILayout.Space(8f);
  2296. GUILayout.BeginHorizontal();
  2297. GUILayout.FlexibleSpace();
  2298. GUI.color = Color.cyan;
  2299. GUILayout.TextArea("Output: " + (int)outSize.x + " x " + (int)outSize.y + " @ " + _frameRate.ToString("F2"));
  2300. GUILayout.FlexibleSpace();
  2301. GUILayout.EndHorizontal();
  2302. GUILayout.Space(8f);
  2303. GUI.color = Color.white;
  2304. }
  2305. _downScaleIndex = EditorGUILayout.Popup("Down Scale", _downScaleIndex, _downScales);
  2306. if (_downScaleIndex == 5)
  2307. {
  2308. Vector2 maxVideoSize = new Vector2(_downscaleX, _downscaleY);
  2309. maxVideoSize = EditorGUILayout.Vector2Field("Size", maxVideoSize);
  2310. _downscaleX = Mathf.Clamp((int)maxVideoSize.x, 1, NativePlugin.MaxRenderWidth);
  2311. _downscaleY = Mathf.Clamp((int)maxVideoSize.y, 1, NativePlugin.MaxRenderHeight);
  2312. }
  2313. GUILayout.Space(8f);
  2314. //EditorGUILayout.LabelField("Codec", EditorStyles.boldLabel);
  2315. DrawConfigGUI_MotionBlur();
  2316. //EditorGUI.indentLevel--;
  2317. EditorGUILayout.EndVertical();
  2318. }
  2319. private void UpdateSelectedCodec()
  2320. {
  2321. // Assign the first codec if none is selected
  2322. if (_videoCodec == null && CodecManager.VideoCodecs.Count > 0)
  2323. {
  2324. _videoCodec = CodecManager.VideoCodecs.Codecs[0];
  2325. }
  2326. if (_videoCodec != null)
  2327. {
  2328. // Ensure the audio codec uses the same API as the video codec,
  2329. // otherwise assign the first audio codec
  2330. if (_audioCodec == null || (_audioCodec != null && _audioCodec.MediaApi != _videoCodec.MediaApi))
  2331. {
  2332. _audioCodec = CodecManager.AudioCodecs.GetFirstWithMediaApi(_videoCodec.MediaApi);
  2333. }
  2334. if (_audioInputDevice == null || (_audioInputDevice != null && _audioInputDevice.MediaApi != _videoCodec.MediaApi))
  2335. {
  2336. _audioInputDevice = DeviceManager.AudioInputDevices.GetFirstWithMediaApi(_videoCodec.MediaApi);
  2337. }
  2338. }
  2339. // Select the appropriate file extension based on the selected codecs
  2340. UpdateFileExtension();
  2341. }
  2342. private void UpdateFileExtension()
  2343. {
  2344. // There are cases where the plugin is deinitalised, so it needs to be inited to be able to query the file extension
  2345. if (NativePlugin.GetVideoCodecCount() <= 0)
  2346. {
  2347. NativePlugin.Init();
  2348. }
  2349. _fileExtensions = GetSuitableFileExtensions(_videoCodec, IsAudioCaptured()?_audioCodec:null);
  2350. if (_fileContainerIndex >= _fileExtensions.Length)
  2351. {
  2352. _fileContainerIndex = 0;
  2353. }
  2354. if (_fileContainerIndex < _fileExtensions.Length)
  2355. {
  2356. _filenameExtension = _fileExtensions[_fileContainerIndex].ToLower();
  2357. }
  2358. }
  2359. private void DrawVisualCodecList()
  2360. {
  2361. GUILayout.Space(8f);
  2362. if (_outputTarget == OutputTarget.VideoFile)
  2363. {
  2364. if (_videoCodec == null && CodecManager.VideoCodecs.Count > 0)
  2365. {
  2366. _videoCodec = CodecManager.VideoCodecs.Codecs[0];
  2367. }
  2368. if (_audioCodec == null && CodecManager.AudioCodecs.Count > 0)
  2369. {
  2370. _audioCodec = CodecManager.AudioCodecs.Codecs[0];
  2371. }
  2372. if (ShowMediaItemList("Video Codec", CodecManager.VideoCodecs, _videoCodec, null))
  2373. {
  2374. _queueConfigureVideoCodec = _videoCodec;
  2375. }
  2376. if (_videoCodec != null)
  2377. {
  2378. #if UNITY_EDITOR_WIN
  2379. if (_videoCodec.MediaApi == MediaApi.DirectShow)
  2380. {
  2381. if (_videoCodec.Name.EndsWith("Cinepak Codec by Radius")
  2382. || _videoCodec.Name.EndsWith("DV Video Encoder")
  2383. || _videoCodec.Name.EndsWith("Microsoft Video 1")
  2384. || _videoCodec.Name.EndsWith("Microsoft RLE")
  2385. || _videoCodec.Name.EndsWith("Logitech Video (I420)")
  2386. || _videoCodec.Name.EndsWith("Intel IYUV codec")
  2387. )
  2388. {
  2389. GUI.color = Color.yellow;
  2390. GUILayout.TextArea("Warning: Legacy codec, not recommended");
  2391. GUI.color = Color.white;
  2392. }
  2393. if (_videoCodec.Name.Contains("Decoder") || _videoCodec.Name.Contains("Decompressor"))
  2394. {
  2395. GUI.color = Color.yellow;
  2396. GUILayout.TextArea("Warning: Codec may contain decompressor only");
  2397. GUI.color = Color.white;
  2398. }
  2399. if (CodecManager.VideoCodecs.Count < 6)
  2400. {
  2401. GUI.color = Color.cyan;
  2402. GUILayout.TextArea("Low number of codecs, consider installing more");
  2403. GUI.color = Color.white;
  2404. }
  2405. }
  2406. #endif
  2407. if (_videoCodec.Name.EndsWith("Uncompressed"))
  2408. {
  2409. GUI.color = Color.yellow;
  2410. GUILayout.TextArea("Warning: Uncompressed may result in very large files");
  2411. GUI.color = Color.white;
  2412. }
  2413. }
  2414. }
  2415. }
  2416. private bool IsCaptureRealTime()
  2417. {
  2418. return (_captureModeIndex == 0);
  2419. }
  2420. private bool IsAudioCaptured()
  2421. {
  2422. return (_outputTarget == OutputTarget.VideoFile && _audioCaptureSource != AudioCaptureSource.None && (IsCaptureRealTime() || _audioCaptureSource != AudioCaptureSource.Manual));
  2423. }
  2424. private void DrawAudioCodecList()
  2425. {
  2426. if (_outputTarget != OutputTarget.VideoFile)
  2427. {
  2428. return;
  2429. }
  2430. GUILayout.Space(8f);
  2431. EditorGUI.BeginDisabledGroup(!IsAudioCaptured());
  2432. if (ShowMediaItemList("Audio Codec", CodecManager.AudioCodecs, _audioCodec, _videoCodec))
  2433. {
  2434. _queueConfigureAudioCodec = _audioCodec;
  2435. }
  2436. #if UNITY_EDITOR_WIN
  2437. if (_audioCodec != null && (_audioCodec.Name.EndsWith("MPEG Layer-3")))
  2438. {
  2439. GUI.color = Color.yellow;
  2440. GUILayout.TextArea("Warning: We have had reports that this codec doesn't work. Consider using a different codec");
  2441. GUI.color = Color.white;
  2442. }
  2443. #endif
  2444. EditorGUI.EndDisabledGroup();
  2445. }
  2446. private void DrawConfigGUI_MotionBlur()
  2447. {
  2448. EditorGUI.BeginDisabledGroup(IsCaptureRealTime());
  2449. //EditorGUILayout.BeginVertical(GUI.skin.box);
  2450. //EditorGUI.indentLevel++;
  2451. GUILayout.Space(8f);
  2452. GUILayout.Label("Motion Blur (beta)", EditorStyles.boldLabel);
  2453. //EditorGUILayout.BeginVertical(GUI.skin.box);
  2454. //EditorGUI.indentLevel++;
  2455. if (IsCaptureRealTime())
  2456. {
  2457. GUI.color = Color.yellow;
  2458. GUILayout.TextArea("Motion Blur only available in Offline Render mode");
  2459. GUI.color = Color.white;
  2460. }
  2461. _useMotionBlur = EditorGUILayout.Toggle("Use Motion Blur", _useMotionBlur);
  2462. EditorGUI.BeginDisabledGroup(!_useMotionBlur);
  2463. EditorGUILayout.PrefixLabel("Samples");
  2464. EditorGUILayout.BeginHorizontal(GUILayout.ExpandWidth(false));
  2465. _motionBlurSampleCount = EditorGUILayout.IntSlider(_motionBlurSampleCount, 0, 64);
  2466. EditorGUILayout.EndHorizontal();
  2467. EditorGUI.EndDisabledGroup();
  2468. //EditorGUI.indentLevel--;
  2469. //EditorGUILayout.EndVertical();
  2470. EditorGUI.EndDisabledGroup();
  2471. }
  2472. private void DrawConfigGUI_Audio()
  2473. {
  2474. bool showAudioSources = true;
  2475. if (_outputTarget != OutputTarget.VideoFile)
  2476. {
  2477. GUI.color = Color.yellow;
  2478. GUILayout.TextArea("Audio capture only available when outputing to video file");
  2479. GUI.color = Color.white;
  2480. showAudioSources = false;
  2481. }
  2482. if (showAudioSources)
  2483. {
  2484. EditorGUILayout.BeginVertical(GUI.skin.box);
  2485. _audioCaptureSource = (AudioCaptureSource)EditorGUILayout.EnumPopup("Audio Source", _audioCaptureSource);
  2486. if (_audioCaptureSource != AudioCaptureSource.None)
  2487. {
  2488. bool showAudioOptions = true;
  2489. #if AVPRO_MOVIECAPTURE_OFFLINE_AUDIOCAPTURE
  2490. if (!IsCaptureRealTime() && _audioCaptureSource != AudioCaptureSource.Manual && _audioCaptureSource != AudioCaptureSource.Unity && _audioCaptureSource != AudioCaptureSource.Wwise)
  2491. {
  2492. GUI.color = Color.yellow;
  2493. GUILayout.TextArea("Only Manual, Unity and Wwise Audio Sources are available in offline capture mode");
  2494. GUI.color = Color.white;
  2495. showAudioOptions = false;
  2496. }
  2497. #else
  2498. if (!IsCaptureRealTime() && _audioCaptureSource != AudioCaptureSource.Manual && _audioCaptureSource != AudioCaptureSource.Wwise)
  2499. {
  2500. GUI.color = Color.yellow;
  2501. GUILayout.TextArea("Only Manual and Wwise Audio Source is available in offline capture mode");
  2502. GUI.color = Color.white;
  2503. showAudioOptions = false;
  2504. }
  2505. #endif
  2506. if (IsCaptureRealTime() && _audioCaptureSource == AudioCaptureSource.Wwise)
  2507. {
  2508. GUI.color = Color.yellow;
  2509. GUILayout.TextArea("Wwise Audio Source is not available in realtime capture mode");
  2510. GUI.color = Color.white;
  2511. showAudioOptions = false;
  2512. }
  2513. #if !AVPRO_MOVIECAPTURE_WWISE_SUPPORT
  2514. if (!IsCaptureRealTime() && _audioCaptureSource == AudioCaptureSource.Wwise)
  2515. {
  2516. GUI.color = Color.red;
  2517. GUILayout.TextArea("To support Wwise audio capture: add AVPRO_MOVIECAPTURE_WWISE_SUPPORT to script defines in Player Settings");
  2518. GUI.color = Color.white;
  2519. showAudioOptions = false;
  2520. }
  2521. #endif
  2522. if (showAudioOptions)
  2523. {
  2524. if (_audioCaptureSource == AudioCaptureSource.Microphone)
  2525. {
  2526. GUILayout.Space(8f);
  2527. ShowMediaItemList("Microphone", DeviceManager.AudioInputDevices, _audioInputDevice, _videoCodec);
  2528. GUILayout.Space(8f);
  2529. }
  2530. else if (_audioCaptureSource == AudioCaptureSource.Manual)
  2531. {
  2532. EditorUtils.IntAsDropdown("Sample Rate", _propManualAudioSampleRate, EditorUtils.CommonAudioSampleRateNames, EditorUtils.CommonAudioSampleRateValues);
  2533. EditorGUILayout.PropertyField(_propManualAudioChannelCount, new GUIContent("Channels"));
  2534. }
  2535. }
  2536. }
  2537. EditorGUILayout.EndVertical();
  2538. }
  2539. }
  2540. private static string[] GetSuitableFileExtensions(Codec videoCodec, Codec audioCodec = null)
  2541. {
  2542. string[] result = null;
  2543. if (videoCodec != null)
  2544. {
  2545. int audioCodecIndex = -1;
  2546. if (audioCodec != null)
  2547. {
  2548. audioCodecIndex = audioCodec.Index;
  2549. }
  2550. result = NativePlugin.GetContainerFileExtensions(videoCodec.Index, audioCodecIndex);
  2551. }
  2552. if (result != null)
  2553. {
  2554. for (int i = 0; i < result.Length; i++)
  2555. {
  2556. result[i] = result[i].ToUpper();
  2557. }
  2558. }
  2559. else
  2560. {
  2561. result = new string[0];
  2562. }
  2563. return result;
  2564. }
  2565. private static CaptureBase.DownScale GetDownScaleFromIndex(int index)
  2566. {
  2567. CaptureBase.DownScale result = CaptureBase.DownScale.Original;
  2568. switch (index)
  2569. {
  2570. case 0:
  2571. result = CaptureBase.DownScale.Original;
  2572. break;
  2573. case 1:
  2574. result = CaptureBase.DownScale.Half;
  2575. break;
  2576. case 2:
  2577. result = CaptureBase.DownScale.Quarter;
  2578. break;
  2579. case 3:
  2580. result = CaptureBase.DownScale.Eighth;
  2581. break;
  2582. case 4:
  2583. result = CaptureBase.DownScale.Sixteenth;
  2584. break;
  2585. case 5:
  2586. result = CaptureBase.DownScale.Custom;
  2587. break;
  2588. }
  2589. return result;
  2590. }
  2591. private static bool IsTrialVersion()
  2592. {
  2593. return NativePlugin.IsTrialVersion();
  2594. }
  2595. }
  2596. }
  2597. #endif