/**************************************************************************** * Copyright 2019 Nreal Techonology Limited. All rights reserved. * * This file is part of NRSDK. * * https://www.nreal.ai/ * *****************************************************************************/ namespace NRKernal.Record { using UnityEngine; using System; using System.Collections.Generic; using AOT; using System.Runtime.InteropServices; /// A video encoder. public class AudioEncoder : IEncoderBase { private NativeEncoder mNativeEncoder; public NativeEncodeConfig EncodeConfig; private IntPtr androidMediaProjection { get; set; } private bool m_IsStarted = false; private AudioDataCallBack mDataCallBack = null; private static List gInactiveAudioEncoders = new List(); #if !UNITY_EDITOR private const int STARTENCODEEVENT = 0x2001; private const int STOPENCODEEVENT = 0x2002; private delegate void RenderEventDelegate(int eventID); private static RenderEventDelegate RenderThreadHandle = new RenderEventDelegate(RunOnRenderThread); private static IntPtr RenderThreadHandlePtr = Marshal.GetFunctionPointerForDelegate(RenderThreadHandle); #endif /// Default constructor. public AudioEncoder() { #if !UNITY_EDITOR mNativeEncoder = NativeEncoder.GetInstance(); mNativeEncoder.Register(this); #endif } #if !UNITY_EDITOR [MonoPInvokeCallback(typeof(RenderEventDelegate))] private static void RunOnRenderThread(int eventID) { if (eventID == STARTENCODEEVENT) { lock (gInactiveAudioEncoders) { for (int i = 0; i < gInactiveAudioEncoders.Count; i++) { NativeEncoder.GetInstance().StartAudioRecorder(gInactiveAudioEncoders[i].mDataCallBack); } gInactiveAudioEncoders.Clear(); } } } #endif /// Configurations the given parameter. /// The parameter. public void Config(CameraParameters param) { EncodeConfig = new NativeEncodeConfig(param); androidMediaProjection = (param.mediaProjection != null) ? param.mediaProjection.GetRawObject() : IntPtr.Zero; } /// Adjust the volume of encoder. /// Recorder index. /// The factor of volume. public void AdjustVolume(RecorderIndex recordIdx, float factor) { #if !UNITY_EDITOR mNativeEncoder.AdjustVolume(recordIdx, factor); #endif } /// Starts this object. public void Start(AudioDataCallBack onAudioDataCallback = null) { if (m_IsStarted) { return; } NRDebugger.Info("[AudioEncoder] Start"); NRDebugger.Info("[AudioEncoder] Config {0}", EncodeConfig.ToString()); mDataCallBack = onAudioDataCallback; lock (gInactiveAudioEncoders) { gInactiveAudioEncoders.Add(this); } #if !UNITY_EDITOR mNativeEncoder.SetConfigration(EncodeConfig, androidMediaProjection); //mNativeEncoder.StartAudioRecorder(mDataCallBack); GL.IssuePluginEvent(RenderThreadHandlePtr, STARTENCODEEVENT); #endif m_IsStarted = true; } /// Stops this object. public void Stop() { if (!m_IsStarted) { return; } NRDebugger.Info("[AudioEncoder] Stop"); lock (gInactiveAudioEncoders) { gInactiveAudioEncoders.Remove(this); } #if !UNITY_EDITOR mNativeEncoder.StopAudioRecorder(mDataCallBack); #endif m_IsStarted = false; } /// Releases this object. public void Release() { NRDebugger.Info("[AudioEncoder] Release..."); #if !UNITY_EDITOR mNativeEncoder.UnRegister(this); mNativeEncoder.Destroy(); #endif } } }