Skip to content

Commit

Permalink
Add widevine support
Browse files Browse the repository at this point in the history
  • Loading branch information
brahmkshatriya committed Oct 23, 2024
1 parent 04a3287 commit 3dbbb1d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ object MediaItemUtils {
track: Track
): MediaItem = with(mediaItem) {
val item = buildUpon()
val drmType = track.streamables.firstNotNullOfOrNull { it.decryptionType }
when (drmType) {
null -> {}
is Streamable.DecryptionType.Widevine -> {
val drmRequest = drmType.license
val config = MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
.setLicenseUri(drmRequest.url)
.setMultiSession(drmType.isMultiSession)
.setLicenseRequestHeaders(drmRequest.headers)
.build()
item.setDrmConfiguration(config)
}
}
val metadata =
track.toMetaData(mediaMetadata.extras!!, clientId, context, true, settings)
item.setMediaMetadata(metadata)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.media3.common.util.UnstableApi
import androidx.media3.datasource.ResolvingDataSource
import androidx.media3.datasource.cache.SimpleCache
import androidx.media3.exoplayer.dash.DashMediaSource
import androidx.media3.exoplayer.drm.DefaultDrmSessionManagerProvider
import androidx.media3.exoplayer.drm.DrmSessionManagerProvider
import androidx.media3.exoplayer.hls.HlsMediaSource
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
Expand All @@ -32,7 +33,20 @@ class MediaFactory(
private val throwableFlow: MutableSharedFlow<Throwable>
) : MediaSource.Factory {

private var drmSessionManagerProvider: DrmSessionManagerProvider? = null
private val mediaResolver = MediaResolver(context, extListFlow)
private val dataSource = ResolvingDataSource.Factory(
CustomCacheDataSource.Factory(cache, MediaDataSource.Factory(context)),
mediaResolver
)
private val default = lazily { DefaultMediaSourceFactory(dataSource) }
private val hls = lazily { HlsMediaSource.Factory(dataSource) }
private val dash = lazily { DashMediaSource.Factory(dataSource) }

private val provider = DefaultDrmSessionManagerProvider().apply {
setDrmHttpDataSourceFactory(dataSource)
}

private var drmSessionManagerProvider: DrmSessionManagerProvider? = provider
private var loadErrorHandlingPolicy: LoadErrorHandlingPolicy? = null
private fun lazily(factory: () -> MediaSource.Factory) = lazy {
factory().apply {
Expand All @@ -47,14 +61,6 @@ class MediaFactory(
mediaResolver.player = player
}

private val mediaResolver = MediaResolver(context, extListFlow)
private val dataSource = ResolvingDataSource.Factory(
CustomCacheDataSource.Factory(cache, MediaDataSource.Factory(context)),
mediaResolver
)
private val default = lazily { DefaultMediaSourceFactory(dataSource) }
private val hls = lazily { HlsMediaSource.Factory(dataSource) }
private val dash = lazily { DashMediaSource.Factory(dataSource) }

override fun getSupportedTypes() = intArrayOf(
C.CONTENT_TYPE_OTHER, C.CONTENT_TYPE_HLS, C.CONTENT_TYPE_DASH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ data class Streamable(
val quality: Int,
val mediaType: MediaType,
val mimeType: MimeType = MimeType.Progressive,
val decryptionType: DecryptionType? = null,
val title: String? = null,
val extra: Map<String, String> = mapOf()
) {
enum class MimeType { Progressive, HLS, DASH }
enum class MediaType { Audio, Video, AudioVideo, Subtitle }
enum class SubtitleType { VTT, SRT, ASS }

@Serializable
sealed class DecryptionType {
data class Widevine(val license: Request, val isMultiSession: Boolean) : DecryptionType()
}

sealed class Media {
data class Subtitle(val url: String, val type: SubtitleType) : Media()

Expand Down Expand Up @@ -61,16 +67,21 @@ data class Streamable(
sealed class Audio {
abstract val skipSilence: Boolean?

data class Http(
val request: Request, override val skipSilence: Boolean? = null
open class Http(
open val request: Request,
override val skipSilence: Boolean? = null
) : Audio()

data class ByteStream(
val stream: InputStream, val totalBytes: Long, override val skipSilence: Boolean? = null
val stream: InputStream,
val totalBytes: Long,
override val skipSilence: Boolean? = null
) : Audio()

data class Channel(
val channel: ByteReadChannel, val totalBytes: Long, override val skipSilence: Boolean? = null
val channel: ByteReadChannel,
val totalBytes: Long,
override val skipSilence: Boolean? = null
) : Audio()

companion object {
Expand All @@ -84,30 +95,35 @@ data class Streamable(
id: String,
quality: Int,
type: MimeType = MimeType.Progressive,
decryptionType: DecryptionType? = null,
title: String? = null,
extra: Map<String, String> = mapOf()
) = Streamable(id, quality, MediaType.Audio, type, title, extra)
) = Streamable(id, quality, MediaType.Audio, type, decryptionType, title, extra)

fun video(
id: String,
quality: Int,
type: MimeType = MimeType.Progressive,
decryptionType: DecryptionType? = null,
title: String? = null,
extra: Map<String, String> = mapOf()
) = Streamable(id, quality, MediaType.Video, type, title, extra)
) = Streamable(id, quality, MediaType.Video, type, decryptionType, title, extra)

fun audioVideo(
id: String,
quality: Int,
type: MimeType = MimeType.Progressive,
decryptionType: DecryptionType? = null,
title: String? = null,
extra: Map<String, String> = mapOf()
) = Streamable(id, quality, MediaType.AudioVideo, type, title, extra)
) = Streamable(id, quality, MediaType.AudioVideo, type, decryptionType, title, extra)

fun subtitle(
id: String,
title: String? = null,
extra: Map<String, String> = mapOf()
) = Streamable(id, 0, MediaType.Subtitle, MimeType.Progressive, title, extra)
) = Streamable(
id, 0, MediaType.Subtitle, MimeType.Progressive, null, title, extra
)
}
}

0 comments on commit 3dbbb1d

Please sign in to comment.