RecordingManager.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using System.Collections;
  2. using UnityEngine;
  3. using System.IO;
  4. using NatSuite.Recorders;
  5. using NatSuite.Recorders.Clocks;
  6. using NatSuite.Recorders.Inputs;
  7. using System;
  8. using EZXR.Glass.Core;
  9. using EZXR.Glass.Device;
  10. namespace EZXR.Glass.Recording
  11. {
  12. public class RecordingManager : MonoBehaviour
  13. {
  14. private static RecordingManager instance;
  15. public static RecordingManager Instance
  16. {
  17. get
  18. {
  19. return instance;
  20. }
  21. }
  22. /// <summary>
  23. /// 保存状态,0是默认状态,1是正在保存,2是保存完毕
  24. /// </summary>
  25. public int savingStatus;
  26. public bool isRecording;
  27. private int width = 1280;
  28. private int height = 960;
  29. private IMediaRecorder recorder;
  30. private CameraInput cameraInput;
  31. bool beSave = false;
  32. private Coroutine captureCoroutine;
  33. private const string gallery_savedDir = "/storage/emulated/0/Pictures/Screenshots";
  34. private void Awake()
  35. {
  36. instance = this;
  37. DontDestroyOnLoad(gameObject);
  38. //ARRenderRGB.SetRGBResolution(width, height);
  39. }
  40. // Start is called before the first frame update
  41. void Start()
  42. {
  43. NormalRGBCameraDevice rgbCameraDevice = new NormalRGBCameraDevice();
  44. int[] sizeRgbCamera = rgbCameraDevice.getCameraSize();
  45. width = sizeRgbCamera[0];
  46. height = sizeRgbCamera[1];
  47. }
  48. private void Update()
  49. {
  50. if (savingStatus == 2)
  51. {
  52. savingStatus = 0;
  53. instance = null;
  54. Debug.Log("RecordingManager Saved");
  55. Destroy(gameObject);
  56. }
  57. }
  58. private void OnApplicationPause(bool pause)
  59. {
  60. if (pause)
  61. {
  62. HandleRecordingClose();
  63. }
  64. }
  65. private async void GetPathAsync()
  66. {
  67. savingStatus = 1;
  68. var path = await recorder.FinishWriting();
  69. Debug.Log("Saved Recording to : " + path);
  70. Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "RecordingResult", "录屏已保存");
  71. SaveToGallery(path);
  72. }
  73. public void HandleRecordingOpen()
  74. {
  75. ARRenderRGB.Instance.HandleARRenderOpen();
  76. var frameRate = 30;
  77. var sampleRate = 0;
  78. var channelCount = 0;
  79. var clock = new RealtimeClock();
  80. recorder = new MP4Recorder(width, height, frameRate, sampleRate, channelCount);
  81. Camera renderCam = ARRenderRGB.Instance.gameObject.GetComponent<Camera>();
  82. cameraInput = new CameraInput(recorder, clock, renderCam);
  83. Debug.Log("UNITY LOG ========= Start Record");
  84. isRecording = true;
  85. }
  86. public void HandleRecordingClose()
  87. {
  88. if (ARRenderRGB.Instance != null)
  89. {
  90. ARRenderRGB.Instance.HandleARRenderClose();
  91. }
  92. if (cameraInput != null)
  93. {
  94. cameraInput.Dispose();
  95. }
  96. Debug.Log("UNITY LOG ========= Stop Record");
  97. GetPathAsync();
  98. }
  99. public void HandleScreenCapture()
  100. {
  101. Debug.Log("UNITY LOG ========= ScreenCapture, size: " + width + ", " + height);
  102. if (captureCoroutine != null) return;
  103. ARRenderRGB.Instance.HandleARRenderOpen();
  104. captureCoroutine = StartCoroutine(WaitForScreenCapture());
  105. }
  106. private IEnumerator WaitForScreenCapture()
  107. {
  108. yield return new WaitUntil(() => ARRenderRGB.Instance.isReady);
  109. //RGB 相机打开时曝光适配需要时间,0.41s是尝试值,如果实际测试有不够亮,再进行调整
  110. yield return new WaitForSeconds(0.41f);
  111. bool status = ARRenderRGB.Instance.HandleARRenderShot();
  112. if (!status)
  113. {
  114. Debug.Log("UNITY LOG ========= HandleARRenderShot failed! ");
  115. Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "RecordingResult", "截屏失败");
  116. captureCoroutine = null;
  117. yield break;
  118. }
  119. else
  120. {
  121. Debug.Log("UNITY LOG ========= HandleARRenderShot success! ");
  122. Utilities.Android.SendIntent("ToSystem", "com.ezxr.glass.systemui", "RecordingResult", "截屏已保存");
  123. }
  124. //fix: RT depth为0会引起渲染层级和blend错乱
  125. RenderTexture rt = new RenderTexture(width, height, 24, RenderTextureFormat.DefaultHDR);
  126. Camera renderCam = ARRenderRGB.Instance.gameObject.GetComponent<Camera>();
  127. renderCam.targetTexture = rt;
  128. renderCam.Render();
  129. RenderTexture.active = rt;
  130. Texture2D screenShot = new Texture2D(width, height, TextureFormat.RGB24, false);
  131. screenShot.ReadPixels(new Rect(0, 0, width, height), 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素  
  132. screenShot.Apply();
  133. //testRenderer.sharedMaterial.SetTexture("_MainTex", screenShot);
  134. // 重置相关参数,以使用camera继续在屏幕上显示  
  135. renderCam.targetTexture = null;
  136. RenderTexture.active = null; // added to avoid errors
  137. GameObject.Destroy(rt);
  138. var imageName = DateTime.Now.ToString("yyyyMMddHHmmss") + ".jpg";
  139. var imagePath = Path.Combine(Application.persistentDataPath, imageName);
  140. var bytes = screenShot.EncodeToJPG();
  141. File.WriteAllBytes(imagePath, bytes);
  142. Debug.Log("UNITY LOG ========= ScreenCapture, save jpg at path: " + imagePath);
  143. SaveToGallery(imagePath);
  144. captureCoroutine = null;
  145. ARRenderRGB.Instance.HandleARRenderClose();
  146. //if (toastCoroutine != null) StopCoroutine(toastCoroutine);
  147. //toastCoroutine = StartCoroutine(WaitForToastTips());
  148. }
  149. private void SaveToGallery(string src_path)
  150. {
  151. Debug.Log("UNITY LOG =========, save to gallery from: " + src_path);
  152. var dst_dir = NativeLib.GetScreenshotsPath();
  153. if (string.IsNullOrEmpty(dst_dir) || !Directory.Exists(dst_dir))
  154. {
  155. dst_dir = Path.GetDirectoryName(gallery_savedDir);
  156. }
  157. var dst_path = Path.Combine(dst_dir, Path.GetFileName(src_path));
  158. File.Move(src_path, dst_path);
  159. Debug.Log("UNITY LOG =========, saved to gallery at: " + dst_path);
  160. NativeLib.AddToAlbum(dst_path);
  161. Debug.Log("UNITY LOG =========, AddToAlbum at: " + dst_path);
  162. //var src_name = Path.GetFileNameWithoutExtension(src_path);
  163. //AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  164. //AndroidJavaObject currentActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");
  165. //AndroidJavaObject contentResolver = currentActivity.Call<AndroidJavaObject>("getContentResolver");
  166. //// 调用insertImage保存到相册
  167. //AndroidJavaClass galleryClass = new AndroidJavaClass("android.provider.MediaStore$Images$Media");
  168. //AndroidJavaObject galleryObject = new AndroidJavaObject("java.io.File", src_path);
  169. //AndroidJavaObject galleryUri = galleryClass.CallStatic<AndroidJavaObject>("insertImage",
  170. // contentResolver, galleryObject.Call<string>("getAbsolutePath"), src_name, "");
  171. //Debug.Log("UNITY LOG =========, saved to gallery!");
  172. //File.Delete(src_path);
  173. savingStatus = 2;
  174. }
  175. }
  176. }