Android使用系统自带的audioreorder和mediaplayer进行录音和播放,外加进度条的滚动!

最近由于项目的需要,需要在app中做一个小的录音模块,在录完音后可以进行播放,由于是新手,做的时候遇到了很多的问题,下面就将我写的demo记下来,作为笔记,希望对大家有点帮助!


一.首先是Mediarecorder的部分进行录音:

1.按照google文档的对录音进行初始设置,代码如下:

    private void startRecorder() {

        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        try {
            recAudioFile = Utils.createImageFile(this,".amr");
            if (!recAudioFile.exists()) {
                recAudioFile.mkdirs();
            }
            mMediaRecorder.setOutputFile(recAudioFile.getAbsolutePath());
            mMediaRecorder.prepare();
            mMediaRecorder.start();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
这段代码当中的createImageFile是一个更具时间戳进行命名的字符串生成工具,为的是录制的音频文件名不冲突(这个方法来至google待用系统相机,大家可以去查看下!)。

2.调用上面的代码就可以进行录音了,接下来就是停止录音的代码:

    private void stopRecorder() {
        if (recAudioFile != null && mMediaRecorder != null) {
            mMediaRecorder.stop();
            mMediaRecorder.release();
        }
    }
这段代码就相对简单了,调用此方法我们录的文件就被保存下来了!

3.接下就是我想说的了,就是在录音的过程中实现时间的滚动:

由于mediarecorder里面没有对录音的时间有一个接口回调,我们不能直接实现时间的改变,所以就需要我们写一个子线程,在开始的录音的时候通过handler不断向主线程中发送message来改变时间。

    private class UpdateThread extends Thread {

        @Override
        public void run() {
            while (isRecording) {
                try {
                    new Thread().sleep(THREAD_DELAYED);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.sendEmptyMessage(UPDATE_TIME_RECORD);
            }
        }
    }
这里我们通过一个标志位来执行线程,isRecorder在录音开始的时候置为true;THREAD_DELAYED是我们间隔多久发一次消息,测试后我设置为100,效果比较理想。

接下来我贴出的就是主线程中处理handler发送来消息的代码,这里面包括了我后面要说的播放录音的代码:

   private class MHandler extends Handler {

        SimpleDateFormat format = new SimpleDateFormat("mm:ss");

        @Override
        public void handleMessage(Message msg) {
            try {
                switch (msg.what) {

                    case UPDATE_TIME_RECORD:
                        long currentTimeMillis = System.currentTimeMillis();
                        String time = format.format(currentTimeMillis - start_time);
                        record_durationTV.setText(time);
                        break;

                    case UPDATE_TIME_PLAY:
                        UpdateTimeing playThread = new UpdateTimeing();
                        playThread.start();
                        break;

                    case UPDATE_PB_PLAY:
                        int position = mMediaPlayer.getCurrentPosition();
                        record_playPB.setProgress(position);
                        record_total.setText(format.format(mMediaPlayer.getDuration()));
                        record_current.setText(format.format(position) + "/");
                        break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

二.接下来就是mediaplayer,对录音文件进行播放了:

1.同样的,首先我们对mediaplayer进行初始化:

    private void mediaPlayMode(String audioPath) {

        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            mMediaPlayer.setDataSource(audioPath);
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            isPlaying = true;

            handler.sendEmptyMessage(UPDATE_TIME_PLAY);
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    record_pasueIB.setBackgroundResource(R.drawable.selector_video_play);
                    isPlaying = false;
                    isFinish = true;
                    handler.removeMessages(UPDATE_TIME_PLAY);
                }
            });
            record_playPB.setMax(mMediaPlayer.getDuration());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
这里的代码和上面差不多,都是按照google的文档进行写的,值得注意的就是handler.removeMessage()这个方法,当我们在播放的过程中点击退出的时候,由于主线handlerMessager中还有代码需要mediaplaer的引用,但是在activity的destory方法中,我们已经将mediaplayer对象释放掉,所以会出现空指针的情况。

2.然后就是跟新进度条的线程代码:

    private class UpdateTimeing extends Thread {
        @Override
        public void run() {
            while (isPlaying) {
                try {
                    new Thread().sleep(THREAD_DELAYED);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                handler.sendEmptyMessage(UPDATE_PB_PLAY);
            }
        }
    }

由于是第一次写学习笔记博客,有不足的地方希望大家指正,以后多多改进,有需要源码的同学可以私信我,下次准备写一篇使用meidaplayer加sufaceview实现视频的本地和在线播放的学习笔记(可以进行全屏切换)。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值