我本来是做Android的,但是来公司之后主要负责Android端的多媒体相关,很多有关音视频编解码的都没有接触过。刚开始有一个项目使用硬编硬解完成音频的转码,刚开始我连怎么用硬编硬解都不知道,所幸在百度上找到一篇文章android MediaCodec 音频编解码的实现——转码。这篇文章介绍的很好,介绍了硬编硬解的整个流程,也接触了MediaCodec这个用来硬编硬解的类,后来还找到一个很好的学习该类的使用方法的一个网站http://bigflake.com/mediacodec/。
我的需求是将原始的视频文件中的音频转码为amr格式的音频,原始音频主要是aac格式。android MediaCodec 音频编解码的实现——转码这篇文章中是MP3到aac的转换。
原理在上述博客中讲的很清楚了,这里不再重复。
一、初始化解码器
private void initDecoder(String srcPath) {
long time = System.currentTimeMillis();
//private MediaExtractor mediaExtractor;
mediaExtractor = new MediaExtractor();
try {
mediaExtractor.setDataSource(srcPath);
//遍历媒体轨道,然后选取音频轨道
for (int i = 0; i < mediaExtractor.getTrackCount(); i++) {
MediaFormat format = mediaExtractor.getTrackFormat(i);
//获取音频轨道
String mime = format.getString(MediaFormat.KEY_MIME);
//public static final String AUDIO = "audio/";
if (mime.startsWith(AUDIO)) {
LogUtils.d(TAG, format.toString());
//选择此音频轨道
mediaExtractor.selectTrack(i);
mediaDecode = MediaCodec.createDecoderByType(mime);
//第二个参数是surface,解码视频的时候需要,第三个是MediaCrypto, 是关于加密的,最后一个flag填0即可
//configure会使MediaCodec进入Configured state
mediaDecode.configure(format, null, null, 0);
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
if (mediaDecode == null) {
LogUtils.e(TAG, "create mediaDecode failed");
return;
}
//启动MediaCodec,等待传入数据
//调用此方法之后mediaCodec进入Executing state
mediaDecode.start();
//MediaCodec在此ByteBuffer[]中获取输入数据
decodeInputBuffers = mediaDecode.getInputBuffers();
decodeOutputBuffers = mediaDecode.getOutputBuffers();
//用于描述解码得到的byte[]数据的相关信息
decodeBufferInfo = new MediaCodec.BufferInfo();
LogUtils.d(TAG, " initial time:" + (System.currentTimeMillis() - time) + " ms");
}
二、初始化编码器
private void initEncoder(String outPath) {
long time = System.currentTimeMillis();
try {
//参数对应-> mime type、采样率、声道数
//public static final String AUDIO_AMR = "audio/3gpp";
MediaFormat encodeFormat = MediaFormat.createAudioFormat(AUDIO_AMR,