I have a VideoView that plays from internal memory. While my video is playing the VideoView logs MediaPlayer: error (1, -1004)
. I have an onErrorListener attached to the VideoView from where I'd like to manage this error. What I am aiming to do, is to get the last position (from getCurrentPosition()
) and start my player again from that position, using seekTo(int position)
. My video file is valid (verified by playing on other players). My problem now is to get the last valid position from VideoView. Calling getCurrentPosition()
from onError(MediaPlayer mp, int what, int extra) returns 0 when I do mp.getCurrentPosition / mVideoView.getCurrentPosition()
(quite rightly so). How do I keep tracking the current position of the player while it is playing ?
Here is my code:
mVideoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
switch (what) {
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Log.v("error", "media error unknown");
mediaErrorExtra(mp, extra, path);
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Log.v("error", "media error server died");
mediaErrorExtra(mp, extra, path);
break;
}
return true;
}
});
private void mediaErrorExtra(MediaPlayer mp, int extra, String path){
switch(extra){
case MediaPlayer.MEDIA_ERROR_IO:
if(!mp.isPlaying()){
Integer currentposition = mVideoView.getCurrentPosition();
if(currentposition != null){
Log.v("currentpos",Integer.toString(currentposition));
}
mVideoView.setVideoPath(path);
mVideoView.start();
//mVideoView.seekTo(currentposition);
}
break;
case MediaPlayer.MEDIA_ERROR_MALFORMED:
Log.v("error extra","media error malformed");
break;
case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
Log.v("error extra","media error unsupported");
break;
case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
Log.v("error extra","media error timed out");
break;
}
}
Alternatively is there any listener that provides the current position of the player while it is playing ? I could use a while(isPlaying()){int currentposition = mVideoView.getCurrrentPosition()}
but I suppose this is a bad way of going about things. Any suggestion would be most appreciated. Thanks in advance.
Answering my question:
A ScheduledExecutorService
helped solve this:
Here's how I get the current position as the player plays:
ScheduledExecutorService mScheduledExecutorService;
int mCurrentposition = 0;
Runnable UpdateCurrentPosition = new Runnable(){
@Override
public void run() {
mCurrentposition = mVideoView.getCurrentPosition();
}
};
@Override
protected void onCreate(){
...
mScheduledExecutorService = new ScheduledExecutor(1);
mScheduledExecutorService.scheduleWithFixedDelay(new Runnable(){
@Override
public void run() {
mVideoView.post(UpdateCurrentPosition);
}
},3000,1000,TimeUnit.MILLISECONDS);
}