PlaybackOverlayFragmentを使用してビデオコンテンツを再生する方法


PlaybackOverlayFragmentを使用してビデオコンテンツを再生する方法

最終更新日:2016年12月

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