/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ using NRKernal.Record; using System; using System.IO; using System.Collections; using System.Linq; using UnityEngine; using UnityEngine.UI; namespace NRKernal.NRExamples { #if UNITY_ANDROID && !UNITY_EDITOR using GalleryDataProvider = NativeGalleryDataProvider; #else using GalleryDataProvider = MockGalleryDataProvider; #endif /// A video capture 2 local example. [HelpURL("https://developer.nreal.ai/develop/unity/video-capture")] public class VideoCapture2LocalExample : MonoBehaviour { [SerializeField] private Button m_PlayButton; [SerializeField] private NRPreviewer m_Previewer; [SerializeField] private Slider m_SliderMic; [SerializeField] private Text m_TextMic; [SerializeField] private Slider m_SliderApp; [SerializeField] private Text m_TextApp; public BlendMode blendMode = BlendMode.Blend; public ResolutionLevel resolutionLevel; public LayerMask cullingMask = -1; public NRVideoCapture.AudioState audioState = NRVideoCapture.AudioState.ApplicationAudio; public bool useGreenBackGround = false; public enum ResolutionLevel { High, Middle, Low, } /// Save the video to Application.persistentDataPath. /// The full pathname of the video save file. public string VideoSavePath { get { string timeStamp = Time.time.ToString().Replace(".", "").Replace(":", ""); string filename = string.Format("Nreal_Record_{0}.mp4", timeStamp); return Path.Combine(Application.persistentDataPath, filename); } } GalleryDataProvider galleryDataTool; void Awake() { if (m_SliderMic != null) { m_SliderMic.maxValue = 10.0f; m_SliderMic.minValue = 0.1f; m_SliderMic.value = 1; m_SliderMic.onValueChanged.AddListener(OnSlideMicValueChange); } if (m_SliderApp != null) { m_SliderApp.maxValue = 10.0f; m_SliderApp.minValue = 0.1f; m_SliderApp.value = 1; m_SliderApp.onValueChanged.AddListener(OnSlideAppValueChange); } RefreshUIState(); } void OnSlideMicValueChange(float val) { if (m_VideoCapture != null) { VideoEncoder encoder = m_VideoCapture.GetContext().GetEncoder() as VideoEncoder; if (encoder != null) encoder.AdjustVolume(RecorderIndex.REC_MIC, val); } RefreshUIState(); } void OnSlideAppValueChange(float val) { if (m_VideoCapture != null) { VideoEncoder encoder = m_VideoCapture.GetContext().GetEncoder() as VideoEncoder; if (encoder != null) encoder.AdjustVolume(RecorderIndex.REC_APP, val); } RefreshUIState(); } /// The video capture. NRVideoCapture m_VideoCapture = null; void CreateVideoCapture(Action callback) { NRVideoCapture.CreateAsync(false, delegate (NRVideoCapture videoCapture) { NRDebugger.Info("Created VideoCapture Instance!"); if (videoCapture != null) { m_VideoCapture = videoCapture; callback?.Invoke(); } else { NRDebugger.Error("Failed to create VideoCapture Instance!"); } }); } public void OnClickPlayButton() { if (m_VideoCapture == null) { CreateVideoCapture(() => { StartVideoCapture(); }); } else if (m_VideoCapture.IsRecording) { this.StopVideoCapture(); } else { this.StartVideoCapture(); } } void RefreshUIState() { bool flag = m_VideoCapture == null || !m_VideoCapture.IsRecording; m_PlayButton.GetComponent().color = flag ? Color.red : Color.green; if (m_TextMic != null && m_SliderMic != null) m_TextMic.text = m_SliderMic.value.ToString(); if (m_TextApp != null && m_SliderApp != null) m_TextApp.text = m_SliderApp.value.ToString(); } /// Starts video capture. public void StartVideoCapture() { if (m_VideoCapture == null || m_VideoCapture.IsRecording) { NRDebugger.Warning("Can not start video capture!"); return; } CameraParameters cameraParameters = new CameraParameters(); Resolution cameraResolution = GetResolutionByLevel(resolutionLevel); cameraParameters.hologramOpacity = 0.0f; cameraParameters.frameRate = cameraResolution.refreshRate; cameraParameters.cameraResolutionWidth = cameraResolution.width; cameraParameters.cameraResolutionHeight = cameraResolution.height; cameraParameters.pixelFormat = CapturePixelFormat.BGRA32; // Set the blend mode. cameraParameters.blendMode = blendMode; // Set audio state, audio record needs the permission of "android.permission.RECORD_AUDIO", // Add it to your "AndroidManifest.xml" file in "Assets/Plugin". cameraParameters.audioState = audioState; m_VideoCapture.StartVideoModeAsync(cameraParameters, OnStartedVideoCaptureMode, true); } private Resolution GetResolutionByLevel(ResolutionLevel level) { var resolutions = NRVideoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height); Resolution resolution = new Resolution(); switch (level) { case ResolutionLevel.High: resolution = resolutions.ElementAt(0); break; case ResolutionLevel.Middle: resolution = resolutions.ElementAt(1); break; case ResolutionLevel.Low: resolution = resolutions.ElementAt(2); break; default: break; } return resolution; } /// Stops video capture. public void StopVideoCapture() { if (m_VideoCapture == null || !m_VideoCapture.IsRecording) { NRDebugger.Warning("Can not stop video capture!"); return; } NRDebugger.Info("Stop Video Capture!"); m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo); m_Previewer.SetData(null, false); } /// Executes the 'started video capture mode' action. /// The result. void OnStartedVideoCaptureMode(NRVideoCapture.VideoCaptureResult result) { if (!result.success) { NRDebugger.Info("Started Video Capture Mode faild!"); return; } NRDebugger.Info("Started Video Capture Mode!"); float volumeMic = m_SliderMic != null ? m_SliderMic.value : NativeConstants.RECORD_VOLUME_MIC; float volumeApp = m_SliderApp != null ? m_SliderApp.value : NativeConstants.RECORD_VOLUME_APP; m_VideoCapture.StartRecordingAsync(VideoSavePath, OnStartedRecordingVideo, volumeMic, volumeApp); // Set preview texture. m_Previewer.SetData(m_VideoCapture.PreviewTexture, true); } /// Executes the 'started recording video' action. /// The result. void OnStartedRecordingVideo(NRVideoCapture.VideoCaptureResult result) { if (!result.success) { NRDebugger.Info("Started Recording Video Faild!"); return; } NRDebugger.Info("Started Recording Video!"); if (useGreenBackGround) { // Set green background color. m_VideoCapture.GetContext().GetBehaviour().SetBackGroundColor(Color.green); } m_VideoCapture.GetContext().GetBehaviour().SetCameraMask(cullingMask.value); RefreshUIState(); } /// Executes the 'stopped recording video' action. /// The result. void OnStoppedRecordingVideo(NRVideoCapture.VideoCaptureResult result) { if (!result.success) { NRDebugger.Info("Stopped Recording Video Faild!"); return; } NRDebugger.Info("Stopped Recording Video!"); m_VideoCapture.StopVideoModeAsync(OnStoppedVideoCaptureMode); } /// Executes the 'stopped video capture mode' action. /// The result. void OnStoppedVideoCaptureMode(NRVideoCapture.VideoCaptureResult result) { NRDebugger.Info("Stopped Video Capture Mode!"); RefreshUIState(); var encoder = m_VideoCapture.GetContext().GetEncoder() as VideoEncoder; string path = encoder.EncodeConfig.outPutPath; string filename = string.Format("Nreal_Shot_Video_{0}.mp4", NRTools.GetTimeStamp().ToString()); StartCoroutine(DelayInsertVideoToGallery(path, filename, "Record")); // Release video capture resource. m_VideoCapture.Dispose(); m_VideoCapture = null; } void OnDestroy() { // Release video capture resource. m_VideoCapture?.Dispose(); m_VideoCapture = null; } IEnumerator DelayInsertVideoToGallery(string originFilePath, string displayName, string folderName) { yield return new WaitForSeconds(0.1f); InsertVideoToGallery(originFilePath, displayName, folderName); } public void InsertVideoToGallery(string originFilePath, string displayName, string folderName) { NRDebugger.Info("InsertVideoToGallery: {0}, {1} => {2}", displayName, originFilePath, folderName); if (galleryDataTool == null) { galleryDataTool = new GalleryDataProvider(); } galleryDataTool.InsertVideo(originFilePath, displayName, folderName); } } }