我正在尝试在Android上解码音频并获取原始数据以应用滤波器。
我正在使用
因此,我首先使用
我正在使用
MediaExtractor
从文件中提取编码数据,这似乎有效。
然后我尝试混合来自 MediaExtractor文档和使用缓冲区进行同步处理的MediaCodec的代码,以分块方式提取数据并对其进行解码。因此,我首先使用
extractor.getTrackFormat(0);
中获取的格式配置了解码器。MediaExtractor extractor = new MediaExtractor();
String path = "...";
extractor.setDataSource(path);
MediaFormat format = extractor.getTrackFormat(0);
mAudioKeyMine = format.getString(MediaFormat.KEY_MIME);
extractor.selectTrack(0);
MediaCodec decoder;
decoder = MediaCodec.createDecoderByType(mAudioKeyMine);
decoder.configure(format, null, null, 0);
然后尝试获取数据:
public void getData(MediaExtractor extractor)
{
int offset = 0;
ByteBuffer inputBuffer = ByteBuffer.allocate(2048);
MediaFormat outputFormat = decoder.getOutputFormat();
Log.v(TAG, "outputFormat: " + outputFormat.toString());
decoder.start();
int index = decoder.dequeueInputBuffer(1000);
boolean sawInputEOS = false;
int sample = 0;
while (sample >= 0)
{
int inputBufferId = decoder.dequeueInputBuffer(1000);
if (inputBufferId >= 0)
{
inputBuffer = decoder.getInputBuffer(index);
sample = extractor.readSampleData(inputBuffer, 0);
long presentationTimeUs = 0;
if (sample < 0)
{
sawInputEOS = true;
sample = 0;
}
else
{
int trackIndex = extractor.getSampleTrackIndex();
presentationTimeUs = extractor.getSampleTime();
Log.v(TAG, "trackIndex: " + trackIndex + ", presentationTimeUs: " + presentationTimeUs);
Log.v(TAG, "sample: " + sample + ", offset: " + offset);
Log.v(TAG, "inputBuffer: " + inputBuffer.toString());
}
decoder.queueInputBuffer(inputBufferId, 0, sample, presentationTimeUs, sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS)
{
extractor.advance();
}
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
int outputBufferId = decoder.dequeueOutputBuffer(info, 1000);
Log.v(TAG, "info: " + info.toString());
if (outputBufferId >= 0)
{
ByteBuffer outputBuffer = decoder.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = decoder.getOutputFormat(outputBufferId);
Log.v(TAG, "option A");
Log.v(TAG, "outputBufferId: " + outputBufferId);
if (outputBuffer != null)
{
Log.v(TAG, "outputBuffer: " + outputBuffer.toString());
}
else
{
Log.v(TAG, "outputBuffer: null");
}
Log.v(TAG, "bufferFormat: " + bufferFormat.toString());
if (outputBuffer != null)
{
int cont = 0;
while (outputBuffer.hasRemaining())
{
int pos = outputBuffer.position();
byte data = outputBuffer.get();
// do something with the data
if (cont < 10)
{
Log.v(TAG, "outputBuffer: " + pos + " -> " + data);
}
cont++;
}
}
else
{
Log.v(TAG, "outputBuffer: null");
}
decoder.releaseOutputBuffer(outputBufferId, 0);
}
else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
Log.v(TAG, "option B");
outputFormat = decoder.getOutputFormat();
Log.v(TAG, "outputFormat: " + outputFormat.toString());
}
Log.v(TAG, "extractor.advance()");
offset += sample;
}
Log.v(TAG, "end of track");
extractor.release();
extractor = null;
decoder.stop();
decoder.release();
}
但我在int outputBufferId = decoder.dequeueOutputBuffer(info, 1000);
这一行遇到了一个IllegalStateException
错误。
我搜索了这个错误以及如何正确解码m4a文件的方法,但大多数解决方案都已经过时了(仅适用于api 21),现在我被卡住了。
所以,有没有适用于api 26/28的音频解码示例,或者请有经验的人可以解释如何正确地进行解码?
整个项目托管在GitHub上。
index
),然后出队输入缓冲区#2(inputBufferId
),然后你将输入缓冲区#2入队。那么输入缓冲区#1发生了什么?你必须按照这些顺序使用它们! - undefined