SoFunction
Updated on 2025-03-01

Video player based on VideoView custom control panel

This article shares the specific code of VideoView native custom video player for your reference. The specific content is as follows

Technical points and highlights used in the project

  • VideoView package video playback tool class
  • Customize video control panel
  • Use of gesture recognizer

1. VideoView encapsulation video playback tool class

Video playback is actually quite simple. The VideoView class provides corresponding methods. See the code for details. The code is relatively simple, but it should be noted that the UI information of the video panel must be updated in the main thread.

/********************************************************
  * Video business category
  * Last modified time: 2017/9/23
  * @author zlc
  *
  ***************************************************************/
package ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
public class VideoBusiness implements ,,{

 private Activity activity;
 private WakeLock mWakeLock;
 public VideoView mVideoView;
 private VideoController mController;

 /**Play status enumeration, there are three playback status: idle, preparing */
 private enum PLAYER_STATUS {
  IDLE, PREPARING,PAUSED, PREPARED,RESUMED,STOPPED
 }
 /**Current playback status*/
 public PLAYER_STATUS mPlayerStatus = PLAYER_STATUS.IDLE;

 /**Asynchronous processing method for updating progress*/
 /**Event Flag*/
 private int mLastPos;

 public VideoBusiness(Activity activity){
   = activity;
  // Keep the screen bright  PowerManager pm = (PowerManager) (Context.POWER_SERVICE);
  mWakeLock = (PowerManager.FULL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "Test");
 }

 //Initialize the video player public void initVideo(VideoView videoView,VideoController controller,String sourceUrl){

   = videoView;
   = controller;
  (this);
  ("msg","Set the playback address = "+sourceUrl);
  (this);
  (this);
  (this);
  (sourceUrl); //Set the playback address
 }

 //Start playback public void startPlay(){
  if (null != mWakeLock && (!())) {
   ();
  }
  if(null != mVideoView) {
   ("msg", "Play");
   ();
   mPlayerStatus = PLAYER_STATUS.PREPARING;
  }
 }


 /**
   * Pause playback
   */
 public void pause() {
  if (null != mWakeLock) {
   ();
  }
  if(null != mVideoView && ()){
   ();
   mPlayerStatus = PLAYER_STATUS.PAUSED;
   mLastPos = getCurrentTime();
  }
 }

 /**
   * Continue to play
   */
 public void resume(){
  if (null != mWakeLock) {
   ();
  }
  if(null != mVideoView){
   //();
   (mLastPos);
   ();
   mPlayerStatus = PLAYER_STATUS.RESUMED;
  }
 }

 /**
   * Stop playing
   */
 public void stop() {

  if (null != mWakeLock) {
   ();
  }
  if(null != mVideoView){
   mLastPos = getCurrentTime();
   ();
   mPlayerStatus = PLAYER_STATUS.STOPPED;
  }
 }

 /**
   * Determine whether it is playing
   * @return
   */
 public boolean isPlaying(){
  return mVideoView!=null && ();
 }

 /**
   * Whether to pause
   */
 public boolean isPause(){
  return mPlayerStatus == PLAYER_STATUS.PAUSED;
 }

 /**
   * Free up resources
   */
 public void release(){
  if (null != mWakeLock) {
   ();
   mWakeLock = null;
  }
  if(null != mVideoView){
   ();
   mVideoView = null;
  }
 }

 @Override
 public void onCompletion(MediaPlayer mediaPlayer) {
  ("onCompletion","The video is finished");
  ();
  (0);
  mLastPos = 0;
  mPlayerStatus = PLAYER_STATUS.IDLE;
  removeUIMessage();
 }

 @Override
 public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
  ("onError","Video playback error");
  return false;
 }

 @Override
 public void onPrepared(MediaPlayer mediaPlayer) {
  ("onPrepared","Video ready");
  if (mPlayerStatus!= PLAYER_STATUS.PAUSED){
   int totalTime = getTotalTime();
   (totalTime);
   (0);
   (totalTime);
   mPlayerStatus = PLAYER_STATUS.PREPARED;
   sendUIMessage();
  }
 }

 /**
   * Drag and drop the progress bar to play
   * @param time
   */
 public void seekToPlay(int time){
  int totalSecond = getTotalTime();
  int tempTime = time > totalSecond ? totalSecond : time;
  (tempTime);
  sendUIMessage();
 }


 //The video is paused to play the magnified button click event public void playVideo(ImageView id_btn_video_play, ImageView img){
  if(isPlaying()){
   pause();
   id_btn_video_play.setVisibility();
   (.video_pause);
   mPlayerStatus = PLAYER_STATUS.PAUSED;
   (UI_EVENT_UPDATE_CURRPOSITION, 500);
  }else if(isPause()){
   resume();
   id_btn_video_play.setVisibility();
   (.video_play);
   mPlayerStatus = PLAYER_STATUS.RESUMED;
  }else{
   (.video_play);
   id_btn_video_play.setVisibility();
   startPlay();
   mPlayerStatus = PLAYER_STATUS.PREPARING;
  }
 }

 private boolean isCurrentLandscape = false; //Is it horizontal screen //How to click on the horizontal and vertical screen switch button public void toggleScreenDir(View v){
  if (isCurrentLandscape) {// If it is currently a horizontal screen, switch to a vertical screen and then turn the button into a larger icon   (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
   if(v instanceof ImageView){
    ((ImageView)v).setImageResource(.zuidahua_2x);
   }
  } else {// If it is currently a vertical screen, switch to horizontal screen and then turn the button into a smaller icon   (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
   if(v instanceof ImageView){
    ((ImageView)v).setImageResource(.xiaohua_2x);
   }
  }
  isCurrentLandscape = !isCurrentLandscape;
 }

 public UIHandler mUIHandler = new UIHandler(());
 public final int UI_EVENT_UPDATE_CURRPOSITION = 1; //Update progress information public boolean isSeekBarEnable = true;

 class UIHandler extends Handler{
  public UIHandler(Looper mainLooper) {
   super(mainLooper);
  }

  @Override
  public void handleMessage(Message msg) {
   switch () {
    //Update progress and time    case UI_EVENT_UPDATE_CURRPOSITION:
     if (isSeekBarEnable) {
      int currentPosition = getCurrentTime();
      String timeString = (currentPosition);
      //("handleMessage",timeString);
      if(isPlaying()) {
       (currentPosition);
       (
         UI_EVENT_UPDATE_CURRPOSITION, 200);
      }
     }
     break;
   }
  }
 }

 public void sendUIMessage(){
  (UI_EVENT_UPDATE_CURRPOSITION);
 }

 public void removeUIMessage(){
  (UI_EVENT_UPDATE_CURRPOSITION);
 }

 //Get the total video time public int getTotalTime(){
  return mVideoView==null ? 0 : ();
 }

 //Get the current video time public int getCurrentTime(){
  return mVideoView==null ? 0 : ();
 }
}

