Android音頻開(kāi)發(fā)(2):使用AudioRecord錄制pcm格式音頻
標(biāo)簽:
Android Studio
一、AudioRecord类的介绍
AudioRecord构造函数:
/** * @param audioSource :录音源 * 这里选择使用麦克风:MediaRecorder.AudioSource.MIC * @param sampleRateInHz: 采样率 * @param channelConfig:声道数 * @param audioFormat: 采样位数. * See {@link AudioFormat#ENCODING_PCM_8BIT}, {@link AudioFormat#ENCODING_PCM_16BIT}, * and {@link AudioFormat#ENCODING_PCM_FLOAT}. * @param bufferSizeInBytes: 音频录制的缓冲区大小 * See {@link #getMinBufferSize(int, int, int)} */public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)getMinBufferSize()
/** * 获取AudioRecord所需的最小缓冲区大小 * @param sampleRateInHz: 采样率 * @param channelConfig:声道数 * @param audioFormat: 采样位数. */public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)
getRecordingState()
/** * 获取AudioRecord当前的录音状态 * @see AudioRecord#RECORDSTATE_STOPPED * @see AudioRecord#RECORDSTATE_RECORDING */public int getRecordingState()
startRecording()
/** * 开始录制 */ public int startRecording()
startRecording()
/** * 停止录制 */ public int stop()
read()
/** * 从录音设备中读取音频数据 * @param audioData 音频数据写入的byte[]缓冲区 * @param offsetInBytes 偏移量 * @param sizeInBytes 读取大小 * @return 返回负数则表示读取失败 * see {@link #ERROR_INVALID_OPERATION} -3 : 初始化错误 {@link #ERROR_BAD_VALUE} -3: 参数错误 {@link #ERROR_DEAD_OBJECT} -6: {@link #ERROR} */public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes)
二、实现
实现过程就是调用上面的API的方法,构造AudioRecord实例后再调用startRecording(),开始录音,并通过read()方法不断获取录音数据记录下来,生成PCM文件。涉及耗时操作,所以最好在子线程中进行。
/**
* @author zhaolewei on 2018/7/10.
*/public class RecordHelper { //0.此状态用于控制线程中的循环操作,应用volatile修饰,保持数据的一致性
private volatile RecordState state = RecordState.IDLE; private AudioRecordThread audioRecordThread; private File tmpFile = null; public void start(String filePath, RecordConfig config) { if (state != RecordState.IDLE) {
Logger.e(TAG, "状态异常当前状态: %s", state.name()); return;
}
recordFile = new File(filePath);
String tempFilePath = getTempFilePath();
Logger.i(TAG, "tmpPCM File: %s", tempFilePath);
tmpFile = new File(tempFilePath); //1.开启录音线程并准备录音
audioRecordThread = new AudioRecordThread();
audioRecordThread.start();
} public void stop() { if (state == RecordState.IDLE) {
Logger.e(TAG, "状态异常当前状态: %s", state.name()); return;
}
state = RecordState.STOP;
} private class AudioRecordThread extends Thread { private AudioRecord audioRecord; private int bufferSize;
AudioRecordThread() { //2.根据录音参数构造AudioRecord实体对象
bufferSize = AudioRecord.getMinBufferSize(currentConfig.getFrequency(),
currentConfig.getChannel(), currentConfig.getEncoding()) * RECORD_AUDIO_BUFFER_TIMES;
audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, currentConfig.getFrequency(),
currentConfig.getChannel(), currentConfig.getEncoding(), bufferSize);
} @Override
public void run() { super.run();
state = RecordState.RECORDING;
Logger.d(TAG, "开始录制");
FileOutputStream fos = null; try {
fos = new FileOutputStream(tmpFile);
audioRecord.startRecording(); byte[] byteBuffer = new byte[bufferSize]; while (state == RecordState.RECORDING) { //3.不断读取录音数据并保存至文件中
int end = audioRecord.read(byteBuffer, 0, byteBuffer.length);
fos.write(byteBuffer, 0, end);
fos.flush();
} //4.当执行stop()方法后state != RecordState.RECORDING,终止循环,停止录音
audioRecord.stop();
} catch (Exception e) {
Logger.e(e, TAG, e.getMessage());
} finally { try { if (fos != null) {
fos.close();
}
} catch (IOException e) {
Logger.e(e, TAG, e.getMessage());
}
}
state = RecordState.IDLE;
Logger.d(TAG, "录音结束");
}
}
}三、其他
这里实现了PCM音频的录制,AudioRecord API中只有开始和停止的方法,在实际开发中可能还需要暂停/恢复的操作,以及PCM转WAV的功能,下一篇再继续完善。
需要录音及文件处理的动态权限
作者:android_赵乐玮
链接:https://www.jianshu.com/p/a72deab95b4c
點(diǎn)擊查看更多內(nèi)容
為 TA 點(diǎn)贊
評(píng)論
評(píng)論
共同學(xué)習(xí),寫(xiě)下你的評(píng)論
評(píng)論加載中...
作者其他優(yōu)質(zhì)文章
正在加載中
感謝您的支持,我會(huì)繼續(xù)努力的~
掃碼打賞,你說(shuō)多少就多少
贊賞金額會(huì)直接到老師賬戶(hù)
支付方式
打開(kāi)微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊(cè)有機(jī)會(huì)得
100積分直接送
付費(fèi)專(zhuān)欄免費(fèi)學(xué)
大額優(yōu)惠券免費(fèi)領(lǐng)