简介
Android中,如果要录制音频的话有两个选择,一个是MediaRecorder
,另一个就是AudioRecord
,前者使用简单,后者就相对复杂点
关于MediaRecorder
的用法相信大家都比较熟悉,而对于AudioRecord
可能要陌生一些,所有我们重点来讲下AudioRecord
的用法
声音
在此之前,我们先来了解下关于声音的知识,下面是来自百度百科的介绍
声音(sound)是由物体振动产生的声波。是通过介质(空气或固体、液体)传播并能被人或动物听觉器官所感知的波动现象。最初发出振动(震动)的物体叫声源。声音以波的形式振动(震动)传播。声音是声波通过任何物质传播形成的运动。
声音作为一种波,频率在20 Hz~20 kHz之间的声音是可以被人耳识别的。
从上面所述我们得到一个信息:人耳可以听到20 Hz~20 kHz的声音,那么根据奈奎斯特定律,采样率要大于或等于信号中两倍的最高频率,这样才能完整得保留原始信号中的信息
也就是说,要一秒钟采样40k次,才能无失帧得记录原始信息
计算机中记录原始音频,一般是用PCM格式存储,pcm的内容都是byte类型的数组,也就是编码格式
PCM8位
如果是单声道,那么byte数组每一个元素都是一次采样的数据
如果是双声道,那么byte数组就是LRLRLR形式的存储(L代表左耳,R代表右耳)
PCM16位
如果是单声道,那么byte数组每两个元素都是一次采样的数据
如果是双声道,那么byte数组就是L低L高 R低R高 L低L高 R低R高形式的存储(L代表左耳,R代表右耳),低表示低八位,高表示高八位
综上我们得出关于音频的三个参数
- 采样率
- 声道数
- 编码格式
创建AudioRecord
private static final int AUDIO_INPUT = MediaRecorder.AudioSource.MIC;//音频来源
private static final int AUDIO_SAMPLE_RATE = 44100;//采样率
private static final int AUDIO_IN_CHANNEL = AudioFormat.CHANNEL_IN_STEREO;//双声道
private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;//编码格式 PCM 16位
private int bufferSizeInBytes = 0;//最小录音缓存
private AudioRecord mAudioRecord;//AudioRecord
public void createDefaultAudio() {
bufferSizeInBytes = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_IN_CHANNEL, AUDIO_ENCODING);
mAudioRecord = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE, AUDIO_IN_CHANNEL, AUDIO_ENCODING, bufferSizeInBytes);
}
我们创建AudioRecord
之前还需要获得一个叫做最小缓存bufferSizeInBytes
的东西,它可以通过AudioRecord.getMinBufferSize()
方法获取,因为我们录音需要不断去读写,所有需要有一个缓存空间,刚好AudioRecord提供给我们现成的方法,我们直接用就可以了。
我们创建成功就可以开始录音了,不过要注意,此时你要检查你的应用是否有录音的权限
录音
mAudioRecord.startRecording();
开启录音后我们还没做任何事,也就没法将录音保存下来,所有我们得开启一个子线程将数据写入文件
开启录音线程
/**
* 开启录制音频子线程
*/
private void startRecordThread() {
new Thread(new Runnable() {
@Override
public void run() {
writeDataToFile();
}
}).start();
}
/**
* 将录音内容写入文件
*/
private void writeDataToFile() {
byte[] audioData = new byte[bufferSizeInBytes];
FileOutputStream fos = null;
int readSize = 0;
try {
File file = new File("你的文件路径");
if (file.exists()) {
file.delete();
}
fos = new FileOutputStream("你的文件路径", true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (!isStop) {
readSize = mAudioRecord.read(audioData, 0, bufferSizeInBytes);
if (readSize == AudioRecord.ERROR_INVALID_OPERATION || readSize == AudioRecord.ERROR_BAD_VALUE) {
continue;
}
if (fos != null) {
try {
fos.write(audioData);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
我们这个线程有一个无线循环的while,在while里我们进行数据的读写,我们可以定义一个boolean变量isStop来控制录音的停止
我们先是新建了一个byte数组
byte[] audioData = new byte[bufferSizeInBytes]
这个数组大小就是之前我们获取到的最小缓存
接着我们打开文件,进行读写,通过mAudioRecord.read()
方法不断从AudioRecord中读取数据,然后将其写入文件中,最后在我们停止之后关闭文件的输出流。
停止录音
/**
* 停止录音
*/
private void stop(){
mAudioRecord.stop();
isStop = ture;
}
停止录音就调用AudioRecord
的stop()
方法并将isStop置为ture即可停止录音
最后
以上就是AudioRecord的基本用法,关于音频的更多知识与应用后面会陆续和大家分享,希望大家能够喜欢。
网友评论