版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huanghuangjin/article/details/82807300
public class AudioRecordActivity extends BaseActivity {
public static void startAudioRecordActivity(Activity activity) {
activity.startActivity(new Intent(activity, AudioRecordActivity.class));
}
// AudioRecord
@BindView(R.id.btn_audiorecord_start) Button mStartBtn;
private AudioRecord mAudioRecord;
private ExecutorService mExecutorService = Executors.newFixedThreadPool(5);
private boolean isRecording = false;
private int bufferSizeInBytes_re;
// AudioTrack
@BindView(R.id.btn_audiorecord_play) Button mPlayBtn;
private AudioTrack mAudioTrack;
private boolean isPlaying = false;
private int bufferSizeInBytes_play;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audiorecord);
mUnbinder = ButterKnife.bind(this);
// AudioRecord
int audioSource = MediaRecorder.AudioSource.MIC; // 表示音频源,来自麦克风
int sampleRateInHz = 44100; // 采样率
int channelConfig = AudioFormat.CHANNEL_IN_STEREO; // 输入,声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; // 样本格式
bufferSizeInBytes_re = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); // 采样需要的缓冲区的大小
mAudioRecord = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes_re);
// AudioTrack
bufferSizeInBytes_play = AudioTrack.getMinBufferSize(sampleRateInHz, AudioFormat.CHANNEL_OUT_STEREO, audioFormat);
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
sampleRateInHz, AudioFormat.CHANNEL_OUT_STEREO,
audioFormat,
bufferSizeInBytes_play, AudioTrack.MODE_STREAM, mAudioRecord.getAudioSessionId()); // AudioTrack 可以直接关联 AudioRecord 的SessionId,不关联也可以
}
private void stopRecord() { // 停止录音
isRecording = false;
if (mStartBtn!=null) mStartBtn.setText("开始录音");
if (mAudioRecord.getState()==AudioRecord.STATE_INITIALIZED) { // 还有其他状态,RECORDSTATE_RECORDING 等
LogUtils.d("mydebug---", "state == AudioRecord.STATE_INITIALIZED");
mAudioRecord.stop(); // 停止
}
}
private void stopPlay() { // 停止播放
isPlaying = false;
if (mPlayBtn!=null) mPlayBtn.setText("开始播放");
mAudioTrack.pause(); // 立即暂停,mAudioTrack.stop函数会播放完缓冲队列中的数据,才停止
mAudioTrack.flush(); // 清空缓冲区数据
}
@OnClick({R.id.btn_audiorecord_start, R.id.btn_audiorecord_play, R.id.btn_audiorecord_stop})
void click(View view) {
final String sdcrad = Environment.getExternalStorageDirectory().getAbsolutePath();
switch (view.getId()) {
case R.id.btn_audiorecord_start: // 开始录音
stopPlay();
if (!isRecording) {
isRecording = true;
mStartBtn.setText("录音中...");
mExecutorService.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); // 声音线程的最高级别,优先程度较THREAD_PRIORITY_AUDIO要高
} catch (Exception e) {}
mAudioRecord.startRecording(); // 开始录音
byte buf[] = new byte[bufferSizeInBytes_re];
File file = new File(sdcrad+"/audiorecord.pcm");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
int len = -1;
while (isRecording) {
len = mAudioRecord.read(buf, 0, bufferSizeInBytes_re); // 读取录制的音频(pcm),返回值为读取的长度
if (len>0) fos.write(buf, 0, len); else stopRecord();
}
} catch (Exception e) {
e.printStackTrace();
}
if (fos!=null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
});
}
break;
case R.id.btn_audiorecord_play: // 播放录音
stopRecord();
if (!isPlaying) {
isPlaying = true;
mPlayBtn.setText("播放中...");
mExecutorService.execute(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(100);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); // 声音线程的最高级别,优先程度较THREAD_PRIORITY_AUDIO要高
} catch (Exception e) {}
mAudioTrack.play();
File file = new File(sdcrad+"/audiorecord.pcm");
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
byte buf[] = new byte[bufferSizeInBytes_play];
int len = -1;
while (isPlaying && (len = fis.read(buf))!=-1) {
mAudioTrack.write(buf, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
runOnUiThread(new Runnable() {
@Override
public void run() {
stopPlay();
}
});
}
}
});
}
break;
case R.id.btn_audiorecord_stop:
stopPlay();
stopRecord();
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mAudioRecord!=null) {
stopRecord();
mAudioRecord.release();
}
if (mAudioTrack!=null) {
stopPlay();
mAudioTrack.release();
}
}
}