一、音频录制AudioRecord
AudioRecord录制的输出格式为PCM,这种格式不能直接播放,但是Android原生也提供了AudioTrack,这使得我们可以在软件内部实现录制播放功能。
首先添加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
以下是AudioRecord的参数配置。
int frequency = 48000;//采样率
int channelConfig = AudioFormat.CHANNEL_IN_MONO;//声道配置
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;//音频格式
File audioFile;
//开始录制
void record() throws IOException {
//如果文件已存在则删除
if (audioFile.exists()) audioFile.delete();
audioFile.createNewFile();
FileOutputStream fos = new FileOutputStream(audioFile);//字节输出流
BufferedOutputStream bos = new BufferedOutputStream(fos);//字节缓冲输出流
DataOutputStream dos = new DataOutputStream(bos);
//计算最小缓冲区
int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfig, audioFormat);
short[] buffer = new short[bufferSize];
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
judgeNeedRequestMicPermission();
return;
}
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, frequency, channelConfig, audioFormat, bufferSize);
//开始录制
audioRecord.startRecording();
recording = true;
new Thread(new Runnable() {
@Override
public void run() {
while(recording){
System.out.println(recording);
int bufferRead = audioRecord.read(buffer, 0, bufferSize);
for(int i=0; i<bufferRead; i++){
try {
dos.writeShort(buffer[i]);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
System.out.println(audioFile);
audioRecord.stop();
audioRecord.release();
try {
dos.close();
bos.close();
fos.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
}
recording为false时结束录制,可以自定义一个按钮修改。
二、音频播放AudioTrack
AudioTrack的配置与AudioRecord基本一致,唯一要注意的是把声道配置改成 AudioFormat.CHANNEL_OUT_MONO。
void play(int frq) throws IOException{
int length = (int)audioFile.length()/2;
if(!audioFile.exists() || length==0) {
Toast.makeText(getBaseContext(), "音频文件不存在或为空", Toast.LENGTH_SHORT).show();
return;
}
short[] data = new short[length];
FileInputStream fis = new FileInputStream(audioFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
int i=0;
while(dis.available()>0) {
data[i] = dis.readShort();
i++;
}
dis.close();
bis.close();
fis.close();
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frq, AudioFormat.CHANNEL_OUT_MONO, audioFormat, length*2, AudioTrack.MODE_STREAM);
audioTrack.play();
audioTrack.write(data, 0, length);
audioTrack.stop();
//audioTrack.release(); // 不能马上release,因为write后是异步播放,此时还刚开始播放,release就不播放了
}
总结
其实也没什么好总结的,本文展示的只是基本用法,AudioRecord能实现很多强大的功能,比如边录边播、语音通话等。以上内容只是对大佬们的拙劣模仿罢了,如果各位有什么其他见解,欢迎在评论区探讨。