Android提供了两个API用于实现录音功能:android.media.AudioRecord、android.media.MediaRecorder。
网上有很多谈论这两个类的资料。现在大致总结下:
1、AudioRecord
主要是实现边录边播(AudioRecord+AudioTrack)以及对音频的实时处理(如会说话的汤姆猫、语音)
优点:语音的实时处理,可以用代码实现各种音频的封装
缺点:输出是PCM语音数据,如果保存成音频文件,是不能够被播放器播放的,所以必须先写代码实现数据编码以及压缩
示例:
使用AudioRecord类录音,并实现WAV格式封装。录音20s,输出的音频文件大概为3.5M左右(已写测试代码)
2、MediaRecorder
已经集成了录音、编码、压缩等,支持少量的录音音频格式,大概有.aac(API = 16) .amr .3gp
优点:大部分以及集成,直接调用相关接口即可,代码量小
缺点:无法实时处理音频;输出的音频格式不是很多,例如没有输出mp3格式文件
示例:
使用MediaRecorder类录音,输出amr格式文件。录音20s,输出的音频文件大概为33K(已写测试代码)
3、音频格式比较
WAV格式:录音质量高,但是压缩率小,文件大
AAC格式:相对于mp3,AAC格式的音质更佳,文件更小;有损压缩;一般苹果或者Android SDK4.1.2(API 16)及以上版本支持播放
AMR格式:压缩比比较大,但相对其他的压缩格式质量比较差,多用于人声,通话录音
至于常用的mp3格式,使用MediaRecorder没有该视频格式输出。一些人的做法是使用AudioRecord录音,然后编码成wav格式,再转换成mp3格式
再贴上一些测试工程。
功能描述:
1、点击“录音WAV文件”,开始录音。录音完成后,生成文件/sdcard/FinalAudio.wav
2、点击“录音AMR文件”,开始录音。录音完成后,生成文件/sdcard/FinalAudio.amr
3、点击“停止录音”,停止录音,并显示录音输出文件以及该文件大小。
大致代码如下:
1、AudioRecord录音,封装成WAV格式.
packagecom.example.audiorecordtest;importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importandroid.media.AudioFormat;importandroid.media.AudioRecord;public classAudioRecordFunc {//缓冲区字节大小
private int bufferSizeInBytes = 0;//AudioName裸音频数据文件 ,麦克风
private String AudioName = "";//NewAudioName可播放的音频文件
private String NewAudioName = "";privateAudioRecord audioRecord;private boolean isRecord = false;//设置正在录制的状态
private staticAudioRecordFunc mInstance;privateAudioRecordFunc(){
}public synchronized staticAudioRecordFunc getInstance()
{if(mInstance == null)
mInstance= newAudioRecordFunc();returnmInstance;
}public intstartRecordAndFile() {//判断是否有外部存储设备sdcard
if(AudioFileFunc.isSdcardExit())
{if(isRecord)
{returnErrorCode.E_STATE_RECODING;
}else{if(audioRecord == null)
creatAudioRecord();
audioRecord.startRecording();//让录制状态为true
isRecord = true;//开启音频文件写入线程
new Thread(newAudioRecordThread()).start();returnErrorCode.SUCCESS;
}
}else{returnErrorCode.E_NOSDCARD;
}
}public voidstopRecordAndFile() {
close();
}public longgetRecordFileSize(){returnAudioFileFunc.getFileSize(NewAudioName);
}private voidclose() {if (audioRecord != null) {
System.out.println("stopRecord");
isRecord= false;//停止文件写入
audioRecord.stop();
audioRecord.release();//释放资源
audioRecord = null;
}
}private voidcreatAudioRecord() {//获取音频文件路径
AudioName =AudioFileFunc.getRawFilePath();
NewAudioName=AudioFileFunc.getWavFilePath();//获得缓冲区字节大小
bufferSizeInBytes =AudioRecord.getMinBufferSize(AudioFileFunc.AUDIO_SAMPLE_RATE,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);//创建AudioRecord对象
audioRecord = newAudioRecord(AudioFileFunc.AUDIO_INPUT, AudioFileFunc.AUDIO_SAMPLE_RATE,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes);
}class AudioRecordThread implementsRunnable {
@Overridepublic voidrun() {
writeDateTOFile();//往文件中写入裸数据
copyWaveFile(AudioName, NewAudioName);//给裸数据加上头文件
}
}/*** 这里将数据写入文件,但是并不能播放,因为AudioRecord获得的音频是原始的裸音频,
* 如果需要播放就必须加入一些格式或者编码的头信息。但是这样的好处就是你可以对音频的 裸数据进行处理,比如你要做一个爱说话的TOM
* 猫在这里就进行音频的处理,然后重新封装 所以说这样得到的音频比较容易做一些音频的处理。*/
private voidwriteDate