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
This commit is contained in:
olly 2020-11-01 19:51:56 +00:00 committed by Oliver Woodman
parent 32b710712e
commit c1dc802050
3 changed files with 35 additions and 19 deletions

View file

@ -231,7 +231,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
@ -243,7 +243,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
@ -294,8 +294,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.
@ -568,8 +568,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;
@ -586,8 +586,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;
@ -605,6 +605,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;

View file

@ -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
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 {
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 {
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"

View file

@ -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 {
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 {
: 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()) {