Bootstrap

android AudioRecord 录制音频

建议阅读:Android音视频架构与学习路线图

 

AudioRecord相较与MediaRecorder拥有更高的灵活性,它的录制输出是音频的原始数据。在录制之前,AudioRecord需要配置几个参数。

 public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes)

分别是

audioSource: 输入源,

sampleRateInHz:音频采样率,

channelConfig: 声道数,

audioFormat: 编码制式和采样大小, android支持的采样大小16bit 或者8bit。主流的采用16bit

bufferSizeInBytes:录制数据的缓冲区大小

 

前面几个参数,在音频的原理一文中都有解释,不懂的可以看下,我们现在要来看下bufferSizeBytes这个参数,一般我们不自己设它的值,而是通过系统提供的方法来获取

mMinBufferSize = getMinBufferSize(sampleRate, channel, audioFormat)

配置完成后调用 startRecording() 开始录制,然后不断的从缓冲区中取数据写入文件输出流中,下面是具体完整代码

package com.codeforfree.cffaudiorecorddemo;

import android.content.Context;
import android.media.AudioRecord;
import android.util.Log;

import com.codeforfree.cffaudiorecorddemo.util.wav.PcmToWav;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class AudioRecorder implements Runnable{
    private static final String TAG = "CFF";
    private AudioRecord mAudioRecord;
    private Context mContext;
    private RecordState mRecordState;
    private Executor mRecordExecuter;
    private int mMinBufferSize;
    private File mPcmFile;
    private File mWavFile;

    public AudioRecorder(Context mContext) {
        this.mContext = mContext;
        mRecordExecuter = Executors.newSingleThreadExecutor();
        mPcmFile = new File(mContext.getExternalFilesDir(""), "demo.pcm");
        mWavFile = new File(mContext.getExternalFilesDir(""), "demo.wav");

        mRecordState = RecordState.IDLE;
    }

    public void initAudioRecord(int audioSource, int sampleRate, int channel, int audioFormat){
        mMinBufferSize = AudioRecord.getMinBufferSize(sampleRate, channel, audioFormat);
        mAudioRecord = new AudioRecord(audioSource, sampleRate, channel, audioFormat, mMinBufferSize);
    }
    public void startRecord(){
        if(mRecordState!=RecordState.IDLE){
            return;
        }
        mRecordState = RecordState.RECORDING;
        mRecordExecuter.execute(this);

    }
    public void stopRecord(){
        mRecordState = RecordState.IDLE;
        mAudioRecord.stop();
    }

    @Override
    public void run() {
        mAudioRecord.startRecording();
        OutputStream outputStream = null;
        try {
            outputStream = new BufferedOutputStream(new FileOutputStream(mPcmFile));
            byte[] data = new byte[mMinBufferSize];
            while(mRecordState==RecordState.RECORDING){
                int size = mAudioRecord.read(data, 0, mMinBufferSize);
                outputStream.write(data, 0, size);
            }
            outputStream.flush();
            outputStream.close();
            PcmToWav.makePcmFileToWavFile(mPcmFile.getAbsolutePath(), mWavFile.getAbsolutePath(), false);
            Log.i(TAG, "录制完成");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public RecordState getRecordStatus(){
        return mRecordState;
    }
    public String getFileSavePath(){
       return mWavFile.getAbsolutePath();
    }

    enum RecordState{
        IDLE,
        RECORDING
    }
}

 

;