16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Building a video player app in Android(Part1 - 2)を読んだメモ

Last updated at Posted at 2018-03-18

本当に読んだときの自分のメモ書きなので、英語読める方はそちらのほうが良いと思います。
https://medium.com/google-developers/building-a-video-player-app-in-android-part-1-5-d95770ef762d
本当はPart5まで見たかったのですが、時間切れしました。もしかしたら追加するかもです。
Listening to player events for UXが良かったです。もう少し深く見ていきたいです。

ExoPlayer introduction(Part 1)

Overview of using ExoPlayer

SimpleExoPlayerMediaSourceがビデオファイルを再生するのに必要になる。
SimpleExoPlayerを作成するにはtrack selector(どのファイルやどの言語でどの音声で再生するか決める)がいる。
MediaSourceクラスを使うことでmp4とかmp3とかのUriを読み込める。(HLSを再生できるHlsMediaSourceとかもある。)player.playWhenReadyをtrueにするとデータが有ると再生する。

そしてPlayerViewにプレーヤーをアタッチしてあげる必要がある。PlayerViewはUIコントロールも提供する。動画のソースを提供する前にUIを用意する方が良い。なぜなら再生されている間にアタッチされるようなことがあり得るため。
またplayerの準備が必要でロードのスタートを知らせる。(バッファリングに時間がかかる可能性があるため。)
playerのplayWhenReadyにtrueをセットするとデータが読み込まれた時に再生を行う。
Proguardをかけてサイズを減らそう。

Create the ExoPlayer instance

このコードはplayerをデフォルトのオプションで作っている。そしてPlayerViewにアタッチしている。
https://gist.github.com/nazmulidris/6a40763185ed0653320d8efae66256bc#file-create-ep-instance-kt

Loading files locally from APK using ExoPlayer

DefaultDataSourceは以下のUriのロードに対応している。

file:///
asset:///
content:///
rtmp
data
http(s)

以下のようにローカルファイルをロードできる(assetフォルダーにネストした形でフォルダを作れる)

