我正在尝试使用OnAudioFilterRead函数将Unity游戏音频录制到mp4文件。
function OnAudioFilterRead(var data:float[], var channels:int)
我的解决方案概述。
步骤1。将从Unity获取的数据样本转换为bytes []
private void Convert2Bytes(float[] samples) {
Int16[] intData = new Int16[samples.Length];
//converting in 2 float[] steps to Int16[], //then Int16[] to Byte[]
Byte[] bytesData = new Byte[samples.Length * 2];
//bytesData array is twice the size of
//dataSource array because a float converted in Int16 is 2 bytes.
float rescaleFactor = 32767; //to convert float to Int16
for (int i = 0; i<samples.Length; i++) {
intData[i] = (short) ((samples[i] * gain) * rescaleFactor);
int n = i*2;
bytesData[n] = (byte)(intData[i]& 0x00FF);
bytesData[n+1] = (byte)(((intData[i]& 0xFF00) >> 8) );
if (muteSceneAudio)
samples[i] = 0.0f;
}
return bytesData;
}
第二步。将字节数组推送到MediaCoder mAudioEncoder
ByteBuffer[] inputBuffers = mAudioEncoder.getInputBuffers();
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(data, 0, countOfByte);
int inputLength = countOfByte;
presentationTimeNs -= (inputLength / SAMPLE_RATE) / 1000000000;
if (inputLength == AudioRecord.ERROR_INVALID_OPERATION)
Log.printLog(Log.ERROR, "Audio read error");
long presentationTimeUs = (presentationTimeNs - startWhen) / 1000;
Log.printLog(Log.INFO, "queueing " + inputLength + " audio bytes with pts "
+ presentationTimeUs);
if (endOfStream) {
Log.printLog(Log.INFO, "EOS received in sendAudioToEncoder");
mAudioEncoder.queueInputBuffer(inputBufferIndex, 0,
inputLength, presentationTimeUs,
MediaCodec.BUFFER_FLAG_END_OF_STREAM);
eosSentToAudioEncoder = true;
} else {
mAudioEncoder.queueInputBuffer(inputBufferIndex, 0,
inputLength, presentationTimeUs, 0);
}
}
步骤3。 DequeueOutputBuffer并写入视频
int encoderStatus = encoder.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
// Bug here
}
错误日志(停止录制时发生):
AndroidJavaException:java.lang.IllegalStateException 在UnityEngine.AndroidJNISafe.CheckException()[0x00000]中:0 在UnityEngine.AndroidJNISafe.CallVoidMethod(IntPtr obj,IntPtr methodID,UnityEngine.jvalue [] args)[0x00000] in:0 在UnityEngine.AndroidJavaObject._Call(System.String methodName,System.Object [] args)[0x00000] in:0 在UnityEngine.AndroidJavaObject.Call(System.String methodName,System.Object [] args)[0x00000] in:0 在VideoCapture.stopAudioRecord()[0x00000]中:0 在OOTAudioRecord.SaveStreamStop()[0x00000] in:0
当我尝试从麦克风录制音频时,它可以解决我的问题?