在上一篇文章介绍了 MediaCodec AudioRecord 硬编 AAC 格式音频,这篇介绍如何用 MediaCodec 硬解码 AAC 文件,并使用 AudioTrack 播放,总体相对而言遇到的坑比硬编要少一些。
介绍
MediaCodec
MediaCodec 是 Android 用于音视频编解码的一套偏底层的 API,直接利用硬件加速进行编解码。
MediaCodec 跟上一篇文章一样的流程:
- dequeueInputBuffer:从 input 缓存区申请 buffer 编号 Index
- getInputBuffer:用编号 Index 取得输入的缓冲区,将需要编码的数据写入 buffer
- queueInputBuffer:将 buffer 入 MediaCodec 的队列,MediaCodec 会从 buffer 中取数据处理
- dequeueOutputBuffer:从 output 缓冲区申请 buffer 编号
- getOutputBuffer:用编号 Index 取得输出的缓冲区,buffer 中就是处理后的数据
- releaseOutputBuffer:将该 buffer 放回 output 缓冲区队列
AudioTrack
使用来播放 PCM 音频数据的类
具体可以参考 Android AudioRecord、AudioTrack 录制播放音频
MediaExtractor
视音频分离器,将一些格式的视频分离出视频轨道和音频轨道。
具体可以参考 MediaExtractor、MediaMuxer 分离和合成 mp4
使用 MediaExtractor 原因是什么?
因为从外部读取了 AAC 文件格式的音频,需要知道 ACC 的具体格式以及其他信息,并且后续还需要从文件一帧一帧的读取出来,放置到 MediaCodec 中进行解码,最后通过 AudioTrack 中播放。刚好 MediaExtractor 可以满足需求。
流程
- 初始化
// MediaExtractor的初始化
mExtractor = new MediaExtractor();
mExtractor.setDataSource(getSDPath() + "/acc_encode.mp4");
MediaFormat mFormat = null;
int samplerate = 0;
int changelConfig = 0;
int selectTrack = 0;
String mine = MediaFormat.MIMETYPE_AUDIO_AAC;
for (int i = 0; i < mExtractor.getTrackCount(); i++) {
mFormat = mExtractor.getTrackFormat(i);
mine = mFormat.getString(MediaFormat.KEY_MIME);
if (mine.startsWith("audio/")) {
selectTrack = i;
samplerate = mFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);// 采样率
changelConfig = mFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT); // 声道数
break;
}
}
mExtractor.selectTrack(selectTrack);
// AudioTrack的初始化
int minBufferSize = AudioTrack.getMinBufferSize(samplerate, changelConfig,
AudioFormat.ENCODING_PCM_16BIT);
mPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, samplerate, changelConfig,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
mPlayer.play();