diff --git a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java index 37c47a2c7f..e3fc32ec64 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java @@ -68,6 +68,7 @@ public final class MediaItem { private boolean drmMultiSession; private boolean drmPlayClearContentWithoutKey; private List drmSessionForClearTypes; + @Nullable private byte[] drmKeySetId; private List streamKeys; @Nullable private String customCacheKey; private List subtitles; @@ -110,6 +111,7 @@ public final class MediaItem { drmPlayClearContentWithoutKey = drmConfiguration.playClearContentWithoutKey; drmSessionForClearTypes = drmConfiguration.sessionForClearTypes; drmUuid = drmConfiguration.uuid; + drmKeySetId = drmConfiguration.getKeySetId(); } } } @@ -311,6 +313,20 @@ public final class MediaItem { return this; } + /** + * Sets the key set ID of the offline license. + * + *

The key set ID identifies an offline license. The ID is required to query, renew or + * release an existing offline license (see {@code DefaultDrmSessionManager#setMode(int + * mode,byte[] offlineLicenseKeySetId)}). + * + *

If no valid DRM configuration is specified, the key set ID is ignored. + */ + public Builder setDrmKeySetId(@Nullable byte[] keySetId) { + this.drmKeySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null; + return this; + } + /** * Sets the optional stream keys by which the manifest is filtered (only used for adaptive * streams). @@ -414,7 +430,8 @@ public final class MediaItem { drmLicenseRequestHeaders, drmMultiSession, drmPlayClearContentWithoutKey, - drmSessionForClearTypes) + drmSessionForClearTypes, + drmKeySetId) : null, streamKeys, customCacheKey, @@ -463,19 +480,29 @@ public final class MediaItem { /** The types of clear tracks for which to use a drm session. */ public final List sessionForClearTypes; + @Nullable private final byte[] keySetId; + private DrmConfiguration( UUID uuid, @Nullable Uri licenseUri, Map requestHeaders, boolean multiSession, boolean playClearContentWithoutKey, - List drmSessionForClearTypes) { + List drmSessionForClearTypes, + @Nullable byte[] keySetId) { this.uuid = uuid; this.licenseUri = licenseUri; this.requestHeaders = requestHeaders; this.multiSession = multiSession; this.playClearContentWithoutKey = playClearContentWithoutKey; this.sessionForClearTypes = drmSessionForClearTypes; + this.keySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null; + } + + /** Returns the key set ID of the offline license. */ + @Nullable + public byte[] getKeySetId() { + return keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null; } @Override @@ -493,7 +520,8 @@ public final class MediaItem { && Util.areEqual(requestHeaders, other.requestHeaders) && multiSession == other.multiSession && playClearContentWithoutKey == other.playClearContentWithoutKey - && sessionForClearTypes.equals(other.sessionForClearTypes); + && sessionForClearTypes.equals(other.sessionForClearTypes) + && Arrays.equals(keySetId, other.keySetId); } @Override @@ -504,6 +532,7 @@ public final class MediaItem { result = 31 * result + (multiSession ? 1 : 0); result = 31 * result + (playClearContentWithoutKey ? 1 : 0); result = 31 * result + sessionForClearTypes.hashCode(); + result = 31 * result + Arrays.hashCode(keySetId); return result; } } diff --git a/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java b/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java index 15a35f3f9d..c7a55b88ff 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java @@ -91,6 +91,7 @@ public class MediaItemTest { Uri licenseUri = Uri.parse(URI_STRING); Map requestHeaders = new HashMap<>(); requestHeaders.put("Referer", "http://www.google.com"); + byte[] keySetId = new byte[] {1, 2, 3}; MediaItem mediaItem = new MediaItem.Builder() .setSourceUri(URI_STRING) @@ -100,6 +101,7 @@ public class MediaItemTest { .setDrmMultiSession(/* multiSession= */ true) .setDrmPlayClearContentWithoutKey(true) .setDrmSessionForClearTypes(Collections.singletonList(C.TRACK_TYPE_AUDIO)) + .setDrmKeySetId(keySetId) .build(); assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull(); @@ -111,6 +113,7 @@ public class MediaItemTest { assertThat(mediaItem.playbackProperties.drmConfiguration.playClearContentWithoutKey).isTrue(); assertThat(mediaItem.playbackProperties.drmConfiguration.sessionForClearTypes) .containsExactly(C.TRACK_TYPE_AUDIO); + assertThat(mediaItem.playbackProperties.drmConfiguration.getKeySetId()).isEqualTo(keySetId); } @Test @@ -304,6 +307,7 @@ public class MediaItemTest { .setDrmMultiSession(true) .setDrmPlayClearContentWithoutKey(true) .setDrmSessionForClearTypes(Collections.singletonList(C.TRACK_TYPE_AUDIO)) + .setDrmKeySetId(new byte[] {1, 2, 3}) .setMediaId("mediaId") .setMediaMetadata(new MediaMetadata.Builder().setTitle("title").build()) .setMimeType(MimeTypes.APPLICATION_MP4)