You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解码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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 15:15:33