ExoPlayer Okhttp Extentionとは
ExoPlayerはAndroidで動画・音声を再生するフレームワークです。
ExoPlayerではたくさんの拡張ライブラリが用意されており、その中のひとつにOkhttp Extentionがあります。
Okhttp Extentionを使用すれば、OkHttpを使ってExoPlayerのネットワークをカスタマイズ出来ます。
具体的には、ExoPlayerが受け取るレスポンスデータを書きかえたり、ステータスコードを書き換えたり... Okhttpで出来ること全てが可能です。
ただ、Httpタイムアウト時間・リクエストヘッダのカスタマイズ・ネットワークイベントなどはコアライブラリのみで対応可能です。
導入
gradleのdependencyにokhttp extentionを追加します。extentionのバージョンはExoPlayer本体のバージョンと一致させます。
def ver_exoplayer = 'x.x.x'
implementation "com.google.android.exoplayer:exoplayer-core:$ver_exoplayer"
implementation "com.google.android.exoplayer:extension-okhttp:$ver_exoplayer"
使い方
DefaultDataSource
, DefaultDataSourceFactory
の代わりにOkHttpDataSource
OkHttpDataSourceFactory
を用います。
例えば以下の例ではサーバー上の動画ファイルを再生・リクエスト時にログします。
val client = OkHttpClient().newBuilder().addNetworkInterceptor(object : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
Log.d("LOG", "REQUEST INTERCEPTED")
return chain.proceed(chain.request())
}
}).build()
val okHttpDataSourceFactory = OkHttpDataSourceFactory(client, "USER_AGENT")
val mediaSource = ProgressiveMediaSource.Factory(okHttpDataSourceFactory)
.createMediaSource("MP4_URL".toUri())
player.prepare(mediaSource)
player.playWhenReady = true
OkHttpDataSource/OkHttpDataSourceFactoryにはカスタマイズしたOkhttp.Callを渡すことができるので、この部分で自由にカスタマイズできるという訳です。
リクエストヘッダ・タイムアウト時間をカスタムする場合はOkhttp Extentionは不要
リクエストヘッダ・タイムアウト時間・リダイレクトなどの設定なら、コアライブラリに含まれるDefaultHttpDataSourceFactoryで対応可能です。
Okhttp Extentionを使用せずに済みます。
例
val factory = DefaultHttpDataSourceFactory(
userAgent,
connectTimeout,
readTimeout,
allowCrossProtocolRedirects/*HTTP<=>HTTPS間のリダイレクトを許容するかどうか*/
)
factory.defaultRequestProperties.set("headerName", "headerValue")
val mediaSource = ProgressiveMediaSource.Factory(factory).createMediaSource("REMOTE_URL".toUri())
player.prepare(mediaSource)
player.playWhenReady = true
ネットワークイベントを作成する場合はOkhttp Extentionは不要
ダウンロードの進捗やリクエストの各パラメータを知りたいなら、コアライブラリのTransferListenerが便利です。
Okhttp Extentionを使用せずに済みます。
例
// dataSpecからリクエストパラメータやストリーム中のポジションを取得できます
// requestパラメータ:
// dataSpec?.httpBody
// dataSpec?.httpRequestHeaders
// dataSpec?.httpMethod
// ストリーム中のポジション:
// dataSpec?.position
// dataSpec?.absoluteStreamPosition
val transferListener = object : TransferListener {
override fun onTransferInitializing(
source: DataSource?,
dataSpec: DataSpec?,
isNetwork: Boolean
) {
}
override fun onTransferStart(
source: DataSource?,
dataSpec: DataSpec?,
isNetwork: Boolean
) {
}
override fun onTransferEnd(
source: DataSource?,
dataSpec: DataSpec?,
isNetwork: Boolean
) {
}
override fun onBytesTransferred(
source: DataSource?,
dataSpec: DataSpec?,
isNetwork: Boolean,
bytesTransferred: Int
) {
}
}
val factory = DefaultDataSourceFactory(getApplication(), userAgent, transferListener)
val mediaSource = ProgressiveMediaSource.Factory(factory).createMediaSource("REMOTE_URL".toUri())
player.prepare(mediaSource)
player.playWhenReady = true
さいごに
Okhttp Extentionは自由度が高く何でもできますが、基本的なことならコアライブラリのみで実装可能です。
レスポンスデータそのもの書きかえたい時など、使用する場面は割と限られてくるかと思います。