我尝试从AudioRecord对象获取原始数据,并使用MediaMuxer和MediaCodec将其保存在文件中。
我启动编解码器,启动复用器,将数据加载到输入缓冲区,没有运气。
通过调试调查,我发现调用dequeueInputBuffer()
时出现问题。看起来前几个数据块成功,但最终dequeueInputBuffer()
不断返回-1
。
有什么明显的东西我不见了吗?这似乎正在发生的事情是我填充输入缓冲区,但它们永远不会被编解码器释放。
相关代码片段:
int numChunks = input.length / CHUNKSIZE;
mAudioEncoder.start();
for (int chunk = 0; chunk <= numChunks; chunk++) {
byte[] passMe = new byte[CHUNKSIZE];
int inputBufferIndex = -1;
Log.d("offerAudioEncoder","printing chunk #" + chunk + "of " + numChunks);
//Copy the data into the chunk array
if (chunk < input.length / CHUNKSIZE)
for (int i = 0; i < CHUNKSIZE; i++)
passMe[i] = input[chunk * CHUNKSIZE + i];
else {
eosReceived = true;
for (int i = 0; chunk * CHUNKSIZE + i < input.length; i++)
passMe[i] = input[chunk * CHUNKSIZE + i];
}
//Get the input buffer
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2) {
while(inputBufferIndex < 0)//justk keep trying.
inputBufferIndex = mAudioEncoder.dequeueInputBuffer(100);
inputBuffer = mAudioEncoder.getInputBuffer(inputBufferIndex);
} else {
//backwards compatibility.
ByteBuffer[] inputBuffers = mAudioEncoder.getInputBuffers();
inputBufferIndex = mAudioEncoder.dequeueInputBuffer(-1);
if (inputBufferIndex >= 0)
inputBuffer = inputBuffers[inputBufferIndex];
}
//Plop the data into the input buffer
if (inputBuffer != null) {
inputBuffer.clear();
inputBuffer.put(passMe);
}
long presentationTimeUs = chunk * 10000000; //each encoded chunk represents one second of audio
//this is what the frame should be labeled as
mAudioEncoder.queueInputBuffer(inputBufferIndex, 0, passMe.length, presentationTimeUs, 0);
//Pull the output buffer.
int encoderStatus = -1;
while(encoderStatus < 0) //Like, seriously, WAIT forever.
encoderStatus = mAudioEncoder.dequeueOutputBuffer(mAudioBufferInfo, -1);//wait forever, why not?
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
outputBuffer = mAudioEncoder.getOutputBuffer(encoderStatus);
else {
ByteBuffer[] encoderOutputBuffers = mAudioEncoder.getOutputBuffers();
outputBuffer = encoderOutputBuffers[encoderStatus];
}
if(encoderStatus >= 0) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR2)
mMuxer.writeSampleData(audioTrackIndex, outputBuffer, mAudioBufferInfo);
//Done with the output buffer, release it.
mAudioEncoder.releaseOutputBuffer(encoderStatus, false);
}//TODO: Add cases for what to do when the output format changes
答案 0 :(得分:0)
好的,我明白了。最终我抛弃了分块逻辑,只是通过设置
来增加输入缓冲区的大小audioFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE,14000000);
传递给MediaCodec的configure方法的MediaFormat对象。
另外一个好的提示:确保使用16位音频编码并使用吐出短路的AudioRecord.read方法。字节似乎产生棘手的音频(可能是因为AudioRecord希望以16位操作)。