mirror of
https://github.com/samsonjs/media.git
synced 2026-03-27 09:45:47 +00:00
Cache the last DrmSessionManager instance inside the default provider
Without this a new manager is instantiated for every item in a playlist, meaning the impact of caching improvements to DefaultDrmSessionManager are reduced (since the cache doesn't persist across playlist items). With this change, playlists of items with identical DRM config will use the same manager instance (and thus share existing sessions). Issue: #8523 PiperOrigin-RevId: 356690852
This commit is contained in:
parent
56feb96fc9
commit
19ab087c61
3 changed files with 68 additions and 2 deletions
|
|
@ -11,6 +11,10 @@
|
|||
* Fix a bug where an assertion would fail if the player started to buffer
|
||||
an ad media period before the ad URI was known then an ad state update
|
||||
arrived that didn't set the ad URI.
|
||||
* DRM:
|
||||
* Re-use the previous `DrmSessionManager` instance when playing a playlist
|
||||
(if possible)
|
||||
([#8523](https://github.com/google/ExoPlayer/issues/8523)).
|
||||
|
||||
### 2.13.0 (2021-02-04)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,23 +16,39 @@
|
|||
package com.google.android.exoplayer2.drm;
|
||||
|
||||
import static com.google.android.exoplayer2.drm.DefaultDrmSessionManager.MODE_PLAYBACK;
|
||||
import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
||||
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import com.google.android.exoplayer2.MediaItem;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
|
||||
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;
|
||||
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
|
||||
|
||||
/** Default implementation of {@link DrmSessionManagerProvider}. */
|
||||
@RequiresApi(18)
|
||||
public final class DefaultDrmSessionManagerProvider implements DrmSessionManagerProvider {
|
||||
|
||||
private final Object lock;
|
||||
|
||||
@GuardedBy("lock")
|
||||
private MediaItem.@MonotonicNonNull DrmConfiguration drmConfiguration;
|
||||
|
||||
@GuardedBy("lock")
|
||||
private @MonotonicNonNull DrmSessionManager manager;
|
||||
|
||||
@Nullable private HttpDataSource.Factory drmHttpDataSourceFactory;
|
||||
@Nullable private String userAgent;
|
||||
|
||||
public DefaultDrmSessionManagerProvider() {
|
||||
lock = new Object();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link HttpDataSource.Factory} to be used for creating {@link HttpMediaDrmCallback
|
||||
* HttpMediaDrmCallbacks} which executes key and provisioning requests over HTTP. If {@code null}
|
||||
|
|
@ -60,12 +76,23 @@ public final class DefaultDrmSessionManagerProvider implements DrmSessionManager
|
|||
|
||||
@Override
|
||||
public DrmSessionManager get(MediaItem mediaItem) {
|
||||
Assertions.checkNotNull(mediaItem.playbackProperties);
|
||||
checkNotNull(mediaItem.playbackProperties);
|
||||
@Nullable
|
||||
MediaItem.DrmConfiguration drmConfiguration = mediaItem.playbackProperties.drmConfiguration;
|
||||
if (drmConfiguration == null || Util.SDK_INT < 18) {
|
||||
return DrmSessionManager.DRM_UNSUPPORTED;
|
||||
}
|
||||
|
||||
synchronized (lock) {
|
||||
if (!Util.areEqual(drmConfiguration, this.drmConfiguration)) {
|
||||
this.drmConfiguration = drmConfiguration;
|
||||
this.manager = createManager(drmConfiguration);
|
||||
}
|
||||
return checkNotNull(this.manager);
|
||||
}
|
||||
}
|
||||
|
||||
private DrmSessionManager createManager(MediaItem.DrmConfiguration drmConfiguration) {
|
||||
HttpDataSource.Factory dataSourceFactory =
|
||||
drmHttpDataSourceFactory != null
|
||||
? drmHttpDataSourceFactory
|
||||
|
|
|
|||
|
|
@ -51,4 +51,39 @@ public class DefaultDrmSessionManagerProviderTest {
|
|||
|
||||
assertThat(drmSessionManager).isNotEqualTo(DrmSessionManager.DRM_UNSUPPORTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void create_reusesCachedInstanceWherePossible() {
|
||||
MediaItem mediaItem1 =
|
||||
new MediaItem.Builder()
|
||||
.setUri("https://example.test/content-1")
|
||||
.setDrmUuid(C.WIDEVINE_UUID)
|
||||
.build();
|
||||
// Same DRM info as item1, but different URL to check it doesn't prevent re-using a manager.
|
||||
MediaItem mediaItem2 =
|
||||
new MediaItem.Builder()
|
||||
.setUri("https://example.test/content-2")
|
||||
.setDrmUuid(C.WIDEVINE_UUID)
|
||||
.build();
|
||||
// Different DRM info to 1 and 2, needs a different manager instance.
|
||||
MediaItem mediaItem3 =
|
||||
new MediaItem.Builder()
|
||||
.setUri("https://example.test/content-3")
|
||||
.setDrmUuid(C.WIDEVINE_UUID)
|
||||
.setDrmLicenseUri("https://example.test/license")
|
||||
.build();
|
||||
|
||||
DefaultDrmSessionManagerProvider provider = new DefaultDrmSessionManagerProvider();
|
||||
DrmSessionManager drmSessionManager1 = provider.get(mediaItem1);
|
||||
DrmSessionManager drmSessionManager2 = provider.get(mediaItem2);
|
||||
DrmSessionManager drmSessionManager3 = provider.get(mediaItem3);
|
||||
|
||||
// Get a manager for the first item again - expect it to be a different instance to last time
|
||||
// since we only cache one.
|
||||
DrmSessionManager drmSessionManager4 = provider.get(mediaItem1);
|
||||
|
||||
assertThat(drmSessionManager1).isSameInstanceAs(drmSessionManager2);
|
||||
assertThat(drmSessionManager1).isNotSameInstanceAs(drmSessionManager3);
|
||||
assertThat(drmSessionManager1).isNotSameInstanceAs(drmSessionManager4);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue