So implementieren Sie oncompletionlistener, um das Ende einer Mediendatei in Exoplayer zu erkennen

Lesezeit: 6 Minuten

Benutzeravatar von user2949215
Benutzer2949215

Ich versuche Videos in Form einer Playlist nacheinander abzuspielen. Ich verwende Android Exoplayer, um meine Dateien abzuspielen, aber es gibt keine Listener im Mediaplayer, um das Ende der Mediendatei anzuhören. Gibt es eine Möglichkeit, das Ende der Mediendatei mit Exoplayer anzuhören?

Ich weiß, das ist alt, aber nur um die akzeptierte Antwort zu erweitern:

exoPlayer.addListener(this);

.....

@Override
public void onPlayerStateChanged(boolean playWhenReady, int state) {

    if (state == ExoPlayer.STATE_ENDED){
        //player back ended
    }
}

  • onPositionDiscontinuity() heißt das in meinem fall wie geht das dann?

    – Maveňツ

    16. Mai 2017 um 13:23 Uhr

Benutzeravatar von Murtaza Khursheed Hussain
Murtaza Khursheed Hussain

Exoplayer bietet eine erweiterte Implementierung, die Mediaplayer nicht bieten.

im Voraus Beispiel für Exoplayer von Android, im FullPlayerActivity.java sie haben umgesetzt onStateChangeddie anbietet STATE_ENDED

Sie können ein Beispiel im rechten Bereich von herunterladen diese Seite unter Laufzeit VERWANDTE PROBEN

  • Sie haben das SDK und die Beispiele aktualisiert, eine kleine Suche wird Ergebnisse liefern. Übrigens habe ich den defekten Link aktualisiert.

    – Murtaza Khursheed Hussain

    17. September 2015 um 6:25 Uhr

  • Kleines Detail Es ist onPlayerStateChanged. Möglich, dass sie es aktualisiert haben.

    – Keith Loughnane

    6. April 2017 um 12:41 Uhr

  • Wenn MediaSource LoopingMediaSource ist, wird das STATE_ENDED-Ereignis nicht ausgelöst.

    – Borsch

    7. November 2017 um 1:09 Uhr

Benutzeravatar von Morgan Koh
Morgan Koh

Google hat abgelehnt ExoPlayer.STATE_ENDED und wurde durch ersetzt Player.STATE_ENDED.

Da dieser Beitrag schon eine Weile her ist, schreibe ich einen Kotlin Version des Listeners unten.

this.simpleExoPlayer?.addListener(object : Player.DefaultEventListener() {
    override fun onPlayerStateChanged(playWhenReady: Boolean,playbackState: Int) {
        when (playbackState) {
            Player.STATE_IDLE -> {}
            Player.STATE_BUFFERING -> {}
            Player.STATE_READY -> {}
            Player.STATE_ENDED -> {}
        }
    }
})

AKTUALISIERUNG: 05-2020
Seit DefaultEventListener und onPlayerStateChanged() sind veraltet.

player.addListener(object : Player.EventListener {
     override fun onPlaybackStateChanged(state: Int) {
           if (state == Player.STATE_ENDED) {
              // your code
           }
     }
})

  • DefaultEventListener() ist veraltet, verwenden Sie stattdessen this.player?.addListener(object :Player.EventListener{ override fun onPlayerStateChanged(playWhenReady: Boolean,playbackState: Int) { when (playbackState) { Player.STATE_IDLE -> { progressBar.visibility=View. VISIBLE} Player.STATE_BUFFERING -> { progressBar.visibility=View.VISIBLE } Player.STATE_READY -> { progressBar.visibility=View.GONE} Player.STATE_ENDED -> { progressBar.visibility=View.GONE} } } })

    – Schwarze Mamba

    8. Juli 2019 um 12:09 Uhr


  • sieht aus als ob EventListener ist auch jetzt veraltet, es scheint nur zu müssen Player.Listener jetzt

    – a_local_nobody

    9. August 2021 um 9:49 Uhr

Du kannst das:

playerExo.addListener(new ExoPlayer.Listener() {

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

                switch(playbackState) {
                    case ExoPlayer.STATE_BUFFERING:
                        break;
                    case ExoPlayer.STATE_ENDED:
                        //do what you want
                        break;
                    case ExoPlayer.STATE_IDLE:
                        break;
                    case ExoPlayer.STATE_PREPARING:
                        break;
                    case ExoPlayer.STATE_READY:
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onPlayWhenReadyCommitted() {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {

            }
        });
        playerExo.seekTo(0);
        playerExo.setPlayWhenReady(true);

Aber die Antwort von @Murtaza Khursheed Hussain ist richtig! Habt einen schönen Codetag! Lassen Sie mich wissen, wenn Sie etwas anderes brauchen!

Sie müssen die Schnittstelle implementieren Player.EventLister und zu Ihrem exoPlayer hinzufügen.

Schreiben Sie einfach Ihren Code in die Methode onPlayerStateChanged. Siehe Code.

exoPlayer.addListener( new Player.EventListener() {
            @Override
            public void onTimelineChanged(Timeline timeline, @Nullable Object manifest, int reason) {

            }

            @Override
            public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

            }

            @Override
            public void onLoadingChanged(boolean isLoading) {

            }

            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

                switch(playbackState) {
                    case Player.STATE_BUFFERING:
                        break;
                    case Player.STATE_ENDED:
                        //Here you do what you want
                        break;
                    case Player.STATE_IDLE:
                        break;
                    case Player.STATE_READY:
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onRepeatModeChanged(int repeatMode) {

            }

            @Override
            public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {

            }

            @Override
            public void onPositionDiscontinuity(int reason) {

            }

            @Override
            public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

            }

            @Override
            public void onSeekProcessed() {

            }


        });

Benutzeravatar von aiga
Adi

Google hat ExoPlayer.STATE_ENDED eingestellt. Verwenden Sie stattdessen Player.STATE_ENDED. Siehe Code unten.

player.addListener(new Player.EventListener() {
    @Override
    public void onTimelineChanged(Timeline timeline, Object manifest, int reason) {


    }

    @Override
    public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {

    }

    @Override
    public void onLoadingChanged(boolean isLoading) {

    }

    @Override
    public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {

        if (playWhenReady && playbackState == Player.STATE_READY) {
            // Active playback.
        } else if (playbackState == Player.STATE_ENDED) {
            //The player finished playing all media

           //Add your code here

        } else if (playWhenReady) {
            // Not playing because playback ended, the player is buffering, stopped or
            // failed. Check playbackState and player.getPlaybackError for details.
        } else {
            // Paused by app.
        }

    }

    @Override
    public void onRepeatModeChanged(int repeatMode) {

    }

    @Override
    public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) {

    }

    @Override
    public void onPlayerError(ExoPlaybackException error) {

    }

    @Override
    public void onPositionDiscontinuity(int reason) {
        //THIS METHOD GETS CALLED FOR EVERY NEW SOURCE THAT IS PLAYED
      //  int latestWindowIndex = player.getCurrentWindowIndex();


    }

    @Override
    public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) {

    }

    @Override
    public void onSeekProcessed() {

    }
});

Du kannst nachschauen ExoPlayer-Entwicklerseite für mehr Informationen.

Akkis Benutzeravatar
Akki

Für nicht verkettete MediaSource (die jedes einzelne Medienelement darstellt, das Sie wiedergeben möchten) erhalten Sie STATE_ENDED wenn das Medienstück die Wiedergabe beendet hat.

Bei einer ConcatenatingMediaSource tritt dies auf, wenn die gesamte Verkettung abgespielt wurde (dh Sie haben bis zum Ende des letzten Elements in der Verkettung gespielt). STATE_ENDED tritt also auf, wenn die Wiedergabe der gesamten MediaSource beendet ist.

Für eine ConcatenatingMediaSource ist der beste Rückruf zum Erkennen des Endes des aktuellen Mediums und des Beginns der nächsten Medienwiedergabe „onPositionDiscontinuity“, das Sie verwenden sollten onPositionDiscontinuity() um herauszufinden, wann Übergänge auftreten. Bitte beachten Sie, dass onPositionDiscontinuity auch für einige andere Fälle aufgerufen wird, aber Sie können anrufen getCurrentWindowIndex() und vergleichen Sie es mit dem Fenster, in dem Sie sich Ihrer Meinung nach befinden, um festzustellen, ob ein Übergang stattgefunden hat. Sie können Folgendes tun:

public void onPositionDiscontinuity() {
  int newIndex = player.getCurrentWindowIndex();
  if (newIndex != currentIndex) {
    // The index has changed ==> last media has ended and next media playback is started.
    currentIndex = newIndex;
  }
}

Bitte beachten Sie: onPositionDiscontinuity() wird nicht für das erste Element in der Wiedergabeliste aufgerufen, es sei denn, wir rufen ausdrücklich player.seekTo(position,0) auf. Um also alles zu handhaben, was Sie für die gesamte Medienwiedergabe in der Wiedergabeliste tun, müssen Sie das erste Element in der Wiedergabeliste separat behandeln.

  • onPositionDiscontinuity() wird aufgerufen, wenn der Track geändert wird, aber was ist, wenn ich direkt vor dem Ändern etwas tun möchte?

    – Sam Chen

    31. März 2021 um 13:24 Uhr

  • HI @SamChen, onPositionDiscontinuity wird anscheinend versendet, nachdem der erste Frame des “nächsten Videos” bereits gerendert wurde. Aber ich glaube nicht, dass es ein solches Ereignis gibt, das ausgelöst werden könnte, kurz bevor das erste Bild des “nächsten Videos” gerendert wurde. Aber man könnte ein hinzufügen VideoFrameMetadataListener an den Video-Renderer, der jedes Mal, wenn ein Frame freigegeben werden soll, eine Methode im Rendering-Thread aufruft Verknüpfung

    – Akki

    1. April 2021 um 6:35 Uhr


  • @SamChen Fand eine Diskussion dazu, die helfen könnte https://stackoverflow.com/questions/27351784/how-to-implement-oncompletionlistener-to-detect-end-of-media-file-in-exoplayer (github.com/google/ExoPlayer/issues/6576)

    – Akki

    1. April 2021 um 8:02 Uhr

  • Danke, aber was ich meine, ist nicht das “nächste Video”, sondern das Ende des aktuellen Videos. Dazu habe ich auch den Beitrag erstellt: stackoverflow.com/questions/66889341/….

    – Sam Chen

    1. April 2021 um 15:11 Uhr


  • @SamChen, ich habe einige Optionen gepostet, die Sie in Ihrem Beitrag ausprobieren können. Ich hoffe, das würde helfen. Viel Glück!!

    – Akki

    1. April 2021 um 20:08 Uhr

1394830cookie-checkSo implementieren Sie oncompletionlistener, um das Ende einer Mediendatei in Exoplayer zu erkennen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy