Skip to content

Commit

Permalink
[APT-9543] Refactor common pieces for header-aware media
Browse files Browse the repository at this point in the history
  • Loading branch information
kschults committed Dec 5, 2023
1 parent f5b1bcd commit 85800ef
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import com.scribd.armadillo.playback.MediaMetadataCompatBuilderImpl
import com.scribd.armadillo.playback.PlaybackEngineFactoryHolder
import com.scribd.armadillo.playback.PlaybackStateBuilderImpl
import com.scribd.armadillo.playback.PlaybackStateCompatBuilder
import com.scribd.armadillo.playback.mediasource.HeadersMediaSourceHelper
import com.scribd.armadillo.playback.mediasource.HeadersMediaSourceHelperImpl
import com.scribd.armadillo.playback.mediasource.MediaSourceRetriever
import com.scribd.armadillo.playback.mediasource.MediaSourceRetrieverImpl
import dagger.Module
Expand Down Expand Up @@ -56,4 +58,8 @@ internal class PlaybackModule {
@Provides
@Singleton
fun mediaSourceRetriever(mediaSourceRetrieverImpl: MediaSourceRetrieverImpl): MediaSourceRetriever = mediaSourceRetrieverImpl

@Provides
@Singleton
fun mediaSourceHelper(mediaSourceHelperImpl: HeadersMediaSourceHelperImpl): HeadersMediaSourceHelper = mediaSourceHelperImpl
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,69 +6,31 @@ import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadHelper
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.dash.DashMediaSource
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
import com.scribd.armadillo.Constants
import com.scribd.armadillo.HeadersStore
import com.scribd.armadillo.download.CacheManager
import com.scribd.armadillo.download.DownloadTracker
import com.scribd.armadillo.extensions.toUri
import com.scribd.armadillo.models.AudioPlayable
import javax.inject.Inject

internal class DashMediaSourceGenerator @Inject constructor(
private val cacheManager: CacheManager,
private val headersStore: HeadersStore,
private val mediaSourceHelper: HeadersMediaSourceHelper,
private val downloadTracker: DownloadTracker) : MediaSourceGenerator {

private val previousRequests = mutableMapOf<String, DefaultHttpDataSource.Factory>()

override fun generateMediaSource(context: Context, request: AudioPlayable.MediaRequest): MediaSource {
val dataSourceFactory = mediaSourceHelper.createDataSourceFactory(context, request)

downloadTracker.getDownload(request.url.toUri())?.let {
if (it.state != Download.STATE_FAILED) {
return DownloadHelper.createMediaSource(it.request, buildDataSourceFactory(context, request))
return DownloadHelper.createMediaSource(it.request, dataSourceFactory)
}
}

val mediaItem = MediaItem.Builder()
.setUri(request.url)

.build()

return DashMediaSource.Factory(buildDataSourceFactory(context, request))
return DashMediaSource.Factory(dataSourceFactory)
.createMediaSource(mediaItem)
}

override fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest) {
previousRequests[request.url]?.let { factory ->
if (request.headers.isNotEmpty()) {
headersStore.keyForUrl(request.url)?.let {
headersStore.setHeaders(it, request.headers)
}
// Updating the factory instance updates future requests generated from this factory by ExoPlayer
factory.setDefaultRequestProperties(request.headers)
}
}
}

private fun buildDataSourceFactory(context: Context, request: AudioPlayable.MediaRequest): DataSource.Factory {
val httpDataSourceFactory = DefaultHttpDataSource.Factory()
.setUserAgent(Constants.getUserAgent(context))
.setConnectTimeoutMs(DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS)
.setReadTimeoutMs(DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS)
.setAllowCrossProtocolRedirects(true)

previousRequests[request.url] = httpDataSourceFactory
if (request.headers.isNotEmpty()) {
headersStore.keyForUrl(request.url)?.let {
headersStore.setHeaders(it, request.headers)
}
httpDataSourceFactory.setDefaultRequestProperties(request.headers)
}

val upstreamFactory = DefaultDataSource.Factory(context, httpDataSourceFactory)
return cacheManager.playbackDataSourceFactory(context, upstreamFactory)
}

override fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest) = mediaSourceHelper.updateMediaSourceHeaders(request)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.scribd.armadillo.playback.mediasource

import android.content.Context
import com.google.android.exoplayer2.upstream.DataSource
import com.scribd.armadillo.models.AudioPlayable

