Skip to content

Commit

Permalink
Merge pull request #30 from scribd/karl/APT-9568-drm-headers
Browse files Browse the repository at this point in the history
[APT-9568] Add model support for DRM info for streaming playback
  • Loading branch information
kschults authored Dec 21, 2023
2 parents 8895c27 + 3573049 commit 5f4401b
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 8 deletions.
26 changes: 23 additions & 3 deletions Armadillo/src/main/java/com/scribd/armadillo/models/Models.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.scribd.armadillo.models

import android.os.Parcel
import android.os.Parcelable
import com.google.android.exoplayer2.C
import com.scribd.armadillo.Milliseconds
import com.scribd.armadillo.extensions.toPrint
import com.scribd.armadillo.time.milliseconds
import java.io.Serializable
import java.util.UUID

data class AudioPlayable(val id: Int,
val title: String,
Expand All @@ -23,11 +25,16 @@ data class AudioPlayable(val id: Int,
/**
* Additional provider-specific metadata required to access the URL (e.g. HTTP authentication headers)
*/
val headers: Map<String, String> = emptyMap()
val headers: Map<String, String> = emptyMap(),
/**
* Additional information required to access a DRM server
*/
val drmInfo: DrmInfo? = null
) : Serializable {
companion object {
// Just roughing in a factory pattern in case we need to generate more complex accessors in the future.
fun createHttpUri(url: String, headers: Map<String, String> = emptyMap()) = MediaRequest(url, headers)
fun createHttpUri(url: String, headers: Map<String, String> = emptyMap(), drmInfo: DrmInfo? = null) =
MediaRequest(url, headers, drmInfo)
}

override fun equals(other: Any?): Boolean {
Expand All @@ -38,13 +45,14 @@ data class AudioPlayable(val id: Int,

if (url != other.url) return false
if (headers != other.headers) return false
if (drmInfo != other.drmInfo) return false

return true
}

override fun hashCode(): Int {
var result = url.hashCode()
result = 31 * result + headers.hashCode()
result = 31 * result + headers.hashCode() + 3 * drmInfo.hashCode()
return result
}

Expand Down Expand Up @@ -131,4 +139,16 @@ data class Chapter(
return arrayOfNulls(size)
}
}
}

data class DrmInfo(val drmType: DrmType, val licenseServer: String, val drmHeaders: Map<String, String> = emptyMap()) : Serializable

enum class DrmType {
WIDEVINE;

internal fun toExoplayerConstant(): UUID {
return when (this) {
WIDEVINE -> C.WIDEVINE_UUID
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.scribd.armadillo.playback.mediasource

import android.content.Context
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.MediaItem.DrmConfiguration
import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadHelper
import com.google.android.exoplayer2.source.MediaSource
Expand All @@ -24,12 +25,20 @@ internal class DashMediaSourceGenerator @Inject constructor(
}
}

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

if (request.drmInfo != null) {
mediaItemBuilder.setDrmConfiguration(
DrmConfiguration.Builder(request.drmInfo.drmType.toExoplayerConstant())
.setLicenseUri(request.drmInfo.licenseServer)
.setLicenseRequestHeaders(request.drmInfo.drmHeaders)
.build()
)
}

return DashMediaSource.Factory(dataSourceFactory)
.createMediaSource(mediaItem)
.createMediaSource(mediaItemBuilder.build())
}

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

import android.content.Context
import android.util.Log
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadHelper
Expand Down Expand Up @@ -28,6 +29,11 @@ internal class HlsMediaSourceGenerator @Inject constructor(
return DownloadHelper.createMediaSource(it.request, dataSourceFactory)
}
}

if (request.drmInfo != null) {
Log.e(MediaSourceGenerator.TAG, "HLS does not currently support DRM")

This comment has been minimized.

Copy link
@NathanSass

NathanSass Dec 28, 2023

Contributor

@kschults Might be good to throw here cause we wouldn't want someone to accidentally think that they were getting DRM protection and then still play the content.

}

return HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(MediaItem.fromUri(request.url))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import com.scribd.armadillo.models.AudioPlayable
/** Creates a MediaSource for starting playback in Exoplayer when this
* class is initialized. */
internal interface MediaSourceGenerator {
companion object {
const val TAG = "MediaSourceGenerator"
}

fun generateMediaSource(context: Context, request: AudioPlayable.MediaRequest): MediaSource

fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.scribd.armadillo.playback.mediasource

import android.content.Context
import android.util.Log
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource
Expand All @@ -16,7 +17,11 @@ internal class ProgressiveMediaSourceGenerator @Inject constructor(
private val cacheManager: CacheManager) : MediaSourceGenerator {

override fun generateMediaSource(context: Context, request: AudioPlayable.MediaRequest): MediaSource =
ProgressiveMediaSource.Factory(buildDataSourceFactory(context)).createMediaSource(MediaItem.fromUri(request.url))
ProgressiveMediaSource.Factory(buildDataSourceFactory(context)).createMediaSource(MediaItem.fromUri(request.url)).also {
if (request.drmInfo != null) {
Log.e(MediaSourceGenerator.TAG, "Progressive media does not currently support DRM")
}
}

override fun updateMediaSourceHeaders(request: AudioPlayable.MediaRequest) = Unit // Doesn't use headers

Expand Down
3 changes: 3 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Project Armadillo Release Notes

## 1.3.0
- Adds support for DRM when playing MPEG-DASH audio

## 1.2.0
- Adds support for MPEG-DASH audio

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ org.gradle.jvmargs=-Xmx1536m
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
PACKAGE_NAME=com.scribd.armadillo
LIBRARY_VERSION=1.2.0
LIBRARY_VERSION=1.3.0
EXOPLAYER_VERSION=2.17.1
RXJAVA_VERSION=2.2.4
RXANDROID_VERSION=2.0.1
Expand Down

0 comments on commit 5f4401b

Please sign in to comment.