Recently Added

6/recent/ticker-posts

Adding Controls in Video Player App Part 13


In this video player app part 13 I am going to implement how to show title and add go 10 seconds previous and go 10 seconds forward and play pause button and also implement seek bar and when you drag the seek bar it goes forward and backward and also implement how much time is left to end video
So let's start.



Add this code to your VideoPlayer.class

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.GestureDetectorCompat;

import android.graphics.Point;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;

import com.example.player.R;

import static com.example.player.adapter.VideosAdapter.videoFolder;

public class VideoPlayer extends AppCompatActivity
implements View.OnTouchListener,
ScaleGestureDetector.OnScaleGestureListener, View.OnClickListener {

RelativeLayout zoomLayout;
ScaleGestureDetector scaleDetector;
GestureDetectorCompat gestureDetector;
private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 5.0f;
boolean intLeft, intRight;
private Display display;
private Point size;
private Mode mode = Mode.NONE;
private enum Mode {
NONE,
DRAG,
ZOOM;
}
int device_width;
private int sWidth;
private boolean isEnable = true;
private float scale = 1.0f;
private float lastScaleFactor = 0f;
// Where the finger first touches the screen
private float startX = 0f;
private float startY = 0f;
// How much to translate the canvas
private float dx = 0f;
private float dy = 0f;
private float prevDx = 0f;
private float prevDy = 0f;


int position = -1;
private VideoView videoView;
LinearLayout one, two , three , four;
ImageButton goBack, rewind, forward, playPause;
TextView title, endTime;
SeekBar videoSeekBar;

@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction() & MotionEvent.ACTION_MASK){
case MotionEvent.ACTION_DOWN:
hideDefaultControls();
if (scale > MIN_ZOOM) {
mode = Mode.DRAG;
startX = event.getX() - prevDx;
startY = event.getY() - prevDy;
}
break;
case MotionEvent.ACTION_MOVE:
hideDefaultControls();
isEnable = false;
if (mode == Mode.DRAG) {
dx = event.getX() - startX;
dy = event.getY() - startY;
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
mode = Mode.ZOOM;
break;
case MotionEvent.ACTION_POINTER_UP:
mode = Mode.DRAG;
break;
case MotionEvent.ACTION_UP:
mode = Mode.NONE;
prevDx = dx;
prevDy = dy;
break;
}
scaleDetector.onTouchEvent(event);
gestureDetector.onTouchEvent(event);
if ((mode == Mode.DRAG && scale >= MIN_ZOOM) || mode == Mode.ZOOM) {
zoomLayout.requestDisallowInterceptTouchEvent(true);
float maxDx = (child().getWidth() - (child().getWidth() / scale)) / 2 * scale;
float maxDy = (child().getHeight() - (child().getHeight() / scale)) / 2 * scale;
dx = Math.min(Math.max(dx, -maxDx), maxDx);
dy = Math.min(Math.max(dy, -maxDy), maxDy);
applyScaleAndTranslation();
}
return true;
}

private void applyScaleAndTranslation() {
child().setScaleX(scale);
child().setScaleY(scale);
child().setTranslationX(dx);
child().setTranslationY(dy);
}

private View child() {
return zoomLayout(0);
}

private View zoomLayout(int i) {
return videoView;
}

@Override
public boolean onScale(ScaleGestureDetector detector) {
float scaleFactor = scaleDetector.getScaleFactor();
if (lastScaleFactor == 0 || (Math.signum(scaleFactor) == Math.signum(lastScaleFactor))) {
scale *= scaleFactor;
scale = Math.max(MIN_ZOOM, Math.min(scale, MAX_ZOOM));
lastScaleFactor = scaleFactor;
} else {
lastScaleFactor = 0;
}
return true;
}

@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
}

@Override
public void onScaleEnd(ScaleGestureDetector detector) { }


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_player);
/*Assigning Variables*/
videoView = findViewById(R.id.video_view);
one = findViewById(R.id.videoView_one_layout);
two = findViewById(R.id.videoView_two_layout);
three = findViewById(R.id.videoView_three_layout);
four = findViewById(R.id.videoView_four_layout);
goBack = findViewById(R.id.videoView_go_back);
title = findViewById(R.id.videoView_title);
rewind = findViewById(R.id.videoView_rewind);
playPause = findViewById(R.id.videoView_play_pause_btn);
forward = findViewById(R.id.videoView_forward);
endTime = findViewById(R.id.videoView_endtime);
videoSeekBar = findViewById(R.id.videoView_seekbar);
/*Adding onClickListener*/
goBack.setOnClickListener(this);
rewind.setOnClickListener(this);
playPause.setOnClickListener(this);
forward.setOnClickListener(this);
/*getting path and preparing for play video*/
position = getIntent().getIntExtra("p", -1);
title.setText(videoFolder.get(position).getTitle());
String path = videoFolder.get(position).getPath();
if (path!=null){
videoView.setVideoPath(path);
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
videoSeekBar.setMax(videoView.getDuration());
videoView.start();
}
});
}else {
Toast.makeText(this, "path didn't exits", Toast.LENGTH_SHORT).show();
}
/*zoom in,out and double tap to go forward,backward
* and single tap to hide and show controls */
zoomLayout = findViewById(R.id.zoom_layout);
display = getWindowManager().getDefaultDisplay();
size = new Point();
display.getSize(size);
sWidth = size.x;
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
device_width = displayMetrics.widthPixels;
zoomLayout.setOnTouchListener(this);
scaleDetector = new ScaleGestureDetector(getApplicationContext(), this);
gestureDetector = new GestureDetectorCompat(getApplicationContext(), new GestureDetector());


