Commit 379cd8a0 by olly Committed by Ian Baker

Make defaultLicenseUrl optional

Some content types always provide the license URL in the media.
The PlayReady example in the demo app doesn't provide a default
license URL for this reason, as an example.

#minor-release

PiperOrigin-RevId: 340125784
parent e35f7d82
...@@ -216,7 +216,7 @@ public final class MediaItem { ...@@ -216,7 +216,7 @@ public final class MediaItem {
} }
/** /**
* Sets the optional DRM license server URI. If this URI is set, the {@link * Sets the optional default DRM license server URI. If this URI is set, the {@link
* DrmConfiguration#uuid} needs to be specified as well. * DrmConfiguration#uuid} needs to be specified as well.
* *
* <p>If {@link #setUri} is passed a non-null {@code uri}, the DRM license server URI is used to * <p>If {@link #setUri} is passed a non-null {@code uri}, the DRM license server URI is used to
...@@ -228,7 +228,7 @@ public final class MediaItem { ...@@ -228,7 +228,7 @@ public final class MediaItem {
} }
/** /**
* Sets the optional DRM license server URI. If this URI is set, the {@link * Sets the optional default DRM license server URI. If this URI is set, the {@link
* DrmConfiguration#uuid} needs to be specified as well. * DrmConfiguration#uuid} needs to be specified as well.
* *
* <p>If {@link #setUri} is passed a non-null {@code uri}, the DRM license server URI is used to * <p>If {@link #setUri} is passed a non-null {@code uri}, the DRM license server URI is used to
...@@ -279,8 +279,8 @@ public final class MediaItem { ...@@ -279,8 +279,8 @@ public final class MediaItem {
} }
/** /**
* Sets whether to use the DRM license server URI of the media item for key requests that * Sets whether to force use the default DRM license server URI even if the media specifies its
* include their own DRM license server URI. * own DRM license server URI.
* *
* <p>If {@link #setUri} is passed a non-null {@code uri}, the DRM force default license flag is * <p>If {@link #setUri} is passed a non-null {@code uri}, the DRM force default license flag is
* used to create a {@link PlaybackProperties} object. Otherwise it will be ignored. * used to create a {@link PlaybackProperties} object. Otherwise it will be ignored.
...@@ -482,8 +482,8 @@ public final class MediaItem { ...@@ -482,8 +482,8 @@ public final class MediaItem {
public final UUID uuid; public final UUID uuid;
/** /**
* Optional DRM license server {@link Uri}. If {@code null} then the DRM license server must be * Optional default DRM license server {@link Uri}. If {@code null} then the DRM license server
* specified by the media. * must be specified by the media.
*/ */
@Nullable public final Uri licenseUri; @Nullable public final Uri licenseUri;
...@@ -500,8 +500,8 @@ public final class MediaItem { ...@@ -500,8 +500,8 @@ public final class MediaItem {
public final boolean playClearContentWithoutKey; public final boolean playClearContentWithoutKey;
/** /**
* Sets whether to use the DRM license server URI of the media item for key requests that * Whether to force use of {@link #licenseUri} even if the media specifies its own DRM license
* include their own DRM license server URI. * server URI.
*/ */
public final boolean forceDefaultLicenseUri; public final boolean forceDefaultLicenseUri;
...@@ -519,6 +519,7 @@ public final class MediaItem { ...@@ -519,6 +519,7 @@ public final class MediaItem {
boolean playClearContentWithoutKey, boolean playClearContentWithoutKey,
List<Integer> drmSessionForClearTypes, List<Integer> drmSessionForClearTypes,
@Nullable byte[] keySetId) { @Nullable byte[] keySetId) {
Assertions.checkArgument(!(forceDefaultLicenseUri && licenseUri == null));
this.uuid = uuid; this.uuid = uuid;
this.licenseUri = licenseUri; this.licenseUri = licenseUri;
this.requestHeaders = requestHeaders; this.requestHeaders = requestHeaders;
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
package com.google.android.exoplayer2.drm; package com.google.android.exoplayer2.drm;
import android.net.Uri;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
...@@ -27,6 +28,7 @@ import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCode ...@@ -27,6 +28,7 @@ import com.google.android.exoplayer2.upstream.HttpDataSource.InvalidResponseCode
import com.google.android.exoplayer2.upstream.StatsDataSource; import com.google.android.exoplayer2.upstream.StatsDataSource;
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.ImmutableMap;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -39,29 +41,35 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback { ...@@ -39,29 +41,35 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
private static final int MAX_MANUAL_REDIRECTS = 5; private static final int MAX_MANUAL_REDIRECTS = 5;
private final HttpDataSource.Factory dataSourceFactory; private final HttpDataSource.Factory dataSourceFactory;
private final String defaultLicenseUrl; @Nullable private final String defaultLicenseUrl;
private final boolean forceDefaultLicenseUrl; private final boolean forceDefaultLicenseUrl;
private final Map<String, String> keyRequestProperties; private final Map<String, String> keyRequestProperties;
/** /**
* @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
* their own license URL. * their own license URL. May be {@code null} if it's known that all key requests will specify
* their own URLs.
* @param dataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @param dataSourceFactory A factory from which to obtain {@link HttpDataSource} instances.
*/ */
public HttpMediaDrmCallback(String defaultLicenseUrl, HttpDataSource.Factory dataSourceFactory) { public HttpMediaDrmCallback(
@Nullable String defaultLicenseUrl, HttpDataSource.Factory dataSourceFactory) {
this(defaultLicenseUrl, /* forceDefaultLicenseUrl= */ false, dataSourceFactory); this(defaultLicenseUrl, /* forceDefaultLicenseUrl= */ false, dataSourceFactory);
} }
/** /**
* @param defaultLicenseUrl The default license URL. Used for key requests that do not specify * @param defaultLicenseUrl The default license URL. Used for key requests that do not specify
* their own license URL, or for all key requests if {@code forceDefaultLicenseUrl} is * their own license URL, or for all key requests if {@code forceDefaultLicenseUrl} is set to
* set to true. * true. May be {@code null} if {@code forceDefaultLicenseUrl} is {@code false} and if it's
* @param forceDefaultLicenseUrl Whether to use {@code defaultLicenseUrl} for key requests that * known that all key requests will specify their own URLs.
* include their own license URL. * @param forceDefaultLicenseUrl Whether to force use of {@code defaultLicenseUrl} for key
* requests that include their own license URL.
* @param dataSourceFactory A factory from which to obtain {@link HttpDataSource} instances. * @param dataSourceFactory A factory from which to obtain {@link HttpDataSource} instances.
*/ */
public HttpMediaDrmCallback(String defaultLicenseUrl, boolean forceDefaultLicenseUrl, public HttpMediaDrmCallback(
@Nullable String defaultLicenseUrl,
boolean forceDefaultLicenseUrl,
HttpDataSource.Factory dataSourceFactory) { HttpDataSource.Factory dataSourceFactory) {
Assertions.checkArgument(!(forceDefaultLicenseUrl && TextUtils.isEmpty(defaultLicenseUrl)));
this.dataSourceFactory = dataSourceFactory; this.dataSourceFactory = dataSourceFactory;
this.defaultLicenseUrl = defaultLicenseUrl; this.defaultLicenseUrl = defaultLicenseUrl;
this.forceDefaultLicenseUrl = forceDefaultLicenseUrl; this.forceDefaultLicenseUrl = forceDefaultLicenseUrl;
...@@ -121,6 +129,14 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback { ...@@ -121,6 +129,14 @@ public final class HttpMediaDrmCallback implements MediaDrmCallback {
if (forceDefaultLicenseUrl || TextUtils.isEmpty(url)) { if (forceDefaultLicenseUrl || TextUtils.isEmpty(url)) {
url = defaultLicenseUrl; url = defaultLicenseUrl;
} }
if (TextUtils.isEmpty(url)) {
throw new MediaDrmCallbackException(
new DataSpec.Builder().setUri(Uri.EMPTY).build(),
Uri.EMPTY,
/* responseHeaders= */ ImmutableMap.of(),
/* bytesLoaded= */ 0,
/* cause= */ new IllegalStateException("No license URL"));
}
Map<String, String> requestProperties = new HashMap<>(); Map<String, String> requestProperties = new HashMap<>();
// Add standard request properties for supported schemes. // Add standard request properties for supported schemes.
String contentType = C.PLAYREADY_UUID.equals(uuid) ? "text/xml" String contentType = C.PLAYREADY_UUID.equals(uuid) ? "text/xml"
......
...@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source; ...@@ -17,7 +17,6 @@ package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.ExoPlayerLibraryInfo.DEFAULT_USER_AGENT; import static com.google.android.exoplayer2.ExoPlayerLibraryInfo.DEFAULT_USER_AGENT;
import static com.google.android.exoplayer2.drm.DefaultDrmSessionManager.MODE_PLAYBACK; import static com.google.android.exoplayer2.drm.DefaultDrmSessionManager.MODE_PLAYBACK;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.MediaItem; import com.google.android.exoplayer2.MediaItem;
...@@ -68,7 +67,7 @@ public final class MediaSourceDrmHelper { ...@@ -68,7 +67,7 @@ public final class MediaSourceDrmHelper {
Assertions.checkNotNull(mediaItem.playbackProperties); Assertions.checkNotNull(mediaItem.playbackProperties);
@Nullable @Nullable
MediaItem.DrmConfiguration drmConfiguration = mediaItem.playbackProperties.drmConfiguration; MediaItem.DrmConfiguration drmConfiguration = mediaItem.playbackProperties.drmConfiguration;
if (drmConfiguration == null || drmConfiguration.licenseUri == null || Util.SDK_INT < 18) { if (drmConfiguration == null || Util.SDK_INT < 18) {
return DrmSessionManager.getDummyDrmSessionManager(); return DrmSessionManager.getDummyDrmSessionManager();
} }
HttpDataSource.Factory dataSourceFactory = HttpDataSource.Factory dataSourceFactory =
...@@ -77,7 +76,7 @@ public final class MediaSourceDrmHelper { ...@@ -77,7 +76,7 @@ public final class MediaSourceDrmHelper {
: new DefaultHttpDataSourceFactory(userAgent != null ? userAgent : DEFAULT_USER_AGENT); : new DefaultHttpDataSourceFactory(userAgent != null ? userAgent : DEFAULT_USER_AGENT);
HttpMediaDrmCallback httpDrmCallback = HttpMediaDrmCallback httpDrmCallback =
new HttpMediaDrmCallback( new HttpMediaDrmCallback(
castNonNull(drmConfiguration.licenseUri).toString(), drmConfiguration.licenseUri == null ? null : drmConfiguration.licenseUri.toString(),
drmConfiguration.forceDefaultLicenseUri, drmConfiguration.forceDefaultLicenseUri,
dataSourceFactory); dataSourceFactory);
for (Map.Entry<String, String> entry : drmConfiguration.requestHeaders.entrySet()) { for (Map.Entry<String, String> entry : drmConfiguration.requestHeaders.entrySet()) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment