安卓音视频开发(2)—— AudioRecord采集pcm音频

安卓SDK提供了两种音频采集的api,MediaRecorder和AudioRecord,相较于前者,后者更接近底层,能够更加灵活的控制。我们学习音视频开发,都是直接对原始的pcm音频进处理包括降噪、增益等。

所需权限

权限的申请自行解决。

 <uses-permission android:name="android.permission.RECORD_AUDIO"/> 
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

AudioRecord参数

  • audioSource:音频输入源,通常为MediaRecorder.AudioSource.MIC(麦克风),此外还有VOICE_CALL、CAMCORDER等等,这里不一一赘述。

  • sampleRateInHz:采样率,目前44100Hz可以保证兼容所有的手机。

  • channelConfig:通道数,同上为了兼容性一般为AudioFormat.CHANNEL_IN_MONO(单通道)。

  • audioFormat:数据位宽,常用16bit可以兼容所有android手机。

  • bufferSizeInBytes:缓冲区大小,这个根据 采样率x位宽x采样时间x通道数 计算得来。

    // 音频输入-麦克风
    private final static int AUDIO_INPUT = MediaRecorder.AudioSource.MIC;
    //8K采集率
    private final static int AUDIO_SAMPLE_RATE = 8000;
    //格式
    private final static int CHANNEL_CONFIG = AudioFormat.CHANNEL_IN_MONO;
    //16Bit
    private final static int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
    // 缓冲区字节大小
    private int bufferSizeInBytes = 1600;

音频录制流程

1.初始化AudioRecord对象,注意其最小录音缓存buffer,可以使用getMinBufferSize得到。

    public void init(Context context) {
        //检查权限
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO)
                != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        audioRecord = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE,
                CHANNEL_CONFIG, AUDIO_FORMAT, bufferSizeInBytes);
        LogUtils.i("初始化成功");
    }

2.初始化一个buffer(用于保存新的录音数据),其大小等于第一步中的缓存buffer大小。

        byte[] audiodata = new byte[bufferSizeInBytes];

3.开始录音,通常另起线程,创建数据流,同时设置正在录音标志flag来控制停止录音。

4.开始采集,一边从AudioRecord读取声音数据,一边将buffer写入数据流。

5.停止录音,将录音标志置为false,关闭数据流。

    public void start() {
        if (isRecord) {
            LogUtils.i("正在录音");
            return;
        }
        LogUtils.i("开始录音");
        isRecord = true;
        audioRecord.startRecording();
        audioHandle = new Thread(() -> saveFile());
        audioHandle.start();
    } 

    private void saveFile() {
        byte[] audiodata = new byte[bufferSizeInBytes];
        FileOutputStream fos = null;
        try {
            File file = new File(filePath);
            if (file.exists()) {
                file.delete();
            }
            fos = new FileOutputStream(file);
        } catch (Exception e) {
            e.printStackTrace();
        }

        while (isRecord) {
            int readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
            if (fos != null) {
                try {
                    fos.write(audiodata);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        try {
            if (fos != null) {
                fos.close();// 关闭写入流
            }
        } catch (IOException e) {

        }
    } 

    public void stop() {
        isRecord = false;
        LogUtils.i("停止录音");
    }

6.释放资源。

    public void release() {
        if (audioRecord != null) {
            isRecord = false;
            audioRecord.release();
            audioRecord = null;
            audioHandle.interrupt();
            audioHandle = null;
            LogUtils.i("释放");
        }
    }

结语

录制是否成功,可以去对应的文件目录下查看是否有相应的pcm文件,下节讲述pcm文件的播放。

本期博客参考:

灰色飘零博客园

你的阿爸博客

需要源码的盆友也可以访问我的gitlub,我的gitlub源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值