Syncing Video View with SeekBar with onStopTrackingTouch

13,332

Solution 1

I think you complicated yourself a bit too much with that utility class. Set the maximum progress of the seekbar to be equal to the videos duration. Then on the seekbar listener you can just directly get its progress and seek to it. I hope you can understand what I typed bellow , this is my first answer :) .

private void playVideo() {
    Uri uri = Uri..parse("android.resource://com.sunshine.handsonequation/raw/title_video");
    vvVideo.setVideoURI(uri);
    vvVideo.start();
    // Updating progress bar
    updateProgressBar();
}

private void updateProgressBar() {
    mHandler.postDelayed(updateTimeTask, 100);
}

private Runnable updateTimeTask = new Runnable() {
    public void run() {
        sbVideo.setProgress(vvVideo.getCurrentPosition());
        sbVideo.setMax(vvVideo.getDuration());
        mHandler.postDelayed(this, 100);
    }
};

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

}
public void onStartTrackingTouch(SeekBar seekbar) {
    mHandler.removeCallbacks(updateTimeTask);
}
public void onStopTrackingTouch(SeekBar seekbar) {
    mHandler.removeCallbacks(updateTimeTask);
    vvVideo.seekTo(sbVideo.getProgress());
    updateProgressBar();
}

Solution 2

Nirmal answer should work but instead of

vvVideo.seekTo(progress); 

it should be

vvVideo.seekTo(progress*1000);

seekTo time should be in milliseconds

http://developer.android.com/reference/android/widget/VideoView.html#seekTo(int)

Solution 3

int mSeekValue = (progress * mTotalDurationInMilliSeconds) / 1000 ;
vvVideo.seekTo(mSeekValue);

instead of

vvVideo.seekTo(progress*1000);

Solution 4

Seek the video to SeekBar progress in onProgressChanged function.

@Override
    public void onProgressChanged(SeekBar seekbar, int progress,
            boolean fromTouch) {
    if(fromTouch)
    {
        vvVideo.seekTo(progress);
    }

    }
Share:
13,332
ark
Author by

ark

Updated on June 09, 2022

Comments

  • ark
    ark about 2 years

    I am making a custom Video Player, I successfully synced the progress of video to the seekbak. I wanted that the videoview should sync its progress with seekbar's progress when user moves the seekbar handler. I achieved this too, but it's not behaving as i want it too. Let me elaborate this proble, When i touch the seekbar handler and move it (forward or backward) i update the seekbar progress, but when i leave the seekbar, the seekbar handler goes a step forward/backward and then starts playing instead of starting at the same point where i left.

    Here's my code:

    public class MainActivity extends Activity implements OnSeekBarChangeListener {
    
        private VideoView vvVideo;
        private SeekBar sbVideo;
        private Handler mHandler = new Handler();
        private Utilities utils;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.custom_video_player);
            initOnjects();
            playVideo();
        }
    
        private void initOnjects() {
            vvVideo = (VideoView) findViewById(R.id.vvVideo);
            sbVideo = (SeekBar) findViewById(R.id.sbVideo);
            sbVideo.setOnSeekBarChangeListener(this);
            utils = new Utilities();
        }
    
        private void playVideo() {
            Uri uri = Uri
                    .parse("android.resource://com.sunshine.handsonequation/raw/title_video");
            vvVideo.setVideoURI(uri);
            sbVideo.setProgress(0);
            sbVideo.setMax(100);
            vvVideo.start();
            // Updating progress bar
            updateProgressBar();
        }
    
        private void updateProgressBar() {
            mHandler.postDelayed(updateTimeTask, 100);
        }
    
        private Runnable updateTimeTask = new Runnable() {
    
            @Override
            public void run() {
                long totalDuration = vvVideo.getDuration();
                long currentDuration = vvVideo.getCurrentPosition();
    
                // update progress bar
                int progress = (int) (utils.getProgressPercentage(currentDuration,
                        totalDuration));
                sbVideo.setProgress(progress);
                mHandler.postDelayed(this, 100);
    
            }
        };
    
        @Override
        public void onProgressChanged(SeekBar seekbar, int progress,
                boolean fromTouch) {
            // TODO Auto-generated method stub
    
        }
    
        // when user starts moving the progress handler
        @Override
        public void onStartTrackingTouch(SeekBar seekbar) {
            // remove message Handler from updating progress bar
            mHandler.removeCallbacks(updateTimeTask);
        }
    
        // when user stops moving the progress handler
        @Override
        public void onStopTrackingTouch(SeekBar seekbar) {
            mHandler.removeCallbacks(updateTimeTask);
            int totalDuration = vvVideo.getDuration();
            int currentPosition = utils.progressToTimer(sbVideo.getProgress(),
                    totalDuration);
    
            // forward or backward to certain seconds
            vvVideo.seekTo(currentPosition);
    
            // update timer progress again
            updateProgressBar();
        }
    }
    

    Utility Class:

    public class Utilities {
    
        /**
         * Function to convert milliseconds time to
         * Timer Format
         * Hours:Minutes:Seconds
         * */
        public String milliSecondsToTimer(long milliseconds){
            String finalTimerString = "";
            String secondsString = "";
    
            // Convert total duration into time
               int hours = (int)( milliseconds / (1000*60*60));
               int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60);
               int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000);
               // Add hours if there
               if(hours > 0){
                   finalTimerString = hours + ":";
               }
    
               // Prepending 0 to seconds if it is one digit
               if(seconds < 10){
                   secondsString = "0" + seconds;
               }else{
                   secondsString = "" + seconds;}
    
               finalTimerString = finalTimerString + minutes + ":" + secondsString;
    
            // return timer string
            return finalTimerString;
        }
    
        /**
         * Function to get Progress percentage
         * @param currentDuration
         * @param totalDuration
         * */
        public int getProgressPercentage(long currentDuration, long totalDuration){
            Double percentage = (double) 0;
    
            long currentSeconds = (int) (currentDuration / 1000);
            long totalSeconds = (int) (totalDuration / 1000);
    
            // calculating percentage
            percentage =(((double)currentSeconds)/totalSeconds)*100;
    
            // return percentage
            return percentage.intValue();
        }
    
        /**
         * Function to change progress to timer
         * @param progress -
         * @param totalDuration
         * returns current duration in milliseconds
         * */
        public int progressToTimer(int progress, int totalDuration) {
            int currentDuration = 0;
            totalDuration = (int) (totalDuration / 1000);
            currentDuration = (int) ((((double)progress) / 100) * totalDuration);
    
            // return current duration in milliseconds
            return currentDuration * 1000;
        }
    }
    

    I have no clue why it is happening, I hope you guys can give me a hint or solution around this.

  • user1788736
    user1788736 over 6 years
    zeroblitz36 could you tell me do i need to use MediaController for your code to work ? i am trying to get video duration from videoview without using MediaController and it crashes the app!int duration =simpleVideoView.getDuration()