I have listview with layout for playing audio.in that layout i have seekbar and play/pause button when i click on play button media file is played but seekbar not updating I also user Runnable and handler but it not works.
I am doing this in baseadapter inside getview method.
Please help me to sort out this
mAudioViewHolder.play.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String yofile = "file://" + filepath;
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(yofile);
} catch (IllegalArgumentException | SecurityException | IllegalStateException | IOException e) {
// TODO Auto-generated catch block
Log.e("Node", "ERRORSS Part 1 is" + e);
mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
mAudioViewHolder.isPlaying = false;
/**
* since audio is stop playing, remove its position value
* */
playingAudioPosition = -1;
}
});
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Node", "ERRORSS is Part 2 " + e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Node", "ERRORSS is Part 3 " + e);
} // might take long! (for buffering, etc)
mediaPlayer.start();
mAudioViewHolder.progressBar.setMax(mediaPlayer.getDuration());
Runnable mRunnable = new Runnable() {
#Override
public void run() {
if (mediaPlayer != null) {
int mCurrentPosition = mediaPlayer.getCurrentPosition() / 1000;
mAudioViewHolder.progressBar.setProgress(mCurrentPosition);
Log.d("Node", "get current position " + mCurrentPosition);
}
}
};
Log.d("Node", "StartTime Updation " + mediaPlayer.getDuration() + " " + mediaPlayer.getCurrentPosition());
mHandler.postDelayed(mRunnable, 1000);
//mAudioViewHolder.isPlaying = false;
}
You are calling your runnable only once, when you need to call it every time you want to update your progress bar.
You can do this
Runnable mRunnable = new Runnable() {
#Override
public void run() {
if(mediaPlayer != null){
int mCurrentPosition = mediaPlayer.getCurrentPosition() / 1000;
mAudioViewHolder.progressBar.setProgress(mCurrentPosition);
Log.d("Node", "get current position "+mCurrentPosition);
mHandler.postDelayed(this, 1000);
}
}
};
Log.d("Node", "StartTime Updation "+mediaPlayer.getDuration()+" "+mediaPlayer.getCurrentPosition());
mHandler.postDelayed(mRunnable, 1000);
Make sure you remove the runnable from the handler when you stop the playback.
mHandler.removeCallbacks(mRunnable);
Related
I'm trying to figure out how to delay an audio file by about 15 seconds. The audio file is 5 seconds long and it's a sound effect saying "5,4,3,2,1 go!", the countdown is from 20 so it should start after 15 seconds. I heard I can do this with a handler but I don't know how to implement it in the code, so here it is, help would be much appreciated!
I edited it with the way below, however now the player doesn't start at all, here's the new code:
public class WorkoutGymEasy1 extends Activity {
CountDownTimer cdt = null;
MediaPlayer mp;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.workout_gym_easy1);
RelativeLayout rl5 = (RelativeLayout) findViewById(R.id.rl5);
rl5.setBackgroundColor(Color.BLACK);
mp = MediaPlayer.create(WorkoutGymEasy1.this, R.raw.countdown);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new CountDownTimer(20000, 1000) { //20 seconds count down with 1s interval (1000 ms)
TextView c = (TextView) findViewById(R.id.timer_gym_easy1); //access TextView element on the screen to set the timer value
public void onTick(long millisUntilFinished) { // Code in this method is executed every 1000ms (1s)
c.setText("" + ((millisUntilFinished / 1000) - 1) + ""); //update the timer
if(millisUntilFinished == 9000) {
mp.start();
}
}
#Override
public void onFinish() {
// TODO Auto-generated method stub
c.setText("GO!");
Intent myIntent = new Intent(getApplicationContext(), WorkoutGymEasy2.class);
startActivity(myIntent);
finish(); // call finish() method to destroy this activity and return to instructions screen
}
}.start();
}
protected void OnPause() {
super.onPause();
mp.release();
finish();
}
}
Don't start playing the audio in onCreate(). Remove mp.start() from onCreate().
mp = MediaPlayer.create(WorkoutGymEasy1.this, R.raw.countdown);
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Play the audio in onTick(). The CountDownTimer is not precise, it will return as close to 1 second as it can. It will never be 20000, 19000... etc. As an optimization you can round the millisUntilFinished on each onTick() and do a simple check to see if you should play the audio or not.
public void onTick(long millisUntilFinished) { // Code in this method is executed every 1000ms (1s)
c.setText("" + ((millisUntilFinished / 1000) - 1) + ""); //update the timer
if(Math.round((float)millisUntilFinished / 1000.0f) == 5) {
mp.start();
}
}
I am trying to update seekbar with respect to the progress of the song in MediaPlayer.
I am using Thread to do that task.
First i have used Thred inside thread and trying to update the UI but it crashing the app and says that only original thread can attached to the view.
Then i have try to update it with handler inside the thread runnable. which works fine but it is not updating the seekbar. When i have do log then i come to know loop is not going inside my handler. I dont know where is the problem. Please help me to updating SeekBar.
Code:
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
try {
if ((musicPath != mIRemoteService.getPath())) {
System.out.println("..... MUSIC CHANGE.....");
setOrUpdateData();
updateFragmentLayout();
}
// Displaying Current Duration time/Progress
new Handler().post(new Runnable() {
#Override
public void run() {
try {
songCurrentDurationLabel.setText(""+ Utilities.milliSecondsToTimer(mIRemoteService.position()));
songProgressBar.setProgress((int)mIRemoteService.position());
System.out.println("Runnnnn.........");
//songProgressBar.invalidate();
} catch (RemoteException e) {
e.printStackTrace();
System.out.println("Runnnnn......... EXCEPTION....");
}
}
});
System.out.println("Runnnnn.........MAIN....");
if (!(mIRemoteService.isPlayerRunning())) {
btnPlay.setImageDrawable(getResources().getDrawable(R.drawable.play_now_playing));
mHandler.removeCallbacks(mUpdateTimeTask);
System.out.println("Runnnnn.........MAIN....IF");
}else{
System.out.println("Runnnnn.........MAIN....ELSE");
mHandler.post(mUpdateTimeTask);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
you can use either a handler or a thread, with thread you should make sure to post the modifications on the UI thread:
private class UpdateSeekBar extends Thread
{
#Override
public void run()
{
super.run();
while (null != mp && mp.isPlaying() && this.isAlive())
{
//final int min = (mp.getCurrentPosition() / 1000) / 60;
//final int sec = (mp.getCurrentPosition() / 1000) % 60;
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
try
{
songCurrentDurationLabel.setText("" + Utilities.milliSecondsToTimer(mIRemoteService.position()));
songProgressBar.setProgress((int) mIRemoteService.position());
System.out.println("Runnnnn.........");
// songProgressBar.invalidate();
}
catch (RemoteException e)
{
e.printStackTrace();
System.out.println("Runnnnn......... EXCEPTION....");
}
}
});
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
i am developing Call recording application. i am managed to show the audio files in ListView and able to play in MediaPlayer. know i am having a problem in SeekBar Handler. when i play the audio file, the MediaPlayer and SeekBar works absolutely right but when i close my application the Handler of SeekBar remains active. how can i stop the Handler.
private void playSong(String string)
throws IllegalArgumentException, SecurityException,
IllegalStateException, IOException {
// seekBar
setContentView(R.layout.dialog_activity);
startButton = (Button) findViewById(R.id.play_button);
stopButton = (Button) findViewById(R.id.pause_button);
seekBar = (SeekBar) findViewById(R.id.seek_bar);
startButton.setOnClickListener(MainActivity.this);
stopButton.setOnClickListener(MainActivity.this);
// MediaPlayer
mp.reset();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
mp.setDataSource(string);
mp.prepare();
mp.start();
seekBar.setMax(mp.getDuration());
try {
seekUpdation();
} catch (Exception e) {
Toast.makeText(MainActivity.this,
"SeekUpdation " + e.toString(), Toast.LENGTH_SHORT)
.show();
}
}
Runnable run = new Runnable() {
#Override
public void run() {
try {
seekUpdation();
} catch (Exception e) {
Log.d("Runnable ", "error in Runnable =" + e.toString());
}
}
};
thats the Handler who remain active after closing the application.
public void seekUpdation() {
seekBar.setProgress(mp.getCurrentPosition());
seekHandler.postDelayed(run, 1000);
Toast.makeText(MainActivity.this, "Uploaded" + seekHandler,
Toast.LENGTH_SHORT).show();
}
});
}
i found the answer by my self.
we have to change the code from this
Runnable run = new Runnable() {
#Override
public void run() {
try {
seekUpdation();
} catch (Exception e) {
Log.d("Runnable ", "error in Runnable =" + e.toString());
}
}
};
public void seekUpdation() {
seekBar.setProgress(mp.getCurrentPosition());
seekHandler.postDelayed(run, 1000);
Toast.makeText(MainActivity.this, "Uploaded" + seekHandler,
Toast.LENGTH_SHORT).show();
}
});
}
to this
Runnable run = new Runnable() {
public void run() {
seekBar.setProgress(mp.getCurrentPosition());
seekHandler.postDelayed(this, 1000);
}
};
private void seekUpdation() {
seekBar.setProgress(mp.getCurrentPosition());
seekHandler.postDelayed(run, 1000);
Toast.makeText(MainActivity.this, "Uploaded" + seekHandler,
Toast.LENGTH_SHORT).show();
}
Am trying to play a .wav file using media-player. Actually, I had done so far shown below. It's playing an updating the progress correctly but the problem media player is not seeking completely. Media-player stops giving out progress before the total duration of the file and stops updating progress. I have also implemented OnComplete listener also am not getting the callback. Here is my code can anyone spot me with where am missing.
public void playAudioFile() {
try {
mMediaPlayer.reset();
setMediaPlayerSource();
mMediaPlayer.prepare();
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer arg0) {
Graphbar.setProgress(mMediaPlayer.getDuration());
}
});
bPlay.setBackgroundResource(R.drawable.pause_selector);
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Playing");
updateProgressBar();
}
}).start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void updateProgressBar() {
Graphbar.setProgress(0);
Graphbar.setMax(mMediaPlayer.getDuration());
mHandler.postDelayed(mUpdateTimeTask, 0);
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if(mMediaPlayer.isPlaying()){
long totalDuration = Graphbar.getMax();
long currentDuration =mMediaPlayer.getCurrentPosition();
String TotalDur = Utilities.milliSecondsToTimer(totalDuration);
tvTimeRight.setText(TotalDur);
tvTimeLeft.setText(""+ Utilities.milliSecondsToTimer(currentDuration));
System.out.println(currentDuration+"/"+totalDuration);
Graphbar.setProgress((int)currentDuration);
mHandler.postDelayed(this, 1);
}
}
};
private void setMediaPlayerSource() {
String audioFile = getFilename();
try {
mMediaPlayer.setDataSource(audioFile);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
for total duration use mediaplayer.getduration. Remove unnecessary code from the runnable handler , because it will create load to ur seek bar . Because at every second u are calculating something and updating layout based on that calculation .
I would suggest you to use chronometer view of android.
public void playAudioFile() {
try {
mMediaPlayer.reset();
setMediaPlayerSource();
mMediaPlayer.prepare();
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer arg0) {
Graphbar.setProgress(mMediaPlayer.getDuration());
}
});
bPlay.setBackgroundResource(R.drawable.pause_selector);
//set this only for once , because for one song total duration is always constant.
updateProgressBar();
}
public void updateProgressBar() {
Graphbar.setProgress(0);
Graphbar.setMax(mMediaPlayer.getDuration());
mHandler.postDelayed(mUpdateTimeTask, 0);
long totalDuration = mMediaPlayer.getDuration();
String TotalDur = Utilities.milliSecondsToTimer(totalDuration);
tvTimeRight.setText(TotalDur);
}
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if(mMediaPlayer.isPlaying()){
//long totalDuration = mMediaPlayer.getDuration();=> no need of calculating total time and updating it to seekbar at every second
long currentDuration =mMediaPlayer.getCurrentPosition();
tvTimeLeft.setText(""+ Utilities.milliSecondsToTimer(currentDuration));
System.out.println(currentDuration+"/"+totalDuration);
Graphbar.setProgress((int)currentDuration);
mHandler.postDelayed(this, 1);
}
}
};
private void setMediaPlayerSource() {
String audioFile = getFilename();
try {
mMediaPlayer.setDataSource(audioFile);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I am playing a song from the sdcard.
Its plays fine. I tried to implement the seekbar such that when the user moves the seekbar the song gets forwarded or rewnided as per the seek bar position.
Here is the code
public class ViewAudio extends Activity implements OnSeekBarChangeListener,OnSeekCompleteListener,OnCompletionListener,OnPreparedListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.audio_player);
System.gc();
Intent i = getIntent();
Bundle extras = i.getExtras();
filename = extras.getString("audiofilename");
try {
mPlayer.setDataSource(filename);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mPlayer.setOnCompletionListener(this);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnSeekCompleteListener((OnSeekCompleteListener) this);
mPlayer.start();
TextView tv=(TextView) findViewById(R.id.file);
tv.setText("Playing "+filename);
seekbar = (SeekBar)findViewById(R.id.seekBar1);
mPlay = (Button)findViewById(R.id.play);
mPause = (Button)findViewById(R.id.pause);
seekbar.setProgress(0);
seekbar.setOnSeekBarChangeListener(this);
total = mPlayer.getDuration();
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
Log.d("Progres changed",""+progress);
if(fromUser){
mPlayer.seekTo(progress);
seekbar.setProgress(progress);
}
}
}
Now where ever i click the seekbar the song is getting played from the beginning not from the position i clicked. And it is not moving based on the song.
Any one please help.
i have solved it.
Create a thread that will check the song position every second and move the seekbar based on the song position
mediaPos = mplayer.getCurrentPosition();
mediaMax = mplayer.getDuration();
seekbar.setMax(mediaMax); // Set the Maximum range of the
seekbar.setProgress(mediaPos);// set current progress to song's
handler.removeCallbacks(moveSeekBarThread);
handler.postDelayed(moveSeekBarThread, 100); //cal the thread after 100 milliseconds
}
/**
* The Move seek bar. Thread to move seekbar based on the current position
* of the song
*/
private Runnable moveSeekBarThread = new Runnable() {
public void run() {
if(mplayer.isPlaying()){
int mediaPos_new = mPlayer.getCurrentPosition();
int mediaMax_new = mPlayer.getDuration();
seekbar.setMax(mediaMax_new);
seekbar.setProgress(mediaPos_new);
handler.postDelayed(this, 100); //Looping the thread after 0.1 second
}
}
};