Uri.parse(“file:///android_asset/video/video.mp4”)
Uri.parse(“asset:///video/video.mp4”)

RawResourceDataSourceを使うとres/rawのなかに置いてアクセスできる
RawResourceDataSource.buildRawResourceUri(R.raw.my_media_file)

Release ExoPlayer resources

コーデックやネットワークやメモリを利用しているので再生が完了したときplayerを終了させる必要がある。システムコーデックはシステム内でシェアされていて、OSや端末によって限られているため、それを開放することは重要である。以下のコードで同じExoPlayerを再利用できる。
https://gist.github.com/nazmulidris/6bb12dcf8e0b67e43f4d47ae0f18176b#file-ep-release-kt
これはplayerにより確保されている全てのリソースを開放している(コーデックやメディアソースなど)。もう一度playerを利用するときはprepare(MediaSource)を呼び、そしてplayWhenReadyをセットする。
ExoPlayer.release()は1つを除いてstop()と同じ動きをします。再生スレッドを停止し、ExpPlayerのインスタンスの再利用を防ぐ。ReleaseはActivity.onDestroyやService.onDestroyなどplayerがもう使われない時に呼び出すべき。

Activity Lifecycle Integration

作成して、利用し、リリースするためにActivityのライフサイクルを利用する必要がある。
シンプルな例が以下になる。
https://gist.github.com/nazmulidris/8e1e8b3cf67ae9b563e4dbe699847d01#file-ep-video-activity-kt

Saving player state between onStart() and onStop()

PlayerStateデータクラスはplayerが最初に読み込まれる前に、playerの状態を読み込むために利用される。Playerがリリースされた時Playerの状態はこのクラスのオブジェクトに保存される。新しいPlayerを作成した時にこのシンプルな状態オブジェクトを利用して前回やめた位置から再開する。
https://gist.github.com/nazmulidris/62f45c3eaa9c77bb7a8cb8d77369261f#file-player-state-kt

UIの観点からはこれはアプリの実行中何かを再生していて、ホームボタンを押し、playerリソースがリリースされ、アプリに戻ってきた時にplayerが再度初期化され、前回の状態がリストアされ、やめたところから再開できる。
どのようにその保存と復元をやるかは以下のコードで行っている。
https://gist.github.com/nazmulidris/6d02ac7e4f64ad86c61a2d081c18ca49#file-playerholder-release-kt

A little more control over player creation

playerをカスタマイズするためにExoPlayerFactor.newSimpleInstanceの別のシグネチャを利用できる。例えばDefaultLoadControlクラスを使うことでExoPlayerのbuffering policyを変更することが出来る。
https://gist.github.com/nazmulidris/f1d66dd5f5962aa187909fec9eaaf687#file-ep-creation-extra-kt
もっと複雑なユースケースではExoPlayerFactory.newSimpleInstance(…)ファクトリーメソッドの全ての引数に、自分の実装を渡すことが出来る。これによりExoPlayerで大きく拡張性を得ることが出来る。

ExoPlayer playlists, UI customization, and events(Part 2)

Creating playlists

一つのExtractorMediaSource(buildMediaSource(Uri)を使う方法)を使う代わりに、DynamicConcatenatingMediaSourceを使うことが出来る。MediaSourceオブジェクトをつなげて利用することが出来る。これがサンプルになる。
https://gist.github.com/nazmulidris/82cebffca8fbd159382fb2c0d89caf69#file-ep-playlist-kt

DynamicConcatenatingMediaSourceは動的にプレイリストを作る。もし静的なプレイリストを作りたければ、ContactenatingMediaSourceを使うことが出来る。どちらもシームレスにメディアをつなげ、プレイリスト全体のバッファリングを処理する。MediaSourceの構成の詳細を知るためにはこの記事を読むと良い。

Customizing the UI

ExoPlayerインスタンスをPlayerViewにアタッチ出来る。PlayerViewのレイアウトの例を示す。
ビデオの早送りや巻き戻しそして他のもっと多くの事ができる。ExoPlayerのJavaDocで全てをみることができる。
https://gist.github.com/nazmulidris/f4a1fc64aa52d01e2844ee4218ca890c#file-ep-custom-layout-xml
コントローラーを使わない場合はapp:use_controller=”false” を利用する。PlayerViewは自動的にmedia controller UIを表示する。これらはユーザーに再生、一時停止、スキップなどを提供する。show_timeoutを使うことで、このコントローラーがどのぐらいの間表示されるかを設定できる。
コントローラーのUIをカスタマイズするために、controller_layout_idを使うことが出来る。これがサンプルとなる。
https://gist.github.com/nazmulidris/d9c92c56bc6d7fb5c83759537575257a#file-ep-controller-ui-xml
PlayerView自身の前に覆って表示される。再生、一時停止、スキップなどを追加したり、削除したりすることができる。ExoPlayerによって提供されているIDを利用することで、ExoPlayerが知ることが出来る。PlayerViewのカスタマイズに関してはこの記事を読んで欲しい。

Listening to player events for UX

ExoPlayer.EventListenerインターフェースを介して、たくさんの価値のある情報を提供する。これをインターフェースを実装するかサブクラスのPlayer.DefaultEventListenerを実装することで、Playerの状態が変わった時に受け取ることが出来る。また、VideoRendererEventListenerAudioRendererEventListenerを実装することができ、これによりaudiovideoのレンダリングの詳細を取得することが出来る。
それぞれを利用することで、アプリのユーザーにとってquality of experience (QoE)がどのように影響を受けているか知ることができる。

これらを利用するサンプル

  • STATE_BUFFERINGとともにExoPlayer.EventListener.OnPlaybackStateChanged()が呼ばれた時に、もし再生開始時や、ユーザーがまだ再生可能でない場所を指定した場合でなければ、QoEにとって有害であると考えられる。
  • ユーザーによって、再生が開始されてから、ExoPlayer.VideListener.onFirstFrameRenderedが呼ばれるまでにかかった時間は、再生の最初の時間となる。良いQoEのためには少ないほうが望ましい。
  • VideoRendererEventListener.onDroppedFramesはframe落ちに関しての情報を提供する。とても多くのこのイベントはQoEに悪い影響をもたらす。

この記事では詳細をカバーしない。ExoPlayerのイベントとQoEシグナルをもっと知るためにはExoPlayer codelabのMeasure QoE sectionを必ず行ってください。Playerの再生、バッファリング、一時停止中を深く理解するためにはこのStackOverflowを参照してください。

Adaptive streaming

ExoPlayerはAPKやネットワークからメディアファイルを読み込むだけでなく、adaptive streamingを広範囲にサポートしている。adaptive streamingはビデオと音声を所定の期間の小さいチャンクにカットする。ExoPlayerはそれを再生のためにつなげる。それぞれのチャンクは異なる品質(サイズまたはビットレート)が利用できる。プレーヤーはデバイスの性能やネットワークの帯域によってその品質を選択する。プレーヤーは低画質から再生を開始し、帯域が利用可能になれば良い画質に切り替える(例えば遅いモバイルネットワークからWiFiに切り替えるなど)

HLS(HTTP Live Streaming)やMPEG-DASH (Dynamic Adaptive Streaming over HTTP)やSmoothStreamingについてMDN記事で学ぶことが出来る。DASH and HLSの違いについて学ぶにはこのExoplayerブログを確認してほしい。これらの記事ではadaptive streamingにExoPlayerを利用することはないが、もっと学びたい場合は、ExoPlayer codelabを確認して欲しい。

16
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?