Make all media source factories create a drm session

PiperOrigin-RevId: 327691347
This commit is contained in:
bachinger 2020-08-20 21:51:38 +01:00 committed by Oliver Woodman
parent 7abece9a39
commit e55b345595
9 changed files with 318 additions and 174 deletions

View File

@ -15,28 +15,19 @@
*/
package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.drm.DefaultDrmSessionManager.MODE_PLAYBACK;
import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.util.SparseArray;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.MediaItem.DrmConfiguration;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
import com.google.android.exoplayer2.drm.MediaDrmCallback;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
@ -44,10 +35,8 @@ import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Log;
import com.google.android.exoplayer2.util.MimeTypes;
import com.google.android.exoplayer2.util.Util;
import com.google.common.primitives.Ints;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* The default {@link MediaSourceFactory} implementation.
@ -79,21 +68,6 @@ import java.util.Map;
* the stream.
* </ul>
*
* <h3>DrmSessionManager creation for protected content</h3>
*
* <p>For a media item with a {@link DrmConfiguration}, a {@link DefaultDrmSessionManager} is
* created based on that configuration. The following setter can be used to optionally configure the
* creation:
*
* <ul>
* <li>{@link #setDrmHttpDataSourceFactory(HttpDataSource.Factory)}: Sets the data source factory
* to be used by the {@link HttpMediaDrmCallback} for network requests (default: {@link
* DefaultHttpDataSourceFactory}).
* </ul>
*
* <p>For media items without a {@link DrmConfiguration}, the {@link DrmSessionManager} passed to
* {@link #setDrmSessionManager(DrmSessionManager)} will be used.
*
* <h3>Ad support for media items with ad tag uri</h3>
*
* <p>For a media item with an ad tag uri, an {@link AdSupportProvider} needs to be passed to {@link
@ -167,21 +141,14 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
}
private static final String TAG = "DefaultMediaSourceFactory";
private static final String DEFAULT_USER_AGENT =
ExoPlayerLibraryInfo.VERSION_SLASHY
+ " (Linux;Android "
+ Build.VERSION.RELEASE
+ ") "
+ ExoPlayerLibraryInfo.VERSION_SLASHY;
private final MediaSourceDrmHelper mediaSourceDrmHelper;
private final DataSource.Factory dataSourceFactory;
@Nullable private final AdSupportProvider adSupportProvider;
private final SparseArray<MediaSourceFactory> mediaSourceFactories;
@C.ContentType private final int[] supportedTypes;
private DrmSessionManager drmSessionManager;
@Nullable private HttpDataSource.Factory drmHttpDataSourceFactory;
private String userAgent;
@Nullable private DrmSessionManager drmSessionManager;
@Nullable private List<StreamKey> streamKeys;
/**
@ -196,8 +163,7 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
DataSource.Factory dataSourceFactory, @Nullable AdSupportProvider adSupportProvider) {
this.dataSourceFactory = dataSourceFactory;
this.adSupportProvider = adSupportProvider;
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
userAgent = DEFAULT_USER_AGENT;
mediaSourceDrmHelper = new MediaSourceDrmHelper();
mediaSourceFactories = loadDelegates(dataSourceFactory);
supportedTypes = new int[mediaSourceFactories.size()];
for (int i = 0; i < mediaSourceFactories.size(); i++) {
@ -205,49 +171,23 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
}
}
/**
* Sets the {@link HttpDataSource.Factory} to be used for creating {@link HttpMediaDrmCallback
* HttpMediaDrmCallbacks} which executes key and provisioning requests over HTTP. If {@code null}
* is passed the {@link DefaultHttpDataSourceFactory} is used.
*
* @param drmHttpDataSourceFactory The HTTP data source factory or {@code null} to use {@link
* DefaultHttpDataSourceFactory}.
* @return This factory, for convenience.
*/
@Override
public DefaultMediaSourceFactory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
this.drmHttpDataSourceFactory = drmHttpDataSourceFactory;
mediaSourceDrmHelper.setDrmHttpDataSourceFactory(drmHttpDataSourceFactory);
return this;
}
/**
* Sets the optional user agent to be used for DRM requests.
*
* <p>In case a factory has been set by {@link
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)}, this user agent is ignored.
*
* @param userAgent The user agent to be used for DRM requests.
* @return This factory, for convenience.
*/
@Override
public DefaultMediaSourceFactory setDrmUserAgent(@Nullable String userAgent) {
this.userAgent = userAgent != null ? userAgent : DEFAULT_USER_AGENT;
mediaSourceDrmHelper.setDrmUserAgent(userAgent);
return this;
}
/**
* Sets the {@link DrmSessionManager} to use for media items that do not specify a {@link
* DrmConfiguration}. The default value is {@link DrmSessionManager#DUMMY}.
*
* @param drmSessionManager The {@link DrmSessionManager}.
* @return This factory, for convenience.
*/
@Override
public DefaultMediaSourceFactory setDrmSessionManager(
@Nullable DrmSessionManager drmSessionManager) {
this.drmSessionManager =
drmSessionManager != null
? drmSessionManager
: DrmSessionManager.getDummyDrmSessionManager();
this.drmSessionManager = drmSessionManager;
return this;
}
@ -292,7 +232,8 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
@Nullable MediaSourceFactory mediaSourceFactory = mediaSourceFactories.get(type);
Assertions.checkNotNull(
mediaSourceFactory, "No suitable media source factory found for content type: " + type);
mediaSourceFactory.setDrmSessionManager(createDrmSessionManager(mediaItem));
mediaSourceFactory.setDrmSessionManager(
drmSessionManager != null ? drmSessionManager : mediaSourceDrmHelper.create(mediaItem));
mediaSourceFactory.setStreamKeys(
!mediaItem.playbackProperties.streamKeys.isEmpty()
? mediaItem.playbackProperties.streamKeys
@ -318,46 +259,6 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
// internal methods
private DrmSessionManager createDrmSessionManager(MediaItem mediaItem) {
Assertions.checkNotNull(mediaItem.playbackProperties);
if (mediaItem.playbackProperties.drmConfiguration == null
|| mediaItem.playbackProperties.drmConfiguration.licenseUri == null
|| Util.SDK_INT < 18) {
return drmSessionManager;
}
DefaultDrmSessionManager drmSessionManager =
new DefaultDrmSessionManager.Builder()
.setUuidAndExoMediaDrmProvider(
mediaItem.playbackProperties.drmConfiguration.uuid,
FrameworkMediaDrm.DEFAULT_PROVIDER)
.setMultiSession(mediaItem.playbackProperties.drmConfiguration.multiSession)
.setPlayClearSamplesWithoutKeys(
mediaItem.playbackProperties.drmConfiguration.playClearContentWithoutKey)
.setUseDrmSessionsForClearContent(
Ints.toArray(mediaItem.playbackProperties.drmConfiguration.sessionForClearTypes))
.build(createHttpMediaDrmCallback(mediaItem.playbackProperties.drmConfiguration));
drmSessionManager.setMode(
MODE_PLAYBACK, mediaItem.playbackProperties.drmConfiguration.getKeySetId());
return drmSessionManager;
}
private MediaDrmCallback createHttpMediaDrmCallback(MediaItem.DrmConfiguration drmConfiguration) {
Assertions.checkNotNull(drmConfiguration.licenseUri);
HttpMediaDrmCallback drmCallback =
new HttpMediaDrmCallback(
drmConfiguration.licenseUri.toString(),
drmConfiguration.forceDefaultLicenseUri,
drmHttpDataSourceFactory != null
? drmHttpDataSourceFactory
: new DefaultHttpDataSourceFactory(userAgent));
for (Map.Entry<String, String> entry : drmConfiguration.requestHeaders.entrySet()) {
drmCallback.setKeyRequestProperty(entry.getKey(), entry.getValue());
}
return drmCallback;
}
private static MediaSource maybeClipMediaSource(MediaItem mediaItem, MediaSource mediaSource) {
if (mediaItem.clippingProperties.startPositionMs == 0
&& mediaItem.clippingProperties.endPositionMs == C.TIME_END_OF_SOURCE

View File

@ -29,6 +29,7 @@ import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.Assertions;
@ -168,6 +169,23 @@ public final class ExtractorMediaSource extends CompositeMediaSource<Void> {
throw new UnsupportedOperationException();
}
/**
* @deprecated Use {@link ProgressiveMediaSource.Factory#setDrmHttpDataSourceFactory} instead.
*/
@Deprecated
@Override
public MediaSourceFactory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
throw new UnsupportedOperationException();
}
/** @deprecated Use {@link ProgressiveMediaSource.Factory#setDrmUserAgent} instead. */
@Deprecated
@Override
public MediaSourceFactory setDrmUserAgent(@Nullable String userAgent) {
throw new UnsupportedOperationException();
}
/** @deprecated Use {@link #createMediaSource(MediaItem)} instead. */
@SuppressWarnings("deprecation")
@Deprecated

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.drm.DefaultDrmSessionManager.MODE_PLAYBACK;
import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.os.Build;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.util.Assertions;
import com.google.android.exoplayer2.util.Util;
import com.google.common.primitives.Ints;
import java.util.Map;
/** A helper to create a {@link DrmSessionManager} from a {@link MediaItem}. */
public final class MediaSourceDrmHelper {
private static final String DEFAULT_USER_AGENT =
ExoPlayerLibraryInfo.VERSION_SLASHY
+ " (Linux;Android "
+ Build.VERSION.RELEASE
+ ") "
+ ExoPlayerLibraryInfo.VERSION_SLASHY;
@Nullable private HttpDataSource.Factory drmHttpDataSourceFactory;
@Nullable private String userAgent;
/**
* Sets the {@link HttpDataSource.Factory} to be used for creating {@link HttpMediaDrmCallback
* HttpMediaDrmCallbacks} which executes key and provisioning requests over HTTP. If {@code null}
* is passed the {@link DefaultHttpDataSourceFactory} is used.
*
* @param drmHttpDataSourceFactory The HTTP data source factory or {@code null} to use {@link
* DefaultHttpDataSourceFactory}.
*/
public void setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
this.drmHttpDataSourceFactory = drmHttpDataSourceFactory;
}
/**
* Sets the optional user agent to be used for DRM requests.
*
* <p>In case a factory has been set by {@link
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)}, this user agent is ignored.
*
* @param userAgent The user agent to be used for DRM requests.
*/
public void setDrmUserAgent(@Nullable String userAgent) {
this.userAgent = userAgent;
}
/** Creates a {@link DrmSessionManager} for the given media item. */
public DrmSessionManager create(MediaItem mediaItem) {
Assertions.checkNotNull(mediaItem.playbackProperties);
@Nullable
MediaItem.DrmConfiguration drmConfiguration = mediaItem.playbackProperties.drmConfiguration;
if (drmConfiguration == null || drmConfiguration.licenseUri == null || Util.SDK_INT < 18) {
return DrmSessionManager.getDummyDrmSessionManager();
}
HttpDataSource.Factory dataSourceFactory =
drmHttpDataSourceFactory != null
? drmHttpDataSourceFactory
: new DefaultHttpDataSourceFactory(userAgent != null ? userAgent : DEFAULT_USER_AGENT);
HttpMediaDrmCallback httpDrmCallback =
new HttpMediaDrmCallback(
castNonNull(drmConfiguration.licenseUri).toString(),
drmConfiguration.forceDefaultLicenseUri,
dataSourceFactory);
for (Map.Entry<String, String> entry : drmConfiguration.requestHeaders.entrySet()) {
httpDrmCallback.setKeyRequestProperty(entry.getKey(), entry.getValue());
}
DefaultDrmSessionManager drmSessionManager =
new DefaultDrmSessionManager.Builder()
.setUuidAndExoMediaDrmProvider(
drmConfiguration.uuid, FrameworkMediaDrm.DEFAULT_PROVIDER)
.setMultiSession(drmConfiguration.multiSession)
.setPlayClearSamplesWithoutKeys(drmConfiguration.playClearContentWithoutKey)
.setUseDrmSessionsForClearContent(Ints.toArray(drmConfiguration.sessionForClearTypes))
.build(httpDrmCallback);
drmSessionManager.setMode(MODE_PLAYBACK, drmConfiguration.getKeySetId());
return drmSessionManager;
}
}

View File

@ -19,13 +19,34 @@ import android.net.Uri;
import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
import com.google.android.exoplayer2.offline.StreamKey;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import java.util.List;
/** Factory for creating {@link MediaSource}s from URIs. */
/**
* Factory for creating {@link MediaSource}s from URIs.
*
* <h3>DrmSessionManager creation for protected content</h3>
*
* <p>In case a {@link DrmSessionManager} is passed to {@link
* #setDrmSessionManager(DrmSessionManager)}, it will be used regardless of the drm configuration of
* the media item.
*
* <p>For a media item with a {@link MediaItem.DrmConfiguration}, a {@link DefaultDrmSessionManager}
* is created based on that configuration. The following setter can be used to optionally configure
* the creation:
*
* <ul>
* <li>{@link #setDrmHttpDataSourceFactory(HttpDataSource.Factory)}: Sets the data source factory
* to be used by the {@link HttpMediaDrmCallback} for network requests (default: {@link
* DefaultHttpDataSourceFactory}).
* </ul>
*/
public interface MediaSourceFactory {
/** @deprecated Use {@link MediaItem.PlaybackProperties#streamKeys} instead. */
@ -35,13 +56,40 @@ public interface MediaSourceFactory {
}
/**
* Sets the {@link DrmSessionManager} to use for acquiring {@link DrmSession DrmSessions}.
* Sets the {@link DrmSessionManager} to use for all media items regardless of their {@link
* MediaItem.DrmConfiguration}.
*
* @param drmSessionManager The {@link DrmSessionManager}.
* @return This factory, for convenience.
*/
MediaSourceFactory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager);
/**
* Sets the {@link HttpDataSource.Factory} to be used for creating {@link HttpMediaDrmCallback
* HttpMediaDrmCallbacks} to execute key and provisioning requests over HTTP.
*
* <p>In case a {@link DrmSessionManager} has been set by {@link
* #setDrmSessionManager(DrmSessionManager)}, this data source factory is ignored.
*
* @param drmHttpDataSourceFactory The HTTP data source factory, or {@code null} to use {@link
* DefaultHttpDataSourceFactory}.
* @return This factory, for convenience.
*/
MediaSourceFactory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory);
/**
* Sets the optional user agent to be used for DRM requests.
*
* <p>In case a factory has been set by {@link
* #setDrmHttpDataSourceFactory(HttpDataSource.Factory)} or a {@link DrmSessionManager} has been
* set by {@link #setDrmSessionManager(DrmSessionManager)}, this user agent is ignored.
*
* @param userAgent The user agent to be used for DRM requests.
* @return This factory, for convenience.
*/
MediaSourceFactory setDrmUserAgent(@Nullable String userAgent);
/**
* Sets an optional {@link LoadErrorHandlingPolicy}.
*

View File

@ -22,7 +22,6 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.extractor.DefaultExtractorsFactory;
import com.google.android.exoplayer2.extractor.Extractor;
@ -30,6 +29,7 @@ import com.google.android.exoplayer2.extractor.ExtractorsFactory;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.TransferListener;
@ -51,9 +51,10 @@ public final class ProgressiveMediaSource extends BaseMediaSource
public static final class Factory implements MediaSourceFactory {
private final DataSource.Factory dataSourceFactory;
private final MediaSourceDrmHelper mediaSourceDrmHelper;
private ExtractorsFactory extractorsFactory;
private DrmSessionManager drmSessionManager;
@Nullable private DrmSessionManager drmSessionManager;
private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private int continueLoadingCheckIntervalBytes;
@Nullable private String customCacheKey;
@ -78,7 +79,7 @@ public final class ProgressiveMediaSource extends BaseMediaSource
public Factory(DataSource.Factory dataSourceFactory, ExtractorsFactory extractorsFactory) {
this.dataSourceFactory = dataSourceFactory;
this.extractorsFactory = extractorsFactory;
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
mediaSourceDrmHelper = new MediaSourceDrmHelper();
loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
continueLoadingCheckIntervalBytes = DEFAULT_LOADING_CHECK_INTERVAL_BYTES;
}
@ -146,19 +147,22 @@ public final class ProgressiveMediaSource extends BaseMediaSource
return this;
}
/**
* Sets the {@link DrmSessionManager} to use for acquiring {@link DrmSession DrmSessions}. The
* default value is {@link DrmSessionManager#DUMMY}.
*
* @param drmSessionManager The {@link DrmSessionManager}.
* @return This factory, for convenience.
*/
@Override
public Factory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager) {
this.drmSessionManager =
drmSessionManager != null
? drmSessionManager
: DrmSessionManager.getDummyDrmSessionManager();
this.drmSessionManager = drmSessionManager;
return this;
}
@Override
public Factory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
mediaSourceDrmHelper.setDrmHttpDataSourceFactory(drmHttpDataSourceFactory);
return this;
}
@Override
public Factory setDrmUserAgent(@Nullable String userAgent) {
mediaSourceDrmHelper.setDrmUserAgent(userAgent);
return this;
}
@ -194,7 +198,7 @@ public final class ProgressiveMediaSource extends BaseMediaSource
mediaItem,
dataSourceFactory,
extractorsFactory,
drmSessionManager,
drmSessionManager != null ? drmSessionManager : mediaSourceDrmHelper.create(mediaItem),
loadErrorHandlingPolicy,
continueLoadingCheckIntervalBytes);
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.exoplayer2.source;
import static com.google.common.truth.Truth.assertThat;
import android.net.Uri;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import org.junit.Test;
import org.junit.runner.RunWith;
/** Unit tests for {@link MediaSourceDrmHelper}. */
@RunWith(AndroidJUnit4.class)
public class MediaSourceDrmHelperTest {
@Test
public void create_noDrmProperties_createsNoopManager() {
DrmSessionManager drmSessionManager =
new MediaSourceDrmHelper().create(MediaItem.fromUri(Uri.EMPTY));
assertThat(drmSessionManager).isEqualTo(DrmSessionManager.DUMMY);
}
@Test
public void create_createsManager() {
MediaItem mediaItem =
new MediaItem.Builder()
.setUri(Uri.EMPTY)
.setDrmLicenseUri(Uri.EMPTY)
.setDrmUuid(C.WIDEVINE_UUID)
.build();
DrmSessionManager drmSessionManager = new MediaSourceDrmHelper().create(mediaItem);
assertThat(drmSessionManager).isNotEqualTo(DrmSessionManager.DUMMY);
}
}

View File

@ -30,7 +30,6 @@ import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.ParserException;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.offline.FilteringManifestParser;
@ -42,6 +41,7 @@ import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceDrmHelper;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.MediaSourceFactory;
@ -54,6 +54,7 @@ import com.google.android.exoplayer2.source.dash.manifest.UtcTimingElement;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader;
@ -91,9 +92,10 @@ public final class DashMediaSource extends BaseMediaSource {
public static final class Factory implements MediaSourceFactory {
private final DashChunkSource.Factory chunkSourceFactory;
private final MediaSourceDrmHelper mediaSourceDrmHelper;
@Nullable private final DataSource.Factory manifestDataSourceFactory;
private DrmSessionManager drmSessionManager;
@Nullable private DrmSessionManager drmSessionManager;
private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private long livePresentationDelayMs;
@ -126,7 +128,7 @@ public final class DashMediaSource extends BaseMediaSource {
@Nullable DataSource.Factory manifestDataSourceFactory) {
this.chunkSourceFactory = checkNotNull(chunkSourceFactory);
this.manifestDataSourceFactory = manifestDataSourceFactory;
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
mediaSourceDrmHelper = new MediaSourceDrmHelper();
loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
livePresentationDelayMs = DEFAULT_LIVE_PRESENTATION_DELAY_MS;
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
@ -155,19 +157,22 @@ public final class DashMediaSource extends BaseMediaSource {
return this;
}
/**
* Sets the {@link DrmSessionManager} to use for acquiring {@link DrmSession DrmSessions}. The
* default value is {@link DrmSessionManager#DUMMY}.
*
* @param drmSessionManager The {@link DrmSessionManager}.
* @return This factory, for convenience.
*/
@Override
public Factory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager) {
this.drmSessionManager =
drmSessionManager != null
? drmSessionManager
: DrmSessionManager.getDummyDrmSessionManager();
this.drmSessionManager = drmSessionManager;
return this;
}
@Override
public Factory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
mediaSourceDrmHelper.setDrmHttpDataSourceFactory(drmHttpDataSourceFactory);
return this;
}
@Override
public Factory setDrmUserAgent(@Nullable String userAgent) {
mediaSourceDrmHelper.setDrmUserAgent(userAgent);
return this;
}
@ -312,7 +317,7 @@ public final class DashMediaSource extends BaseMediaSource {
/* manifestParser= */ null,
chunkSourceFactory,
compositeSequenceableLoaderFactory,
drmSessionManager,
drmSessionManager != null ? drmSessionManager : mediaSourceDrmHelper.create(mediaItem),
loadErrorHandlingPolicy,
livePresentationDelayMs,
livePresentationDelayOverridesManifest);
@ -403,7 +408,7 @@ public final class DashMediaSource extends BaseMediaSource {
manifestParser,
chunkSourceFactory,
compositeSequenceableLoaderFactory,
drmSessionManager,
drmSessionManager != null ? drmSessionManager : mediaSourceDrmHelper.create(mediaItem),
loadErrorHandlingPolicy,
livePresentationDelayMs,
livePresentationDelayOverridesManifest);

View File

@ -26,7 +26,6 @@ import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.extractor.Extractor;
@ -36,6 +35,7 @@ import com.google.android.exoplayer2.source.CompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.DefaultCompositeSequenceableLoaderFactory;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceDrmHelper;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.MediaSourceFactory;
import com.google.android.exoplayer2.source.SequenceableLoader;
@ -49,6 +49,7 @@ import com.google.android.exoplayer2.source.hls.playlist.HlsPlaylistTracker;
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.TransferListener;
import com.google.android.exoplayer2.util.MimeTypes;
@ -93,12 +94,13 @@ public final class HlsMediaSource extends BaseMediaSource
public static final class Factory implements MediaSourceFactory {
private final HlsDataSourceFactory hlsDataSourceFactory;
private final MediaSourceDrmHelper mediaSourceDrmHelper;
private HlsExtractorFactory extractorFactory;
private HlsPlaylistParserFactory playlistParserFactory;
private HlsPlaylistTracker.Factory playlistTrackerFactory;
private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private DrmSessionManager drmSessionManager;
@Nullable private DrmSessionManager drmSessionManager;
private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private boolean allowChunklessPreparation;
@MetadataType private int metadataType;
@ -125,10 +127,10 @@ public final class HlsMediaSource extends BaseMediaSource
*/
public Factory(HlsDataSourceFactory hlsDataSourceFactory) {
this.hlsDataSourceFactory = checkNotNull(hlsDataSourceFactory);
mediaSourceDrmHelper = new MediaSourceDrmHelper();
playlistParserFactory = new DefaultHlsPlaylistParserFactory();
playlistTrackerFactory = DefaultHlsPlaylistTracker.FACTORY;
extractorFactory = HlsExtractorFactory.DEFAULT;
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
metadataType = METADATA_TYPE_ID3;
@ -285,19 +287,22 @@ public final class HlsMediaSource extends BaseMediaSource
return this;
}
/**
* Sets the {@link DrmSessionManager} to use for acquiring {@link DrmSession DrmSessions}. The
* default value is {@link DrmSessionManager#DUMMY}.
*
* @param drmSessionManager The {@link DrmSessionManager}.
* @return This factory, for convenience.
*/
@Override
public Factory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager) {
this.drmSessionManager =
drmSessionManager != null
? drmSessionManager
: DrmSessionManager.getDummyDrmSessionManager();
this.drmSessionManager = drmSessionManager;
return this;
}
@Override
public Factory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
mediaSourceDrmHelper.setDrmHttpDataSourceFactory(drmHttpDataSourceFactory);
return this;
}
@Override
public MediaSourceFactory setDrmUserAgent(@Nullable String userAgent) {
mediaSourceDrmHelper.setDrmUserAgent(userAgent);
return this;
}
@ -374,7 +379,7 @@ public final class HlsMediaSource extends BaseMediaSource
hlsDataSourceFactory,
extractorFactory,
compositeSequenceableLoaderFactory,
drmSessionManager,
drmSessionManager != null ? drmSessionManager : mediaSourceDrmHelper.create(mediaItem),
loadErrorHandlingPolicy,
playlistTrackerFactory.createTracker(
hlsDataSourceFactory, loadErrorHandlingPolicy, playlistParserFactory),

