開発者コンソール

手順6: PlaybackOverlayFragmentを使用してビデオコンテンツを再生する

手順6: PlaybackOverlayFragmentを使用してビデオコンテンツを再生する

閲覧やコンテンツの発見から、特定コンテンツの詳細の確認やアクションの実行まで、Fire TVについて詳しく見てきました。それでは、最後の部分であるビデオの再生方法について見ていきましょう。

Leanback対応プロジェクトでは、ビデオコンテンツの再生がPlaybackOverlayActivity内で実行されます。PlaybackOverlayActivityのUIはシンプルです。フルスクリーンのビデオプレーヤーでコンテンツを再生します。ビデオプレーヤーの上にあるのがPlaybackOverlayFragmentです。すべてのメディアコントロールを表示し、基となるコンテンツの再生を管理します。

ビデオプレーヤーは任意のものを使用できます。ただし、Leanback対応プロジェクトを初めてデプロイした場合、デフォルトのビデオプレーヤーはVideoViewになります。

VideoViewは簡易なビデオプレーヤーであり、暗号化されていないビデオファイルを手軽に再生する場合に最適です。ほとんどの開発者は、よりパワフルで機能が豊富なプレーヤーを選びます。Fire TVで通常選択されるのは、AmazonがカスタマイズしたExoPlayerです。簡素化するために、デフォルトのLeanbackテンプレートにあるVideoViewを使用します。

PlaybackOverlayActivityでUIのxmlファイルを調べると、次の2つのコンポーネントしかないことがわかります。

<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の基本的な設定は非常にシンプルで、次の4つの主要コンポーネントに分かれています。

public class PlaybackOverlayActivity extends Activity implements
        PlaybackOverlayFragment.OnPlayPauseClickedListener {

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

    ...

}
  1. リスナーPlaybackOverlayActivityに多くのリスナーを追加することができます。これは、ユーザーがリモコンで実行したすべてのアクション(再生、一時停止、早戻しなど)のコールバックを追加するのに便利です。簡素化するために、Leanbackテンプレートで使用可能なリスナーであるOnPlayPauseClickedListenerのみを確認します。
  2. VideoView:ビデオコンテンツの再生に使用するプレーヤーです。
  3. LeanbackPlaybackState:アプリのステータスを追跡するために使用されるフラグです(例:LeanbackPlaybackState.PLAYINGLeanbackPlaybackState.PAUSED)。
  4. MediaSession: MediaSessionの主なタスクは、基盤となるAndroidフレームワークと通信し、リモコンで実行されたアクションの権限を管理することです。

リモコン

Fire TVがそのほかのAndroidデバイスと大きく異なる点の1つは、リモコンでのみ操作可能ということです。

Fire OS 5はAndroid Lollipopをベースにしているため、Fire TVリモコンで生成されたKeyEventsは、従来のAndroidデバイスで生成されたKeyEventsと同じです。異なるのは物理的ボタンの有無だけです。

まず、アプリがリモコンを制御していることを確認する必要があります。これは、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では、アプリのビュー内の動き(上、右、下、左)を制御するナビゲーションボタンをアプリがリッスンできます。

リモコンでのKeyEventsのリッスン

アプリでMediaSessionの設定が完了したので、リモコンで実行されるアクションのリッスンを開始できます。

それには、KeyEventsに対応する必要があります。

@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を確認します。PLAYINGの場合は、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テンプレートはとても複雑ですが、ユーザー向けの機能豊富なTV視聴エクスペリエンスを構築できます。たとえば、デフォルトでは、コンテンツの一部が表示される場合のおすすめビデオを定義できます。また、開発者はSearchFragmentを実装して、カスタム検索エクスペリエンスを構築することもできます。