internal interface HeadersMediaSourceHelper {
fun createDataSourceFactory(context: Context, request: AudioPlayable.MediaRequest): DataSource.Factory
fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.scribd.armadillo.playback.mediasource

import android.content.Context
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
import com.scribd.armadillo.Constants
import com.scribd.armadillo.HeadersStore
import com.scribd.armadillo.download.CacheManager
import com.scribd.armadillo.models.AudioPlayable
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
internal class HeadersMediaSourceHelperImpl @Inject constructor(
private val cacheManager: CacheManager,
private val headersStore: HeadersStore
): HeadersMediaSourceHelper {
private val previousRequests = mutableMapOf<String, DefaultHttpDataSource.Factory>()

override fun createDataSourceFactory(context: Context, request: AudioPlayable.MediaRequest): DataSource.Factory {
val httpDataSourceFactory = DefaultHttpDataSource.Factory()
.setUserAgent(Constants.getUserAgent(context))
.setConnectTimeoutMs(DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS)
.setReadTimeoutMs(DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS)
.setAllowCrossProtocolRedirects(true)

previousRequests[request.url] = httpDataSourceFactory
if (request.headers.isNotEmpty()) {
headersStore.keyForUrl(request.url)?.let {
headersStore.setHeaders(it, request.headers)
}
httpDataSourceFactory.setDefaultRequestProperties(request.headers)
}

val upstreamFactory = DefaultDataSource.Factory(context, httpDataSourceFactory)
return cacheManager.playbackDataSourceFactory(context, upstreamFactory)

}

override fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest) {
previousRequests[request.url]?.let { factory ->
if (request.headers.isNotEmpty()) {
headersStore.keyForUrl(request.url)?.let {
headersStore.setHeaders(it, request.headers)
}
// Updating the factory instance updates future requests generated from this factory by ExoPlayer
factory.setDefaultRequestProperties(request.headers)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadHelper
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.hls.HlsMediaSource
import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSource
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource
import com.scribd.armadillo.Constants
import com.scribd.armadillo.HeadersStore
import com.scribd.armadillo.download.CacheManager
import com.scribd.armadillo.download.DownloadTracker
import com.scribd.armadillo.extensions.toUri
import com.scribd.armadillo.models.AudioPlayable
Expand All @@ -22,50 +16,21 @@ import javax.inject.Inject
*
*/
internal class HlsMediaSourceGenerator @Inject constructor(
private val cacheManager: CacheManager,
private val headersStore: HeadersStore,
private val mediaSourceHelper: HeadersMediaSourceHelper,
private val downloadTracker: DownloadTracker) : MediaSourceGenerator {

private val previousRequests = mutableMapOf<String, DefaultHttpDataSource.Factory>()

override fun generateMediaSource(context: Context, request: AudioPlayable.MediaRequest): MediaSource {
val dataSourceFactory = mediaSourceHelper.createDataSourceFactory(context, request)

downloadTracker.getDownload(request.url.toUri())?.let {
if (it.state != Download.STATE_FAILED) {
return DownloadHelper.createMediaSource(it.request, buildDataSourceFactory(context, request))
return DownloadHelper.createMediaSource(it.request, dataSourceFactory)
}
}
return HlsMediaSource.Factory(buildDataSourceFactory(context, request))
return HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(request.url))
}

override fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest) {
previousRequests[request.url]?.let { factory ->
if (request.headers.isNotEmpty()) {
headersStore.keyForUrl(request.url)?.let {
headersStore.setHeaders(it, request.headers)
}
// Updating the factory instance updates future requests generated from this factory by ExoPlayer
factory.setDefaultRequestProperties(request.headers)
}
}
}

private fun buildDataSourceFactory(context: Context, request: AudioPlayable.MediaRequest): DataSource.Factory {
val httpDataSourceFactory = DefaultHttpDataSource.Factory()
.setUserAgent(Constants.getUserAgent(context))
.setConnectTimeoutMs(DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS)
.setReadTimeoutMs(DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS)
.setAllowCrossProtocolRedirects(true)

previousRequests[request.url] = httpDataSourceFactory
if (request.headers.isNotEmpty()) {
headersStore.keyForUrl(request.url)?.let {
headersStore.setHeaders(it, request.headers)
}
httpDataSourceFactory.setDefaultRequestProperties(request.headers)
}

val upstreamFactory = DefaultDataSource.Factory(context, httpDataSourceFactory)
return cacheManager.playbackDataSourceFactory(context, upstreamFactory)
}
override fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest) = mediaSourceHelper.updateMediaSourceHeaders(request)
}

0 comments on commit 85800ef

Please sign in to comment.