美文网首页音视频
Android音视频开发(一):音频录制

Android音视频开发(一):音频录制

作者: JYangkai | 来源:发表于2019-05-09 19:30 被阅读61次

    简介

    Android中,如果要录制音频的话有两个选择,一个是MediaRecorder,另一个就是AudioRecord,前者使用简单,后者就相对复杂点

    关于MediaRecorder的用法相信大家都比较熟悉,而对于AudioRecord可能要陌生一些,所有我们重点来讲下AudioRecord的用法

    声音

    在此之前,我们先来了解下关于声音的知识,下面是来自百度百科的介绍

    声音(sound)是由物体振动产生的声波。是通过介质空气固体液体)传播并能被人或动物听觉器官所感知的波动现象。最初发出振动(震动)的物体叫声源。声音以的形式振动(震动)传播。声音是声波通过任何物质传播形成的运动。

    声音作为一种波,频率在20 Hz~20 kHz之间的声音是可以被人耳识别的。

    从上面所述我们得到一个信息:人耳可以听到20 Hz~20 kHz的声音,那么根据奈奎斯特定律,采样率要大于或等于信号中两倍的最高频率,这样才能完整得保留原始信号中的信息

    也就是说,要一秒钟采样40k次,才能无失帧得记录原始信息

    计算机中记录原始音频,一般是用PCM格式存储,pcm的内容都是byte类型的数组,也就是编码格式

    PCM8位

    如果是单声道,那么byte数组每一个元素都是一次采样的数据
    如果是双声道,那么byte数组就是LRLRLR形式的存储(L代表左耳,R代表右耳)

    PCM16位

    如果是单声道,那么byte数组每两个元素都是一次采样的数据
    如果是双声道,那么byte数组就是L低L高 R低R高 L低L高 R低R高形式的存储(L代表左耳,R代表右耳),低表示低八位,高表示高八位

    综上我们得出关于音频的三个参数

    • 采样率
    • 声道数
    • 编码格式

    创建AudioRecord

    private static final int AUDIO_INPUT = MediaRecorder.AudioSource.MIC;//音频来源
    private static final int AUDIO_SAMPLE_RATE = 44100;//采样率
    private static final int AUDIO_IN_CHANNEL = AudioFormat.CHANNEL_IN_STEREO;//双声道
    private static final int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;//编码格式 PCM 16位
    private int bufferSizeInBytes = 0;//最小录音缓存
    private AudioRecord mAudioRecord;//AudioRecord
    
    public void createDefaultAudio() {
        bufferSizeInBytes = AudioRecord.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_IN_CHANNEL, AUDIO_ENCODING);
        mAudioRecord = new AudioRecord(AUDIO_INPUT, AUDIO_SAMPLE_RATE, AUDIO_IN_CHANNEL, AUDIO_ENCODING, bufferSizeInBytes);
    }
    

    我们创建AudioRecord之前还需要获得一个叫做最小缓存bufferSizeInBytes的东西,它可以通过AudioRecord.getMinBufferSize()方法获取,因为我们录音需要不断去读写,所有需要有一个缓存空间,刚好AudioRecord提供给我们现成的方法,我们直接用就可以了。

    我们创建成功就可以开始录音了,不过要注意,此时你要检查你的应用是否有录音的权限

    录音

    mAudioRecord.startRecording();
    

    开启录音后我们还没做任何事,也就没法将录音保存下来,所有我们得开启一个子线程将数据写入文件

    开启录音线程

    /**
     * 开启录制音频子线程
     */
    private void startRecordThread() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                writeDataToFile();
            }
        }).start();
    }
    
    /**
     * 将录音内容写入文件
     */
    private void writeDataToFile() {
        byte[] audioData = new byte[bufferSizeInBytes];
        FileOutputStream fos = null;
        int readSize = 0;
        try {
            File file = new File("你的文件路径");
            if (file.exists()) {
                file.delete();
            }
            fos = new FileOutputStream("你的文件路径", true);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        while (!isStop) {
            readSize = mAudioRecord.read(audioData, 0, bufferSizeInBytes);
            if (readSize == AudioRecord.ERROR_INVALID_OPERATION || readSize == AudioRecord.ERROR_BAD_VALUE) {
                continue;
            }
            if (fos != null) {
                try {
                    fos.write(audioData);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            if (fos != null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    我们这个线程有一个无线循环的while,在while里我们进行数据的读写,我们可以定义一个boolean变量isStop来控制录音的停止

    我们先是新建了一个byte数组
    byte[] audioData = new byte[bufferSizeInBytes]
    这个数组大小就是之前我们获取到的最小缓存

    接着我们打开文件,进行读写,通过mAudioRecord.read()方法不断从AudioRecord中读取数据,然后将其写入文件中,最后在我们停止之后关闭文件的输出流。

    停止录音

    /**
     * 停止录音
     */
    private void stop(){
        mAudioRecord.stop();
        isStop = ture;
    }
    

    停止录音就调用AudioRecordstop()方法并将isStop置为ture即可停止录音

    最后

    以上就是AudioRecord的基本用法,关于音频的更多知识与应用后面会陆续和大家分享,希望大家能够喜欢。

    相关文章

      网友评论

        本文标题:Android音视频开发(一):音频录制

        本文链接:https://www.haomeiwen.com/subject/tmhwoqtx.html