1.封装音频录制工具类:
public class RecorderAudioManagerUtils {
private static volatile RecorderAudioManagerUtils mInstance;
public static RecorderAudioManagerUtils getInstance() {
if (mInstance == null) {
synchronized (RecorderAudioManagerUtils.class) {
if (mInstance == null) {
mInstance = new RecorderAudioManagerUtils();
}
}
}
return mInstance;
}
}
2.音频录制方法:
public void startRecord(WeakReference<Context> weakReference) {
this.weakReference = weakReference;
Log.e(TAG, "开始录音");
//生成PCM文件
String fileName = DateFormat.format("yyyy-MMdd-HHmmss", Calendar.getInstance(Locale.getDefault())) + ".pcm";
File file = new File(Environment.getExternalStorageDirectory(), "/ACC音频/");
if (!file.exists()) {
file.mkdir();
}
String audioSaveDir = file.getAbsolutePath();
Log.e(TAG, audioSaveDir);
recordFile = new File(audioSaveDir, fileName);
Log.e(TAG, "生成文件" + recordFile);
//如果存在,就先删除再创建
if (recordFile.exists()) {
recordFile.delete();
Log.e(TAG, "删除文件");
}
try {
recordFile.createNewFile();
Log.e(TAG, "创建文件");
} catch (IOException e) {
Log.e(TAG, "未能创建");
throw new IllegalStateException("未能创建" + recordFile.toString());
}
if (filePathList.size() == 2) {
filePathList.clear();
}
filePathList.add(recordFile);
try {
//输出流
OutputStream os = new FileOutputStream(recordFile);
BufferedOutputStream bos = new BufferedOutputStream(os);
DataOutputStream dos = new DataOutputStream(bos);
int bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, AudioFormat.CHANNEL_IN_STEREO, audioEncoding);
if (ActivityCompat.checkSelfPermission(weakReference.get(), Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
return;
}
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, AudioFormat.CHANNEL_IN_STEREO, audioEncoding, bufferSize);
short[] buffer = new short[bufferSize];
audioRecord.startRecording();
Log.e(TAG, "开始录音");
isRecording = true;
while (isRecording) {
int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
for (int i = 0; i < bufferReadResult; i++) {
dos.writeShort(buffer[i]);
}
}
audioRecord.stop();
dos.close();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "录音失败");
showToast("录音失败");
}
}
3.播放音频方法:
public void playPcm(boolean isChecked) {
try {
if (isChecked) {
//两首一起播放
for (File recordFiles : filePathList) {
threadPoolExecutor.execute(() -> playPcmData(recordFiles));
}
} else {
//只播放最后一次录音
playPcmData(recordFile);
}
}catch (Exception e){
e.printStackTrace();
}
}
4.播放pcm流边录边播:
/**
* 播放Pcm流,边读取边播
*/
public void playPcmData(File recordFiles) {
Log.e(TAG, "打印线程" + Thread.currentThread().getName());
try {
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(recordFiles)));
//最小缓存区
int bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, AudioFormat.CHANNEL_OUT_STEREO, audioEncoding);
AudioTrack player = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRateInHz, AudioFormat.CHANNEL_OUT_STEREO, audioEncoding, bufferSizeInBytes, AudioTrack.MODE_STREAM);
short[] data = new short[bufferSizeInBytes];
//开始播放
player.play();
while (true) {
int i = 0;
while (dis.available() > 0 && i < data.length) {
data[i] = dis.readShort();
i++;
}
player.write(data, 0, data.length);
//表示读取完了
if (i != bufferSizeInBytes) {
player.stop();//停止播放
player.release();//释放资源
dis.close();
showToast("播放完成了!!!");
break;
}
}
} catch (Exception e) {
Log.e(TAG, "播放异常: " + e.getMessage());
showToast("播放异常!!!!");
e.printStackTrace();
}
}
5.播放所有音频方法:
public void playAllRecord() {
if (recordFile == null) {
return;
}