Add option to use a custom DrmSessionManager into OfflineLicenseHelper

This allows to customize the DrmSessionManager, e.g. with a
LoadErrorHandlingPolicy.

Issue:issue:#7078
PiperOrigin-RevId: 301571783
This commit is contained in:
tonihei 2020-03-18 12:43:32 +00:00 committed by Oliver Woodman
parent 14aa56d62b
commit 2e5444b49b
4 changed files with 53 additions and 47 deletions

View File

@ -80,6 +80,9 @@
* Remove `DrmSessionManager` references from all renderers. * Remove `DrmSessionManager` references from all renderers.
`DrmSessionManager` must be injected into the MediaSources using the `DrmSessionManager` must be injected into the MediaSources using the
MediaSources factories. MediaSources factories.
* Add option to inject a custom `DefaultDrmSessionManager` into
`OfflineLicenseHelper`
([#7078](https://github.com/google/ExoPlayer/issues/7078)).
* Downloads: Merge downloads in `SegmentDownloader` to improve overall * Downloads: Merge downloads in `SegmentDownloader` to improve overall
download speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)). download speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)).
* DASH: * DASH:

View File

@ -88,16 +88,19 @@ public class DefaultDrmSessionManager<T extends ExoMediaCrypto> implements DrmSe
/** /**
* Sets the key request parameters to pass as the last argument to {@link * Sets the key request parameters to pass as the last argument to {@link
* ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. * ExoMediaDrm#getKeyRequest(byte[], List, int, HashMap)}. May be null if not parameters need to
* be passed.
* *
* <p>Custom data for PlayReady should be set under {@link #PLAYREADY_CUSTOM_DATA_KEY}. * <p>Custom data for PlayReady should be set under {@link #PLAYREADY_CUSTOM_DATA_KEY}.
* *
* @param keyRequestParameters A map with parameters. * @param keyRequestParameters A map with parameters.
* @return This builder. * @return This builder.
*/ */
public Builder setKeyRequestParameters(Map<String, String> keyRequestParameters) { public Builder setKeyRequestParameters(@Nullable Map<String, String> keyRequestParameters) {
this.keyRequestParameters.clear(); this.keyRequestParameters.clear();
this.keyRequestParameters.putAll(Assertions.checkNotNull(keyRequestParameters)); if (keyRequestParameters != null) {
this.keyRequestParameters.putAll(keyRequestParameters);
}
return this; return this;
} }

View File

