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.
`DrmSessionManager` must be injected into the MediaSources using the
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
download speed ([#5978](https://github.com/google/ExoPlayer/issues/5978)).
* 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
* 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}.
*
* @param keyRequestParameters A map with parameters.
* @return This builder.
*/
public Builder setKeyRequestParameters(Map<String, String> keyRequestParameters) {
public Builder setKeyRequestParameters(@Nullable Map<String, String> keyRequestParameters) {
this.keyRequestParameters.clear();
this.keyRequestParameters.putAll(Assertions.checkNotNull(keyRequestParameters));
if (keyRequestParameters != null) {
this.keyRequestParameters.putAll(keyRequestParameters);
}
return this;
}

View File

@ -22,13 +22,11 @@ import android.os.HandlerThread;
import android.util.Pair;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager.Mode;
import com.google.android.exoplayer2.drm.DrmSession.DrmSessionException;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.MediaSourceEventDispatcher;
import java.util.Collections;
import java.util.Map;
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
* events.
* @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,
HttpDataSource.Factory httpDataSourceFactory,
MediaSourceEventDispatcher eventDispatcher)
throws UnsupportedDrmException {
return newWidevineInstance(defaultLicenseUrl, false, httpDataSourceFactory, eventDispatcher);
MediaSourceEventDispatcher eventDispatcher) {
return newWidevineInstance(
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
* events.
* @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,
boolean forceDefaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory,
MediaSourceEventDispatcher eventDispatcher)
throws UnsupportedDrmException {
MediaSourceEventDispatcher eventDispatcher) {
return newWidevineInstance(
defaultLicenseUrl,
forceDefaultLicenseUrl,
@ -106,37 +102,29 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
* @param eventDispatcher A {@link MediaSourceEventDispatcher} used to distribute DRM-related
* events.
* @return A new instance which uses Widevine CDM.
* @throws UnsupportedDrmException If the Widevine DRM scheme is unsupported or cannot be
* instantiated.
* @see DefaultDrmSessionManager.Builder
*/
public static OfflineLicenseHelper<FrameworkMediaCrypto> newWidevineInstance(
@SuppressWarnings("unchecked")
public static OfflineLicenseHelper<ExoMediaCrypto> newWidevineInstance(
String defaultLicenseUrl,
boolean forceDefaultLicenseUrl,
HttpDataSource.Factory httpDataSourceFactory,
@Nullable Map<String, String> optionalKeyRequestParameters,
MediaSourceEventDispatcher eventDispatcher)
throws UnsupportedDrmException {
MediaSourceEventDispatcher eventDispatcher) {
return new OfflineLicenseHelper<>(
C.WIDEVINE_UUID,
FrameworkMediaDrm.DEFAULT_PROVIDER,
new HttpMediaDrmCallback(defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory),
optionalKeyRequestParameters,
new DefaultDrmSessionManager.Builder()
.setKeyRequestParameters(optionalKeyRequestParameters)
.build(
new HttpMediaDrmCallback(
defaultLicenseUrl, forceDefaultLicenseUrl, httpDataSourceFactory)),
eventDispatcher);
}
/**
* Constructs an instance. Call {@link #release()} when the instance is no longer required.
*
* @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 Use {@link #OfflineLicenseHelper(DefaultDrmSessionManager,
* MediaSourceEventDispatcher)} instead.
*/
@Deprecated
@SuppressWarnings("unchecked")
public OfflineLicenseHelper(
UUID uuid,
@ -144,6 +132,27 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
MediaDrmCallback callback,
@Nullable Map<String, String> optionalKeyRequestParameters,
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.start();
conditionVariable = new ConditionVariable();
@ -169,17 +178,7 @@ public final class OfflineLicenseHelper<T extends ExoMediaCrypto> {
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);
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.drm.DrmInitData;
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.source.dash.DashUtil;
import com.google.android.exoplayer2.source.dash.manifest.DashManifest;
@ -54,7 +54,7 @@ public final class DashWidevineOfflineTest {
private DashTestRunner testRunner;
private DefaultHttpDataSourceFactory httpDataSourceFactory;
private OfflineLicenseHelper<FrameworkMediaCrypto> offlineLicenseHelper;
private OfflineLicenseHelper<ExoMediaCrypto> offlineLicenseHelper;
private byte[] offlineLicenseKeySetId;
@Rule public ActivityTestRule<HostActivity> testRule = new ActivityTestRule<>(HostActivity.class);
@ -69,6 +69,7 @@ public final class DashWidevineOfflineTest {
.setFullPlaybackNoSeeking(true)
.setCanIncludeAdditionalVideoFormats(false)
.setAudioVideoFormats(
DashTestData.WIDEVINE_AAC_AUDIO_REPRESENTATION_ID,
DashTestData.WIDEVINE_H264_CDD_FIXED);