2. Use of gesture recognizer

//1. Create gesture recognizer progressGestureDetector = new GestureDetector(mContext,new ProgressGestureListenr());

//2. 6 ways to rewriteboolean onDown(MotionEvent e) //The user presses the screen and triggers
void onShowPress(MotionEvent e) /////The down event occurs and move or up triggers the event before it occurs
boolean onSingleTapUp(MotionEvent e) //One click up event
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) //Drag events on the screen
void onLongPress(MotionEvent e) //Long press event
 boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) //Swipe gesture event
 //3 Intercept in onTouch @Override
 public boolean onTouch(View view, MotionEvent event) {

  return (event);
 }
 //4 Event binding (this);

3. Customize the video control panel

The code is relatively simple and the code is not long. There are comments. If you need it, please refer to it. Don't spray it.

package ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;

public class VideoController extends RelativeLayout implements ,,{

 private Context mContext;
 private View mContainer;
 private VideoBusiness videoBusiness;
 /** Indicates whether the current video control panel is displayed*/
 public boolean isShow = true;
 private Handler hideHandler = new Handler() {
  @Override
  public void handleMessage(Message msg) {
   if (isShow) {
    hideController();
   }
  }
 };
 /** Video function control bottom sidebar*/
 private LinearLayout mMediaController;

