Android 音频开发 目录

  1. Android音频开发(1):音频相关知识
  2. Android音频开发(2):使用AudioRecord录制pcm格式音频
  3. Android音频开发(3):使用AudioRecord实现录音的暂停和恢复
  4. Android音频开发(4):PCM转WAV格式音频
  5. Android音频开发(5):Mp3的录制 - 编译Lame源码
  6. Android音频开发(6):Mp3的录制 - 使用Lame实时录制MP3格式音频
  7. Android音频开发(7):音乐可视化-FFT频谱图

项目地址

https://github.com/zhaolewei/ZlwAudioRecorder


一、AudioRecord类的介绍

  1. 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)
  2. getMinBufferSize()
    /*** 获取AudioRecord所需的最小缓冲区大小* @param sampleRateInHz: 采样率* @param channelConfig:声道数  * @param audioFormat: 采样位数.*/public static int getMinBufferSize (int sampleRateInHz,             int channelConfig,             int audioFormat)
  3. getRecordingState()
    /*** 获取AudioRecord当前的录音状态 *   @see AudioRecord#RECORDSTATE_STOPPED    *   @see AudioRecord#RECORDSTATE_RECORDING*/public int getRecordingState()
  4. startRecording()
     /** * 开始录制 */ public int startRecording()
  5. startRecording()
     /** * 停止录制 */ public int stop()
  6. 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的功能,下一篇再继续完善。
  • 需要录音及文件处理的动态权限

更多相关文章

  1. Android音频开发(4):PCM转WAV格式音频
  2. Android音频开发(7):音乐可视化-FFT频谱图
  3. Android音频开发(3):使用AudioRecord实现录音的暂停和恢复
  4. Android隐藏状态栏和标题栏
  5. Android中的drawable state的各种状态
  6. 使用C语言怎样清空输入缓冲区?这里有多种方法值得借鉴
  7. Unity 3D 浅谈Shader 运行时状态及渲染模式遇到的问题
  8. 在 Vue.js 中使用无状态组件[每日前端夜话0xB9]
  9. Linux学习:文件IO(不带缓冲区),原子操作概念

随机推荐

  1. Android studio 使用问题
  2. Android Gradle Task依赖
  3. Android 调用相机和调用图库
  4. 『ANDROID』Android实现圆形的图片边角
  5. Android(安卓)ANR keyDispatchingTimedOu
  6. 使用http协议获取网络图片
  7. android 导入第三方库出现java.lang.NoCl
  8. java.util.concurrent.ExecutionExceptio
  9. Android 安装apk的方法
  10. android开发笔记之LayoutInflater的理解