Как реализовать oncompletionlistener для обнаружения конца медиа файла в Exoplayer

Я пытаюсь воспроизводить видео в виде плейлиста один за другим. Я использую Android Exoplayer для воспроизведения моих файлов, но в медиаплеере нет слушателей, которые могли бы прослушивать конец медиа файла. Есть ли способ прослушать конец медиа файла с помощью exoplayer.

Ответ 1

Exoplayer предлагает предварительную реализацию, которой нет в медиаплеере.

в расширенном примере Exoplayer для Android, в FullPlayerActivity.java они реализовали onStateChanged, который предлагает STATE_ENDED

Вы можете скачать пример из правого раздела этой страницы под термином СВЯЗАННЫЕ ОБРАЗЦЫ

Ответ 2

Я знаю, что это старо, но просто для того, чтобы расширить принятый ответ:

exoPlayer.addListener(this);

.....

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

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

Ответ 3

Google устарел ExoPlayer.STATE_ENDED и заменил его на Player.STATE_ENDED.

Поскольку этот пост уже давно, я напишу версию слушателя на Kotlin ниже.

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 -> {}
                }
            }
        })

Ответ 4

Вы можете сделать это:

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

Но ответ @Муртаза Хуршид Хуссейн прав! Имейте хороший день кода! Дайте мне знать, если вам нужно что-то еще!

Ответ 5

Вы должны реализовать интерфейс Player.EventLister и добавить его в exoPlayer.

Просто напишите свой код по методу onPlayerStateChanged. Смотрите код.

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() {

            }


        });

Ответ 6

ExoPlayer.STATE_ENDED обесценивается. Вместо этого используйте Player.STATE_ENDED. Пример:

@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
    if(playbackState == Player.STATE_ENDED){
        // your brain put here
    }
}

Ответ 7

Я использовал плейлист с exoplayer и хотел остановить мультимедиа после его завершения.

Для меня Player.STATE_ENDED вызывался, когда плейлист заканчивался для меня внутри

Поэтому, чтобы выполнить мой вариант использования, я сначала установил это в exoplayer

 simpleExoPlayer.setRepeatMode(Player.REPEAT_MODE_ONE);

Поэтому вместо использования EventListener я использовал AnalyticsListener, который дает onPositionDiscontinuity переопределить с параметром eventTime и просто добавить простой код, чтобы узнать, СМИ перезапустились.

   @Override
   public void onPositionDiscontinuity(EventTime eventTime, int reason) {
        if (eventTime.currentPlaybackPositionMs / 1000 < 1) {
            exoPlayer.setPlayWhenReady(false);
            tvReplay.setVisibility(View.VISIBLE);
        }
    }

Надеюсь, это поможет вам

Ответ 8

Google не поддерживает ExoPlayer.STATE_ENDED. Вместо этого используйте Player.STATE_ENDED. Смотрите код ниже.

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() {

    }
});

Вы можете проверить страницу разработчика ExoPlayer для получения дополнительной информации.

Ответ 9

Для неконкатенированного MediaSource (представляющего какой-либо отдельный фрагмент мультимедиа, который вы хотите воспроизвести), вы получите STATE_ENDED после завершения воспроизведения фрагмента мультимедиа.

Для ConcatenatingMediaSource это происходит, когда закончена вся конкатенация (т.е. вы играли до конца последнего элемента в конкатенации). Итак, STATE_ENDED происходит, когда весь MediaSource завершил воспроизведение.

Для ConcatenatingMediaSource лучшим обратным вызовом для определения конца текущего мультимедиа и начала следующего воспроизведения мультимедиа является "onPositionDiscontinuity" Вы должны использовать onPositionDiscontinuity(), чтобы выяснить, когда происходят переходы. Обратите внимание, что onPositionDiscontinuity также вызывается для некоторых других случаев, но вы можете вызвать getCurrentWindowIndex() и сравнить его с тем окном, в котором вы находитесь, чтобы определить, произошел ли переход. Вы можете сделать что-то вроде ниже:

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

Обратите внимание: onPositionDiscontinuity() не вызывается для 1-го элемента в списке воспроизведения, если мы явно не вызываем player.seekTo(position, 0). Поэтому для обработки всего, что вы делаете для воспроизведения всего мультимедиа в списке воспроизведения, вы должны обрабатывать отдельно для 1-го элемента в списке воспроизведения.