@ -22,13 +22,11 @@ import android.os.HandlerThread;
import android.util.Pair; import android.util.Pair;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi; import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode; import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher; import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -53,15 +51,16 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related * @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events. * events.
* @return A new instance which uses Widevine CDM. * @return A new instance which uses Widevine CDM.
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
* instantiated.
*/ */
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance( public static OfflineLicenseHelper<ExoMediaCrypto> newWidevineInstance(
String defaultLicenseUrl, String defaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory, HttpDataSource.Factory httpDataSourceFactory,
MediaSourceEventDispatcher eventDispatcher) MediaSourceEventDispatcher eventDispatcher) {
throws UnsupportedDrmException { return newWidevineInstance(
return newWidevineInstance(defaultLicenseUrl, false, httpDataSourceFactory, eventDispatcher); defaultLicenseUrl,
/* forceDefaultLicenseUrl= */ false,
httpDataSourceFactory,
eventDispatcher);
} }
/** /**
@ -76,15 +75,12 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related * @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events. * events.
* @return A new instance which uses Widevine CDM. * @return A new instance which uses Widevine CDM.
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
* instantiated.
*/ */
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance( public static OfflineLicenseHelper<ExoMediaCrypto> newWidevineInstance(
String defaultLicenseUrl, String defaultLicenseUrl,
boolean forceDefaultLicenseUrl, boolean forceDefaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory, HttpDataSource.Factory httpDataSourceFactory,
MediaSourceEventDispatcher eventDispatcher) MediaSourceEventDispatcher eventDispatcher) {
throws UnsupportedDrmException {
return newWidevineInstance( return newWidevineInstance(
defaultLicenseUrl, defaultLicenseUrl,
forceDefaultLicenseUrl, forceDefaultLicenseUrl,
@ -106,37 +102,29 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related * @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events. * events.
* @return A new instance which uses Widevine CDM. * @return A new instance which uses Widevine CDM.
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
* instantiated.
* @see DefaultDrmSessionManager.Builder * @see DefaultDrmSessionManager.Builder
*/ */
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance( @SuppressWarnings("unchecked")
public static OfflineLicenseHelper<ExoMediaCrypto> newWidevineInstance(
String defaultLicenseUrl, String defaultLicenseUrl,
boolean forceDefaultLicenseUrl, boolean forceDefaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory, HttpDataSource.Factory httpDataSourceFactory,
@Nullable Map<String, String> optionalKeyRequestParameters, @Nullable Map<String, String> optionalKeyRequestParameters,
MediaSourceEventDispatcher eventDispatcher) MediaSourceEventDispatcher eventDispatcher) {
throws UnsupportedDrmException {
return new OfflineLicenseHelper<>( return new OfflineLicenseHelper<>(
C.WIDEVINE_UUID, new DefaultDrmSessionManager.Builder()
FrameworkMediaDrm.DEFAULT_PROVIDER, .setKeyRequestParameters(optionalKeyRequestParameters)
new HttpMediaDrmCallback(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory), .build(
optionalKeyRequestParameters, new HttpMediaDrmCallback(
defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory)),
eventDispatcher); eventDispatcher);
} }
/** /**
* Constructs an instance. Call {@link #release()} when the instance is no longer required. * @deprecated Use {@link #OfflineLicenseHelper(DefaultDrmSessionManager,
* * MediaSourceEventDispatcher)} instead.
* @param uuid The UUID of the drm scheme.
* @param mediaDrmProvider A {@link ExoMediaDrm.Provider}.
* @param callback Performs key and provisioning requests.
* @param optionalKeyRequestParameters An optional map of parameters to pass as the last argument
* to {@link MediaDrm#getKeyRequest}. May be null.
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events.
* @see DefaultDrmSessionManager.Builder
*/ */
@Deprecated
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public OfflineLicenseHelper( public OfflineLicenseHelper(
UUID uuid, UUID uuid,
@ -144,6 +132,27 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
MediaDrmCallback callback, MediaDrmCallback callback,
@Nullable Map<String, String> optionalKeyRequestParameters, @Nullable Map<String, String> optionalKeyRequestParameters,
MediaSourceEventDispatcher eventDispatcher) { MediaSourceEventDispatcher eventDispatcher) {
this(
(DefaultDrmSessionManager<T>)
new DefaultDrmSessionManager.Builder()
.setUuidAndExoMediaDrmProvider(uuid, mediaDrmProvider)
.setKeyRequestParameters(optionalKeyRequestParameters)
.build(callback),
eventDispatcher);
}
/**
* Constructs an instance. Call {@link #release()} when the instance is no longer required.
*
* @param defaultDrmSessionManager The {@link DefaultDrmSessionManager} used to download licenses.
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events.
*/
public OfflineLicenseHelper(
DefaultDrmSessionManager<T> defaultDrmSessionManager,
MediaSourceEventDispatcher eventDispatcher) {
this.drmSessionManager = defaultDrmSessionManager;
this.eventDispatcher = eventDispatcher;
handlerThread = new HandlerThread("OfflineLicenseHelper"); handlerThread = new HandlerThread("OfflineLicenseHelper");
handlerThread.start(); handlerThread.start();
conditionVariable = new ConditionVariable(); conditionVariable = new ConditionVariable();
@ -169,17 +178,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
conditionVariable.open(); conditionVariable.open();
} }
}; };
if (optionalKeyRequestParameters == null) {
optionalKeyRequestParameters = Collections.emptyMap();
}
drmSessionManager =
(DefaultDrmSessionManager<T>)
new DefaultDrmSessionManager.Builder()
.setUuidAndExoMediaDrmProvider(uuid, mediaDrmProvider)
.setKeyRequestParameters(optionalKeyRequestParameters)
.build(callback);
drmSessionManager.addListener(new Handler(handlerThread.getLooper()), eventListener); drmSessionManager.addListener(new Handler(handlerThread.getLooper()), eventListener);
this.eventDispatcher = eventDispatcher;
} }
/** /**

View File

@ -27,7 +27,7 @@ import androidx.test.rule.ActivityTestRule;
import com.google.android.exoplayer2.Player; import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.drm.DrmInitData; import com.google.android.exoplayer2.drm.DrmInitData;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException; import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto; import com.google.android.exoplayer2.drm.ExoMediaCrypto;
import com.google.android.exoplayer2.drm.OfflineLicenseHelper; import com.google.android.exoplayer2.drm.OfflineLicenseHelper;
import com.google.android.exoplayer2.source.dash.DashUtil; import com.google.android.exoplayer2.source.dash.DashUtil;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest; import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
@ -54,7 +54,7 @@ public final class DashWidevineOfflineTest {
private DashTestRunner testRunner; private DashTestRunner testRunner;
private DefaultHttpDataSourceFactory httpDataSourceFactory; private DefaultHttpDataSourceFactory httpDataSourceFactory;
private OfflineLicenseHelper<FrameworkMediaCrypto> offlineLicenseHelper; private OfflineLicenseHelper<ExoMediaCrypto> offlineLicenseHelper;
private byte[] offlineLicenseKeySetId; private byte[] offlineLicenseKeySetId;
@Rule public ActivityTestRule<HostActivity> testRule = new ActivityTestRule<>(HostActivity.class); @Rule public ActivityTestRule<HostActivity> testRule = new ActivityTestRule<>(HostActivity.class);
@ -69,6 +69,7 @@ public final class DashWidevineOfflineTest {
.setFullPlaybackNoSeeking(true) .setFullPlaybackNoSeeking(true)
.setCanIncludeAdditionalVideoFormats(false) .setCanIncludeAdditionalVideoFormats(false)
.setAudioVideoFormats( .setAudioVideoFormats(
DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID, DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
DashTestData.WIDEVINE_H264_CDD_FIXED); DashTestData.WIDEVINE_H264_CDD_FIXED);