MediaPlayer seekTo () does not update SurfaceView

I have already seen many questions about Android MediaPlayer issues, most of them due to the seekTo() function. Now I tried to use it, and it worked as expected: bad!

This feature seems very inconsistent, especially when we want to provide its functionality while the video is paused. In my case, I have videos from 30 to 60 frames and I want to play them one by one - without this delay, which MediaMetadataRetriever.getFrameAtTime () provides.

The problem I am facing is when I call seekTo() , it does not update the SurfaceView . It only works for the first time, after which the SurfaceView remains unchanged, it never updates.

I heard rumors that seekTo() only works with a minimum interval of 1 second, but I tested with a longer video and finding the second one didn’t work either.

code

 mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); mSurfaceHolder.addCallback(this); mMediaPlayer = new MediaPlayer(); mMediaPlayer.setDisplay(mSurfaceHolder); mMediaPlayer.setOnSeekCompleteListener(new OnSeekCompleteListener() { @Override public void onSeekComplete(MediaPlayer mp) { // Need this postDelayed(), otherwise the media player always // returns 0 in getCurrentPosition(), don't know why... Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { mMediaPlayer.pause(); } }, 100); } }); mMediaPlayer.setDataSource(localfile_source); mMediaPlayer.prepare(); // Set the initial position. mMediaPlayer.start(); mMediaPlayer.seekTo(500); 

 /** We're assuming that targetMs is within 0 and the video duration. Also, targetMs is calculated to always move to the next/previous frame: Example: currentMs + ( 1000 / framerate) (if framerate = 20, then it will exist a frame in each 50ms) */ private void seekTo(int targetMs) { mMediaPlayer.start(); mMediaPlayer.seekTo(targetMs); } 

Please note that due to a known error regarding the use of this function, a workaround is used when pausing the video:

  • Launch the video;

  • Call seekTo() ;

  • Pause it on onSeekComplete() .
+6
source share
1 answer

From [ this question ]:

"You cannot search frame by frame using the MediaPlayer APIs provided by Android.

If you really want to implement frame by frame, you will have to use a third-party multimedia infrastructure such as FFMPEG, or you will need to implement your own. "

I created test code to try it anyway. I did not start() video before using seekTo() I just used seekTo() while pausing.

When I moved forward in increments of 50 ms, I saw a series of about 4-5 frames repeating in about 2 seconds; then the set of preview frames has changed to a new series of 4-5 frames. This seems to coincide with my previous test, in which I moved forward with a step of 2000 ms and saw a unique frame for each call to seekTo() .

In general, it looks like MediaPlayer selects a few frames for every 2 second interval that will be used as preview frames when the video is paused.

+4
source

All Articles