user3626048
user3626048

Reputation: 736

VideoView and MediaPlayer seekTo always starts from beginning

I have some problem with seeking video played in VideoView and resuming it.

Here's some part of my code:

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();
        mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
            @Override
            public void onSeekComplete(MediaPlayer mp) {
                Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
                videoView.start();
                Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
            }
        });
    }
});
videoView.setVideoURI('some local uri');

At some point I'm pausing video using: videoView.pause();

After button click I'm seeking video to certain time, eg. 10 seconds (10 000 ms).

@OnClick(R2.id.ivMove)
void clickMove() {
   videoView.seekTo(10000);
}

After that in log I see:

onSeekComplete1 10000
onSeekComplete2 0

So after calling videoView.start() it is starting video from beginning!

But when I call start() without seeking video (eg. one button calls pause() and second calls start() then video is playing correctly - from the moment when it was paused, not from beginning.

Could you tell me what I'm doing wrong?

Upvotes: 4

Views: 4882

Answers (4)

Developer Reyaz
Developer Reyaz

Reputation: 41

Try this solution. It works like charm....

   videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start();
            mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
                @Override
                public void onSeekComplete(MediaPlayer mp) {
                    mp.start();
                }
            });

        }
    });

Upvotes: 0

Clay Martin
Clay Martin

Reputation: 249

There is a new overload for the MediaPlayer seekTo method. It has a second int parameter, in which you can pass a SEEK_CLOSEST constant. According to Google, "This mode is used with seekTo(long, int) to move media position to a frame (not necessarily a key frame) associated with a data source that is located closest to or at the given time." In testing my own app, it solves the problem for API level >= 26. I'm not sure if there are any good options prior to API level 26.

Upvotes: 3

user3626048
user3626048

Reputation: 736

The problem was caused by MediaPlayer - it is seeking to closest keyframe of the video and it turns out that my testing video has keyframes every ~30 seconds.

I changed to ExoPlayer https://github.com/google/ExoPlayer - it can seek to exact time.

Upvotes: 4

cancit
cancit

Reputation: 172

Try videoView.resume() instead of start()

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();
        mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
            @Override
            public void onSeekComplete(MediaPlayer mp) {
                Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
                videoView.resume();
                Log.d("V", "onSeekComplete1 " + videoView.getCurrentPosition());
            }
        });
    }
});
videoView.setVideoURI('some local uri');

Upvotes: 0

Related Questions