手順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;
...
}
リスナー
:PlaybackOverlayActivity
に多くのリスナー
を追加することができます。これは、ユーザーがリモコンで実行したすべてのアクション(再生、一時停止、早戻しなど)のコールバックを追加するのに便利です。簡素化するために、Leanbackテンプレートで使用可能なリスナー
であるOnPlayPauseClickedListener
のみを確認します。VideoView
:ビデオコンテンツの再生に使用するプレーヤーです。LeanbackPlaybackState
:アプリのステータスを追跡するために使用されるフラグです(例:LeanbackPlaybackState.PLAYING
、LeanbackPlaybackState.PAUSED
)。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();
}
...
}
}
ここでは、実行される処理について順に説明します。
- 再生するビデオのURLを設定します。それには、
VideoView.setVideoPath()
を使用してビデオのURLをバイパスします。これは、クラウドリポジトリ上のシンプルなビデオファイルか、アプリ内の埋め込みビデオです。重要な点は、URLがビデオファイルを指す必要があるということです。 LeanbackPlaybackState
を確認します。- コンテンツの再生を始める必要がある場合は、
seekTo()
を使用して、ビデオの再生開始位置(ミリ秒単位、通常は0)を設定します。 - 最後に
VideoView.start()
を呼び出して、ビデオを再生します。
Leanback対応プロジェクトのその他の機能
Leanbackテンプレートはとても複雑ですが、ユーザー向けの機能豊富なTV視聴エクスペリエンスを構築できます。たとえば、デフォルトでは、コンテンツの一部が表示される場合のおすすめビデオを定義できます。また、開発者はSearchFragment
を実装して、カスタム検索エクスペリエンスを構築することもできます。