 /***************Gelephics Related******************/
 private int GESTURE_FLAG = 0;//1 Adjust progress, 2 Adjust volume, 3 Adjust brightness private FrameLayout mProgressIndicator;
 private ProgressBar progressBar;
 /**Progress related*/
 private GestureDetector progressGestureDetector;
 private static final int GESTURE_MODIFY_PROGRESS = 1;
 /**Volume related*/
 private static final int GESTURE_MODIFY_VOLUME = 2;
 private AudioManager audiomanager;
 private int maxVolume, currentVolume;
 /**Brightness related*/
 private static final int GESTURE_MODIFY_BRIGHTNESS = 3;
 private  brightnessLp;
 private int maxBrightness,currentBrightness;
 private LinearLayout progressArea;
 private int targetTime;
 //UI related private RelativeLayout id_rl_video_controller;
 private FrameLayout id_fl_video_play;
 private FrameLayout id_fl_video_expand;
 private TextView id_video_time;
 private TextView id_video_totaltime;
 private SeekBar id_sb_progress;
 private ImageView id_btn_video_play;
 private ImageView id_iv_video_play;
 private TextView id_tv_video_info;


 public VideoController(Context context) {
  this(context, null);
 }

 public VideoController(Context context, AttributeSet attrs) {
  this(context, attrs, 0);
 }

 public VideoController(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  mContext = context;
  init();
  initListener();
 }

 private void init() {
  //Initialize volume related  audiomanager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
  maxVolume = (AudioManager.STREAM_MUSIC); // Get the maximum volume of the system  currentVolume = (AudioManager.STREAM_MUSIC); // Get the current value  //Initialize brightness related  brightnessLp=((Activity)mContext).getWindow().getAttributes();
  currentBrightness = getCurrentBrightness();
  maxBrightness = 255; //Set maximum brightness  initView();
 }

 private void initView() {
  mContainer = (mContext, .video_controller, null);
  id_rl_video_controller = findView(.id_rl_video_controller);
  mMediaController = findView(.id_ll_controller);
  mProgressIndicator = findView(.id_fl_progress_indicator);
  progressBar = findView(.id_pb_gesture_progress);
  progressArea = findView(.id_ll_video_gesture_progress);
  id_fl_video_play = findView(.id_fl_video_play);
  id_fl_video_expand = findView(.id_fl_video_expand);
  id_video_time = findView(.id_video_time);
  id_video_totaltime = findView(.id_video_totaltime);
  id_sb_progress = findView(.id_sb_progress);
  id_btn_video_play = findView(.id_btn_video_play);
  id_iv_video_play = findView(.id_iv_video_play);
  id_tv_video_info = findView(.id_tv_video_info);
  addView(mContainer);
 }

 private <T extends View> T findView(int viewId) {
  return (T) (viewId);
 }

 public void setVideoBusiness(VideoBusiness videoBusiness) {
   = videoBusiness;
 }

 private void initListener() {
  //Progress gesture related  progressGestureDetector = new GestureDetector(mContext,new ProgressGestureListenr());
  (true);
  (true);
  (this);
  (this);
  id_rl_video_controller.setOnClickListener(this);
  id_fl_video_play.setOnClickListener(this);
  id_fl_video_expand.setOnClickListener(this);
  id_btn_video_play.setOnClickListener(this);
  id_sb_progress.setOnSeekBarChangeListener(this);
 }

