为何使用AudioTrack的静态模式无法播放原始音频字节数据?
Android AudioTrack 静态模式播放异常问题解答
故障根因
1. 缓冲区大小配置不符合静态模式要求
AudioTrack.MODE_STATIC的设计目标是播放短音频,要求构造实例时传入的缓冲区大小必须≥待播放的全部原始音频数据的总长度。你当前代码中使用的MY_CHOSEN_BUFFER_SIZE大概率是通过AudioTrack.getMinBufferSize()计算的、适用于流模式的最小缓冲区值,这个值远小于你录制的完整音频字节数组recordedAudioAsBytes的长度,调用write()时仅能写入缓冲区可容纳的前一小段数据,剩余数据全部丢失,因此只能听到极短的爆音。
而MODE_STREAM是边加载边播放,只要缓冲区大小满足单次写入的块大小要求即可正常工作,因此你用流模式播放没有问题。
2. 缺少写入结果校验
你当前没有读取write()方法的返回值,无法感知到缓冲区不足导致的写入不完整问题,也就无法定位故障点。
关于文件头的疑问
MODE_STATIC不需要音频数据携带任何文件头,它和MODE_STREAM一样直接接收原始PCM裸数据即可播放。你用流模式能正常播放已经验证了你的音频数据本身是合法的,故障和文件头完全无关。
修复方案
修改你的静态模式初始化逻辑即可:
- 构造
AudioTrack实例时,直接将缓冲区大小设置为recordedAudioAsBytes.length,不要沿用流模式的MY_CHOSEN_BUFFER_SIZE - 读取
write()的返回值,确认返回值等于音频数组的总长度,保证所有数据都被完整写入缓冲区 - 写入完成后再调用
play()方法即可正常播放
示例修改后的代码:
// 静态模式修复后代码 AudioTrack player = new AudioTrack(AudioManager.STREAM_MUSIC, SAMPLERATE, PLAYBACK_CHANNELS, ENCODING, recordedAudioAsBytes.length, AudioTrack.MODE_STATIC); int writeSize = player.write(recordedAudioAsBytes, 0, recordedAudioAsBytes.length); if(writeSize == recordedAudioAsBytes.length) { player.play(); }
内容的提问来源于stack exchange,提问作者Nerdy Bunz
相关产品推荐
相关产品推荐