setHandler();
initalizeSeekBars();
}

private void initalizeSeekBars(){
videoSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (videoSeekBar.getId() == R.id.videoView_seekbar) {
if (fromUser) {
videoView.seekTo(progress);
videoView.start();
int currentPosition = videoView.getCurrentPosition();
endTime.setText("" + convertIntoTime(videoView.getDuration() - currentPosition));
}
}
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {

}
});
}

private String convertIntoTime(int ms){
String time;
int x, seconds, minutes, hours;
x = ms / 1000;
seconds = x % 60;
x /= 60;
minutes = x % 60;
x /= 60;
hours = x % 24;
if (hours != 0)
time = String.format("%02d", hours) + ":" + String.format("%02d", minutes) + ":" + String.format("%02d", seconds);
else time = String.format("%02d", minutes) + ":" + String.format("%02d", seconds);
return time;
}

private void setHandler(){
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
if (videoView.getDuration()>0){
int currentPosition = videoView.getCurrentPosition();
videoSeekBar.setProgress(currentPosition);
endTime.setText(""+convertIntoTime(videoView.getDuration()-currentPosition));
}
handler.postDelayed(this,0);
}
};
handler.postDelayed(runnable,500);
}

@Override
public void onClick(View v) {
switch (v.getId()){

case R.id.videoView_go_back:
onBackPressed();
break;

case R.id.videoView_rewind:
//1000 = 1sec
videoView.seekTo(videoView.getCurrentPosition() -10000);
break;

case R.id.videoView_forward:
//1000 = 1sec
videoView.seekTo(videoView.getCurrentPosition() +10000);
break;

case R.id.videoView_play_pause_btn:
if (videoView.isPlaying()){
videoView.pause();
playPause.setImageDrawable(getResources().getDrawable(R.drawable.ic_play));
}else {
videoView.start();
playPause.setImageDrawable(getResources().getDrawable(R.drawable.netflix_pause_button));
}
break;
}
}

private class GestureDetector extends android.view.GestureDetector.SimpleOnGestureListener{

@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
if (isEnable){
hideDefaultControls();
isEnable = false;
}else {
showDefaultControls();
isEnable = true;
}
return super.onSingleTapConfirmed(e);
}

@Override
public boolean onDoubleTap(MotionEvent event) {
if (event.getX() < (sWidth / 2)) {
intLeft = true;
intRight = false;
videoView.seekTo(videoView.getCurrentPosition() - 20000);
Toast.makeText(VideoPlayer.this, "-20sec", Toast.LENGTH_SHORT).show();
} else if (event.getX() > (sWidth / 2)) {
intLeft = false;
intRight = true;
videoView.seekTo(videoView.getCurrentPosition() + 20000);
Toast.makeText(VideoPlayer.this, "+20sec", Toast.LENGTH_SHORT).show();
}
return super.onDoubleTap(event);
}


}

private void hideDefaultControls(){
one.setVisibility(View.GONE);
two.setVisibility(View.GONE);
three.setVisibility(View.GONE);
four.setVisibility(View.GONE);
//Todo this function will hide status and navigation when we click on screen
final Window window = this.getWindow();
if (window == null){
return;
}
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
final View decorView = window.getDecorView();
if (decorView!=null){
int uiOption = decorView.getSystemUiVisibility();
if (Build.VERSION.SDK_INT >= 14) {
uiOption |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
if (Build.VERSION.SDK_INT >= 16) {
uiOption |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
if (Build.VERSION.SDK_INT >= 19) {
uiOption |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
decorView.setSystemUiVisibility(uiOption);
}
}

private void showDefaultControls(){
one.setVisibility(View.VISIBLE);
two.setVisibility(View.VISIBLE);
three.setVisibility(View.VISIBLE);
four.setVisibility(View.VISIBLE);
//todo this function will show status and navigation when we click on screen
final Window window = this.getWindow();
if (window == null){
return;
}
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
final View decorView = window.getDecorView();
if (decorView!=null){
int uiOption = decorView.getSystemUiVisibility();
if (Build.VERSION.SDK_INT >= 14) {
uiOption &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
}
if (Build.VERSION.SDK_INT >= 16) {
uiOption &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
}
if (Build.VERSION.SDK_INT >= 19) {
uiOption &= ~View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
decorView.setSystemUiVisibility(uiOption);
}
}

@Override
public void onBackPressed() {
super.onBackPressed();
}
}

Watch Full Tutorial

Post a Comment

2 Comments