 //Status Switch public void toggle() {
  if (isShow) {
   hideController();
  } else {
   showController();
  }
 }

 //Hide the bottom control bar public void hideController() {
  isShow = false;
  ();
  endTimer();
 }

 //Show the bottom control bar public void showController() {
  isShow = true;
  ();
  startTimer();
 }

 private void startTimer() {
  if (hideHandler != null){
   (0);
  }
  (0, 5000);
 }

 private void endTimer() {
  (0);
 }

 public void resetTimer() {
  endTimer();
  startTimer();
 }

 public void showLong() {
  isShow = true;
  ();
 }

 //Set the total video time public void setTotalTime(int time) {
  String totalTime = getTimeString(time);
  id_video_totaltime.setText(totalTime);
 }

 //Set the current video progress public void setProgress(int progress){
  int maxProgress = ();
  int tempProgress = progress > maxProgress ? maxProgress : progress;
  id_sb_progress.setProgress(tempProgress);
 }

 //Refers to the total video progress public void setMaxProgress(int maxProgress){
  id_sb_progress.setMax(maxProgress);
 }

 //Get the current brightness private int getCurrentBrightness(){
  int currentBrightness = 255;
  if ( == .BRIGHTNESS_OVERRIDE_NONE){
   // Get system brightness   try {
    currentBrightness = (((Activity)mContext).getContentResolver(), .SCREEN_BRIGHTNESS);
   } catch ( e) {
    ();
   }
  }else{
   // Get the current window brightness   currentBrightness = (int)( * 255);
  }
  return currentBrightness;
 }


 @Override
 public void onClick(View view) {
  switch (()){
   case .id_ll_controller: //Bottom Controller    showController();
    break;
   case .id_rl_video_controller: //Click on full screen    toggle();
    break;
   case .id_fl_video_play: // Pause/play   case .id_btn_video_play: // Pause/play    (id_btn_video_play,id_iv_video_play);
    break;
   case .id_fl_video_expand: //full screen    resetTimer();
    (view);
    break;
  }
 }


 @Override
 public boolean onTouch(View view, MotionEvent event) {

  getParent().requestDisallowInterceptTouchEvent(true);
  if (() == MotionEvent.ACTION_UP) {
   ();
   if (GESTURE_FLAG == GESTURE_MODIFY_PROGRESS) { //Adjust the progress    ("Progress Time","targetTime="+targetTime);
    (targetTime);
     = true;
    hideController();
   }
   GESTURE_FLAG = 0;// After your finger leaves the screen, reset the sign to adjust the volume or progress  }
  return (event);
 }

 private int currentPosition; //Current playback progress private int totalPosition; //Total playback progress class ProgressGestureListenr implements {
  private boolean firstScroll = false;// The first scroll logo after each touching the screen  private int slop;// Minimum distance to trigger the setting change  @Override
  public boolean onDown(MotionEvent e) { //The user presses the screen and triggers   //Initial data   slop = DensityUtil.dp2px(mContext,2);
   currentPosition = ();
   totalPosition = ();
   firstScroll = true;
   return false;
  }

  @Override
  public void onShowPress(MotionEvent e) { //The down event occurs and move or up triggers the event before it occurs  }

  @Override
  public boolean onSingleTapUp(MotionEvent e) { //One click up event   toggle();
   if(()){ // Playing    return false;
   }else{ //Pause or start playback    (id_btn_video_play,id_iv_video_play);
    isShow = false;
    return true;
   }
  }

  //Drag events on the screen  @Override
  public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
   if (firstScroll) {// Use the first swipe after touching the screen to avoid messy switching on the screen    // If the horizontal distance changes greatly, adjust the progress; if the vertical distance changes greatly, adjust the volume    ("xxxxxxx",()+"");
    ("yyyyyyy",()+"");
    setScroll(e1, distanceX, distanceY);
   }
   // If the first scroll scroll after each touching the screen is to adjust the progress, then the subsequent scroll event will process the volume progress until the next operation is left to perform the next operation   switch (GESTURE_FLAG){
    case GESTURE_MODIFY_PROGRESS: //Adjust the current progress     setCurrentProgress(distanceX, distanceY,slop);
     break;
    case GESTURE_MODIFY_VOLUME: //Adjust the current volume     setCurrentVolume(distanceX, distanceY,slop);
     break;
    case GESTURE_MODIFY_BRIGHTNESS: //Adjust the current brightness     setCurrentBrightess(distanceX, distanceY,slop);
     break;
   }
   firstScroll=false;
   return false;
  }

  @Override
  public void onLongPress(MotionEvent e) { //Long press event  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { //Swipe gesture event   return false;
  }
 }

 //Sliding Event private void setScroll(MotionEvent e1, float distanceX, float distanceY) {
  int screenWidth = (mContext);
  ("Screen Width",screenWidth+"");
  //If the horizontal distance changes greatly, adjust the progress; if the vertical distance changes greatly, adjust the volume.  ();
  if ((distanceX) >= (distanceY)) { //Adjust the progress   ();
   id_tv_video_info.setVisibility(VISIBLE);
   GESTURE_FLAG = GESTURE_MODIFY_PROGRESS;
    = false;
   endTimer();
   showLong();
  }else { //Adjust the volume   (VISIBLE);
   id_tv_video_info.setVisibility(INVISIBLE);
   if (() > screenWidth / 2){ //Swipe up and down to adjust the volume on the right side of the screen    //The volume of the right half screen    setVideoVolume();
   }else{        //Swipe up and down to adjust brightness on the left side of the screen    //The brightness of the left half screen    setVideoBrightness();
   }
  }
 }

 //Set the current progress private void setCurrentProgress(float distanceX, float distanceY,float slop) {
  if ((distanceX) > (distanceY)) {// horizontal movement is greater than vertical movement   //("setCurrentProgress",distanceX+"");
   if(distanceX >= slop){ //Swipe from right to left    ();
    if (currentPosition > 1000) {
     currentPosition -= 1500;
    }
   }else if(distanceX <= -slop){ //Swipe from left to right    ();
    if (currentPosition < totalPosition) {
     currentPosition += 1500;
    }
   }
  }
  targetTime = currentPosition;
  ("Progress Time","currentPosition="+currentPosition);
  id_sb_progress.setProgress(currentPosition);
  id_video_time.setText(getTimeString(currentPosition));
  String videoPbInfo = getTimeString(currentPosition)+"/"+ getTimeString(totalPosition);
  id_tv_video_info.setText(videoPbInfo);
 }

 //Set the current brightness private void setCurrentBrightess(float distanceX, float distanceY, float slop) {
  currentBrightness = getCurrentBrightness();
  if ((distanceY) > (distanceX)) {// Vertical movement is greater than horizontal movement   if (distanceY >= slop) {// Slide up and increase the brightness, pay attention to the coordinate system when horizontal screen. Although the upper left corner is the origin, distanceY is positive when sliding horizontally upward    if (currentBrightness < maxBrightness) {// To avoid too fast adjustment, distanceY should be greater than one set value     currentBrightness += 8;
    }
   } else if (distanceY <= -slop) {// Change the brightness    if (currentBrightness > 0) {
     currentBrightness -= 8;
    }
    if (currentBrightness<0){
     currentBrightness=0;
    }
   }
   ();
   (currentBrightness);
   changeAppBrightness(mContext,currentBrightness);
  }
 }

 //Set the current volume private void setCurrentVolume(float distanceX, float distanceY,float slop) {

  currentVolume = (AudioManager.STREAM_MUSIC); // Get the current value  if ((distanceY) > (distanceX)) { // Vertical movement is greater than horizontal movement   if (distanceY >= slop) { // Swipe up. Turn up the volume. Pay attention to the coordinate system when horizontal screen. Although the upper left corner is the origin, distanceY is positive when sliding horizontally upward.    if (currentVolume < maxVolume) {// To avoid too fast adjustment, distanceY should be greater than one set value     currentVolume++;
    }
    ();
   } else if (distanceY <= -slop) {// Turn down the volume and slide down    if (currentVolume > 0) {
     currentVolume--;
     if (currentVolume == 0) {// Mute, set the unique picture of mute      ();
     }
    }
   }
   (currentVolume);
   (AudioManager.STREAM_MUSIC, currentVolume, 0);
  }
 }

 //Set video brightness private void setVideoBrightness() {
  (maxBrightness);
  (currentBrightness);
  ();
  GESTURE_FLAG = GESTURE_MODIFY_BRIGHTNESS;
 }

 //Set the video volume private void setVideoVolume() {
  (maxVolume);
  (currentVolume);
  ();
  GESTURE_FLAG = GESTURE_MODIFY_VOLUME;
 }

 //Change the brightness of the system public void changeAppBrightness(Context context, int brightness) {
  Window window = ((Activity) context).getWindow();
   lp = ();
  if (brightness == -1) {
    = .BRIGHTNESS_OVERRIDE_NONE;
  } else {
    = (brightness <= 0 ? 1 : brightness) / 255f;
  }
  (lp);
 }

 public String getTimeString(int second) {
  int temp = second / 1000;
  int hh = temp / 3600;
  SimpleDateFormat sdf;
  if (0 != hh) {
   sdf = new SimpleDateFormat("HH:mm:ss");
  } else {
   sdf = new SimpleDateFormat("mm:ss");
  }
  String format = (new Date(second));
  return format;
 }

 //The progress bar changes @Override
 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
  String timeString = getTimeString(progress);
  id_video_time.setText(timeString);
 }

 //Start drag @Override
 public void onStartTrackingTouch(SeekBar seekBar) {
  showLong();
  ();
 }

 //End drag @Override
 public void onStopTrackingTouch(SeekBar seekBar) {
  showController();
  int progress = ();
  (progress);
 }

}

4. Download address

VideoView native custom video player

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.