Android 实现音频的裁剪,拼接和混音
基本流程
在项目中我们的音频一般都是指的mp3的文件,mp3文件作为一种编码压缩过的文件格式并不能直接对音频的数据进行很好的操作,我们都知道这种压缩过后的文件播放的时候也必须通过解码器才能播放,而解码出来的原始数据就是pcm数据。pcm数据包含了音频最原始的信息,对实现对pcm数据的处理就能实现对音频的处理。所以对MP3音频流程如下图
pcm文件关键属性
pcm文件有这样几个关键参数,分别是采样率,采样大小,和声道数。这几个指标是十分关键的,我们可以通过他们的乘积得到这段音频的码率,或者通过文件大小除以码率算出这段音频的长度。并且如果要对两端音频进行拼接或混音操作必须保证这几个关键参数的一致,这样才能将两段音频进行处理,当然如果采样率不同怎么办呢?这里就需要SSRC来对采样率进行转换了。我们在实际应用的过程中尽量要避免进行采样率的转换,因为对于现在手机来说,这个过程是十分耗时的。
Android中的解码器
Android系统本身为我们提供了非常好的解码器来对Mp3文件进行解码通过MediaExtractor类和mediaCodec类我们可以进行解码工作。MediaCodec:负责媒体文件的编码和解码工作,内部方法均为native,MediaExtractor:负责将指定类型的媒体文件从文件中找到轨道和媒体信息,并填充到MediaCodec的缓冲区中。
获取关于一个mp3的完整信息
MediaExtractor mediaExtractor = new MediaExtractor();
try {
mediaExtractor.setDataSource(musicFileUrl);
} catch (Exception e) {
Log.e(TAG,e.toString());
return false;
}
mediaFormat = mediaExtractor.getTrackFormat(0);
//采样率
sampleRate = mediaFormat.containsKey(MediaFormat.KEY_SAMPLE_RATE) ?
mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE) : 44100;
//通道数
channelCount = mediaFormat.containsKey(MediaFormat.KEY_CHANNEL_COUNT) ?
mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT) : 1;
//音频长度
duration = mediaFormat.containsKey(MediaFormat.KEY_DURATION) ? mediaFormat.getLong
(MediaFormat.KEY_DURATION)
: 0;
//mime
mime = mediaFormat.containsKey(MediaFormat.KEY_MIME) ? mediaFormat.getString(MediaFormat
.KEY_MIME) : "";
try {
//得到进行解码的解码器
mediaCodec = MediaCodec.createDecoderByType(mime);
mediaCodec.configure(mediaFormat, null, null, 0);
} catch (Exception e) {
Log.e(TAG,e.toString());
return false;
}