Android开发之PCM音频采集

通过ijkplayer播放视频,需求:移动端实现实时对讲。即pcm音频录制实时推送到设备端,本篇主要记录pcm音频采集

为保证语音连续性,bufferSize 1m在网不好的情况下可能出现语音时断时续,需要调小bufferSize 到最合适的值


import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.util.Log;

/**
 * Created by idea on 2017/12/11.
 */

public class AudioRecordManager {

    private static AudioRecordManager instance;

    boolean isRecording = false; //true表示正在录音

    AudioRecord audioRecord=null;

    int bufferSize=0;//最小缓冲区大小

    int sampleRateInHz = 8000;//采样率

    int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO; //单声道

    int audioFormat = AudioFormat.ENCODING_PCM_16BIT; //量化位数

    String TAG="AudioRecordManager";

    private AudioRecordManager(){
        //计算最小缓冲区
        bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig, audioFormat);
        bufferSize= bufferSize>320?320:bufferSize;
        audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz,channelConfig, audioFormat, bufferSize);//创建AudioRecorder对象
    }

    public static AudioRecordManager getInstance(){
        if(instance==null){
            synchronized (AudioRecordManager.class){
                if(instance==null){
                    instance = new AudioRecordManager();
                }
            }
        }
        return instance;
    }

    /**
     * 开始音频采集
     * @param onAudioRecordListener
     */
    public void startRecording(OnAudioRecordListener onAudioRecordListener) {
        setOnAudioRecordListener(onAudioRecordListener);

        if(audioRecord==null){
            audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz,channelConfig, audioFormat, bufferSize);//创建AudioRecorder对象
        }

        new Thread(new Runnable() {
            @Override
            public void run() {
                isRecording = true;
                try {
                    byte[] buffer = new byte[bufferSize];
                    audioRecord.startRecording();//开始录音
                    while (isRecording) {
                        int bufferReadResult = audioRecord.read(buffer,0,bufferSize);
                        if(getOnAudioRecordListener()!=null){
                            getOnAudioRecordListener().onVoiceRecord(buffer,bufferReadResult);
                        }
                    }
                    audioRecord.stop();//停止录音
                } catch (Throwable t) {
                    Log.e(TAG, "Recording Failed");
                }
            }
        }).start();
    }

    /**
     * 停止音频采集
     */
    public void stopRecording() {
        isRecording = false;
        setOnAudioRecordListener(null);
    }

    public void onDestroy(){
        audioRecord.release();
        audioRecord = null;
    }

    public interface OnAudioRecordListener{

        /**
         * 采集到的音频信息数据回调到上层,通过IdeaVideoView 传送到设备端
         * @param data
         */
        void onVoiceRecord(byte[] data,int size);

    }

    private OnAudioRecordListener onAudioRecordListener;

    public OnAudioRecordListener getOnAudioRecordListener() {
        return onAudioRecordListener;
    }

    public void setOnAudioRecordListener(OnAudioRecordListener onAudioRecordListener) {
        this.onAudioRecordListener = onAudioRecordListener;
    }
}

调用实例代码块

/**
     * '开始采集音频数据
     */
    public void startRecordVoice() {
        AudioRecordManager.getInstance()
                          .startRecording(new AudioRecordManager.OnAudioRecordListener() {

            @Override
            public void onVoiceRecord(byte[] data, int size) {
                //向ijkplayer发送数据
                playerManager.pushVoice(data, size, new VideoView.OnPushVoiceCallback() {
                    @Override
                    public void onPushVoiceFail() {
                        onError();
                    }
                });
            }
        });
    }


    /**
     * 停止对讲
     */
    private void stopPushVoice() {
        AudioRecordManager.getInstance().stopRecording();
    }

你可能感兴趣的:(Android,Android音视频学习)