视频使用OnAudioFilterRead数据编码错误

时间:2014-10-01 09:28:18

标签: android unity3d mp4 h.264 mediacodec

我正在尝试使用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

当我尝试从麦克风录制音频时,它可以解决我的问题?

0 个答案:

没有答案