我们在开发中经常会用到录音、播放录音等功能。有好几种方式,今天主要讲解的是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());
}
}
}
以上就是讲解的全部内容了啊!