0

I am adding a basic video player with VideoView and MediaController.

The SeekBar provided by the MediaController stops at 0:02 min while the video is playing till the end. I have tried this on 3 different devices with different video lengths.

How to ensure that SeekBar progress and time are in sync with the video?

Here is the relevant code:

VideoPlayerDialog.java

videoView.setVisibility(View.VISIBLE);
MediaController mediaController = new MediaController(getContext());

FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT);
lp.gravity = Gravity.BOTTOM;
mediaController.setLayoutParams(lp);

((ViewGroup) mediaController.getParent()).removeView(mediaController);
((FrameLayout) findViewById(R.id.videoViewWrapper)).addView(mediaController);

videoView.setMediaController(mediaController);
videoView.setVideoURI(imageUri);
videoView.requestFocus();

dialog_image_preview.xml

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black87">

    <uk.co.senab.photoview.PhotoView
        android:id="@+id/photo_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" />

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/videoViewWrapper"
        android:layout_centerInParent="true"
        android:layout_margin="30dp">

        <VideoView
            android:id="@+id/videoplayer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </FrameLayout>

    <ImageButton
        android:id="@+id/close"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/circular_button_material"
        android:elevation="10dp"
        android:padding="5dp"
        android:src="@drawable/ic_close" />
</RelativeLayout>
Harish Vishwakarma
  • 480
  • 1
  • 5
  • 14

3 Answers3

3

I have found the answer. On your MediaController constructor, override it's hide() void and use this.show() in it so the MediaController shows when it hides. The reason for this, is because MediaController automatically hides itself after 3 seconds by default, even with show(0). So, if you force the MediaController to be shown, it will still act as if it's hiding after 3 seconds (seekbar stops syncing, play/pause button not updating). Overriding the hide() void to show the MediaController combats this.

You can also create a custom class that extends MediaPlayer to ovverride hide() as well.

Example code:

final MediaController mediaController =  new MediaController(context){
    @Override
    public void hide() {
        this.show();
    }
};
xjonx
  • 83
  • 2
  • 6
  • 1
    This looks like a good answer. However I found another way around using this code. Cannot test the answer myself. If someone confirms I will mark this as correct answer. – Harish Vishwakarma Jul 20 '18 at 20:12
  • 1
    @HarishVishwakarma - what was your other way around? You can always post as a comment. – Charan Aug 04 '20 at 11:02
  • I tested it and it really works!! but the issue is I played video in dialog and after pressing back button it freezes the screen, and if I remove this line video dialog closes perfectly fine and no issue with back press also but then seekbar stops after 2 sec – Anshul Khare Jun 10 '21 at 15:21
  • @AnshulKhare It's been awhile but you can try to create a subclass of MediaController, add a field `private bool shouldSync = false;`, add both a getter and a setter for `shouldSync`, then override `hide` and write `if (shouldSync) show();`. Now you can do `mMediaCtrl.setShouldSync(true);` on dialog open and `mMediaCtrl.setShouldSync(false);` on dialog close. – xjonx Jun 13 '21 at 01:39
0

You could try connecting automatically the media controller to the Video View with

MediaController mediaController = new MediaController(this); mediaController.setAnchorView(videoView); videoView.setMediaController(mediaController);

Alex T
  • 163
  • 1
  • 9
0

Followed reference from here, I was able to resolve issue of seekbar which was stopping after 2 seconds and back press issue on which the screen was getting freeze.

I used dispatchkeyevent to detect back press and showed media controller after the start of video.

        videoView.setOnPreparedListener { mp ->

        progressBar.visibility = View.GONE

        mc = object : MediaController(mContext) {

            override fun dispatchKeyEvent(event: KeyEvent): Boolean {

                if (event.keyCode == KeyEvent.KEYCODE_BACK) {
                    super.hide()//Hide mediaController
                    scoreDialog.dismiss()//Close this dialog/activity

                    return true//If press Back button, finish here
                }
                //If not Back button, other button work as usual.
                return super.dispatchKeyEvent(event)
            }

        }
        videoView.setMediaController(mc)
        mc.setAnchorView(videoView)

        (mc.parent as ViewGroup).removeView(mc)

        (scoreDialog.findViewById(R.id.videoViewWrapper) as FrameLayout).addView(mc)
        
        mp.start()
        mc.show(0)
    }
Anshul Khare
  • 219
  • 1
  • 3
  • 15