开发者控制台

步骤6: 使用PlaybackOverlayFragment播放视频内容

步骤6: 使用PlaybackOverlayFragment播放视频内容

我们在Fire TV上跟踪了整个流程,包括浏览、查找内容、阅读特色内容详情、执行操作。现在进入最后一个环节:如何播放视频。

在支持Leanback的项目中,播放视频内容是在PlaybackOverlayActivity中进行的。PlaybackOverlayActivity的UI很简单:一个用于显示内容的全屏视频播放器。PlaybackOverlayFragment位于视频播放器顶部,负责显示所有媒体控件和管理底层内容播放。

有很多不同的视频播放器可供使用,但首次部署Leanback支持的项目时,默认视频播放器是VideoView。

VideoView是一个非常基础的视频播放器,用于播放非加密视频文件非常方便。大部分开发者喜欢选择功能更强大更丰富的播放器,而对于Fire TV,通常选择Amazon定制版的ExoPlayer。为简单起见,继续使用默认Leanback模板VideoView中找到的内容。

分析PlaybackOverlayActivity的UI的xml文件时,发现只有这两个组件:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <VideoView
        android:id="@+id/videoView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
/>
    <fragment
        android:id="@+id/playback_controls_fragment"
        android:name="PlaybackOverlayFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
/>
</FrameLayout>

PlaybackOverlayActivity主要组件

PlaybackOverlayActivity的基本设置非常简单,集中在四个主要组件:

public class PlaybackOverlayActivity extends Activity implements
        PlaybackOverlayFragment.OnPlayPauseClickedListener {

    private VideoView mVideoView;
    private LeanbackPlaybackState mPlaybackState;
    private MediaSession mSession;

    ...

}
  1. Listeners: 可向PlaybackOverlayActivity添加大量Listeners,这对于用户在遥控器上进行的所有操作(播放、暂停、倒回等)添加回调非常有用。为简单起见,我们将查看Leanback模板上唯一可用的侦听器,即OnPlayPauseClickedListener
  2. VideoView是用于播放视频内容的播放器。
  3. LeanbackPlaybackState只是一个标记,用于跟踪应用的状态(例如LeanbackPlaybackState.PLAYINGLeanbackPlaybackState.PAUSED)。
  4. MediaSession: MediaSession主要负责与底层的Android框架通信,以及管理使用遥控器进行的操作的所有权。

遥控器

Fire TV和其他Android设备之间的主要区别之一是,与Fire TV进行交互的唯一方式是通过其遥控器。

由于Fire OS 5是基于Android Lollipop,因此Fire TV遥控器生成的KeyEvent与经典Android设备生成的KeyEvent相同,但有物理按钮。

首先,需确保应用受遥控器的控制。这可通过在MediaSession中设置几个标记轻松实现。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.playback_controls);
    ...

    mSession = new MediaSession(this, "LeanbackSampleApp");
    mSession.setCallback(new MediaSessionCallback());
    mSession.setFlags(MediaSession.FLAG_HANDLES_MEDIA_BUTTONS
            | MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
    );

    mSession.setActive(true);

}

当调用MediaSession.setFlags()时,应用可控制在遥控器按钮上执行的操作。特别是,利用FLAG_HANDLES_MEDIA_BUTTONS,用户可控制遥控器底部的按钮(倒回、播放/暂停和快进),而通过FLAG_HANDLES_TRANSPORT_CONTROLS,应用可侦听导航按钮,这些按钮控制应用在视图中的移动(向上、向右、向下、向左)。

侦听遥控器上的KeyEvent

现在已设置应用的MediaSession,可开始侦听在遥控器上执行的操作。

此时,需对KeyEvent做出反应:

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    PlaybackOverlayFragment playbackOverlayFragment =
		findFragmentById(R.id.playback_controls_fragment);
    switch (keyCode) {
        ...
        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
            if (mPlaybackState == LeanbackPlaybackState.PLAYING) {
                playbackOverlayFragment.togglePlayback(false);
            } else {
                playbackOverlayFragment.togglePlayback(true);
            }
            return true;
        ...
    }
}

我们需覆盖onKeyUp(),因为这是当用户单击按钮并抬起手指时触发的事件(单击/操作结束)。

我们将演示在这种情况下,如何对用户按下播放/暂停按钮作出反应。我们对KeyEvent作出反应: KEYCODE_MEDIA_PLAY_PAUSE,然后检查当前的LeanbackPlaybackState。若正在播放,可在PlaybackOverlayFragment上将播放切换为false(停止播放)。否则,将其设置为true,触发底层片段的回调。

触发播放

最后,需在VideoView上触发播放。如需完成上述操作,需在活动中实现ClickListener提供的回调(在这种情况下,PlaybackOverlayFragment.OnPlayPauseClickedListener)。

public void onFragmentPlayPause(Movie movie, int position, Boolean playPause) {
   mVideoView.setVideoPath(movie.getVideoUrl());
    ...
    if (mPlaybackState != LeanbackPlaybackState.PLAYING) {
        	mPlaybackState = LeanbackPlaybackState.PLAYING;
        	if (position > 0) {
            mVideoView.seekTo(position);
            mVideoView.start();
        }
    ...
 }
}

以下是所发生情况的分步流程:

  1. 设置需播放的视频的URL。为此,使用VideoView.setVideoPath(),从而绕过视频的URL。它可以是云存储库中的简单视频文件,也可以是应用中的嵌入式视频。重要的是URL需指向视频文件。
  2. 检查LeanbackPlaybackState
  3. 如需开始播放内容,可使用seekTo()设置希望开始播放视频的位置(以毫秒为单位,通常为0)。
  4. 最终调用VideoView.start()以播放视频。

支持Leanback项目的其他功能

Leanback模板相当复杂,用户可享受丰富的电视体验。例如,默认情况下,可定义在所显示内容时推荐的视频。此外,开发者可执行SearchFragment以创建自定义搜索体验。