i have a seekbar that should move while streaming from url but it's not automatically moving, but when you press on the seekbar it takes you where you should be. and my class doesnt fire run() function!
public void run() {
// TODO Auto-generated method stub
int currentPosition = 0;
int total = mediaPlayer.getDuration();
seekprogress.setMax(total);
while (mediaPlayer != null && currentPosition <total) {
try {
Thread.sleep(100);
currentPosition = mediaPlayer.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
seekprogress.setProgress(currentPosition);
}
}
You can update UI elements only from the UI thread. Use runOnUiThread
Related
#Override
public void run() {
int currentPosition = 0;
int total = mediaPlayer.getDuration();
while (mediaPlayer != null && currentPosition < total) {
try {
Thread.sleep(1000);
currentPosition = mediaPlayer.getCurrentPosition();
} catch (InterruptedException e) {
return;
} catch (Exception e) {
return;
}
pbRingtonePreviewHorizontal.setProgress(currentPosition);
}
}
Above is the code for update progress value, this works perfectly in horizontal progress bar.. I want same for circular progress bar.
Code for initializing progress bar is
public void onPrepared(MediaPlayer mediaplayer) {
System.out.println("on prepared");
if (!mediaPlayer.isPlaying()) {
isPlayEnabled = true;
mediaPlayer.start();
pbRingtonePreview.setVisibility(View.INVISIBLE);
pbRingtonePreviewHorizontal.setProgress(0);
pbRingtonePreviewHorizontal.setMax(mediaPlayer
.getDuration());
ivRingtonePreview.setImageResource(R.drawable.stop);
new Thread(this).start();
}
}
I'm facing with a problem. I want to get duration of video when i 'm recording it.
I can get duration of video when it's finish by code
MediaPlayer mp = MediaPlayer.create(mContext, Uri.parse(video));
if(mp == null)
return -1;
int duration = mp.getDuration();
mp.release();
But i want to get duration everytime when i record video to update to progressbar.
Hope your reply!
private class PlaybackObserver extends Thread {
public void run() {
currentPosition = 0;
try {
while (!killObserverThread) {
Thread.sleep(1000);
currentPosition = (int) mediaPlayer.getCurrentPosition();
runOnUiThread(new Runnable() {
public void run() {
yourProgressBar.setProgress(currentPosition);
}
});
}
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
killObserverThread = false;
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if (task == null || !task.isAlive()) {
task = new PlaybackObserver();
task.start();
}
startPlaying();
}
add a private class for your UiThread to update your seekbar/progressbar. Then start it from onResume()
I am starting a thread when invoking a method to play an audio file.
The code runs ok the first time but when I call the play method again I need the thread to start as if it were being called the first time. I have tried to interrupt the thread and even stop it but nothing seems to work.
How can I properly restart the thread?
Here is some code to help explain.
Global variable
private Thread thread1;
Thread code:
thread1 = new Thread(new Runnable()
{
#Override
public void run()
{
try {
int i=0;
final TextView timeDuration = (TextView) findViewById(R.id.timeDisplay);
final SeekBar seekBar = (SeekBar)findViewById(R.id.seekBar1);
while (running)
{
info();
j = 0;
while(i>0 && running)
{
while(j<duration && running && (playStatus.getValue() == "TRANSITIONING" || playStatus.getValue() == "PLAYING"))
{
seekBar.setMax((int) duration);
seekBar.setProgress(0);
runOnUiThread(new Runnable()
{
public void run()
{
System.out.println("PLAYBACK STATUS: "+playStatus.getValue());
timeDuration.setText(""+(j+1));
seekBar.setProgress(j+1);
if(j==(duration-1))
{
setRunning(false);
}
}
});
Thread.sleep(1 * 1000);
j++;
if(seekBar.getProgress() == seekBar.getMax())
{
runOnUiThread(new Runnable()
{
public void run()
{
playButton.setVisibility(View.VISIBLE);
pauseButton.setVisibility(View.GONE);
timeDuration.setText(""+"0");
seekBar.setProgress(0);
flag = false;
System.out.println("J VALUE 1: = "+j);
duration = 0;
setRunning(false);
}
});
}
}
}
j = 0;
i++;
Thread.sleep(1 * 1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
play();
This code works fine and plays the track. It then resets the seekbar and awaits for the play method to be called again.
public void play()
{
try
{
thread1.start();
}
catch(Exception e)
{
return;
}
}
Here is the setRunning method recommended to me.
public void setRunning(boolean b)
{
this.running = b;
}
If anyone know of a solution to this problem I would really appreciate it.
Threads are not supposed to be stopped manually. You should use a boolean instead of true in your while loop, and put the boolean to false through a setter when you want to stop:
private boolean running;
#Override
public void run(){
running = true;
while(running) {...}
}
public void setRunning(boolean b){
this.running = b;
}
To restart your player you need to prepare again.
public void restartAudio() {
Log.e(TAG, "restartAudio");
if (mp.isPlaying()) {
mp.seekTo(0);
}else{
mp.stop();
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
When using extra boolean flag to controll thread's while loop don't forget to use volatile modifier on it:
private volatile boolean running;
or put appropriate synchronization.
Apart from that, I'd think about using Thread.isInterrupted() method instead of the additional 'running' flag:
http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#isInterrupted()
here's why:
https://stackoverflow.com/a/3196058/1350225
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
}
}
};
in my app i am using media player and i want to place a seek bar there. In my code the song is playing but the seek bar is not moving. Following is the part of my code...
sv = (SurfaceView)findViewById(R.id.surfaceView1);
sv.postDelayed(runnable,200);
final Runnable runnable = new Runnable()
{
#Override
public void run()
{
if (mediaPlayer != null)
{
if (isPlaying)
{
try
{
int currentPosition = mediaPlayer.getCurrentPosition();
audioProgress.setProgress((int) ((currentPosition / (float) mediaPlayer.getDuration()) * 100f));
} catch (Exception e) {
e.printStackTrace();
}
sv.postDelayed(runnable, 150);
}
}
}
};
Please anyone help me in clearing the errors...
Make these changes to your code:
sv = (SurfaceView)findViewById(R.id.surfaceView1);
audioProgress.setMax(mediaPlayer.getDuration()); // this is one change
sv.postDelayed(runnable,200);
final Runnable runnable = new Runnable()
{
#Override
public void run()
{
if (mediaPlayer != null)
{
if (isPlaying)
{
try
{
int currentPosition = mediaPlayer.getCurrentPosition();
// the other change:
audioProgress.setProgress(currentPosition);
} catch (Exception e) {
e.printStackTrace();
}
sv.postDelayed(runnable, 150);
}
}
}
};