RenderHeads / UnityPlugin-AVProMovieCapture

AVPro Movie Capture is a Unity Plugin for advanced video capture to AVI/MP4/MOV files
https://renderheads.com/products/avpro-movie-capture/
48 stars 8 forks source link

Switch audio between microphone and unity audio while recording #158

Open SridharaQweebi opened 2 years ago

SridharaQweebi commented 2 years ago

I would like to switch between audio source while recoding . currently audio source can be switch only before recoding start.

kahnivore commented 2 years ago

Which platform are you using?

SridharaQweebi commented 2 years ago

we want to have this option for all platform. I tried to capture microphone as UnityAudioCapture, but its not working, Please find attached script. So we can switch source or alter read function to read from 2 different source.

SridharaQweebi commented 2 years ago

public class AVGMicrophoneCapture : UnityAudioCapture { [SerializeField] bool _debugLogging = false; [SerializeField] bool _muteAudio = false;

private const int BufferSize = 16;
private float[] _buffer = new float[0];
private float[] _readBuffer = new float[0];
private int _bufferIndex;
private GCHandle _bufferHandle;
private int _numChannels;

private int _overflowCount;
private object _lockObject = new object();

public float[] Buffer { get { return _readBuffer; } }
public int BufferLength { get { return _bufferIndex; } }
public System.IntPtr BufferPtr { get { return _bufferHandle.AddrOfPinnedObject(); } }

public override int OverflowCount { get { return _overflowCount; } }
public override int SampleRate { get { return AudioSettings.outputSampleRate; } }
public override int ChannelCount { get { return _numChannels; } }

public UnityAudioCapture MicrophoneCatpte;
AudioSource microphoneSource;
private bool isRecording = false;
public override void PrepareCapture()
{
    int bufferLength = 0;
    int numBuffers = 0;
    AudioSettings.GetDSPBufferSize(out bufferLength, out numBuffers);

    _numChannels = GetUnityAudioChannelCount();
    if (_debugLogging)
    {
        Debug.Log(string.Format("[UnityAudioCapture] SampleRate: {0}hz SpeakerMode: {1} BestDriverMode: {2} (DSP using {3} buffers of {4} bytes using {5} channels)", AudioSettings.outputSampleRate, AudioSettings.speakerMode.ToString(), AudioSettings.driverCapabilities.ToString(), numBuffers, bufferLength, _numChannels));
    }

    _buffer = new float[bufferLength * _numChannels * numBuffers * BufferSize];
    _readBuffer = new float[bufferLength * _numChannels * numBuffers * BufferSize];
    _bufferIndex = 0;
    _bufferHandle = GCHandle.Alloc(_readBuffer, GCHandleType.Pinned);
    _overflowCount = 0;

    //MicrophoneCatpte.PrepareCapture();
    if(microphoneSource == null)
            {
            microphoneSource = gameObject.AddComponent<AudioSource>();
            microphoneSource.mute =
            microphoneSource.loop = true;
            microphoneSource.bypassEffects =
            microphoneSource.bypassListenerEffects = false;
    }
}

public override void StartCapture()
{
    FlushBuffer();
    microphoneSource.clip = Microphone.Start(null, true, 10, AudioSettings.outputSampleRate);
    microphoneSource.Play();
    isRecording = true;
}

public override void StopCapture()
{
    lock (_lockObject)
    {
        _bufferIndex = 0;
        if (_bufferHandle.IsAllocated)
            _bufferHandle.Free();
        _readBuffer = _buffer = null;
    }
    _numChannels = 0;
    Microphone.End(null);
    isRecording = false;
}

public override System.IntPtr ReadData(out int length)
{

    lock (_lockObject)
    {
        System.Array.Copy(_buffer, 0, _readBuffer, 0, _bufferIndex);
        length = _bufferIndex;
        _bufferIndex = 0;
    }
    Debug.LogError("data" + _readBuffer.Length);
    return _bufferHandle.AddrOfPinnedObject();

}

public override void FlushBuffer()
{
    lock (_lockObject)
    {
        _bufferIndex = 0;
        _overflowCount = 0;
    }
}

private void OnAudioFilterRead(float[] data, int channels)
{
    if (!isRecording)
    {
        return;
    }
    Debug.LogError("data" + isRecording);
    if (_buffer != null && _buffer.Length > 0)
    {
        lock (_lockObject)
        {
            int length = Mathf.Min(data.Length, _buffer.Length - _bufferIndex);
            if (!_muteAudio)
            {
                for (int i = 0; i < length; i++)
                {
                    _buffer[i + _bufferIndex] = data[i];
                }
            }
            else
            {
                for (int i = 0; i < length; i++)
                {
                    _buffer[i + _bufferIndex] = data[i];
                    data[i] = 0f;
                }
            }
            _bufferIndex += length;

            if (length < data.Length)
            {
                _overflowCount++;
                Debug.LogWarning("[AVProMovieCapture] Audio buffer overflow, may cause sync issues.  Disable this component if not recording Unity audio.");
            }
        }
    }
}

}

SridharaQweebi commented 2 years ago

any update ?