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(); }