27

I'm using a VideoView component to play videos. I can't seem to clear the VideoView display after I manually invoke stopPlayback(). I would like to reset the VideoView so that the original background is visible.

  1. Play a video in a VideoView component.
  2. Select a new video to play.
  3. The VideoView is stuck on the last frame of the first video until the next video starts. If there is an error with the next video, the static image from the first video remains stuck there.
  4. If I let the video play to completion state, the display is cleared.

The code I'm using:

private VideoView videoViewer = null;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
  if (videoViewer != null) {
    videoViewer.setOnPreparedListener(new OnPreparedListener());
  }
...
}

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  if (videoViewer != null) {
    videoViewer.stopPlayback();
    videoViewer.setVideoURI(Uri.parse("http://my_vido_url/playlist.m3u8"));
  }
}

private class OnPreparedListener implements MediaPlayer.OnPreparedListener {
  @Override
  public void onPrepared(MediaPlayer mp) {
    videoViewer.start();
  }
}

Note that based on the VideoView.java source, stopPlayback() takes the following action on the underlying MediaPlayer:

public void stopPlayback() {
  if (mMediaPlayer != null) {
    mMediaPlayer.stop();
    mMediaPlayer.release();
    mMediaPlayer = null;
  }
}
DanielB6
  • 1,181
  • 1
  • 10
  • 22

6 Answers6

18

For me, what worked was simply to hide then show the VideoView using setVisibility.

public void clearCurrentFrame() {
    videoView.setVisibility(GONE);
    videoView.setVisibility(VISIBLE);
}

This was because I wanted the VideoView to become transparent, not be a solid colour. Setting the background to transparent doesn't work -- the video frame still shows.

William
  • 2,917
  • 5
  • 30
  • 47
  • 1
    I just received a suggested edit from an anonymous user saying to put `videoView.stopPlayback();` as the last line of code. I cannot verify that it is necessary, although the video will need to already be stopped for my answer to work. Just wanted to leave it here in case it helps anybody :) – William Dec 20 '16 at 17:33
  • @Willam thanks for you answer, i just address one issue. – hio Dec 25 '20 at 14:31
14

The solution I settled on, unless someone can offer a better one, is to use setBackgroundResource, which seems oddly named since it appears to change the foreground resource.

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
...
  videoViewer.setBackgroundResource(R.drawable.viewer_background);
...
}

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  if (videoViewer != null) {
    videoViewer.stopPlayback();
    // Set the background back to the drawable resource to clear the current video when switching to a new one.
    videoViewer.setBackgroundResource(R.drawable.viewer_background);
    videoViewer.setVideoURI(Uri.parse("http://my_vido_url/playlist.m3u8"));
  }
}

private class OnPreparedListener implements MediaPlayer.OnPreparedListener {
  @Override
  public void onPrepared(MediaPlayer mp) {
    videoViewer.start();
    // Clear the background resource when the video is prepared to play.
    videoViewer.setBackgroundResource(0);
  }
}

The drawable I'm referencing is a simple layer-list with a custom blue background and a centered logo image.

drawable\viewer_background.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
  <item>
    <shape android:shape="rectangle">
      <solid android:color="@color/custom_blue" />
    </shape>
  </item>
  <item>
    <bitmap android:src="@drawable/img_logo"
      android:gravity="center" />
  </item>
</layer-list>

Alternatively I was also able to use setZOrderOnTop to control where the surface view is placed (you could also define another view on top of the VideoViewer and toggle the visibility that way):

videoViewer.setZOrderOnTop(false);
videoViewer.setZOrderOnTop(true);

Alternatively I could also use setBackgoundColor to accomplish the same thing as setBackgroundResource:

videoViewer.setBackgroundColor(getResources().getColor(R.color.custom_blue));
videoViewer.setBackgroundColor(Color.TRANSPARENT);
DanielB6
  • 1,181
  • 1
  • 10
  • 22
  • When I do this, the next playback still shows the last frame of the previous one. Any ideas as to why that happens? – slhck Nov 17 '14 at 09:40
  • Actual video frame is drawn on a surface "underneath" the VideoView. Setting background on VideoView will hide the frame, but not erase it. When the background is cleared the old frame is still there. – William Feb 12 '15 at 02:14
2

just this code:

videoView.setVideoURI(null);
mojtaba
  • 86
  • 2
1

Well, for me none of the solutions from this thread worked, so I tried something else and below is the solution that worked for me,

new Handler().postDelayed(new Runnable() {

     @Override
     public void run() {
        mVideoViewPlayList.setVisibility(View.GONE);
        mVideoViewPlayList.setVisibility(View.VISIBLE);
        mVideoViewPlayList.setVideoURI(Uri.parse(path));
    }
}, 500);
Lalit Poptani
  • 67,150
  • 23
  • 161
  • 242
  • No offense. I really wonder what's the purpose of those lines. mVideoViewPlayList.setVisibility(View.GONE); mVideoViewPlayList.setVisibility(View.VISIBLE); – Evren Ozturk Nov 30 '16 at 08:23
  • 3
    @PsyCoder in some devices, mVideoViewPlayList.setVideoURI(Uri.parse(path)) was not taking effect until the visibility change atleast once! – Lalit Poptani Nov 30 '16 at 09:40
  • Thank you for the explanation. It might save my time some day :) – Evren Ozturk Dec 01 '16 at 06:34
1

You can do like this;

videoView.stopPlayBack();   
 videoView.seekTo(0);  

hope that may help you

0

The Media Controller class already has this feature among itself, with this simple code below you can create all the necessary interactions.

MediaController mediaController = new MediaController (this); 
videoView.setMediaController(mediaController);
kalehmann
  • 4,821
  • 6
  • 26
  • 36