我正在尝试做的事情:使用 Android 的 MediaCodec 将原始 PCM 音频样本编码为原始 AAC 文件。
我遇到的问题是:当我使用 FFMPEG 将生成的原始 AAC 文件打包到 M4A 容器中时,FFMPEG 抱怨文件中缺少编解码器参数。
Details:
由于我找不到任何生成输出AAC文件的音频编码器的MediaCodec示例代码,因此我尝试将视频编码器修改为音频编码器。原始代码在这里:源代码 https://android.googlesource.com/platform/cts/+/jb-mr2-release/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
我这样配置音频编码器:
mEncoderFormat = MediaFormat.createAudioFormat("audio/mp4a-latm", (int)mAudioSampleRate, 2);
// redundant?
mEncoderFormat.setString(MediaFormat.KEY_MIME, "audio/mp4a-latm");
mEncoderFormat.setInteger(MediaFormat.KEY_AAC_PROFILE,
MediaCodecInfo.CodecProfileLevel.AACObjectELD);
mEncoderFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, kSampleRates);
mEncoderFormat.setInteger(MediaFormat.KEY_BIT_RATE, kBitRates);
mEncoderFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 2);
testEncoderWithFormat("audio/mp4a-latm", mEncoderFormat);
try {
codec.configure(
mEncoderFormat,
null /* surface */,
null /* crypto */,
MediaCodec.CONFIGURE_FLAG_ENCODE);
} catch (IllegalStateException e) {
Log.e(TAG, "codec '" + componentName + "' failed configuration.");
return;
}
Log.d(TAG, " testEncoder configured with format = " + format);
然后我向编码器提供每帧 10 毫秒的 PCM 样本。编码器获取每一帧,生成一帧比特流,然后将比特流写入 FileOutputStream。循环一直持续到输入文件末尾。
代码运行到最后。我执行“adb pull”将生成的 AAC 文件从设备获取到我的 PC,并使用 FFMPEG 读取它。下面是命令和 FFMPEG 输出的错误:
$ ffmpeg -f aac -i BlessedNoColor_nexus7_api18.aac
ffmpeg version N-45739-g04bf2e7 Copyright (c) 2000-2012 the FFmpeg developers
built on Oct 20 2012 00:20:36 with gcc 4.7.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-pthreads --enable-runt
ime-cpudetect --enable-avisynth --enable-bzlib --enable-frei0r --enable-libass -
-enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfreetype --enab
le-libgsm --enable-libmp3lame --enable-libnut --enable-libopenjpeg --enable-libo
pus --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheo
ra --enable-libutvideo --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-li
bvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --ena
ble-zlib
libavutil 51. 76.100 / 51. 76.100
libavcodec 54. 67.100 / 54. 67.100
libavformat 54. 33.100 / 54. 33.100
libavdevice 54. 3.100 / 54. 3.100
libavfilter 3. 19.103 / 3. 19.103
libswscale 2. 1.101 / 2. 1.101
libswresample 0. 16.100 / 0. 16.100
libpostproc 52. 1.100 / 52. 1.100
[aac @ 00000000002efae0] channel element 2.0 is not allocated
[aac @ 00000000003cf520] decoding for stream 0 failed
[aac @ 00000000003cf520] Could not find codec parameters for stream 0 (Audio: aac, 0 channels, s16): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
[aac @ 00000000003cf520] Estimating duration from bitrate, this may be inaccurate
BlessedNoColor_nexus7_api18.aac: could not find codec parameters
我的问题:
- 我在调用 codec.start() 之前已经配置了编码器。为什么生成的AAC文件缺少编解码器参数?
- 在原始视频编解码器示例中,参数“csd-0”从编码器传递到解码器,但没有显式写入比特流文件。我需要将它们显式写入 AAC 文件吗?
- 我将输入 PCM 样本划分为每帧 10ms,这并不一定会产生完整的输出数据包。对于每个输入帧,我只需将编码器输出的任何内容写入文件中。这值得担忧吗?
任何帮助将不胜感激。如果有一个示例项目可以完成我在这里尝试做的事情,那就太好了。如果我的源代码可以帮助你帮助我,我会发布它。我需要做一些清理工作。谢谢!
Edit:将标题从“MediaCodec 缺少编解码器参数生成的基本 AAC 文件”更改为“如何使用 Android MediaCodec 生成 AAC ADTS 基本流”