View File

@ -27,7 +27,6 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayerLibraryInfo;
import com.google.android.exoplayer2.MediaItem;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.drm.DrmSession;
import com.google.android.exoplayer2.drm.DrmSessionEventListener;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.offline.FilteringManifestParser;
@ -39,6 +38,7 @@ import com.google.android.exoplayer2.source.LoadEventInfo;
import com.google.android.exoplayer2.source.MediaLoadData;
import com.google.android.exoplayer2.source.MediaPeriod;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.MediaSourceDrmHelper;
import com.google.android.exoplayer2.source.MediaSourceEventListener;
import com.google.android.exoplayer2.source.MediaSourceEventListener.EventDispatcher;
import com.google.android.exoplayer2.source.MediaSourceFactory;
@ -50,6 +50,7 @@ import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestP
import com.google.android.exoplayer2.upstream.Allocator;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultLoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy;
import com.google.android.exoplayer2.upstream.LoadErrorHandlingPolicy.LoadErrorInfo;
import com.google.android.exoplayer2.upstream.Loader;
@ -77,10 +78,11 @@ public final class SsMediaSource extends BaseMediaSource
public static final class Factory implements MediaSourceFactory {
private final SsChunkSource.Factory chunkSourceFactory;
private final MediaSourceDrmHelper mediaSourceDrmHelper;
@Nullable private final DataSource.Factory manifestDataSourceFactory;
private CompositeSequenceableLoaderFactory compositeSequenceableLoaderFactory;
private DrmSessionManager drmSessionManager;
@Nullable private DrmSessionManager drmSessionManager;
private LoadErrorHandlingPolicy loadErrorHandlingPolicy;
private long livePresentationDelayMs;
@Nullable private ParsingLoadable.Parser<? extends SsManifest> manifestParser;
@ -111,7 +113,7 @@ public final class SsMediaSource extends BaseMediaSource
@Nullable DataSource.Factory manifestDataSourceFactory) {
this.chunkSourceFactory = checkNotNull(chunkSourceFactory);
this.manifestDataSourceFactory = manifestDataSourceFactory;
drmSessionManager = DrmSessionManager.getDummyDrmSessionManager();
mediaSourceDrmHelper = new MediaSourceDrmHelper();
loadErrorHandlingPolicy = new DefaultLoadErrorHandlingPolicy();
livePresentationDelayMs = DEFAULT_LIVE_PRESENTATION_DELAY_MS;
compositeSequenceableLoaderFactory = new DefaultCompositeSequenceableLoaderFactory();
@ -197,19 +199,22 @@ public final class SsMediaSource extends BaseMediaSource
return this;
}
/**
* Sets the {@link DrmSessionManager} to use for acquiring {@link DrmSession DrmSessions}. The
* default value is {@link DrmSessionManager#DUMMY}.
*
* @param drmSessionManager The {@link DrmSessionManager}.
* @return This factory, for convenience.
*/
@Override
public Factory setDrmSessionManager(@Nullable DrmSessionManager drmSessionManager) {
this.drmSessionManager =
drmSessionManager != null
? drmSessionManager
: DrmSessionManager.getDummyDrmSessionManager();
this.drmSessionManager = drmSessionManager;
return this;
}
@Override
public Factory setDrmHttpDataSourceFactory(
@Nullable HttpDataSource.Factory drmHttpDataSourceFactory) {
mediaSourceDrmHelper.setDrmHttpDataSourceFactory(drmHttpDataSourceFactory);
return this;
}
@Override
public Factory setDrmUserAgent(@Nullable String userAgent) {
mediaSourceDrmHelper.setDrmUserAgent(userAgent);
return this;
}
@ -280,7 +285,7 @@ public final class SsMediaSource extends BaseMediaSource
/* manifestParser= */ null,
chunkSourceFactory,
compositeSequenceableLoaderFactory,
drmSessionManager,
drmSessionManager != null ? drmSessionManager : mediaSourceDrmHelper.create(mediaItem),
loadErrorHandlingPolicy,
livePresentationDelayMs);
}
@ -357,7 +362,7 @@ public final class SsMediaSource extends BaseMediaSource
manifestParser,
chunkSourceFactory,
compositeSequenceableLoaderFactory,
drmSessionManager,
drmSessionManager != null ? drmSessionManager : mediaSourceDrmHelper.create(mediaItem),
loadErrorHandlingPolicy,
livePresentationDelayMs);
}