Exoplayer2.x: ​​Player.STATE_ENDED срабатывает дважды по окончании видео, как реализовать exoplayer в android? - PullRequest
3 голосов
/ 18 июня 2020

Я использую Exoplayer для воспроизведения видео в плейлисте. Я хочу автоматически воспроизвести следующее видео, когда закончится текущее видео. Для этого я добавил в свой плеер EventListener. Вот фрагмент:

private val videoPlayerListener = object: Player.EventListener {
    override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
        when(playbackState) {
            Player.STATE_IDLE -> showLoadingView()
            Player.STATE_READY -> hideLoadingView()
            Player.STATE_BUFFERING -> showVideoProgressWheel()
            Player.STATE_ENDED -> {
                Log.d(TAG, "fired")
                playNextVideo()
            }
        }
    }

    override fun onPlayerError(error: ExoPlaybackException?) {
        // handle error event
    }
}

Проблема с этим подходом состоит в том, что мои журналы показывают, что Player.STATE_ENDED срабатывает дважды. Цепной эффект этого заключается в том, что мой список воспроизведения воспроизводится из

видео 1 -> видео 3 -> видео 5 -> видео 7 ...

вместо

видео 1 -> видео 2 -> видео 3 -> видео 4 ...

Я провел небольшое исследование и нашел эту проблему на Github . Я проверил свой код и понял, что на самом деле вызываю метод, содержащий addListener(videoPlayerListener) в OnCreate (), OnStart (), OnPause (), OnResume () и OnStop (). Чтобы решить эту проблему, я добавил следующее перед строкой addListener:

try {
    player.removeListener(videoPlayerListener)
    Log.d(TAG, "Listener temporarily deleted")
}
catch (e: Exception) {}

Обратите внимание, что в моем коде есть только одна функция, которая содержит addListener(...), и я помещаю вызов removeListener() напрямую перед строкой addListener(). Несмотря на это, Player.STATE_ENDED по-прежнему вызывается дважды каждый раз, когда заканчивается видео.

Что мне делать?

1 Ответ

4 голосов
/ 18 июня 2020

Используйте этот код

Возьмите такую ​​переменную глобально

var isVideoEnded=false

, затем сделайте это в вашем слушателе

private val videoPlayerListener = object: Player.EventListener {
    override fun onPlayerStateChanged(playWhenReady: Boolean, playbackState: Int) {
        when(playbackState) {
            Player.STATE_IDLE -> showLoadingView()
            Player.STATE_READY -> {
                    hideLoadingView()
                    isVideoEnded=false
                                }
            Player.STATE_BUFFERING -> showVideoProgressWheel()
            Player.STATE_ENDED -> {
                   if(!isVideoEnded){
                      playNextVideo()
                      isVideoEnded=true
                  }

                Log.d(TAG, "fired")

            }
        }
    }

    override fun onPlayerError(error: ExoPlaybackException?) {
        // handle error event
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...