Płynna pętla wideo dzięki VideoView

88

Mam następujący kod, aby pobrać wideo jako surowe zasoby, uruchomić wideo i zapętlić je, ale potrzebuję, aby wideo było teraz płynnie zapętlone, jeśli chodzi o koniec klipu i ponownie uruchamia klip, przejście między powoduje migotanie przez ułamek sekundy, czego naprawdę nie mogę mieć w mojej aplikacji.

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();
    }
}

Klip ma tylko 22 sekundy, ale został stworzony tak, aby był płynny, więc można pracować bez opóźnień.

SamRowley
źródło

Odpowiedzi:

230

Spróbuj, to zadziała w 100%


VideoView videoView;<--- zapisz to poza metodą lub zadeklaruj jako zmienną końcową.

videoView.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.setLooping(true);
    }
});
PravinDodia
źródło
Nadal rebuffer dla każdej pętli, nie jest tak płynny, jak metoda poprzednia dla mnie
Pencilcheck
@Pencilcheck to prosta pętla dla lokalnego wideo, jeśli chcesz użyć go do adresu URL i buforować go, musisz zaimplementować inną logikę.
PravinDodia,
Informacja dla wszystkich. To nie działa również w przypadku lokalnych filmów. Jeśli odtwarzasz wideo ze stałym dźwiękiem, możesz usłyszeć przerwę między pętlami.
Edison,
1
@PravinDodia Działa z wideo mp4 (plik), ale nie działa z m3u8. Proszę zasugerować mi rozwiązanie, jeśli masz jakiś pomysł na plik m3u8.
Maroti,
2
@PravinDodia Dzięki za informację. Tak, korzystałem ze strumienia wideo. Użyłem vv.start () w MediaPlayer.OnCompletionListener () zamiast pętli.
Maroti,
7

Nie jestem pewien, czy to pomoże po latach, ale użyłem

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

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

i ma płynną pętlę

lexodus k
źródło
5

Przerwa służy MediaPlayerdo odświeżania buforów przez element bazowy . To, jak długo to potrwa, zależy od wielu czynników, z których wiele jest poza Twoją kontrolą (np. Szybkość procesora, prędkość wbudowanej pamięci flash).

Jedną z możliwości kontrolowania jest przeniesienie wideo z zasobu do systemu plików. Zasoby są przechowywane w pliku APK, który jest plikiem ZIP, więc wyodrębnienie wideo w ten sposób prawdopodobnie zajmie więcej czasu.

Może zajść potrzeba przełączenia się VideoViewi użycia SurfaceViewdwóch MediaPlayers, naprzemiennie - jeden gra, a drugi przygotowuje, więc gdy gra się skończy, możesz przełączyć się na nowego gracza. Nie próbowałem tego, więc nie wiem, jakie mogą być tego konsekwencje. Wiem jednak, że ta technika jest często używana do odtwarzania dźwięku w celu przejścia z jednego klipu do drugiego.

CommonsWare
źródło
Jeśli dobrze pamiętam, MediaPlayery trzymają się SurfaceViews podczas przygotowań, więc nie możesz przygotować innego mediaPlayera, gdy jeden z nich korzysta.
Edison,
2

W Kotlinie po prostu użyj

videoView.setOnPreparedListener { mp -> mp.isLooping = true }
Chirag Kalra
źródło
1

Trochę późno, ale jest jakiś powód, dla którego nie możesz użyć następujących?

MediaPlayer.setLooping(true);
JJ
źródło
1
To było dawno temu, ale myślę, że po wywołaniu pętli w filmie była zauważalna przerwa.
SamRowley,
1

Jeśli używasz 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");
                }
            });

Używanie krótkiej formy wyrażenia strzałki

videoView.setOnPreparedListener { mp ->
            //Start Playback
            videoView.start()
            //Loop Video
            mp!!.isLooping = true;
            Log.i(TAG, "Video Started");
        };
Hitesh Sahu
źródło
0

Odpowiedzią na to jest usunięcie dźwięku z wideo i przekonwertowanie go na .oggplik, który można płynnie zapętlić, a następnie użyć wideo bez dźwięku do zapętlenia i to działa.

SamRowley
źródło