Android 音视频之音频录制

Android提供了两个API用于实现录音功能:AudioRecord、MediaRecorder。

AudioRecord

    AudioRecord与MediaRecorder一样用来录制音频的。相对于MediaRecorder来说,AudioRecorder 录音时直接操纵硬件实时获取音频流数据,可以对录制的数据进行实时的处理,比如降噪,除杂,或者将音频进行实时传输,比如IP电话,对讲功能等操作。同时也可实现暂停功能。
    AudioRecord通过设置不同的采样率,采样位数,声道数,"拉"取不同的音质流,我们可以查看Android官方的API来查看他的初始化方法。
    因为AudioRecord比MediaRecorder更接近底层,录制的音频是PCM格式的,最接近原始声音的音频数据。只能用AudioTraker进行播放,或者可以将PCM数据用算法进行压缩编码后,转换成mp3等格式播放。
    AudioRecord的使用还算简单,没有太多复杂的方法,下面就是代码样例。

    // 音频获取源
    private int audioSource = MediaRecorder.AudioSource.MIC;
    // 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025
    private static int sampleRateInHz = 44100;
    // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道
    private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
    // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。
    private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    // 缓冲区字节大小
    private int bufferSizeInBytes = 0;
    private AudioRecord audioRecord;
    // 设置正在录制的状态
    private boolean isRecord = false;
    //AudioName裸音频数据文件
    private static final String AudioName = "/sdcard/love.pcm";//不推荐这么写,可以用Enviroment.

    private void creatAudioRecord() {
        // 获得缓冲区字节大小
        bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,
                channelConfig, audioFormat);
        // 创建AudioRecord对象
        audioRecord = new AudioRecord(audioSource, sampleRateInHz,
                channelConfig, audioFormat, bufferSizeInBytes);
    }

    public void startRecord() {
        if (!isRecord) {
             // 让录制状态为true
             isRecord = true;
             //开始录制
             audioRecord.startRecording();
             // 开启音频文件写入线程
             new Thread(new AudioRecordThread()).start();
        }
    }

    public void stopRecord() {
        if (audioRecord != null) {
            if (isRecord) {
                //停止文件写入
                isRecord = false;
                //停止录制
                audioRecord.stop();
                //释放资源
                audioRecord.release();
            }
        }
    }

    private class AudioRecordThread implements Runnable {
        @Override
        public void run() {
            //往文件中写入裸数据
            writeDateTOFile();
        }
    }

    /**
     * 这里将数据写入文件,但是并不能播放,因为AudioRecord获得的音频是原始的裸音频,
     * 如果需要播放就必须加入一些格式或者编码的头信息。但是这样的好处就是你可以对音频的 裸数据进行处理,比如你要做一个爱说话的TOM
     * 猫在这里就进行音频的处理,然后重新封装 所以说这样得到的音频比较容易做一些音频的处理。
     */
    private void writeDateTOFile() {
        // new一个byte数组用来存一些字节数据,大小为缓冲区大小
        byte[] audiodata = new byte[bufferSizeInBytes];
        FileOutputStream fos = null;
        int readsize = 0;
        try {
            File file = new File(AudioName);
            if (file.exists()) {
                file.delete();
            }
            fos = new FileOutputStream(file);// 建立一个可存取字节的文件
        } catch (Exception e) {
            e.printStackTrace();
        }
        while (isRecord) {
            readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);
            if (AudioRecord.ERROR_INVALID_OPERATION != readsize) {
                try {
                    fos.write(audiodata);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        try {
            fos.close();// 关闭写入流
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

下面是Android所支持的音频源:

/**默认声音**/
public static final int DEFAULT = 0;
/**麦克风声音*/
public static final int MIC = 1;
/**通话上行声音*/
public static final int VOICE_UPLINK = 2;
/**通话下行声音*/
public static final int VOICE_DOWNLINK = 3;
/**通话上下行声音*/
public static final int VOICE_CALL = 4;
/**根据摄像头转向选择麦克风*/
public static final int CAMCORDER = 5;
/**对麦克风声音进行声音识别,然后进行录制*/
public static final int VOICE_RECOGNITION = 6;
/**对麦克风中类似ip通话的交流声音进行识别,默认会开启回声消除和自动增益*/
public static final int VOICE_COMMUNICATION = 7;
/**录制系统内置声音*/
public static final int REMOTE_SUBMIX = 8;

MediaRecorder

    MediaRecorder已经集成了录音、编码、压缩等,支持少量的录音音频格式。大部分已经集成,直接调用相关接口即可,代码量小。
    如下面代码样例,录制的m4a文件可以直接播放,并且录制一分钟的音频,只有100KB大小,相对于AudioRecord录制的原始音频,1分钟需要10.34MB的大小,已经被压缩很多了。

// 音频获取源
    private int audioSource = MediaRecorder.AudioSource.MIC;
    // 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025
    private static int sampleRateInHz = 44100;
    // 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道
    private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
    // 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。
    private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
    private MediaRecorder mRecorder;
    //AudioName裸音频数据文件
    private static final String AudioName = "/sdcard/MRecord.m4a";//不推荐这么写,可以用Enviroment.

    public void startRecord() {
        try {
            // 创建AudioRecord对象
            mRecorder = new MediaRecorder();
            // 设置录音的声音来源
            mRecorder.setAudioSource(audioSource);
            // 设置录制的声音的输出格式(必须在设置声音编码格式之前设置)
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            // 设置声音编码格式
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
            //所有android系统都支持的适中采样的频率
            mRecorder.setAudioSamplingRate(sampleRateInHz);
            File file = new File(AudioName);
            if (file.exists()) {
                file.delete();
            }
            mRecorder.setOutputFile(file.getAbsolutePath());

            mRecorder.prepare();

            // 开始录音
            mRecorder.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stopRecord() {
        if (mRecorder != null) {
            mRecorder.stop();
            mRecorder.release();//释放资源
            mRecorder = null;
        }
    }

权限申请

注意:由于该程序需要使用系统的麦克风进行录音,因此还需要在清单文件AndroidManifest.xml文件中授权相应的权限:





github项目地址

未完待更新...

上一篇:Android 音视频之音频编码

有问题的地方请大家帮忙指出,谢谢。
持续更新中...

你可能感兴趣的:(Android 音视频之音频录制)