我正在尝试将来自MIC的音频流编码为3gpp(AMR-NB)。问题是输出缓冲区包含奇怪的数据。代码和输出如下:
创建媒体编码器:
MediaFormat format = MediaFormat.createAudioFormat("audio/3gpp", 8*1024, 1);
format.setInteger(MediaFormat.KEY_BIT_RATE, 8*1024);
format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, minBufSize);
MediaCodec encoder = MediaCodec.createEncoderByType("audio/3gpp");
encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
来自MIC的PCM数据似乎是正确的(存储到文件,用Audacity收听)
读取编码的字节(缓冲区,在线程中运行):
ByteBuffer[] outputBuffers = encoder.getOutputBuffers();
int outputBufferIndex = 0;
while( outputBufferIndex >= 0 )
{
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
outputBufferIndex = encoder.dequeueOutputBuffer(bufferInfo, -1);
if (outputBufferIndex >= 0)
{
ByteBuffer outputBuffer = outputBuffers[outputBufferIndex];
byte[] outData = new byte[bufferInfo.size];
outputBuffer.get(outData);
outputBuffer.clear();
encoder.releaseOutputBuffer(outputBufferIndex, false);
Log.d(LOG_TAG_ENCODING, util.bytesToString(outData));
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
outputBuffers = encoder.getOutputBuffers();
}
}
输出是:
07-11 13:13:58.622: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00
07-11 13:13:58.632: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00
07-11 13:13:58.667: 34 ff d9 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00
07-11 13:13:58.672: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00
07-11 13:13:58.677: 34 6c 1e 08 27 80 05 28 56 40 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00
我用Google搜索并没有找到任何帮助。关于MediaCodec使用的Android文档也不是很好 - 很多在outputbuffer上下文中使用ByteBuffer.clear()的试验和错误。
最好的问候, 阿赫蒂。
答案 0 :(得分:1)
对那里的所有患者,回答我自己的问题。
真正的问题实际上是将原始PCM数据输入编码器输入。关于如何将数据准确输入到输入缓冲区中的Android文档很模糊(好吧,实际上它更多地与ByteBuffer行为有关):
int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferIndex >= 0) {
// fill inputBuffers[inputBufferIndex] with valid data
...
codec.queueInputBuffer(inputBufferIndex, ...);
}
我的解释是添加数据如下:
inputBuffers[inputBufferIndex].clear();
inputBuffers[inputBufferIndex].put(audioPCMbuffer);
codec.queueInputBuffer(inputBufferIndex, ...);
上面的代码有一点缺失:翻转ByteBuffer的位置!
inputBuffers[inputBufferIndex].flip();
保留它以供将来参考,因为很难找到简单的代码来查看实现。