ExoPlayer and start / pause / seekTo commands

2019-02-01 18:02发布

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"...

2条回答
Lonely孤独者°
2楼-- · 2019-02-01 18:48

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.

查看更多
我只想做你的唯一
3楼-- · 2019-02-01 18:53

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.

查看更多
登录 后发表回答