问题很简单,但我没有任何线索来解决它:
我编写一行代码来在我的Nexus 4(Android 4.4.2)上创建AAC编码器
MediaCodec codec = MediaCodec.createEncoderByType("audio/mp4a-latm");
保存在“codec”中的返回值不为空,但我在Logcat中收到一条红色错误消息:
03-20 15:25:08.985: E/OMXMaster(24517): A component of name 'OMX.qcom.audio.decoder.aac' already exists, ignoring this one.
我还尝试了另一条线:
MediaCodec codec = MediaCodec.createByCodecName("OMX.google.aac.encoder");
并得到相同的错误结果。
在使用MediaCodec之前,我是否错过了任何初始化步骤?我在官方文档中没有找到有关此的任何信息。
有人遇到过这个问题吗?
实际上,我正在尝试将PCM编码为AAC文件。我已经读了@hubeir的这篇帖子。看来他成功了。我做了同样的事情:(1)设置mediacodec并输入PCM数据以获得编码帧。为此,我阅读了cts的代码。每个编码帧长度约为371-379。(2) 将adts头添加到帧中,然后保存到文件。我已经一点一点地检查了头部,它是正确的。但该文件仍然无法播放。所以我想可能是错误日志出了问题。
以下是我的全部代码,仅供参考:
MediaCodec codec = MediaCodec.createByCodecName("OMX.google.aac.encoder");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectELD);
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, nSamplerate);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, nChannels);
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
boolean bEndInput = false;
boolean bEndOutput = false;
while(true)
{
if (!bEndInput)
{
int inputBufferIndex = codec.dequeueInputBuffer(0);
if (inputBufferIndex >= 0)
{
int nLen = app.readPCM(nHandle,inputBuffers[inputBufferIndex]);//This line read PCM, return 0 if end of data.
int nBufLen = inputBuffers[inputBufferIndex].capacity();
if (nLen == nBufLen)
codec.queueInputBuffer(inputBufferIndex, 0, nLen, 0, MediaCodec.BUFFER_FLAG_SYNC_FRAME);
else if (nLen < nBufLen)
{
codec.queueInputBuffer(inputBufferIndex, 0, nLen, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
bEndInput = true;
break;
}
}
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
if (!bEndOutput)
{
int outputBufferIndex = codec.dequeueOutputBuffer(info, 0);
if (outputBufferIndex >= 0)
{
int outBitsSize = info.size;
Log.d("test", "Offset:"+info.offset);
Log.d("test", "Size:"+info.size);
Log.d("test", "Time:"+info.presentationTimeUs);
Log.d("test", "Flags:"+info.flags);
if (outBitsSize <= 10)
{
codec.releaseOutputBuffer(outputBufferIndex, false /* render */);
continue;
}
int outPacketSize = outBitsSize + 7; // 7 is ADTS size
ByteBuffer outBuf = outputBuffers[outputBufferIndex];
outBuf.position(info.offset);
outBuf.limit(info.offset + outBitsSize);
try {
byte[] data = new byte[outPacketSize]; //space for ADTS header included
addADTStoPacket(data, outPacketSize);
outBuf.get(data, 7, outBitsSize);
outBuf.position(info.offset);
outputStream.write(data, 0, outPacketSize); //open FileOutputStream beforehand
} catch (IOException e) {
Log.e("test", "failed writing bitstream data to file");
e.printStackTrace();
}
outBuf.clear();
codec.releaseOutputBuffer(outputBufferIndex, false /* render */);
Log.d("test", " dequeued " + outBitsSize + " bytes of output data.");
Log.d("test", " wrote " + outPacketSize + " bytes into output file.");
if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM)
{
bEndOutput = true;
//break;
}
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
outputBuffers = codec.getOutputBuffers();
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
}
}
if (bEndInput && bEndOutput)
break;
}
有趣的是,前一段时间我在一些设备上遇到了类似的问题:如果MediaCodec的话,AAC解码器被创建,而不是编码器。使用createEncoderByType()。为了解决这个问题,我使用了:
String codecName = selectEncoder(mime);
mediaCodec = MediaCodec.createByCodecName(codecName);
和
private String selectEncoder(String mime) {
for (int index = 0; index < MediaCodecList.getCodecCount(); index++) {
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(index);
if (!codecInfo.isEncoder()) {
continue;
}
for (String type : codecInfo.getSupportedTypes()) {
if (type.equalsIgnoreCase(mime)) {
return codecInfogetName();
}
}
}
return null;
}
诸如此类
你能检查一下媒体编解码器吗。xml,位于设备文件夹下(注意:xxxx通常取决于您的硬件平台)。
这里有OMX。qcom。音频解码器。aac和OMX。谷歌。aac。编码器。请使用其中任何一个,并对另一个进行评论
请参考https://source.android.com/devices/media.html(向框架公开编解码器),这将对您有所帮助
我想通了。
(1)媒体格式中的错误设置:
format.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectELD);
应该是
format.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectLC);
(2) 仅当(info.flags==0)时,编码帧才能与adts文件一起写入文件
(3) 输出文件名后缀应为“aac”。“mp4”或“m4a”可能不适用于某些应用程序。
MediaCodec codec = MediaCodec.createByCodecName("OMX.google.aac.encoder");
MediaFormat format = new MediaFormat();
format.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
format.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectLC); //fixed version
format.setInteger(MediaFormat.KEY_SAMPLE_RATE, nSamplerate);
format.setInteger(MediaFormat.KEY_BIT_RATE, 128000);
format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, nChannels);
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
codec.start();
ByteBuffer[] inputBuffers = codec.getInputBuffers();
ByteBuffer[] outputBuffers = codec.getOutputBuffers();
boolean bEndInput = false;
boolean bEndOutput = false;
while(true)
{
if (!bEndInput)
{
int inputBufferIndex = codec.dequeueInputBuffer(0);
if (inputBufferIndex >= 0)
{
int nLen = app.readPCM(nHandle,inputBuffers[inputBufferIndex]);//This line read PCM, return 0 if end of data.
int nBufLen = inputBuffers[inputBufferIndex].capacity();
if (nLen == nBufLen)
codec.queueInputBuffer(inputBufferIndex, 0, nLen, 0, MediaCodec.BUFFER_FLAG_SYNC_FRAME);
else if (nLen < nBufLen)
{
codec.queueInputBuffer(inputBufferIndex, 0, nLen, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
bEndInput = true;
break;
}
}
}
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
if (!bEndOutput)
{
int outputBufferIndex = codec.dequeueOutputBuffer(info, 0);
if (outputBufferIndex >= 0)
{
int outBitsSize = info.size;
Log.d("test", "Offset:"+info.offset);
Log.d("test", "Size:"+info.size);
Log.d("test", "Time:"+info.presentationTimeUs);
Log.d("test", "Flags:"+info.flags);
if (info.flags != 0) //fixed version
{
codec.releaseOutputBuffer(outputBufferIndex, false /* render */);
continue;
}
int outPacketSize = outBitsSize + 7; // 7 is ADTS size
ByteBuffer outBuf = outputBuffers[outputBufferIndex];
outBuf.position(info.offset);
outBuf.limit(info.offset + outBitsSize);
try {
byte[] data = new byte[outPacketSize]; //space for ADTS header included
addADTStoPacket(data, outPacketSize);
outBuf.get(data, 7, outBitsSize);
outBuf.position(info.offset);
outputStream.write(data, 0, outPacketSize); //open FileOutputStream beforehand
} catch (IOException e) {
Log.e("test", "failed writing bitstream data to file");
e.printStackTrace();
}
outBuf.clear();
codec.releaseOutputBuffer(outputBufferIndex, false /* render */);
Log.d("test", " dequeued " + outBitsSize + " bytes of output data.");
Log.d("test", " wrote " + outPacketSize + " bytes into output file.");
if (info.flags == MediaCodec.BUFFER_FLAG_END_OF_STREAM)
{
bEndOutput = true;
//break;
}
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED)
{
outputBuffers = codec.getOutputBuffers();
}
else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED)
{
}
}
if (bEndInput && bEndOutput)
break;
}
我正在尝试使用使用编解码器对一些音频流进行编码。为此,我使用了google cts ExtractEncodeMust的这个实现。 对于某些aac文件,它会在编码某些帧后抛出。更准确地说,它会在第1030行抛出异常,。 我正在配置如下: 我完全不知道如何解决这个问题。任何形式的帮助都将不胜感激。 带有一些日志的堆栈跟踪: 设备:小米POCO x3 操作系统:Android10 导致溢出的示例文件信
我正在尝试使用android AudioRecord和MediaCodec对aac音频进行编码。我创建了一个非常类似于(使用Android MediaCodec从相机编码H.264)的编码器类。使用此类,我创建了一个AudioRecord实例,并告诉它将其byte[]数据读出到AudioEncoder(audioEncoder.offerEncoder(Data))。 这是我的音频记录设置 我成功
我正在使用MediaCodec将PCM数据转换为AAC,并使用MediaMuxer将此aac数据存储到m4a文件中。没有视频。 该文件会生成,甚至会播放。但是没有声音。如果我将aac文件导入Audacity,它不会显示任何数据。音频的长度甚至是预期的时间。我知道数据正在被编码,尽管我不确定这些数据是否被正确编码。 对pcm数据进行编码: 我已经浏览了大量示例,我所做的一切似乎都是正确的。如果我在o
我正在尝试使用Android上的MediaCodec API来解码AAC流。(它是原始AAC。)我尝试使用MediaFormat.createAudioFormat()来创建要传递给MediaCodec.configure()的格式对象,但我在使用AAC(音频/mp4a-latm)时一直出错。(不过它适用于MP3(音频/mpeg)...) 最后,我为一个AAC文件创建了一个MediaExtract
aac解码器初始化如下: 但编码器在两种设备上的行为不同。 一个输出正常表示:64000 128000 192000 256000 320000 另一个输出为两个通道:64000 64000 128000 128000 192000 192000 256000 256000 320000 320000 使用MediaExtractor提取的格式在两种设备上有所不同: 正常的是{max input
我正在尝试捕获和编码音频数据,我正在使用FFMPEG AAC编码音频,为了捕获PCM数据,我使用ALSA,捕获部分在我的情况下工作,但是AAC编码器不工作。 我试图播放test.aac文件使用 ffplaytest.aac 但它包含很多噪音。 附加aac编码器代码: 这里,请忽略DUMP_TEST标志,我已经启用了。 有人能告诉我什么是问题吗? 谢谢,哈希尔