Android录音功能实现

实现录音功能:

public class MainActivity extends AppCompatActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initAudioRecordBtn();
    }
    
    //Mic audio record function
    private static final int PLAY_END = 1;
    private static final int RECORD_END = 2;
    private TextView mRecordTimeTv;
    private Button mStartRecordBtn;
    private Button mPlayBtn;
    private String mFileName = null;// 存储录音文件的路径

    private AudioRecord mAudioRecord;
    private volatile boolean mIsRecording = false;
    private AudioFormat.Builder mAudioFormat;
    private AudioAttributes mPlaybackAttributes;
    private boolean mIsPlay;
    private AudioTrack mAudio = null;
    private RecorderHandler mHandler;

    private class RecorderHandler extends Handler {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case PLAY_END:
                    stopPlayBack();
                    mPlayBtn.setText("播放录音");
                    mStartRecordBtn.setEnabled(true);
                    mIsPlay = false;
                    break;
                case RECORD_END:
                    mRecordTimeTv.setText("");
                    mAudioRecord.stop();
                    mStartRecordBtn.setText("开始录音");
                    mPlayBtn.setEnabled(true);
                    mIsRecording = false;
                    mTimer.cancel();
                    break;
                default:
                    break;
            }
        }
    }

    private CountDownTimer mTimer = new CountDownTimer(30 * 1000, 1000) {
        @Override
        public void onTick(long millisUntilFinished) {
            long time = (30 * 1000 - millisUntilFinished) / 1000;
            mRecordTimeTv.setText(String.format("00:%s", time < 10 ? "0" + time : time));
        }

        @Override
        public void onFinish() {
            mHandler.sendEmptyMessage(RECORD_END);
        }
    };

    private void initAudioRecordBtn() {
        mRecordTimeTv = findViewById(R.id.audio_record_time);
        mStartRecordBtn = findViewById(R.id.audio_record_start);
        mPlayBtn = findViewById(R.id.audio_record_play);
    }

    public String getSDPath() {
        String path = null;
        boolean sdCardExist = Environment.getExternalStorageState()
                .equals(Environment.MEDIA_MOUNTED);
        if (sdCardExist) {
            path = Environment.getExternalStorageDirectory().getAbsolutePath();
        } else {

        }
        return path;
    }

    private void setListener() {
        // 开始录音
        mStartRecordBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mAudioRecord == null || mAudioRecord.getState() == AudioRecord.STATE_UNINITIALIZED) {
                    return;
                }

                if (!mIsRecording) {
                    mIsRecording = true;
                    mStartRecordBtn.setText("结束录音");
                    mPlayBtn.setEnabled(false);
                    new Thread() {
                        @Override
                        public void run() {
                            super.run();
                            mTimer.start();
                            writeAudioDataToFile();
                        }
                    }.start();
                } else {
                    mHandler.sendEmptyMessage(RECORD_END);
                }
            }

        });

        // 播放录音
        mPlayBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //play();
                // return;
                //   String name = pcm2();

                if (mIsPlay) {
                    stopPlayBack();
                    mPlayBtn.setText("播放录音");
                    mStartRecordBtn.setEnabled(true);
                    mIsPlay = false;
                } else {
                    mIsPlay = true;
                    mPlayBtn.setText("停止播放");
                    mStartRecordBtn.setEnabled(false);
                    new Thread() {
                        @Override
                        public void run() {
                            super.run();
                            playBackNow();
                        }
                    }.start();
                }

            }
        });

    }


    public void stopPlayBack() {
        if (mAudio != null && mIsPlay && mAudio.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
            mAudio.stop();
        }
    }

    public void playBackNow() {
        int length = 0;
        Log.d(TAG, " before mAudio track");

        mPlaybackAttributes = new AudioAttributes.Builder()
                // .setUsage(AudioAttributes.USAGE_ASSISTANT)
                .setUsage(AudioAttributes.USAGE_MEDIA)
                // .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE)
                .build();
        mAudioFormat = new AudioFormat.Builder();
//        mAudioFormat.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO);
        mAudioFormat.setChannelMask(AudioFormat.CHANNEL_OUT_STEREO); //CHANNEL_IN_STEREO
        mAudioFormat.setSampleRate(32000);
        mAudioFormat.setEncoding(AudioFormat.ENCODING_PCM_16BIT);

        //  int bufferSize = AudioRecord.getMinBufferSize(64000, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);

        if (mAudio == null) {
            mAudio = new AudioTrack(mPlaybackAttributes, // attributes
                    // AudioManager.STREAM_TTS,
                    //48000, // sample rate
                    mAudioFormat.build(),
                    AudioTrack.getMinBufferSize(32000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT) * 2,
                    AudioTrack.MODE_STREAM,
                    AudioManager.AUDIO_SESSION_ID_GENERATE
            );
        }
        Log.d(TAG, " after mAudio track");
        Log.d(TAG, "bufrer size:" + AudioTrack.getMinBufferSize(32000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT));

        FileInputStream fis = null;
        try {
            Log.d(TAG, " get stream in");
//            fis = new FileInputStream(getSDPath()+"/20190525_035557voice.pcm");
            Log.d(TAG, "PALY - > " + mFileName);
            fis = new FileInputStream(mFileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        try {
            length = fis.available();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Log.d(TAG, "wav file readlen_1:" + length);
        byte buffer[] = new byte[length];

        try {
            while (fis.available() > 0) {
                length = fis.read(buffer);
                if (length == AudioTrack.ERROR_INVALID_OPERATION || length == AudioTrack.ERROR_BAD_VALUE) {
                    continue;
                }
                if (length != 0 && length != -1) {
                    mAudio.play();
                    mAudio.write(buffer, 0, length);
                }
                Log.d(TAG, "play length --> " + length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        mHandler.sendEmptyMessage(PLAY_END);

        try {
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void setBtnAudioRecord() {
        int bufferSize = AudioRecord.getMinBufferSize(64000, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
        final AudioFormat audioFormat = new AudioFormat.Builder()
                .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
                .setSampleRate(64000)
                .setChannelMask(AudioFormat.CHANNEL_IN_STEREO)
                .build();

        mAudioRecord = new AudioRecord.Builder()
                .setAudioSource(MediaRecorder.AudioSource.MIC)
                .setBufferSizeInBytes(bufferSize)
                .setAudioFormat(audioFormat)
                .build();
        Log.d(TAG, "record bufferSize=(" + bufferSize + ")");
    }

    @Override
    public void onStart() {
        super.onStart();
        mHandler = new RecorderHandler();

        Log.d(TAG, "start --");
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mAudioRecord == null) {
            setBtnAudioRecord();
        }
        mPlayBtn.setEnabled(false);
        setListener();
        Log.d(TAG, "onResume --");
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.d(TAG, "stop --");

        if (mTimer != null) {
            mTimer.cancel();
        }

        if (mAudioRecord != null && mAudioRecord.getState() == AudioRecord.STATE_INITIALIZED) {
            mAudioRecord.stop();
            mAudioRecord.release();
            mAudioRecord = null;
        }

        mStartRecordBtn.setText("开始录音");
        mPlayBtn.setEnabled(true);
        mIsRecording = false;
        mRecordTimeTv.setText("");

        if (mAudio != null) {
            if (mAudio.getPlayState() == AudioTrack.PLAYSTATE_PLAYING) {
                mAudio.stop();
            }
            mAudio.release();
            mAudio = null;
        }
    }

    /**
     * write sound file
     */
    private void writeAudioDataToFile() {
        int bytesRecord = 0;
        String filePath = getSDPath() + "/" + new SimpleDateFormat("yyyyMMdd_hhmmss").format(new Date()) + "voice.pcm";
        mFileName = filePath;
        File file = new File(filePath);
        if (file.exists()) {

        } else {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        int bufferSize = AudioRecord.getMinBufferSize(64000, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
        //int bufferSize = AudioRecord.getMinBufferSize(128000, AudioFormat.CHANNEL_IN_STEREO,  AudioFormat.ENCODING_PCM_16BIT);
        Log.d(TAG, "record bufferSize=(" + bufferSize + ")");
        byte[] tempBuffer = new byte[bufferSize];
        OutputStream os = null;

        try {
            os = new FileOutputStream(filePath);
            Log.d(TAG, "after recorder create file");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        mAudioRecord.startRecording();

        while (mIsRecording) {
            // gets the voice output from microphone to byte format
            bytesRecord = mAudioRecord.read(tempBuffer, 0, bufferSize);
            Log.d(TAG, "record byte=(" + bytesRecord + ")");
            if (bytesRecord == AudioRecord.ERROR_INVALID_OPERATION || bytesRecord == AudioRecord.ERROR_BAD_VALUE) {
                Log.d(TAG, " Audio record read err");
            }
            if (bytesRecord != 0 && bytesRecord != -1) {
                try {
                    os.write(splitStereoPcm(tempBuffer), 0, bytesRecord / 2);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                Log.d(TAG, "$$$record byte=0");
            }
        }

        Log.d(TAG, "after writer record");
        try {
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private byte[] splitStereoPcm(byte[] data) {
        int monoLength = data.length / 2;
        byte[] pcmData = new byte[monoLength];
        for (int i = 0; i < monoLength; i++) {
            if (i % 2 == 0) {
                System.arraycopy(data, i * 2, pcmData, i, 2);
            } else {
                System.arraycopy(data, i * 2, pcmData, i - 1, 2);
            }
        }
        return pcmData;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunxiaolin2016

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值