I have a simple player and recorder. Everything works great but have one problem. I want to add seek bar to see progress in playing record and use this seek bar to set the place from the player should play. I have onProgress but with no effect. This is the code:
package com.example.recorder;
import java.io.IOException;
import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MainActivity extends Activity implements OnSeekBarChangeListener
{
private static final String LOG_TAG = "AudioRecordTest";
private static String mFileName = null;
private SeekBar seekBar;
private MediaRecorder mRecorder = null;
private Button startRecord, startPlaying, stopPlaying;
private MediaPlayer mPlayer = null;
private void onRecord(boolean start) {
if (start) {
startRecording();
} else {
stopRecording();
}
}
private void startPlaying() {
if(mPlayer != null && mPlayer.isPlaying()){
mPlayer.pause();
} else if(mPlayer != null){
mPlayer.start();
}else{
mPlayer = new MediaPlayer();
try {
mPlayer.setDataSource(mFileName);
mPlayer.prepare();
mPlayer.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
}
}
private void stopPlaying() {
mPlayer.release();
mPlayer = null;
startPlaying.setText("Start playing");
}
private void pausePlaying(){
if(mPlayer.isPlaying()){
mPlayer.pause();
} else {
mPlayer.start();
}
}
private void startRecording() {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
mRecorder.start();
}
private void stopRecording() {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
public MainActivity() {
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
startPlaying = (Button) findViewById(R.id.buttonStartPlay);
stopPlaying = (Button) findViewById(R.id.buttonStopPlaying);
startRecord = (Button) findViewById(R.id.buttonStartRecord);
seekBar = (SeekBar) findViewById(R.id.seekBar);
startRecord.setOnClickListener(new OnClickListener() {
boolean mStartRecording = true;
@Override
public void onClick(View v) {
onRecord(mStartRecording);
if (mStartRecording) {
startRecord.setText("Stop recording");
} else {
startRecord.setText("Start recording");
}
mStartRecording = !mStartRecording;
}
});
startPlaying.setOnClickListener(new OnClickListener() {
boolean mStartPlaying = true;
@Override
public void onClick(View v) {
//onPlay(mStartPlaying);
startPlaying();
if (mStartPlaying) {
startPlaying.setText("Stop playing");
} else {
startPlaying.setText("Start playing");
}
mStartPlaying = !mStartPlaying;
}
});
stopPlaying.setOnClickListener(new OnClickListener() {
boolean mStartPlaying = true;
@Override
public void onClick(View v) {
stopPlaying();
}
});
}
@Override
public void onPause() {
super.onPause();
if (mRecorder != null) {
mRecorder.release();
mRecorder = null;
}
if (mPlayer != null) {
mPlayer.release();
mPlayer = null;
}
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if(fromUser){
mPlayer.seekTo(progress);
seekBar.setProgress(progress);
}
else{
// the event was fired from code and you shouldn't call player.seekTo()
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
Any ideas on how to use seek bar to see progress and set place from the record should play?
To create a 'connection' between SeekBar
and MediaPlayer
you need first to get your current recording max duration and set it to your seek bar.
mSeekBar.setMax(mFileDuration/1000); // where mFileDuration is mMediaPlayer.getDuration();
After you initialise your MediaPlayer
and for example press play button, you should create handler and post runnable so you can update your SeekBar
(in the UI thread
itself) with the current position of your MediaPlayer
like this :
private Handler mHandler = new Handler();
//Make sure you update Seekbar on UI thread
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
if(mMediaPlayer != null){
int mCurrentPosition = mMediaPlayer.getCurrentPosition() / 1000;
mSeekBar.setProgress(mCurrentPosition);
}
mHandler.postDelayed(this, 1000);
}
});
and update that value every second.
If you need to update the MediaPlayer
's position while user drag your SeekBar
you should add OnSeekBarChangeListener
to your SeekBar
and do it there :
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mMediaPlayer != null && fromUser){
mMediaPlayer.seekTo(progress * 1000);
}
}
});
And that should do the trick! : )
EDIT: One thing which I've noticed in your code, don't do :
public MainActivity() {
mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();
mFileName += "/audiorecordtest.3gp";
}
make all initialisations in your onCreate();
, do not create constructors of your Activity
.