您的位置:首页 > 移动开发 > Android开发

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

2016-01-06 20:50 831 查看
最近由于项目的需要,需要在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实现视频的本地和在线播放的学习笔记(可以进行全屏切换)。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: