Reputation: 563
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.
Upvotes: 5
Views: 14303
Reputation: 11
int mSeekValue = (progress * mTotalDurationInMilliSeconds) / 1000 ;
vvVideo.seekTo(mSeekValue);
instead of
vvVideo.seekTo(progress*1000);
Upvotes: 1
Reputation: 171
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();
}
Upvotes: 15
Reputation: 69
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)
Upvotes: 1
Reputation: 602
Seek the video to SeekBar
progress in onProgressChanged
function.
@Override
public void onProgressChanged(SeekBar seekbar, int progress,
boolean fromTouch) {
if(fromTouch)
{
vvVideo.seekTo(progress);
}
}
Upvotes: 1