In my Android application I am facing issue with seekbar of MediaController that I am using for Videoview.
I would like to know if the user seeks to a position greater than the buffered position,I need to show a dialog and then dismiss the dialogue on seek completed.
Please let me know if I can have this solved.
mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar arg0) {
// you can check for the current buffer state and where the use seek using mSeekBar.getProgress() and then open up a dialog.
if(condition to match buffering and seek position)
openDialog();
}
#Override
public void onStartTrackingTouch(SeekBar arg0) {
}
#Override
public void onProgressChanged(SeekBar arg0, int progress, boolean arg2) {
}
});
...
public void openDialog()
{
...
// check for buffer level to match your seek position
// when it meets the codition,cancel the dialog.
...
}
Couple ways of doing this.
Option 1: Just use the OnInfoListener from the media player.
This will send you info when the buffering has started and stopped.
mPlayer.setOnInfoListener(OnInfo);
Then create your listener code.
// info from player sent.
OnInfoListener OnInfo =
new OnInfoListener() {
public boolean onInfo(MediaPlayer mp, int what, int extra) {
Log.d(TAG,"media info what:"+what+" extra:"+extra);
// check about buffering status.
if(what==MediaPlayer.MEDIA_INFO_BUFFERING_START) {
// note: we are assuming _progressDialog was created already
_progressDialog.setMessage("Buffering...");
_progressDialog.show();
} else if(what==MediaPlayer.MEDIA_INFO_BUFFERING_END) {
if(_progressDialog.isShowing())
_progressDialog.dismiss();
}
return false;
}
};
Option 2: use the OnBufferingUpdateListener to keep track of how much has been buffered.
mPlayer.setOnBufferingListener(OnBufferingUpdate);
Then create the actual listen code.
// buffering update
OnBufferingUpdateListener OnBufferingUpdate =
new OnBufferingUpdateListener() {
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
Log.d(TAG,"BUFFERING: "+ String.valueOf(percent));
// store the percent value and check it in onStopTrackingTouch()
// which is in your setOnSeekBarChangeListener
}
};
Related
I'm using MediaPlayer to play some recorded audio and SeekBar to show the progress of the play. My problem is: when I click on the SeekBar to jump to a time position the following example happens and i see on the Log when i want to see the progess:
getprogress(ms): 10000
getprogress(ms): 9956
getprogress(ms): 10000
So I jump to the recorded audio's 10th second. The MediaPlayer jumps to the 10th second but after It jumps back a bit as you can see.
I tried everything i could. I tried playing other recorder's audio files but happened the same. Tried playing with the bit rate and sampling rate but happened the same.
I hope someone knows the solution to this. Thank You.
Edit:
Code:
SeekBar:
progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver);
// handler2.removeCallbacks(updateTimeTask);
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (PlayerForegroundService.player != null) {
// handler2.removeCallbacks(updateTimeTask);
PlayerForegroundService.player.seekTo(seekBar.getProgress());
// handler2.post(updateTimeTask);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter(Constants.ACTION.PLAYER_UPDATE_UI));
}
}
});
}
getProgess():
public int getProgress(){
if ( player != null) {
Log.i(Constants.DEFAULTS.LOG_TAG, ""+player.getCurrentPosition());
return player.getCurrentPosition();
}
else
return 0;
}
The code when getProgress gets called:
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, final Intent intent) {
actPosition.setText(intent.getStringExtra("formattedtimeplay"));
progressBar.setProgress(PlayerForegroundService.player.getProgress());
if (intent.getBooleanExtra("pausedplay", false))
playButton.setImageResource(R.drawable.playfilled);
}
};
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter(Constants.ACTION.PLAYER_UPDATE_UI));
super.onCreate(savedInstanceState);
}
It seems i solved the problem. Before, I used to set the maximum value of the SeekBar in seconds. But after I set the max in milliseconds and the values of the seekTo in milliseconds it works fine.
I have been having this issue for a while now.
I have a simple application that plays a playlist of videos within a videoview with a pause of a few seconds between them.
private final Runnable playNormalVideo = new Runnable() {
public void run() {
try {
final String filepath = ...;
viewVideo.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int extra) {
onEndVideo(false);
return true;
}
});
viewVideo.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
onEndVideo(false);
}
});
viewVideo.setOnPreparedListener(new OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
background.setVisibility(View.INVISIBLE);
viewVideo.start();
}
});
viewVideo.setVideoPath(filepath);
viewVideo.setVisibility(View.VISIBLE);
viewVideo.requestFocus();
} catch (Exception e) {
String error = Utils.getStackTrace(e);
Utils.log(true, error);
}
}
};
and in my onEndVideo() function I make the background visible and check what video to play next and with a Handler i request to play it after x seconds.
My issue is the following :
Within a long run (approx 1 day) the background becomes invisible within a lot of seconds before the video starts. I don't understand why. If someone could help me get rid of this issue.
I also thought I should free memory between video plays but i don't seem to find how to do that.
Note : All the videos are saved on the device.
Thanks for any help.
I intend to write a custom media controller for my app. I was planning to use seekbar to do both seeking and showing progress. Trying to implement this.
Does anyone have such implementation or am I on the wrong path ?
Finally I figured it out!!
The solution that I came up with was something like this :
First of all set the max progress for seekbar as the duration of the video
videoView.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
seekBar.setMax(videoView.getDuration());
seekBar.postDelayed(onEverySecond, 1000);
}
});
This runnable will keep on updating the progressbar :
private Runnable onEverySecond=new Runnable() {
#Override
public void run() {
if(seekBar != null) {
seekBar.setProgress(videoView.getCurrentPosition());
}
if(videoView.isPlaying()) {
seekBar.postDelayed(onEverySecond, 1000);
}
}
};
And then the setOnSeekBarChangeListener for the seekbar can be used to take the user seeks on the media. By using the fromUser boolean we can make out whether it was a call back due to user's interaction or the
seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if(fromUser) {
// this is when actually seekbar has been seeked to a new position
videoView.seekTo(progress);
}
}
});
You set the seconday progress.
No, you're on the right track. It is very good for displaying stuff like download progress and current location for streams (media).
Originally, I had a MediaPlayer mPlayers to play/pause/stop my Audio file. Now, I'm trying to add a seek bar for my media. I tried using Threads and this is what I came up with:
In onCreate() :
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
mPlayer.seekTo(progress);
}
////........Omitted Code..........\\\\
//At the very end of the method:
seekThread = new Thread(this); //My Activity implements:Runnable
seekThread.start();
Then, I implemented a method run() to update my seek bar every 1 sec:
public void run() {
try {
while(mPlayer != null){
int currentPosition = mPlayer.getCurrentPosition();
Message msg = new Message();
msg.what = currentPosition;
threadHandler.sendMessage(msg);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private Handler threadHandler = new Handler(){
public void handleMessage(Message msg){
seekBar.setProgress(msg.what);
}
};
However, In my HTC Magic, the audio run inefficiently. Some words are repeated. It seems like the seek bar is going back a little bit every some time.
To make you understand the problem well, Let's say this: if the audio says that: abcdefghijklmn , then it will be like this: abccdeffghijjklmnn.
Any improvement you suggest to my thread ? Am I doing it right?
Not sure this will help, but try:
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
mPlayer.seekTo(progress);
}
}
Without this condition, mPlayer.seekTo(progress); is called every time you call seekBar.setProgress(msg.what);
I have some Android code to stream an audio file from the internet and play the stream after 10 seconds.
I am using a SeekBar to view the buffering status and playing status. I want to play the audio starting from the middle of the buffered stream. For that, I move the SeekBar point to the middle, but I cannot play the audio from the middle; it will go back and start from the beginning. How can I get the seeked position and how can I play the audio from that particular position?
Here is my SeekBar code. How can I make this code use the OnSeekBarChangeListener properly?
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
if (arg2 && mediaPlayer.isPlaying()) {
//myProgress = oprogress;
arg1=mediaPlayer.getCurrentPosition();
mediaPlayer.seekTo(arg1);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
arg1=mediaPlayer.getCurrentPosition();
mediaPlayer.seekTo(arg1);
You are forcing the player to seek to the current position, and not to the positon retuned by the Seekbar
Remove the line: arg1=mediaPlayer.getCurrentPosition(); and it should work. Of course after MediaPlayer.prepare() set SeekBar.setMax(MediaPlayer.getDuration()), so seeking will be accurate.
I think you have to make a thread... I have some code given below which you can try to implement.
public void run() {
try
{
while(song1.getDuration()!=song1.getCurrentPosition())
{
skbar.setProgress(song1.getCurrentPosition());
//bStop.setText(song1.getCurrentPosition());
}
if (song1.getDuration()==song1.getCurrentPosition())
Log.v("log","Sanket");
t.suspend();
}
catch (Exception e)
{
Log.e("log",e.toString());
}
}