Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exoplayer2.x: Player.STATE_ENDED fires twice when a video ends ,how to implement exoplayer in android?

I'm using Exoplayer to play a video in a playlist. I want to auto play the next video when the current video end. To do this, I added an EventListener to my player. Here's a snippet:

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

The problem with this approach is that my logs show that Player.STATE_ENDED fires twice. The chain effect of this is that my playlist plays from

video 1 -> video 3 -> video 5 -> video 7...

instead of

video 1 -> video 2 -> video 3 -> video 4...

I did some research and I found this issue on Github. I checked my code and I realized I was actually calling a method that contains addListener(videoPlayerListener) in OnCreate(), OnStart(), OnPause(), OnResume() and OnStop(). To solve this problem, I added the following before the addListener line:

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

Kindly note that there is only one function in my code that contains addListener(...) and I put the removeListener() call directly before the addListener() line. Despite this, Player.STATE_ENDED still gets called twice every single time a video ends.

What do I do?

like image 998
Taslim Oseni Avatar asked Oct 22 '25 18:10

Taslim Oseni


1 Answers

Use this code

Take a variable like this globally

var isVideoEnded=false

then in your listener do this

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
    }
}
like image 109
Quick learner Avatar answered Oct 25 '25 09:10

Quick learner