What’s new in Leanback: Part 1

Introduction to Android TV’s PlayerAdapter

New to Android TV? Curious about the new changes with the 26.0.0 support library? In this series of articles, we’ll look into several components. In this first post, we start by exploring how the new components help manage the seek bar / timeline for you.


Starting with release 26.0.0-beta1 the leanback library has a new component called PlaybackTransportControlGlue. This is a helper class that manages primary and secondary actions for example, rewind and skip to next, and provides hooks for seek control.

Note that the old way of playback, with no seek support, is available by using PlaybackBannerControlGlue. The UI looks the same as when using PlaybackControlGlue, however, the PlaybackBannerControlGlue uses a PlayerAdapter internally.

Components managed by PlaybackTrasportControlGlue

PlaybackTrasportControlGlue, or a subclass that you create, requires an instance of PlayerAdapter. The leanback library supplies MediaPlayerAdapter for easy use with MediaPlayer.

If you’d rather use ExoPlayer you can extend PlayerAdapter and provide your own player implementation.

In order to animate the seekbar properly, you must override some of the methods in PlayerAdapter.

First things first

When you create a new subclass of PlayerAdapter, Android Studio helps by letting you know to implement two abstract methods as shown below.

Letting Android Studio code for me, I end up with the following:

public class ExoPlayer2PlayerAdapter extends PlayerAdapter {
@Override
public void play() {

}

@Override
public void pause() {

}
}

At this point, it seems like implementing PlayerAdapter is easy, but there’s more to be done.

Seeking help

The following abstract methods should be overridden (even though they are optional) in order to control the seekbar.

  • getCurrentPosition()
  • getDuration()
  • getBufferedPosition()

When you implement these methods the PlaybackTrasportControlGlue can automatically update the seekbar.

The following snapshot shows how the seekbar uses these callbacks:

Current Position

To update the current position, you need to override getCurrentPositon(). The implementation is trivial, just delegate to your player and return its current position:

@Override
public long getCurrentPosition() {
return isInitialized() ? mPlayer.getCurrentPosition() : -1L;
}

Duration

The implementation of getDuraion() is similar:

@Override
public long getDuration() {
return isInitialized() ? mPlayer.getDuration() : -1L;
}

When you define getCurrentPosition() and getDuration() the PlaybackTransportControlGlue can update the seekbar.

With the current position and duration available, the seekbar can update.

Buffered Position

The PlaybackTranslportControlGlue updates the progress of a video as it buffers. All you need to do is return the buffered position from the player:

@Override
public long getBufferedPosition() {
return mPlayer.getBufferedPosition();
}

While the player is buffering, you can use the PlayerAdapter’s callback to update the UI with the buffered position:

getCallback().onBufferedPositionChanged(this);
The UI when only implementing getBufferedPostion()

Continue learning

I recommend reading the source code for MediaPlayerAdapter. It is a really good example. You can also read the ExoPlayerAdapter that implements PlayerAdapter.

In the next part of the series, we will look at how to add thumbnails to the seekbar.

If you would like to join the discussion, leave a response or talk to me on twitter.

One clap, two clap, three clap, forty?

By clapping more or less, you can signal to us which stories really stand out.