我们在开发中经常会用到录音、播放录音等功能。有好几种方式,今天主要讲解的是AudioRecord:
第一步:先添加对应的录音、存储等权限: <!--存储和录音文件--> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
第二步:创建对应的存储文件夹以及文件:
private static String file_home_storage = "/storage/emulated/0"; public static String file_path_hrv_all = file_home_storage + "/Pcm/";
/** * 开始录音,返回临时缓存文件(.pcm)的文件路径 */ public static void initHRVCacheDirPath(Context context) { File f; if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { f = new File(file_path_hrv_all); if (f.exists()) { // Log.e(TAG, "已经存在"); } else { boolean iscreat = f.mkdirs(); Log.e(TAG, "是否创建成功:" + iscreat); } if (!f.exists()) { f.mkdirs(); } } else { f = context.getCacheDir(); } Log.e(TAG, "" + f.getAbsolutePath()); }
第三步:AudioRecord的使用 // 获取最小录音缓存大小, final int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_INHZ, CHANNEL_CONFIG, AUDIO_FORMAT); audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_INHZ, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize);
// 创建数据流,将缓存导入数据流 byte[] data = new byte[minBufferSize]; int read; if (fos != null) { while (isRecording && !recordingAudioThread.isInterrupted()) { read = audioRecord.read(data, 0, minBufferSize); if (AudioRecord.ERROR_INVALID_OPERATION != read) { try { fos.write(data); Log.e("audioRecordTest", "写录音数据->" + read); } catch (IOException e) { e.printStackTrace(); } } } }
第四步:停止录音:
/** * 停止录音 */ public static void stopRecordAudio(){ try { isRecording = false; if (audioRecord != null) { audioRecord.stop(); audioRecord.release(); audioRecord = null; recordingAudioThread.interrupt(); recordingAudioThread = null; } } catch (Exception e){ Log.w(TAG,e.getLocalizedMessage()); } }
最后附上全部的代码以供大家的参考啦:
public class AudioRecordUtils {
? ? // 采样率,现在能够保证在所有设备上使用的采样率是44100Hz, 但是其他的采样率(22050, 16000, 11025)在一些设备上也可以使用。
? ? public static final int SAMPLE_RATE_INHZ = 44100;
? ? // 声道数。CHANNEL_IN_MONO and CHANNEL_IN_STEREO. 其中CHANNEL_IN_MONO是可以保证在所有设备能够使用的。
? ? public static final int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_STEREO;
? ? // 返回的音频数据的格式。 ENCODING_PCM_8BIT, ENCODING_PCM_16BIT, and ENCODING_PCM_FLOAT.
? ? public static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
? ? private static AudioRecord audioRecord;
? ? public static ?String TAG="timo-AudioRecordUtils";
? ? /**
? ? ?* 录音的工作线程
? ? ?*/
? ? private static Thread recordingAudioThread;
? ? private static boolean isRecording = false;//mark if is recording
? ? private static String ?file_home_storage ? ? = "/storage/emulated/0";
? ? public static ?String ?file_path_hrv_all ? ? = file_home_storage + "/Pcm/";
? ? /**
? ? ?* 开始录音,返回临时缓存文件(.pcm)的文件路径
? ? ?*/
? ? public static void initHRVCacheDirPath(Context context) {
? ? ? ? File f;
? ? ? ? if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
? ? ? ? ? ? f = new File(file_path_hrv_all);
? ? ? ? ? ? if (f.exists()) {
// ? ? ? ? ? ? ? ?Log.e(TAG, "已经存在");
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? boolean iscreat = f.mkdirs();
? ? ? ? ? ? ? ? Log.e(TAG, "是否创建成功:" + iscreat);
? ? ? ? ? ? }
? ? ? ? ? ? if (!f.exists()) {
? ? ? ? ? ? ? ? f.mkdirs();
? ? ? ? ? ? }
? ? ? ? } else {
? ? ? ? ? ? f = context.getCacheDir();
? ? ? ? }
? ? ? ? Log.e(TAG, "" + f.getAbsolutePath());
? ? }
? ? public static String startRecordAudio(Context context) {
// ? ? ? ?final String audioCacheFilePath = context.getExternalFilesDir(Environment.DIRECTORY_MUSIC).getAbsolutePath() + "/" + "jerboa_audio_cache.pcm";
? ? ? ? initHRVCacheDirPath(context);
? ? ? ? final String audioCacheFilePath =file_path_hrv_all + System.currentTimeMillis() + ".pcm";
? ? ? ? try{
? ? ? ? ? ? // 获取最小录音缓存大小,
? ? ? ? ? ? final int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_INHZ, CHANNEL_CONFIG, AUDIO_FORMAT);
? ? ? ? ? ? audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_INHZ, CHANNEL_CONFIG, AUDIO_FORMAT, minBufferSize);
? ? ? ? ? ? // 开始录音
? ? ? ? ? ? isRecording = true;
? ? ? ? ? ? audioRecord.startRecording();
? ? ? ? ? ? // 创建数据流,将缓存导入数据流
? ? ? ? ? ? recordingAudioThread = new Thread(new Runnable() {
? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? ? ? File file = new File(audioCacheFilePath);
? ? ? ? ? ? ? ? ? ? Log.e(TAG, "audio cache pcm file path:" + audioCacheFilePath);
? ? ? ? ? ? ? ? ? ? /*
? ? ? ? ? ? ? ? ? ? ?* ?以防万一,看一下这个文件是不是存在,如果存在的话,先删除掉
? ? ? ? ? ? ? ? ? ? ?*/
? ? ? ? ? ? ? ? ? ? if (file.exists()) {
? ? ? ? ? ? ? ? ? ? ? ? file.delete();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? file.createNewFile();
? ? ? ? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? FileOutputStream fos = null;
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? fos = new FileOutputStream(file);
? ? ? ? ? ? ? ? ? ? } catch (FileNotFoundException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? ? ? Log.e(TAG, "临时缓存文件未找到");
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? if (fos == null) {
? ? ? ? ? ? ? ? ? ? ? ? return;
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? byte[] data = new byte[minBufferSize];
? ? ? ? ? ? ? ? ? ? int read;
? ? ? ? ? ? ? ? ? ? if (fos != null) {
? ? ? ? ? ? ? ? ? ? ? ? while (isRecording && !recordingAudioThread.isInterrupted()) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? read = audioRecord.read(data, 0, minBufferSize);
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (AudioRecord.ERROR_INVALID_OPERATION != read) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? fos.write(data);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Log.e("audioRecordTest", "写录音数据->" + read);
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? // 关闭数据流
? ? ? ? ? ? ? ? ? ? ? ? fos.close();
? ? ? ? ? ? ? ? ? ? } catch (IOException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? });
? ? ? ? ? ?recordingAudioThread.start();
? ? ? ? }
? ? ? ? catch(IllegalStateException e){
? ? ? ? ? ? Log.e(TAG,"需要获取录音权限!");
// ? ? ? ? ? ?checkIfNeedRequestRunningPermission();
? ? ? ? }
? ? ? ? catch(SecurityException e){
? ? ? ? ? ? Log.e(TAG,"需要获取录音权限!");
// ? ? ? ? ? ?checkIfNeedRequestRunningPermission();
? ? ? ? }
? ? ? ? return audioCacheFilePath;
? ? }
? ? /**
? ? ?* 停止录音
? ? ?*/
? ? public static void stopRecordAudio(){
? ? ? ? try {
? ? ? ? ? ? isRecording = false;
? ? ? ? ? ? if (audioRecord != null) {
? ? ? ? ? ? ? ? audioRecord.stop();
? ? ? ? ? ? ? ? audioRecord.release();
? ? ? ? ? ? ? ? audioRecord = null;
? ? ? ? ? ? ? ? recordingAudioThread.interrupt();
? ? ? ? ? ? ? ? recordingAudioThread = null;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? catch (Exception e){
? ? ? ? ? ? Log.w(TAG,e.getLocalizedMessage());
? ? ? ? }
? ? }
}
以上就是讲解的全部内容了啊!