I have a simple player and recorder. Everything works great but have a one problem. I want to add seek bar to see progress in playing record and use this seek bar to set place from player should play. I have onProgress but with no effect. This is 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 how use seek bar to see progress and set place from 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();
android.widget.SeekBar. A SeekBar is an extension of ProgressBar that adds a draggable thumb. The user can touch the thumb and drag left or right to set the current progress level or use the arrow keys. Placing focusable widgets to the left or right of a SeekBar is discouraged.
In Android, SeekBar is an extension of ProgressBar that adds a draggable thumb, a user can touch the thumb and drag left or right to set the value for current progress. SeekBar is one of the very useful user interface element in Android that allows the selection of integer values using a natural user interface.
Step1: Create a new project. After that, you will have java and XML file. Step2: Open your xml file and add a SeekBar and TextView for message as shown below, max attribute in SeekBar define the maximum it can take. Assign ID to SeekBar And TextView.
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
.
I've used this tutorial with success, it's really simple to understand: www.androidhive.info/2012/03/android-building-audio-player-tutorial/
This is the interesting part:
/** * Update timer on seekbar * */ public void updateProgressBar() { mHandler.postDelayed(mUpdateTimeTask, 100); } /** * Background Runnable thread * */ private Runnable mUpdateTimeTask = new Runnable() { public void run() { long totalDuration = mp.getDuration(); long currentDuration = mp.getCurrentPosition(); // Displaying Total Duration time songTotalDurationLabel.setText(""+utils.milliSecondsToTimer(totalDuration)); // Displaying time completed playing songCurrentDurationLabel.setText(""+utils.milliSecondsToTimer(currentDuration)); // Updating progress bar int progress = (int)(utils.getProgressPercentage(currentDuration, totalDuration)); //Log.d("Progress", ""+progress); songProgressBar.setProgress(progress); // Running this thread after 100 milliseconds mHandler.postDelayed(this, 100); } }; /** * * */ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) { } /** * When user starts moving the progress handler * */ @Override public void onStartTrackingTouch(SeekBar seekBar) { // remove message Handler from updating progress bar mHandler.removeCallbacks(mUpdateTimeTask); } /** * When user stops moving the progress hanlder * */ @Override public void onStopTrackingTouch(SeekBar seekBar) { mHandler.removeCallbacks(mUpdateTimeTask); int totalDuration = mp.getDuration(); int currentPosition = utils.progressToTimer(seekBar.getProgress(), totalDuration); // forward or backward to certain seconds mp.seekTo(currentPosition); // update timer progress again updateProgressBar(); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With