2

I'm using VideoView to loop a small video, all works fine on the emulators, but when I deploy that to TV, after the first loop video turns black, but sound keeps going. This is the code:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.layout);

    VideoView videoview = (VideoView) findViewById(R.id.videoview1);
    Uri uri = Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.video);
    videoview.setVideoURI(uri);

    videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.setLooping(true);
            videoview.start();
        }
    });
}

The Emulator is using Android 6.0, the TV is Sony Bravia with Android 6.0.1. I tested using SurfaceView, instead of VideoView - the same thing happens.

Any idea how to get rid of that black screen?

PS: There is a workaround that works - make OnCompletionListener and do videoview.start() there - this way it loops, but there's an ugly gap between the loops.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
LachoTomov
  • 3,312
  • 30
  • 42
  • Have you tried removing videoview.start(); out of setOnPreparedListener? You will always notice a pause on some devices with this approach by the way, as setLooping(true) doesn't refresh its buffers in time before it restarts. I've heard that other people do it with two mediaplayers and switch between them. But what I've done is used is a gif with sound on the background it's also cumborsome but looks nice. – jobbert Dec 05 '17 at 15:54

4 Answers4

4

Just use this mVideoView.setZOrderOnTop(true); It will not show the black screen as the view appears.

ॐ Rakesh Kumar
  • 1,318
  • 1
  • 14
  • 24
3

Try to set your VideoView using handler like this.

   videoview.setBackgroundColor(Color.WHITE); //color what you want as background
   videoview.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        videoview.setVideoURI(videoUri);
                    }
                }, 100);
    videoview.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        vv.setBackgroundColor(Color.TRANSPARENT);
                    }
                }, 300);
                videoview.requestFocus();
                videoview.start();

    videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener()            {            @Override
        public void onPrepared(MediaPlayer mp) {
            mp.setLooping(true);

        }
    });
Radhey
  • 2,139
  • 2
  • 24
  • 42
2

I have looked into the source code of VideoView and the first thing that I would like to point out is that inside the setVideoURI() method the MediaPlayer object will be created, and the OnPreparedListener will be set.

Your mistake is that you set the OnPreparedListener after the MediaPlayer may already have prepared the video, thus never call the onPrepared in the listener you have set after that, which means the setLooping(true) was maybe never set on the MediaPlayer.

TL;DR:

Put videoview.setVideoURI(uri); after videoview.setOnPreparedListener().

videoview.start() should be after setVideoURI(). On finish it should start again without additional input because this time mp.setLooping(true); was correctly set and will be executed. No videoview.start() is necessary after the initial one.

Chapz
  • 605
  • 7
  • 13
0

I actually ended up using ExoPlayer instead of the default one. It's a bit harder to set up, but this problem didn't show up there.

LachoTomov
  • 3,312
  • 30
  • 42