建议阅读:Android音视频架构与学习路线图
AudioRecord相较与MediaRecorder拥有更高的灵活性,它的录制输出是音频的原始数据。在录制之前,AudioRecord需要配置几个参数。
public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)
分别是
audioSource: 输入源,
sampleRateInHz:音频采样率,
channelConfig: 声道数,
audioFormat: 编码制式和采样大小, android支持的采样大小16bit 或者8bit。主流的采用16bit
bufferSizeInBytes:录制数据的缓冲区大小
前面几个参数,在音频的原理一文中都有解释,不懂的可以看下,我们现在要来看下bufferSizeBytes这个参数,一般我们不自己设它的值,而是通过系统提供的方法来获取
mMinBufferSize = getMinBufferSize(sampleRate, channel, audioFormat)
配置完成后调用 startRecording() 开始录制,然后不断的从缓冲区中取数据写入文件输出流中,下面是具体完整代码
package com.codeforfree.cffaudiorecorddemo;
import android.content.Context;
import android.media.AudioRecord;
import android.util.Log;
import com.codeforfree.cffaudiorecorddemo.util.wav.PcmToWav;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class AudioRecorder implements Runnable{
private static final String TAG = "CFF";
private AudioRecord mAudioRecord;
private Context mContext;
private RecordState mRecordState;
private Executor mRecordExecuter;
private int mMinBufferSize;
private File mPcmFile;
private File mWavFile;
public AudioRecorder(Context mContext) {
this.mContext = mContext;
mRecordExecuter = Executors.newSingleThreadExecutor();
mPcmFile = new File(mContext.getExternalFilesDir(""), "demo.pcm");
mWavFile = new File(mContext.getExternalFilesDir(""), "demo.wav");
mRecordState = RecordState.IDLE;
}
public void initAudioRecord(int audioSource, int sampleRate, int channel, int audioFormat){
mMinBufferSize = AudioRecord.getMinBufferSize(sampleRate, channel, audioFormat);
mAudioRecord = new AudioRecord(audioSource, sampleRate, channel, audioFormat, mMinBufferSize);
}
public void startRecord(){
if(mRecordState!=RecordState.IDLE){
return;
}
mRecordState = RecordState.RECORDING;
mRecordExecuter.execute(this);
}
public void stopRecord(){
mRecordState = RecordState.IDLE;
mAudioRecord.stop();
}
@Override
public void run() {
mAudioRecord.startRecording();
OutputStream outputStream = null;
try {
outputStream = new BufferedOutputStream(new FileOutputStream(mPcmFile));
byte[] data = new byte[mMinBufferSize];
while(mRecordState==RecordState.RECORDING){
int size = mAudioRecord.read(data, 0, mMinBufferSize);
outputStream.write(data, 0, size);
}
outputStream.flush();
outputStream.close();
PcmToWav.makePcmFileToWavFile(mPcmFile.getAbsolutePath(), mWavFile.getAbsolutePath(), false);
Log.i(TAG, "录制完成");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public RecordState getRecordStatus(){
return mRecordState;
}
public String getFileSavePath(){
return mWavFile.getAbsolutePath();
}
enum RecordState{
IDLE,
RECORDING
}
}