123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- //-----------------------------------------------------------------------------
- // Copyright 2012-2022 RenderHeads Ltd. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace RenderHeads.Media.AVProMovieCapture
- {
- /// <summary>
- /// Encodes audio directly from an AudioClip
- /// Requires AudioCaptureSource.Manual to be set on the Capture component
- /// Make sure the AudioClip sample rate and channel count matches that of the Capture component
- /// Designed to work in offline capture mode
- /// </summary>
- [AddComponentMenu("AVPro Movie Capture/Audio/Capture Audio (From AudioClip)", 500)]
- public class CaptureAudioFromAudioClip : MonoBehaviour
- {
- [SerializeField] CaptureBase _capture = null;
- [SerializeField] AudioClip _audioClip = null;
- //[SerializeField] bool _loopAudio = false;
- private int _videoOffsetInSamples = 0;
- private int _committedFrames = 0;
- private int _committedSamples = 0;
- private int _lastCommittedSample = -1;
- private float[] _frameBuffer = null;
- void OnEnable()
- {
- _lastCommittedSample = -1;
- if (_audioClip && _capture)
- {
- if (_audioClip.frequency != _capture.ManualAudioSampleRate)
- {
- Debug.LogError(string.Format("[AVProMovieCapture] AudioClip audio frequency {0} doesn't match the encoding frequency {1}", _audioClip.frequency, _capture.ManualAudioSampleRate));
- }
- if (_audioClip.channels != _capture.ManualAudioChannelCount)
- {
- Debug.LogError(string.Format("[AVProMovieCapture] AudioClip audio channelCount {0} doesn't match the encoding channelCount {1}", _audioClip.channels, _capture.ManualAudioChannelCount));
- }
- }
- }
- void Update()
- {
- if (_capture != null && _capture.IsCapturing())
- {
- float[] samples = GetAudioSamplesForFrame();
- if (samples != null)
- {
- _capture.EncodeAudio(samples);
- }
- _committedFrames++;
- }
- }
- private float[] GetAudioSamplesForFrame()
- {
- float[] result = null;
- if (_audioClip != null && _audioClip.samples > 0)
- {
- int sampleCommitSize = (int)(_capture.ManualAudioSampleRate / _capture.FrameRate);
- float videoRenderTime = (float)_committedFrames / _capture.FrameRate;
- float videoTimeInSamples = videoRenderTime * (float)_audioClip.frequency;
- if (_lastCommittedSample < videoTimeInSamples && videoTimeInSamples >= 0)
- {
- int startSampleIndex = (_lastCommittedSample + 1) - _videoOffsetInSamples;
- int endSampleIndex = startSampleIndex + sampleCommitSize - 1;
- int requiredSamples = (_audioClip.channels * sampleCommitSize);
- if (_lastCommittedSample < _audioClip.samples - 1)
- {
- if (endSampleIndex >= _audioClip.samples)
- {
- // We've reached the end of the clip samples, so just grab what remains
- requiredSamples = (_audioClip.channels * (_audioClip.samples - startSampleIndex));
- }
- // Allocate buffer if needed
- if (_frameBuffer == null || _frameBuffer.Length != requiredSamples)
- {
- _frameBuffer = new float[requiredSamples];
- }
- _audioClip.GetData(_frameBuffer, startSampleIndex);
- _committedSamples++;
- _lastCommittedSample = (_committedSamples * sampleCommitSize) - 1;
- }
- else
- {
- // We've reached the end of the audio clip, so just create empty audio data
- requiredSamples = (_audioClip.channels * sampleCommitSize);
- // Allocate buffer if needed
- if (_frameBuffer == null || _frameBuffer.Length != requiredSamples)
- {
- _frameBuffer = new float[requiredSamples];
- }
- }
- result = _frameBuffer;
- }
- }
- return result;
- }
- }
- }
|