Hemant Menaria
Hemant Menaria

Reputation: 701

VideoView not playing Video from desired position

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);
}

Upvotes: 15

Views: 13695

Answers (6)

Hans Cappelle
Hans Cappelle

Reputation: 17495

You're missing the listeners to start once seek is completed. The correct sequence to restart a video from a previously stored position using a VideoView would look like this in Kotlin.

Video Position and Resume handling

Storing the position, could be done in onPause of Activity or any other lifecycle aware view:

val videoPosition = videoView.currentPosition
videoView.pause() // you can also use .stopPlayBack() since you'll restart anyway

And onResume you can resume playback from that stored position, note how listeners are used to detect video prepare and video seek being complete:

videoView.setOnPreparedListener { mediaPlayer ->
   mediaPlayer.seekTo(videoPosition)
   mediaPlayer.setOnSeekCompleteListener { seekMediaPlayer ->
      seekMediaPlayer.start()
}

VideoView visibility

For all of this to work the actual VideoView has to be visible in the layout. If hidden (either using visibility INVISIBLE or GONE) the video will never prepare so nothing will happen.

If you encounter black screens or other artifacts caused by the view being visible before the content is fully loaded you can use alpha instead to hide it.

videoView.alpha = 0f
videoView.setOnInfoListener { _, what, _ ->
   if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
      videoView.alpha = 1f
   false
}

Lifecycle handling

If you're working with an Activity or Fragment you can just hook onto the existing onPause and onResume methods.

override fun onPause() {
   // handlePauseVideo()
   super.onPause()
}

override fun onResume() {
   super.onResume()
   // handleResumeVideo()
}

When working with a custom view you'll need to make it lifecycle aware like so:

init {
   inflate(context, R.layout.your_custom_view, this)
   (context as? LifecycleOwner)?.lifecycle?.addObserver(this)
}

override fun onPause(owner: LifecycleOwner) {
   // handlePauseVideo()
   super.onPause(owner)
}

override fun onResume(owner: LifecycleOwner) {
   super.onResume(owner)
   // handleResumeVideo()
}

override fun onDestroy(owner: LifecycleOwner) {
   // handleEndVideo()
   super.onDestroy(owner)
}

Upvotes: 0

jay patoliya
jay patoliya

Reputation: 761

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);
     }
    

Upvotes: 0

Matthieu Coisne
Matthieu Coisne

Reputation: 634

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
            }
        });

    }
});

Upvotes: 28

vu Cong
vu Cong

Reputation: 1

You should use

mVideoView.seekTo(progress, SEEK_CLOSEST)

Upvotes: -3

Peter Tran
Peter Tran

Reputation: 1669

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.

Upvotes: 6

Reno
Reno

Reputation: 33792

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

Upvotes: 4

Related Questions