Add MediaItem.DrmConfiguration.Builder and use it in MediaItem.Builder
PiperOrigin-RevId: 395896034
This commit is contained in:
parent
7dff223d80
commit
9f3c2fb5e1
@ -26,13 +26,14 @@ import androidx.annotation.Nullable;
|
|||||||
import com.google.android.exoplayer2.offline.StreamKey;
|
import com.google.android.exoplayer2.offline.StreamKey;
|
||||||
import com.google.android.exoplayer2.util.Assertions;
|
import com.google.android.exoplayer2.util.Assertions;
|
||||||
import com.google.android.exoplayer2.util.Util;
|
import com.google.android.exoplayer2.util.Util;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -71,14 +72,9 @@ public final class MediaItem implements Bundleable {
|
|||||||
private boolean clipRelativeToLiveWindow;
|
private boolean clipRelativeToLiveWindow;
|
||||||
private boolean clipRelativeToDefaultPosition;
|
private boolean clipRelativeToDefaultPosition;
|
||||||
private boolean clipStartsAtKeyFrame;
|
private boolean clipStartsAtKeyFrame;
|
||||||
@Nullable private Uri drmLicenseUri;
|
// TODO: Change this to @Nullable DrmConfiguration once all the deprecated individual setters
|
||||||
private Map<String, String> drmLicenseRequestHeaders;
|
// are removed.
|
||||||
@Nullable private UUID drmUuid;
|
private DrmConfiguration.Builder drmConfiguration;
|
||||||
private boolean drmMultiSession;
|
|
||||||
private boolean drmPlayClearContentWithoutKey;
|
|
||||||
private boolean drmForceDefaultLicenseUri;
|
|
||||||
private List<Integer> drmSessionForClearTypes;
|
|
||||||
@Nullable private byte[] drmKeySetId;
|
|
||||||
private List<StreamKey> streamKeys;
|
private List<StreamKey> streamKeys;
|
||||||
@Nullable private String customCacheKey;
|
@Nullable private String customCacheKey;
|
||||||
private List<Subtitle> subtitles;
|
private List<Subtitle> subtitles;
|
||||||
@ -93,10 +89,10 @@ public final class MediaItem implements Bundleable {
|
|||||||
private float liveMaxPlaybackSpeed;
|
private float liveMaxPlaybackSpeed;
|
||||||
|
|
||||||
/** Creates a builder. */
|
/** Creates a builder. */
|
||||||
|
@SuppressWarnings("deprecation") // Temporarily uses DrmConfiguration.Builder() constructor.
|
||||||
public Builder() {
|
public Builder() {
|
||||||
clipEndPositionMs = C.TIME_END_OF_SOURCE;
|
clipEndPositionMs = C.TIME_END_OF_SOURCE;
|
||||||
drmSessionForClearTypes = Collections.emptyList();
|
drmConfiguration = new DrmConfiguration.Builder();
|
||||||
drmLicenseRequestHeaders = Collections.emptyMap();
|
|
||||||
streamKeys = Collections.emptyList();
|
streamKeys = Collections.emptyList();
|
||||||
subtitles = Collections.emptyList();
|
subtitles = Collections.emptyList();
|
||||||
liveTargetOffsetMs = C.TIME_UNSET;
|
liveTargetOffsetMs = C.TIME_UNSET;
|
||||||
@ -128,17 +124,10 @@ public final class MediaItem implements Bundleable {
|
|||||||
streamKeys = playbackProperties.streamKeys;
|
streamKeys = playbackProperties.streamKeys;
|
||||||
subtitles = playbackProperties.subtitles;
|
subtitles = playbackProperties.subtitles;
|
||||||
tag = playbackProperties.tag;
|
tag = playbackProperties.tag;
|
||||||
@Nullable DrmConfiguration drmConfiguration = playbackProperties.drmConfiguration;
|
drmConfiguration =
|
||||||
if (drmConfiguration != null) {
|
playbackProperties.drmConfiguration != null
|
||||||
drmLicenseUri = drmConfiguration.licenseUri;
|
? playbackProperties.drmConfiguration.buildUpon()
|
||||||
drmLicenseRequestHeaders = drmConfiguration.requestHeaders;
|
: new DrmConfiguration.Builder();
|
||||||
drmMultiSession = drmConfiguration.multiSession;
|
|
||||||
drmForceDefaultLicenseUri = drmConfiguration.forceDefaultLicenseUri;
|
|
||||||
drmPlayClearContentWithoutKey = drmConfiguration.playClearContentWithoutKey;
|
|
||||||
drmSessionForClearTypes = drmConfiguration.sessionForClearTypes;
|
|
||||||
drmUuid = drmConfiguration.uuid;
|
|
||||||
drmKeySetId = drmConfiguration.getKeySetId();
|
|
||||||
}
|
|
||||||
@Nullable AdsConfiguration adsConfiguration = playbackProperties.adsConfiguration;
|
@Nullable AdsConfiguration adsConfiguration = playbackProperties.adsConfiguration;
|
||||||
if (adsConfiguration != null) {
|
if (adsConfiguration != null) {
|
||||||
adTagUri = adsConfiguration.adTagUri;
|
adTagUri = adsConfiguration.adTagUri;
|
||||||
@ -243,149 +232,111 @@ public final class MediaItem implements Bundleable {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sets the optional DRM configuration. */
|
||||||
|
public Builder setDrmConfiguration(@Nullable DrmConfiguration drmConfiguration) {
|
||||||
|
this.drmConfiguration =
|
||||||
|
drmConfiguration != null ? drmConfiguration.buildUpon() : new DrmConfiguration.Builder();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the optional default DRM license server URI. If this URI is set, the {@link
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
* DrmConfiguration#uuid} needs to be specified as well.
|
* DrmConfiguration.Builder#setLicenseUri(Uri)} instead.
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmLicenseUri(@Nullable Uri licenseUri) {
|
public Builder setDrmLicenseUri(@Nullable Uri licenseUri) {
|
||||||
drmLicenseUri = licenseUri;
|
drmConfiguration.setLicenseUri(licenseUri);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the optional default DRM license server URI. If this URI is set, the {@link
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
* DrmConfiguration#uuid} needs to be specified as well.
|
* DrmConfiguration.Builder#setLicenseUri(String)} instead.
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmLicenseUri(@Nullable String licenseUri) {
|
public Builder setDrmLicenseUri(@Nullable String licenseUri) {
|
||||||
drmLicenseUri = licenseUri == null ? null : Uri.parse(licenseUri);
|
drmConfiguration.setLicenseUri(licenseUri);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the optional request headers attached to the DRM license request.
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
*
|
* DrmConfiguration.Builder#setLicenseRequestHeaders(Map)} instead.
|
||||||
* <p>{@code null} or an empty {@link Map} can be used for a reset.
|
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmLicenseRequestHeaders(
|
public Builder setDrmLicenseRequestHeaders(
|
||||||
@Nullable Map<String, String> licenseRequestHeaders) {
|
@Nullable Map<String, String> licenseRequestHeaders) {
|
||||||
this.drmLicenseRequestHeaders =
|
drmConfiguration.setLicenseRequestHeaders(licenseRequestHeaders);
|
||||||
licenseRequestHeaders != null && !licenseRequestHeaders.isEmpty()
|
|
||||||
? Collections.unmodifiableMap(new HashMap<>(licenseRequestHeaders))
|
|
||||||
: Collections.emptyMap();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the {@link UUID} of the protection scheme.
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and pass the {@code uuid} to
|
||||||
*
|
* {@link DrmConfiguration.Builder#Builder(UUID)} instead.
|
||||||
* <p>If {@code uuid} is null or unset then no {@link DrmConfiguration} object is created during
|
|
||||||
* {@link #build()} and no other {@code Builder} methods that would populate {@link
|
|
||||||
* MediaItem.PlaybackProperties#drmConfiguration} should be called.
|
|
||||||
*
|
|
||||||
* <p>This method should only be called if {@link #setUri} is passed a non-null value.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmUuid(@Nullable UUID uuid) {
|
public Builder setDrmUuid(@Nullable UUID uuid) {
|
||||||
drmUuid = uuid;
|
drmConfiguration.setNullableUuid(uuid);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the DRM configuration is multi session enabled.
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
*
|
* DrmConfiguration.Builder#setMultiSession(boolean)} instead.
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmMultiSession(boolean multiSession) {
|
public Builder setDrmMultiSession(boolean multiSession) {
|
||||||
drmMultiSession = multiSession;
|
drmConfiguration.setMultiSession(multiSession);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether to force use the default DRM license server URI even if the media specifies its
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
* own DRM license server URI.
|
* DrmConfiguration.Builder#setForceDefaultLicenseUri(boolean)} instead.
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmForceDefaultLicenseUri(boolean forceDefaultLicenseUri) {
|
public Builder setDrmForceDefaultLicenseUri(boolean forceDefaultLicenseUri) {
|
||||||
this.drmForceDefaultLicenseUri = forceDefaultLicenseUri;
|
drmConfiguration.setForceDefaultLicenseUri(forceDefaultLicenseUri);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether clear samples within protected content should be played when keys for the
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
* encrypted part of the content have yet to be loaded.
|
* DrmConfiguration.Builder#setPlayClearContentWithoutKey(boolean)} instead.
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmPlayClearContentWithoutKey(boolean playClearContentWithoutKey) {
|
public Builder setDrmPlayClearContentWithoutKey(boolean playClearContentWithoutKey) {
|
||||||
this.drmPlayClearContentWithoutKey = playClearContentWithoutKey;
|
drmConfiguration.setPlayClearContentWithoutKey(playClearContentWithoutKey);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether a DRM session should be used for clear tracks of type {@link C#TRACK_TYPE_VIDEO}
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
* and {@link C#TRACK_TYPE_AUDIO}.
|
* DrmConfiguration.Builder#setSessionForClearPeriods(boolean)} instead.
|
||||||
*
|
|
||||||
* <p>This method overrides what has been set by previously calling {@link
|
|
||||||
* #setDrmSessionForClearTypes(List)}.
|
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmSessionForClearPeriods(boolean sessionForClearPeriods) {
|
public Builder setDrmSessionForClearPeriods(boolean sessionForClearPeriods) {
|
||||||
this.setDrmSessionForClearTypes(
|
drmConfiguration.setSessionForClearPeriods(sessionForClearPeriods);
|
||||||
sessionForClearPeriods
|
|
||||||
? Arrays.asList(C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_AUDIO)
|
|
||||||
: Collections.emptyList());
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a list of {@link C.TrackType track types} for which to use a DRM session even when the
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
* tracks are in the clear.
|
* DrmConfiguration.Builder#setSessionForClearTypes(List)} instead.
|
||||||
*
|
|
||||||
* <p>For the common case of using a DRM session for {@link C#TRACK_TYPE_VIDEO} and {@link
|
|
||||||
* C#TRACK_TYPE_AUDIO} the {@link #setDrmSessionForClearPeriods(boolean)} can be used.
|
|
||||||
*
|
|
||||||
* <p>This method overrides what has been set by previously calling {@link
|
|
||||||
* #setDrmSessionForClearPeriods(boolean)}.
|
|
||||||
*
|
|
||||||
* <p>{@code null} or an empty {@link List} can be used for a reset.
|
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmSessionForClearTypes(@Nullable List<Integer> sessionForClearTypes) {
|
public Builder setDrmSessionForClearTypes(@Nullable List<Integer> sessionForClearTypes) {
|
||||||
this.drmSessionForClearTypes =
|
drmConfiguration.setSessionForClearTypes(sessionForClearTypes);
|
||||||
sessionForClearTypes != null && !sessionForClearTypes.isEmpty()
|
|
||||||
? Collections.unmodifiableList(new ArrayList<>(sessionForClearTypes))
|
|
||||||
: Collections.emptyList();
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the key set ID of the offline license.
|
* @deprecated Use {@link #setDrmConfiguration(DrmConfiguration)} and {@link
|
||||||
*
|
* DrmConfiguration.Builder#setKeySetId(byte[])} instead.
|
||||||
* <p>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)}).
|
|
||||||
*
|
|
||||||
* <p>This method should only be called if both {@link #setUri} and {@link #setDrmUuid(UUID)}
|
|
||||||
* are passed non-null values.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public Builder setDrmKeySetId(@Nullable byte[] keySetId) {
|
public Builder setDrmKeySetId(@Nullable byte[] keySetId) {
|
||||||
this.drmKeySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
|
drmConfiguration.setKeySetId(keySetId);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,7 +519,8 @@ public final class MediaItem implements Bundleable {
|
|||||||
|
|
||||||
/** Returns a new {@link MediaItem} instance with the current builder values. */
|
/** Returns a new {@link MediaItem} instance with the current builder values. */
|
||||||
public MediaItem build() {
|
public MediaItem build() {
|
||||||
checkState(drmLicenseUri == null || drmUuid != null);
|
// TODO: remove this check once all the deprecated individual DRM setters are removed.
|
||||||
|
checkState(drmConfiguration.licenseUri == null || drmConfiguration.uuid != null);
|
||||||
@Nullable PlaybackProperties playbackProperties = null;
|
@Nullable PlaybackProperties playbackProperties = null;
|
||||||
@Nullable Uri uri = this.uri;
|
@Nullable Uri uri = this.uri;
|
||||||
if (uri != null) {
|
if (uri != null) {
|
||||||
@ -576,17 +528,7 @@ public final class MediaItem implements Bundleable {
|
|||||||
new PlaybackProperties(
|
new PlaybackProperties(
|
||||||
uri,
|
uri,
|
||||||
mimeType,
|
mimeType,
|
||||||
drmUuid != null
|
drmConfiguration.uuid != null ? drmConfiguration.build() : null,
|
||||||
? new DrmConfiguration(
|
|
||||||
drmUuid,
|
|
||||||
drmLicenseUri,
|
|
||||||
drmLicenseRequestHeaders,
|
|
||||||
drmMultiSession,
|
|
||||||
drmForceDefaultLicenseUri,
|
|
||||||
drmPlayClearContentWithoutKey,
|
|
||||||
drmSessionForClearTypes,
|
|
||||||
drmKeySetId)
|
|
||||||
: null,
|
|
||||||
adTagUri != null ? new AdsConfiguration(adTagUri, adsId) : null,
|
adTagUri != null ? new AdsConfiguration(adTagUri, adsId) : null,
|
||||||
streamKeys,
|
streamKeys,
|
||||||
customCacheKey,
|
customCacheKey,
|
||||||
@ -615,6 +557,165 @@ public final class MediaItem implements Bundleable {
|
|||||||
/** DRM configuration for a media item. */
|
/** DRM configuration for a media item. */
|
||||||
public static final class DrmConfiguration {
|
public static final class DrmConfiguration {
|
||||||
|
|
||||||
|
/** Builder for {@link DrmConfiguration}. */
|
||||||
|
public static final class Builder {
|
||||||
|
|
||||||
|
// TODO remove @Nullable annotation when the deprecated zero-arg constructor is removed.
|
||||||
|
@Nullable private UUID uuid;
|
||||||
|
@Nullable private Uri licenseUri;
|
||||||
|
private ImmutableMap<String, String> licenseRequestHeaders;
|
||||||
|
private boolean multiSession;
|
||||||
|
private boolean playClearContentWithoutKey;
|
||||||
|
private boolean forceDefaultLicenseUri;
|
||||||
|
private ImmutableList<Integer> sessionForClearTypes;
|
||||||
|
@Nullable private byte[] keySetId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance.
|
||||||
|
*
|
||||||
|
* @param uuid The {@link UUID} of the protection scheme.
|
||||||
|
*/
|
||||||
|
public Builder(UUID uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
this.licenseRequestHeaders = ImmutableMap.of();
|
||||||
|
this.sessionForClearTypes = ImmutableList.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This only exists to support the deprecated setters for individual DRM
|
||||||
|
* properties on {@link MediaItem.Builder}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private Builder() {
|
||||||
|
this.licenseRequestHeaders = ImmutableMap.of();
|
||||||
|
this.sessionForClearTypes = ImmutableList.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Builder(DrmConfiguration drmConfiguration) {
|
||||||
|
this.uuid = drmConfiguration.uuid;
|
||||||
|
this.licenseUri = drmConfiguration.licenseUri;
|
||||||
|
this.licenseRequestHeaders = drmConfiguration.requestHeaders;
|
||||||
|
this.multiSession = drmConfiguration.multiSession;
|
||||||
|
this.playClearContentWithoutKey = drmConfiguration.playClearContentWithoutKey;
|
||||||
|
this.forceDefaultLicenseUri = drmConfiguration.forceDefaultLicenseUri;
|
||||||
|
this.sessionForClearTypes = drmConfiguration.sessionForClearTypes;
|
||||||
|
this.keySetId = drmConfiguration.keySetId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the {@link UUID} of the protection scheme. */
|
||||||
|
public Builder setUuid(UUID uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated This only exists to support the deprecated {@link
|
||||||
|
* MediaItem.Builder#setDrmUuid(UUID)}.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
private Builder setNullableUuid(@Nullable UUID uuid) {
|
||||||
|
this.uuid = uuid;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the optional default DRM license server URI. */
|
||||||
|
public Builder setLicenseUri(@Nullable Uri licenseUri) {
|
||||||
|
this.licenseUri = licenseUri;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the optional default DRM license server URI. */
|
||||||
|
public Builder setLicenseUri(@Nullable String licenseUri) {
|
||||||
|
this.licenseUri = licenseUri == null ? null : Uri.parse(licenseUri);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets the optional request headers attached to DRM license requests. */
|
||||||
|
public Builder setLicenseRequestHeaders(@Nullable Map<String, String> licenseRequestHeaders) {
|
||||||
|
this.licenseRequestHeaders =
|
||||||
|
licenseRequestHeaders != null
|
||||||
|
? ImmutableMap.copyOf(licenseRequestHeaders)
|
||||||
|
: ImmutableMap.of();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets whether multi session is enabled. */
|
||||||
|
public Builder setMultiSession(boolean multiSession) {
|
||||||
|
this.multiSession = multiSession;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether to always use the default DRM license server URI even if the media specifies
|
||||||
|
* its own DRM license server URI.
|
||||||
|
*/
|
||||||
|
public Builder setForceDefaultLicenseUri(boolean forceDefaultLicenseUri) {
|
||||||
|
this.forceDefaultLicenseUri = forceDefaultLicenseUri;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether clear samples within protected content should be played when keys for the
|
||||||
|
* encrypted part of the content have yet to be loaded.
|
||||||
|
*/
|
||||||
|
public Builder setPlayClearContentWithoutKey(boolean playClearContentWithoutKey) {
|
||||||
|
this.playClearContentWithoutKey = playClearContentWithoutKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether a DRM session should be used for clear tracks of type {@link
|
||||||
|
* C#TRACK_TYPE_VIDEO} and {@link C#TRACK_TYPE_AUDIO}.
|
||||||
|
*
|
||||||
|
* <p>This method overrides what has been set by previously calling {@link
|
||||||
|
* #setSessionForClearTypes(List)}.
|
||||||
|
*/
|
||||||
|
public Builder setSessionForClearPeriods(boolean sessionForClearPeriods) {
|
||||||
|
this.setSessionForClearTypes(
|
||||||
|
sessionForClearPeriods
|
||||||
|
? ImmutableList.of(C.TRACK_TYPE_VIDEO, C.TRACK_TYPE_AUDIO)
|
||||||
|
: ImmutableList.of());
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a list of {@link C}{@code .TRACK_TYPE_*} constants for which to use a DRM session even
|
||||||
|
* when the tracks are in the clear.
|
||||||
|
*
|
||||||
|
* <p>For the common case of using a DRM session for {@link C#TRACK_TYPE_VIDEO} and {@link
|
||||||
|
* C#TRACK_TYPE_AUDIO} the {@link #setSessionForClearPeriods(boolean)} can be used.
|
||||||
|
*
|
||||||
|
* <p>This method overrides what has been set by previously calling {@link
|
||||||
|
* #setSessionForClearPeriods(boolean)}.
|
||||||
|
*
|
||||||
|
* <p>{@code null} or an empty {@link List} can be used for a reset.
|
||||||
|
*/
|
||||||
|
public Builder setSessionForClearTypes(@Nullable List<Integer> sessionForClearTypes) {
|
||||||
|
this.sessionForClearTypes =
|
||||||
|
sessionForClearTypes != null
|
||||||
|
? ImmutableList.copyOf(sessionForClearTypes)
|
||||||
|
: ImmutableList.of();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the key set ID of the offline license.
|
||||||
|
*
|
||||||
|
* <p>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)}).
|
||||||
|
*/
|
||||||
|
public Builder setKeySetId(@Nullable byte[] keySetId) {
|
||||||
|
this.keySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DrmConfiguration build() {
|
||||||
|
|
||||||
|
return new DrmConfiguration(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** The UUID of the protection scheme. */
|
/** The UUID of the protection scheme. */
|
||||||
public final UUID uuid;
|
public final UUID uuid;
|
||||||
|
|
||||||
@ -625,7 +726,7 @@ public final class MediaItem implements Bundleable {
|
|||||||
@Nullable public final Uri licenseUri;
|
@Nullable public final Uri licenseUri;
|
||||||
|
|
||||||
/** The headers to attach to the request to the DRM license server. */
|
/** The headers to attach to the request to the DRM license server. */
|
||||||
public final Map<String, String> requestHeaders;
|
public final ImmutableMap<String, String> requestHeaders;
|
||||||
|
|
||||||
/** Whether the DRM configuration is multi session enabled. */
|
/** Whether the DRM configuration is multi session enabled. */
|
||||||
public final boolean multiSession;
|
public final boolean multiSession;
|
||||||
@ -643,28 +744,23 @@ public final class MediaItem implements Bundleable {
|
|||||||
public final boolean forceDefaultLicenseUri;
|
public final boolean forceDefaultLicenseUri;
|
||||||
|
|
||||||
/** The types of clear tracks for which to use a DRM session. */
|
/** The types of clear tracks for which to use a DRM session. */
|
||||||
public final List<Integer> sessionForClearTypes;
|
public final ImmutableList<Integer> sessionForClearTypes;
|
||||||
|
|
||||||
@Nullable private final byte[] keySetId;
|
@Nullable private final byte[] keySetId;
|
||||||
|
|
||||||
private DrmConfiguration(
|
private DrmConfiguration(Builder builder) {
|
||||||
UUID uuid,
|
checkState(!(builder.forceDefaultLicenseUri && builder.licenseUri == null));
|
||||||
@Nullable Uri licenseUri,
|
this.uuid = checkNotNull(builder.uuid);
|
||||||
Map<String, String> requestHeaders,
|
this.licenseUri = builder.licenseUri;
|
||||||
boolean multiSession,
|
this.requestHeaders = builder.licenseRequestHeaders;
|
||||||
boolean forceDefaultLicenseUri,
|
this.multiSession = builder.multiSession;
|
||||||
boolean playClearContentWithoutKey,
|
this.forceDefaultLicenseUri = builder.forceDefaultLicenseUri;
|
||||||
List<Integer> drmSessionForClearTypes,
|
this.playClearContentWithoutKey = builder.playClearContentWithoutKey;
|
||||||
@Nullable byte[] keySetId) {
|
this.sessionForClearTypes = builder.sessionForClearTypes;
|
||||||
Assertions.checkArgument(!(forceDefaultLicenseUri && licenseUri == null));
|
this.keySetId =
|
||||||
this.uuid = uuid;
|
builder.keySetId != null
|
||||||
this.licenseUri = licenseUri;
|
? Arrays.copyOf(builder.keySetId, builder.keySetId.length)
|
||||||
this.requestHeaders = requestHeaders;
|
: null;
|
||||||
this.multiSession = multiSession;
|
|
||||||
this.forceDefaultLicenseUri = forceDefaultLicenseUri;
|
|
||||||
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. */
|
/** Returns the key set ID of the offline license. */
|
||||||
@ -673,6 +769,10 @@ public final class MediaItem implements Bundleable {
|
|||||||
return keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
|
return keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Builder buildUpon() {
|
||||||
|
return new Builder(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(@Nullable Object obj) {
|
public boolean equals(@Nullable Object obj) {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
|
@ -22,6 +22,7 @@ import android.net.Uri;
|
|||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
import com.google.android.exoplayer2.offline.StreamKey;
|
import com.google.android.exoplayer2.offline.StreamKey;
|
||||||
import com.google.android.exoplayer2.util.MimeTypes;
|
import com.google.android.exoplayer2.util.MimeTypes;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -77,14 +78,15 @@ public class MediaItemTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void builderSetDrmConfig_isNullByDefault() {
|
public void builder_drmConfigIsNullByDefault() {
|
||||||
// Null value by default.
|
// Null value by default.
|
||||||
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).build();
|
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).build();
|
||||||
assertThat(mediaItem.playbackProperties.drmConfiguration).isNull();
|
assertThat(mediaItem.playbackProperties.drmConfiguration).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void builderSetDrmConfig_setsAllProperties() {
|
@SuppressWarnings("deprecation") // Testing deprecated methods
|
||||||
|
public void builderSetDrmPropertiesIndividually() {
|
||||||
Uri licenseUri = Uri.parse(URI_STRING);
|
Uri licenseUri = Uri.parse(URI_STRING);
|
||||||
Map<String, String> requestHeaders = new HashMap<>();
|
Map<String, String> requestHeaders = new HashMap<>();
|
||||||
requestHeaders.put("Referer", "http://www.google.com");
|
requestHeaders.put("Referer", "http://www.google.com");
|
||||||
@ -92,14 +94,14 @@ public class MediaItemTest {
|
|||||||
MediaItem mediaItem =
|
MediaItem mediaItem =
|
||||||
new MediaItem.Builder()
|
new MediaItem.Builder()
|
||||||
.setUri(URI_STRING)
|
.setUri(URI_STRING)
|
||||||
.setDrmUuid(C.WIDEVINE_UUID)
|
|
||||||
.setDrmLicenseUri(licenseUri)
|
.setDrmLicenseUri(licenseUri)
|
||||||
.setDrmLicenseRequestHeaders(requestHeaders)
|
.setDrmLicenseRequestHeaders(requestHeaders)
|
||||||
.setDrmMultiSession(true)
|
.setDrmMultiSession(true)
|
||||||
.setDrmForceDefaultLicenseUri(true)
|
.setDrmForceDefaultLicenseUri(true)
|
||||||
.setDrmPlayClearContentWithoutKey(true)
|
.setDrmPlayClearContentWithoutKey(true)
|
||||||
.setDrmSessionForClearTypes(Collections.singletonList(C.TRACK_TYPE_AUDIO))
|
.setDrmSessionForClearTypes(ImmutableList.of(C.TRACK_TYPE_AUDIO))
|
||||||
.setDrmKeySetId(keySetId)
|
.setDrmKeySetId(keySetId)
|
||||||
|
.setDrmUuid(C.WIDEVINE_UUID)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull();
|
assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull();
|
||||||
@ -116,6 +118,73 @@ public class MediaItemTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // Testing deprecated methods
|
||||||
|
public void builderSetDrmConfigurationOverwritesIndividualProperties() {
|
||||||
|
Uri licenseUri = Uri.parse(URI_STRING);
|
||||||
|
Map<String, String> requestHeaders = new HashMap<>();
|
||||||
|
requestHeaders.put("Referer", "http://www.google.com");
|
||||||
|
byte[] keySetId = new byte[] {1, 2, 3};
|
||||||
|
MediaItem mediaItem =
|
||||||
|
new MediaItem.Builder()
|
||||||
|
.setUri(URI_STRING)
|
||||||
|
.setDrmLicenseUri(licenseUri)
|
||||||
|
.setDrmLicenseRequestHeaders(requestHeaders)
|
||||||
|
.setDrmMultiSession(true)
|
||||||
|
.setDrmForceDefaultLicenseUri(true)
|
||||||
|
.setDrmPlayClearContentWithoutKey(true)
|
||||||
|
.setDrmSessionForClearTypes(Collections.singletonList(C.TRACK_TYPE_AUDIO))
|
||||||
|
.setDrmKeySetId(keySetId)
|
||||||
|
.setDrmUuid(C.WIDEVINE_UUID)
|
||||||
|
.setDrmConfiguration(new MediaItem.DrmConfiguration.Builder(C.CLEARKEY_UUID).build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.uuid).isEqualTo(C.CLEARKEY_UUID);
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.licenseUri).isNull();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.requestHeaders).isEmpty();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.multiSession).isFalse();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.forceDefaultLicenseUri).isFalse();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.playClearContentWithoutKey).isFalse();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.sessionForClearTypes).isEmpty();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.getKeySetId()).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void builderSetDrmConfiguration() {
|
||||||
|
Uri licenseUri = Uri.parse(URI_STRING);
|
||||||
|
Map<String, String> requestHeaders = new HashMap<>();
|
||||||
|
requestHeaders.put("Referer", "http://www.google.com");
|
||||||
|
byte[] keySetId = new byte[] {1, 2, 3};
|
||||||
|
MediaItem mediaItem =
|
||||||
|
new MediaItem.Builder()
|
||||||
|
.setUri(URI_STRING)
|
||||||
|
.setDrmConfiguration(
|
||||||
|
new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
|
||||||
|
.setLicenseUri(licenseUri)
|
||||||
|
.setLicenseRequestHeaders(requestHeaders)
|
||||||
|
.setMultiSession(true)
|
||||||
|
.setForceDefaultLicenseUri(true)
|
||||||
|
.setPlayClearContentWithoutKey(true)
|
||||||
|
.setSessionForClearTypes(ImmutableList.of(C.TRACK_TYPE_AUDIO))
|
||||||
|
.setKeySetId(keySetId)
|
||||||
|
.build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration).isNotNull();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.uuid).isEqualTo(C.WIDEVINE_UUID);
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.licenseUri).isEqualTo(licenseUri);
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.requestHeaders)
|
||||||
|
.isEqualTo(requestHeaders);
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.multiSession).isTrue();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.forceDefaultLicenseUri).isTrue();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.playClearContentWithoutKey).isTrue();
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.sessionForClearTypes)
|
||||||
|
.containsExactly(C.TRACK_TYPE_AUDIO);
|
||||||
|
assertThat(mediaItem.playbackProperties.drmConfiguration.getKeySetId()).isEqualTo(keySetId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // Testing deprecated methods
|
||||||
public void builderSetDrmSessionForClearPeriods_setsAudioAndVideoTracks() {
|
public void builderSetDrmSessionForClearPeriods_setsAudioAndVideoTracks() {
|
||||||
Uri licenseUri = Uri.parse(URI_STRING);
|
Uri licenseUri = Uri.parse(URI_STRING);
|
||||||
MediaItem mediaItem =
|
MediaItem mediaItem =
|
||||||
@ -132,6 +201,21 @@ public class MediaItemTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
public void drmConfigurationBuilderSetSessionForClearPeriods_overridesSetSessionForClearTypes() {
|
||||||
|
Uri licenseUri = Uri.parse(URI_STRING);
|
||||||
|
MediaItem.DrmConfiguration drmConfiguration =
|
||||||
|
new MediaItem.DrmConfiguration.Builder(C.WIDEVINE_UUID)
|
||||||
|
.setLicenseUri(licenseUri)
|
||||||
|
.setSessionForClearTypes(ImmutableList.of(C.TRACK_TYPE_AUDIO))
|
||||||
|
.setSessionForClearPeriods(true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
assertThat(drmConfiguration.sessionForClearTypes)
|
||||||
|
.containsExactly(C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("deprecation") // Testing deprecated methods
|
||||||
public void builderSetDrmUuid_notCalled_throwsIllegalStateException() {
|
public void builderSetDrmUuid_notCalled_throwsIllegalStateException() {
|
||||||
assertThrows(
|
assertThrows(
|
||||||
IllegalStateException.class,
|
IllegalStateException.class,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user