Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ExoPlayer STATE_ENDED called multiple times #568

Closed
FastDr1v3r opened this issue Jun 20, 2015 · 1 comment
Closed

ExoPlayer STATE_ENDED called multiple times #568

FastDr1v3r opened this issue Jun 20, 2015 · 1 comment

Comments

@FastDr1v3r
Copy link

It was easy on MediaPlayer with onCompletionListener to detect when a song finished playing but on ExoPlayer I have an issue with the states.
I used "addListener()" method to detect when the ExoPlayer's states are changing and I have an if condition whenever the ExoPlayer is in STATE_ENDED which is something like this:

public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { if (exoPlayer.getPlaybackState() == ExoPlayer.STATE_ENDED) { Log.d("myFilter", "Song finished"); } } The problem is that when a song finishes and I played some songs before, the STATE_ENDED is detected (or the code in the if condition below is called) multiple times, for those previous songs played too (as it would finish them too).

Example:
If I play one song and then the song finish, the STATE_ENDED is detected only once, which is great, but if I play let's say 3 songs, then when the 3th songs finishes the STATE_ENDED is detected 3 times (and the code in the if condition below is executed 3 times). Even if I left the first song to finish playing, always when the second song will be finished the STATE_ENDED will be detected 2 times not once (this is available to any other number of songs played, STATE_ENDED will be detected according to how many songs I played, even they finished before).

FOR THE SAKE OF EXPLANATION:

Shortly: If I play let's say 5 songs, then the ExoPlayer STATE_ENDED is called/detected 5 times.

Even shortly: The ExoPlayer STATE_ENDED is detected multiple times...

Here is my code on my method to play music:

public void playMusic(final int position, ArrayList songsPaths, final ArrayList songsNames) { try {
       //all the variables used in this method are class variables;

        this.songsPaths = songsPaths;
        this.songsNames = songsNames;

        this.position = position;

        exoPlayer = InitVars.setExoPlayer();
        playerControl = InitVars.setPlayerControl();

        if (playerControl.isPlaying())
            exoPlayer.stop();

        exoPlayer.seekTo(0);

        pathUri = Uri.parse(songsPaths.get(position).toString());

        source = new FrameworkSampleSource(this, pathUri, null, 2);

        audioRenderer = new MediaCodecAudioTrackRenderer(source);
        exoPlayer.prepare(audioRenderer);

        exoPlayer.setPlayWhenReady(true);

        exoPlayer.addListener(new ExoPlayer.Listener() {
            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                if (exoPlayer.getPlaybackState() == ExoPlayer.STATE_ENDED) {
                   Log.d("myFilter", "Song finished");
                }
            }

            @Override
            public void onPlayWhenReadyCommitted() {

            }

            @Override
            public void onPlayerError(ExoPlaybackException error) {

            }
        });

    } catch (Exception ex) {
        Log.d("myFilter", ex.getMessage());
    }
}

The ExoPlayer and PlayerControl instances are kept in a class called InitVars which role is to initialize and get the ExoPlayer and PlayerControl variables (I don't want to create them multiple times across the app so would be easy to say ExoPlayer = InitVars.getExoPlayer() than making a totally new instance).

public final class InitVars { private static ExoPlayer exoPlayer; private static PlayerControl playerControl;
private InitVars() {

}

public static PlayerControl getPlayerControl() {
    return playerControl;
}
public static ExoPlayer getExoPlayer() {
    return exoPlayer;
}

public static ExoPlayer setExoPlayer() {
    if (exoPlayer == null) {
        exoPlayer = ExoPlayer.Factory.newInstance(1);
    }

    return exoPlayer;
}

public static PlayerControl setPlayerControl() {
    if (playerControl == null)
        if (exoPlayer != null)
            playerControl = new PlayerControl(exoPlayer);

    return playerControl;
}

}

How can I make the ExoPlayer STATE_ENDED to be detected only once for a song.
I even tried with a custom thread to detect whenever the ExoPlayer finishes, and the logic was something like this:
I check in a while loop if the exoPlayer.getCurrentPosition() returns a value equals to the total song length, the last value when the exoplayer finishes playing should be equal to the total song length, but it always is lesser than it, so not even this didn't work, so I went back to checking the states...
I need to check when the song finished to play the next song.

@ojw28
Copy link
Contributor

ojw28 commented Jun 20, 2015

I think you're calling addListener every time you start playing a song. By the time you're playing the 5th song, you've probably added 5 different listeners using the addListener method. STATE_ENDED only happens once, but each of your 5 listeners receives the event. You need to change your code to only add a single listener, or to remove the old listener when attaching the new one, or something like that.

@ojw28 ojw28 closed this as completed Jun 20, 2015
@google google locked and limited conversation to collaborators Jun 28, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants