104

I have the following code to take a video as a raw resource, start the video and loop it but I need the video to loop seamlessly as of now when it comes to an end of the clip and starts the clip again the transition between causes a flicker for a split second, which I really can't have for my app.

public class Example extends Activity {
    VideoView vv;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        vv = (VideoView)findViewById(R.id.VideoView01);

        //Video Loop
        vv.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            public void onCompletion(MediaPlayer mp) {
                vv.start(); //need to make transition seamless.
            }
        });

        Uri uri = Uri.parse("android.resource://com.example/"
                + R.raw.video);

        vv.setVideoURI(uri);
        vv.requestFocus();    
        vv.start();
    }
}

The clip is only 22 seconds long but was created to be seamless so it is possible to work without the delay.

Jonik
  • 80,077
  • 70
  • 264
  • 372
SamRowley
  • 3,435
  • 7
  • 48
  • 77

8 Answers8

256

Try this it will work 100%


VideoView videoView;<---write this in outside of method or else declare it as final variable.

videoView.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.setLooping(true);
    }
});
luckyging3r
  • 3,047
  • 3
  • 18
  • 37
PravinDodia
  • 3,271
  • 1
  • 18
  • 22
  • Still rebuffer for every loop, it's not smooth as the method before to me – Pencilcheck Dec 29 '13 at 21:04
  • @Pencilcheck this is simple looping for local video, if you want to use it for url and buffering it, then you have to implement other logic. – PravinDodia Jan 06 '14 at 08:50
  • FYI to everyone, This does not work for local videos as well. If you play a video with constant sound, you can hear the pause in between loops. – Edison Mar 17 '14 at 18:17
  • I can confirm it works for local videos without voice. I'm using it as a video background... – Aron Lorincz Oct 06 '15 at 17:45
  • 1
    @PravinDodia It works for mp4 video(File) but not working with m3u8. Please suggest me a solution if you have any Idea about the m3u8 file. – Maroti Dec 11 '15 at 07:31
  • @Shailesh, As per my knowledge the looping can be done, only while the video is local or downloaded and then played. and if i am not wrong, the m3u8 is used to stream videos, which will not loop, you might have to restart the whole media again on finish. But make sure that you release the old obj of media player and create a new one, other wise it would not be memory friendly. – PravinDodia Dec 11 '15 at 11:00
  • 2
    @PravinDodia Thanks for the info. Yes, I have used stream video. I have used vv.start() in MediaPlayer.OnCompletionListener() instead of looping. – Maroti Dec 11 '15 at 11:05
19

In Kotlin simply use

videoView.setOnPreparedListener { it.isLooping = true }
Chirag Kalra
  • 509
  • 2
  • 8
  • 23
9

Not sure if this helps years later, but I used

vv.start();
vv.setOnCompletionListener ( new MediaPlayer.OnCompletionListener() {

 @Override 
  public void onCompletion(MediaPlayer mediaPlayer) {   
    vv.start();
  }
});

and it has a seamless loop

lexodus k
  • 97
  • 1
  • 2
5

The pause is for the underlying MediaPlayer to refresh its buffers. How long that will take will depend on a number of factors, many of which are outside your control (e.g., speed of CPU, speed of on-board flash storage).

One you can control is to get your video out of the resource and into the filesystem. Resources are stored in the APK, which is a ZIP file, so extracting the video this way probably takes extra time.

You may need to switch away from VideoView and use a SurfaceView with two MediaPlayers, alternating between them -- one is playing while the next is preparing, so when the playing one ends you can switch to the new player. I have not tried this, and so I do not know what the ramifications might be. However, I know that this technique is frequently used for audio playback to transition from one clip to another.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • If I remember correctly, MediaPlayers hold on to surfaceViews when getting prepared, so you can't prepare another mediaPlayer while one is using it. – Edison Mar 17 '14 at 18:18
2

Little late, but any reason that you can't use the following?

MediaPlayer.setLooping(true);
J J
  • 1,550
  • 4
  • 17
  • 27
  • 1
    This was a long time ago, but with that I think there was a noticeable pause in the video when the loop around was called. – SamRowley Jul 18 '11 at 07:52
1

If you are using Kotlin

 videoView.setOnPreparedListener(object : MediaPlayer.OnPreparedListener {
                override fun onPrepared(mp: MediaPlayer?) {
                    //Start Playback
                    videoView.start()
                    //Loop Video
                    mp!!.isLooping = true;
                    Log.i(TAG, "Video Started");
                }
            });

Using Arrow Expression short form

videoView.setOnPreparedListener { mp ->
            //Start Playback
            videoView.start()
            //Loop Video
            mp!!.isLooping = true;
            Log.i(TAG, "Video Started");
        };
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
0

Here is answer friends, you must use vv.resume in setOnCompletionListener class

[https://stackoverflow.com/a/27606389/3414469][1]

Community
  • 1
  • 1
ylmzekrm1223
  • 103
  • 5
  • 15
0

Answer to this is to remove the audio from the video and convert that to a .ogg file which can be looped seamlessly and then use the video without audio to loop round and this works.

SamRowley
  • 3,435
  • 7
  • 48
  • 77