15

i am using VideoView and seek bar but when i seekTo(..) on desired position through seekBar it play video from starting.

i trying this code:

 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {

           mVideoView.seekTo(progress);
}
Larry Morries
  • 669
  • 7
  • 17
Hemant Menaria
  • 701
  • 1
  • 7
  • 17

5 Answers5

27

As Reno mentioned, you have to wait for the seeking to complete.

VideoView does not have a OnSeekCompleteListener() but you can access the MediaPlayer from the onPrepared method of the VideoView and then set the OnSeekCompleteListener, like this :

mVideoView.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {

        mp.setOnSeekCompleteListener(new OnSeekCompleteListener() {
            @Override
            public void onSeekComplete(MediaPlayer mp) {
                //TODO: Your code here
            }
        });

    }
});
Matthieu Coisne
  • 624
  • 1
  • 13
  • 25
  • 5
    I think this should be the preferred solution. it's much less dirty and much less troublesome than having to maintain your own fork of VideoView – havchr Aug 06 '13 at 13:48
  • 1
    Thank you! This is clearly the cleanest and most reliable solution. Everything else I've seen is a hacky mess. – Wookie Dec 02 '14 at 22:03
6

The call to VideoView.seekTo() is a wrapper around MediaPlayer.seekTo(). This function returns almost immediately even though the actual seeking is still being performed. Therefore you want to wait for seeking to complete via MediaPlayer.OnSeekCompleteListener.

However, as Reno mentioned, the standard VideoView does not support OnSeekCompleteListener.

But you can copy and locally customize the VideoView class to add this support yourself.

First, start with a copy of VideoView.java. Or you can clone the entire frameworks/base repo but warning it is over 1 gig of data to download.

Copy VideoView.java into your Eclipse Android project and it will start building but fail. Here's what I did to get it to compile:

  1. Update the package statement to match your project.
  2. Comment out the references to MetaData. The fix for this is on my todo list. These need to be replaced with calls to MediaMetadataRetriever.
  3. Replace mContext with calls to getBaseContext()

Now you are ready to add the code for OnSeekCompleteListener. The implementation is similar to the other listeners, i.e OnCompletionListener.

public class VideoView extends SurfaceView
        implements MediaPlayerControl {

    // The client's listener which is the notification callback.
    private OnSeekCompleteListener mOnSeekCompleteListener;

    // Set up MediaPlayer to forward notifications to client.
    private MediaPlayer.OnSeekCompleteListener mSeekCompleteListener =
        new MediaPlayer.OnSeekCompleteListener() {
        public void onSeekComplete(MediaPlayer mp) {
            if (mOnCompletionListener != null) {
                mOnCompletionListener.onCompletion(mMediaPlayer);
            }
        }
    };

    // API for client to set their listener.
    public void setOnSeekCompleteListener(OnSeekCompleteListener l)
    {
        mOnSeekCompleteListener = l;
    }
}

Finally, update your own code:

  1. Update references to android.widget.VideoView to use your customized VideoView.
  2. Implement a listener and set it via by calling setOnSeekCompleteListener().

Your code now receives notifications when the seek has really completed and it can then perform subsequent seeks.

Sufian
  • 6,405
  • 16
  • 66
  • 120
Peter Tran
  • 1,626
  • 1
  • 17
  • 26
  • 1
    It still doesnt work for me - i ve modified videoview but the listener still fires about 6 seconds before the actual time. Any idea why – Vrashabh Irde Oct 17 '12 at 10:28
  • Hi Slartibartfast, are you saying the listener is called 6 seconds before the seek is actually completed? I'm curious how you measured this. – Peter Tran Nov 25 '12 at 19:18
  • Sorry, but what I need to do with MediaPlayer.METADATA_ALL, MediaPlayer.BYPASS_METADATA_FILTER ,Metadata.PAUSE_AVAILABLE etc.? MediaPlayer and MediaMetadataRetriever doesn't have these constants. – valerybodak Jul 19 '13 at 13:50
  • Hi anivaler, I'm not familiar with these constants. But as you said, they are are not part of the MediaPlayer and MediaMetadataRetriever APIs so things should work with using them. – Peter Tran Aug 09 '13 at 20:46
4

You have to wait for the seeking to complete, unfortunately VideoView does not have a OnSeekCompleteListener() (why Google? -_-)

Tofeeq Ahmad
  • 11,935
  • 4
  • 61
  • 87
Reno
  • 33,594
  • 11
  • 89
  • 102
0

use my method works like charm

  1. Take mediaPlayer

    MediaPlayer mediaPlayer;
    
  2. init mediaPlayer

    videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
         @Override
         public void onPrepared(MediaPlayer mp) {
             mediaPlayer = mp; 
         }
     });
    
  3. use seekTo method like this

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
         mediaPlayer.seekTo((int) mStartPosition, MediaPlayer.SEEK_CLOSEST);
     } else {
         mediaPlayer.seekTo((int) mStartPosition);
     }
    
StealthRT
  • 10,108
  • 40
  • 183
  • 342
jay patoliya
  • 611
  • 7
  • 8
-3

You should use

mVideoView.seekTo(progress, SEEK_CLOSEST)

vu Cong
  • 1
  • 1