解码AAC流后,如何从MediaCodec输出的MediaFormat获取PCM位深度?
提问内容
我正在使用MediaCodec解码在线AAC流,并尝试用AudioTrack播放。AudioTrack需要AudioFormat,而后者需了解PCM编码的详细信息。我将其配置为ENCODING_PCM_16BIT后能正常播放,但不确定是否始终为16位PCM编码,不想做出该假设。
我原本期望通过MediaCodec.Callback.onOutputFormatChanged的MediaFormat参数获取编码信息,但调用toString()后得到的MediaFormat信息如下:
aac-drc-heavy-compression=1 sample-rate=48000 aac-drc-boost-level=127 aac-drc-output-loudness=-1 mime=audio/raw channel-count=2 aac-drc-effect-type=3 aac-drc-cut-level=127 aac-encoded-target-level=-1 aac-max-output-channel_count=8 aac-target-ref-level=64 aac-drc-album-mode=0
我是否应该直接假设是16位PCM,还是有办法获取该信息?
注:我的最低目标SDK为28,当前在Pixel 2 API 30模拟器的调试环境中测试。
解决方案
不要直接硬编码16位PCM,针对SDK 28+的环境,可通过以下方式可靠获取PCM编码信息:
- 从
onOutputFormatChanged回调的MediaFormat对象中,读取MediaFormat.KEY_PCM_ENCODING字段,该字段从API 21起就已支持,完全适配你的最低SDK版本。 - 示例代码:
@Override public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) { // 获取PCM编码类型 int pcmEncoding = format.getInteger(MediaFormat.KEY_PCM_ENCODING); // 动态配置AudioFormat int sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE); int channelCount = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT); int channelMask = channelCount == 1 ? AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO; AudioFormat audioFormat = new AudioFormat.Builder() .setEncoding(pcmEncoding) .setSampleRate(sampleRate) .setChannelMask(channelMask) .build(); // 用audioFormat初始化或更新AudioTrack }
关键说明
你通过toString()看不到PCM编码字段,是因为MediaFormat的toString()方法不会输出所有内部维护的字段,直接调用getInteger(MediaFormat.KEY_PCM_ENCODING)才是正确的获取方式。虽然AAC解码输出多数为16位PCM,但部分设备或特殊编码配置可能输出24位PCM或浮点格式,动态获取能避免兼容性问题。
内容的提问来源于stack exchange,提问作者barteks2x
相关产品推荐
相关产品推荐

