Android SDK提供了两套音频采集的API,分别是:MediaRecorder
和AudioRecord
。前者是一个更加上层的API,它可以直接对手机麦克风录入的音频数据进行编码压缩(如AMR,MP3等),并存储为文件;后者更加接近底层,能够更加灵活地控制,其可以让开发者得到内存中的PCM音频流数据。如果想做一个简单的录音机,输出音频文件,则推荐使用MediaRecorder
;如果需要对音频做进一步的算法处理,或者需要采用第三方的编码库进行编码压缩,又或者需要用到网络传输等场景中,那么只能使用AudioRecord
或者OpenSL ES
,其实MediaRecorder
底层也是调用了AudioRecord
与Android Framework层的AudioFlinger进行交互的。至于OpenSL ES
,请参考另一篇文章音视频开发进阶指南(第四章)-OpenSL-ES播放PCM音频。
本章讲解如何使用AudioRecord
录音音频,并使用AudioTrack播放
播放步骤
1. 初始化AudioRecord
private static final int SAMPLE_RATE = 44100;//采样率
private static final int CHANNEL_CONFIG_IN = AudioFormat.CHANNEL_IN_MONO;//通道配置
private static final int CHANNEL_CONFIG_OUT = AudioFormat.CHANNEL_OUT_MONO;//通道配置
private static final int ENCODING_FORMAT = AudioFormat.ENCODING_PCM_16BIT;//编码配置
private static final String PCM_FILE = "/mnt/sdcard/test.pcm";
private static final String TAG = "MainActivity";
int minBufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG_IN, ENCODING_FO
mAudioRecord = new AudioRecord(
MediaRecorder.AudioSource.DEFAULT,//默认音频源
SAMPLE_RATE, //采样率
CHANNEL_CONFIG_IN, //通道
ENCODING_FORMAT, //表示格式
minBufferSize); //最小缓存
//开启录音
mAudioRecord.startRecording();
读取音频数据并写入文件
/**
* 读取音频数据并写入文件
*/
private void startReadThread() {
Log.d(TAG, "startReadThread");
new Thread() {
@Override
public void run() {
super.run();
short[] buf = new short[1024];//一次读取的音频数据大小
BufferedOutputStream bos = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(PCM_FILE);
bos = new BufferedOutputStream(fos);
while (mAudioRecord.read(buf, 0, buf.length) > 0) {
//把short转为字节数组
byte[] bytes = ArrayUtil.toByteArraySmallEnd(buf);
bos.write(bytes);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bos.close();
fos.close();
if (mAudioRecord != null) {
mAudioRecord.stop();
mAudioRecord.release();
mAudioRecord = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}
使用AudioTrack进行播放
private void play() {
File file = new File(PCM_FILE);
if (!file.exists()) {
Toast.makeText(this, "请先开始录音", Toast.LENGTH_SHORT).show();
return;
}
int minBufferSize = AudioTrack.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIG_OUT, ENCODI
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
SAMPLE_RATE,
CHANNEL_CONFIG_OUT,
ENCODING_FORMAT,
minBufferSize,
AudioTrack.MODE_STREAM);
mAudioTrack.play();
new Thread() {
@Override
public void run() {
super.run();
FileInputStream fis = null;
BufferedInputStream bis = null;
byte[] buf = new byte[1024];
try {
fis = new FileInputStream(PCM_FILE);
bis = new BufferedInputStream(fis);
int read = 0;
while ((read = bis.read(buf)) > 0) {
mAudioTrack.write(buf, 0, read);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bis.close();
fis.close();
if (mAudioTrack != null) {
mAudioTrack.stop();
mAudioTrack.release();
mAudioTrack = null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}.start();
}
附上源码[AudioRecord-Test(https://github.com/dd-Dog/AudioRecord-Test.git)
代码比较简单,没有过多注释,如有问题,欢迎留言!
网友评论