Home » Android » android – ExoPlayer and start / pause / seekTo commands

android – ExoPlayer and start / pause / seekTo commands

Posted by: admin April 23, 2020 Leave a comment

Questions:

I am trying to use ExoPlayer, as opposed to MediaPlayer and I can’t seem to figure it out…

MediaPlayer has .start() / .pause() commands… and I can just seekTo(1287) and it automatically starts playing…

How do I do this with ExoPlayer? I have tried to do seekTo(1287) but it doesn’t start playing after… I have also added .setPlayWhenReady(true) after that, and still no luck…

I am able to .stop()… but I can’t get it to start playing again after that unless I .prepare() again… but I don’t think I should have to do that between every pause and play.

I am using my own controls and methods opposed to MediaController like in the ExoPlayer Demo… I can’t quite see how the controls are implemented…

Any suggestions anyone?

Edit:

OK, I figured out pause and start…

.setPlayWhenReady(true) // start
.setPlayWhenReady(false) // pause

But I’m still having problems with the tracking… .seekTo works intermittently… sometimes it works… but other times I get this error:

E/AudioTrack: AudioTrack::set : Exit

(and it only gets to the buffer state… doesn’t quite get to “ready”…

How to&Answers:

The official example of the PlayerControl in the ExoPlayer source code do exactly what you asked:

public class PlayerControl implements MediaPlayerControl {

  private final ExoPlayer exoPlayer;

  public PlayerControl(ExoPlayer exoPlayer) {
    this.exoPlayer = exoPlayer;
  }

  @Override
  public boolean canPause() {
    return true;
  }

  @Override
  public boolean canSeekBackward() {
    return true;
  }

  @Override
  public boolean canSeekForward() {
    return true;
  }

  @Override
  public int getAudioSessionId() {
    throw new UnsupportedOperationException();
  }

  @Override
  public int getBufferPercentage() {
    return exoPlayer.getBufferedPercentage();
  }

  @Override
  public int getCurrentPosition() {
    return exoPlayer.getDuration() == ExoPlayer.UNKNOWN_TIME ? 0
        : (int) exoPlayer.getCurrentPosition();
  }

  @Override
  public int getDuration() {
    return exoPlayer.getDuration() == ExoPlayer.UNKNOWN_TIME ? 0
        : (int) exoPlayer.getDuration();
  }

  @Override
  public boolean isPlaying() {
    return exoPlayer.getPlayWhenReady();
  }

  @Override
  public void start() {
    exoPlayer.setPlayWhenReady(true);
  }

  @Override
  public void pause() {
    exoPlayer.setPlayWhenReady(false);
  }

  @Override
  public void seekTo(int timeMillis) {
    long seekPosition = exoPlayer.getDuration() == ExoPlayer.UNKNOWN_TIME ? 0
        : Math.min(Math.max(0, timeMillis), getDuration());
    exoPlayer.seekTo(seekPosition);
  }

}

If you are experiencing strange behaviors during the seek operation, it may be due to you particular stream/file type. I can suggest you to take a look at the base implementation of the ExoPlayer and, eventually, report any issue on Github.

Answer:

Here’s how the example code does it for Exoplayer 2:

player.setPlayWhenReady(true);

starts playback, (false stops)

If the player is already in the ready state then this method can be used to pause and resume playback.

To seek, they use

boolean haveStartPosition = startWindow != C.INDEX_UNSET;
if (haveStartPosition) {
  player.seekTo(startWindow, startPosition);
}
player.prepare(mediaSource, !haveStartPosition, false);

So it seems you need to prepare after the seekTo.