Commit d7280f09 by bachinger

Add custom cache key to media item

This is required to migrate the PlayerActivity away from Sample to MediaItem. It hence needs adding buildUpon to MediaItem to mix in the customCacheKey and streamKeys before playback.

PiperOrigin-RevId: 306710643
parent 88de7745
...@@ -42,7 +42,6 @@ import com.google.android.exoplayer2.audio.AudioAttributes; ...@@ -42,7 +42,6 @@ import com.google.android.exoplayer2.audio.AudioAttributes;
import com.google.android.exoplayer2.demo.Sample.UriSample; import com.google.android.exoplayer2.demo.Sample.UriSample;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException; import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException; import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.offline.DownloadHelper;
import com.google.android.exoplayer2.offline.DownloadRequest; import com.google.android.exoplayer2.offline.DownloadRequest;
import com.google.android.exoplayer2.source.BehindLiveWindowException; import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory; import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
...@@ -473,7 +472,12 @@ public class PlayerActivity extends AppCompatActivity ...@@ -473,7 +472,12 @@ public class PlayerActivity extends AppCompatActivity
.getDownloadTracker() .getDownloadTracker()
.getDownloadRequest(mediaItem.playbackProperties.sourceUri); .getDownloadRequest(mediaItem.playbackProperties.sourceUri);
if (downloadRequest != null) { if (downloadRequest != null) {
return DownloadHelper.createMediaSource(downloadRequest, dataSourceFactory); mediaItem =
mediaItem
.buildUpon()
.setStreamKeys(downloadRequest.streamKeys)
.setCustomCacheKey(downloadRequest.customCacheKey)
.build();
} }
return mediaSourceFactory return mediaSourceFactory
.setDrmHttpDataSourceFactory(drmDataSourceFactory) .setDrmHttpDataSourceFactory(drmDataSourceFactory)
......
...@@ -69,17 +69,47 @@ public final class MediaItem { ...@@ -69,17 +69,47 @@ public final class MediaItem {
private boolean drmPlayClearContentWithoutKey; private boolean drmPlayClearContentWithoutKey;
private List<Integer> drmSessionForClearTypes; private List<Integer> drmSessionForClearTypes;
private List<StreamKey> streamKeys; private List<StreamKey> streamKeys;
@Nullable private String customCacheKey;
private List<Subtitle> subtitles; private List<Subtitle> subtitles;
@Nullable private Object tag; @Nullable private Object tag;
@Nullable private MediaMetadata mediaMetadata; @Nullable private MediaMetadata mediaMetadata;
/** Creates a builder. */ /** Creates a builder. */
public Builder() { public Builder() {
streamKeys = Collections.emptyList(); clipEndPositionMs = C.TIME_END_OF_SOURCE;
subtitles = Collections.emptyList();
drmSessionForClearTypes = Collections.emptyList(); drmSessionForClearTypes = Collections.emptyList();
drmLicenseRequestHeaders = Collections.emptyMap(); drmLicenseRequestHeaders = Collections.emptyMap();
clipEndPositionMs = C.TIME_END_OF_SOURCE; streamKeys = Collections.emptyList();
subtitles = Collections.emptyList();
}
private Builder(MediaItem mediaItem) {
this();
clipEndPositionMs = mediaItem.clippingProperties.endPositionMs;
clipRelativeToLiveWindow = mediaItem.clippingProperties.relativeToLiveWindow;
clipRelativeToDefaultPosition = mediaItem.clippingProperties.relativeToDefaultPosition;
clipStartsAtKeyFrame = mediaItem.clippingProperties.startsAtKeyFrame;
clipStartPositionMs = mediaItem.clippingProperties.startPositionMs;
mediaId = mediaItem.mediaId;
mediaMetadata = mediaItem.mediaMetadata;
@Nullable PlaybackProperties playbackProperties = mediaItem.playbackProperties;
if (playbackProperties != null) {
customCacheKey = playbackProperties.customCacheKey;
mimeType = playbackProperties.mimeType;
sourceUri = playbackProperties.sourceUri;
streamKeys = playbackProperties.streamKeys;
subtitles = playbackProperties.subtitles;
tag = playbackProperties.tag;
@Nullable DrmConfiguration drmConfiguration = playbackProperties.drmConfiguration;
if (drmConfiguration != null) {
drmLicenseUri = drmConfiguration.licenseUri;
drmLicenseRequestHeaders = drmConfiguration.requestHeaders;
drmMultiSession = drmConfiguration.multiSession;
drmPlayClearContentWithoutKey = drmConfiguration.playClearContentWithoutKey;
drmSessionForClearTypes = drmConfiguration.sessionForClearTypes;
drmUuid = drmConfiguration.uuid;
}
}
} }
/** /**
...@@ -297,6 +327,17 @@ public final class MediaItem { ...@@ -297,6 +327,17 @@ public final class MediaItem {
} }
/** /**
* Sets the optional custom cache key (only used for progressive streams).
*
* <p>If a {@link PlaybackProperties#sourceUri} is set, the custom cache key is used to create a
* {@link PlaybackProperties} object. Otherwise it will be ignored.
*/
public Builder setCustomCacheKey(@Nullable String customCacheKey) {
this.customCacheKey = customCacheKey;
return this;
}
/**
* Sets the optional subtitles. * Sets the optional subtitles.
* *
* <p>{@code null} or an empty {@link List} can be used for a reset. * <p>{@code null} or an empty {@link List} can be used for a reset.
...@@ -352,6 +393,7 @@ public final class MediaItem { ...@@ -352,6 +393,7 @@ public final class MediaItem {
drmSessionForClearTypes) drmSessionForClearTypes)
: null, : null,
streamKeys, streamKeys,
customCacheKey,
subtitles, subtitles,
tag); tag);
mediaId = mediaId != null ? mediaId : sourceUri.toString(); mediaId = mediaId != null ? mediaId : sourceUri.toString();
...@@ -461,6 +503,9 @@ public final class MediaItem { ...@@ -461,6 +503,9 @@ public final class MediaItem {
/** Optional stream keys by which the manifest is filtered. */ /** Optional stream keys by which the manifest is filtered. */
public final List<StreamKey> streamKeys; public final List<StreamKey> streamKeys;
/** Optional custom cache key (only used for progressive streams). */
@Nullable public final String customCacheKey;
/** Optional subtitles to be sideloaded. */ /** Optional subtitles to be sideloaded. */
public final List<Subtitle> subtitles; public final List<Subtitle> subtitles;
...@@ -476,12 +521,14 @@ public final class MediaItem { ...@@ -476,12 +521,14 @@ public final class MediaItem {
@Nullable String mimeType, @Nullable String mimeType,
@Nullable DrmConfiguration drmConfiguration, @Nullable DrmConfiguration drmConfiguration,
List<StreamKey> streamKeys, List<StreamKey> streamKeys,
@Nullable String customCacheKey,
List<Subtitle> subtitles, List<Subtitle> subtitles,
@Nullable Object tag) { @Nullable Object tag) {
this.sourceUri = sourceUri; this.sourceUri = sourceUri;
this.mimeType = mimeType; this.mimeType = mimeType;
this.drmConfiguration = drmConfiguration; this.drmConfiguration = drmConfiguration;
this.streamKeys = streamKeys; this.streamKeys = streamKeys;
this.customCacheKey = customCacheKey;
this.subtitles = subtitles; this.subtitles = subtitles;
this.tag = tag; this.tag = tag;
} }
...@@ -500,6 +547,7 @@ public final class MediaItem { ...@@ -500,6 +547,7 @@ public final class MediaItem {
&& Util.areEqual(mimeType, other.mimeType) && Util.areEqual(mimeType, other.mimeType)
&& Util.areEqual(drmConfiguration, other.drmConfiguration) && Util.areEqual(drmConfiguration, other.drmConfiguration)
&& streamKeys.equals(other.streamKeys) && streamKeys.equals(other.streamKeys)
&& Util.areEqual(customCacheKey, other.customCacheKey)
&& subtitles.equals(other.subtitles) && subtitles.equals(other.subtitles)
&& Util.areEqual(tag, other.tag); && Util.areEqual(tag, other.tag);
} }
...@@ -510,6 +558,7 @@ public final class MediaItem { ...@@ -510,6 +558,7 @@ public final class MediaItem {
result = 31 * result + (mimeType == null ? 0 : mimeType.hashCode()); result = 31 * result + (mimeType == null ? 0 : mimeType.hashCode());
result = 31 * result + (drmConfiguration == null ? 0 : drmConfiguration.hashCode()); result = 31 * result + (drmConfiguration == null ? 0 : drmConfiguration.hashCode());
result = 31 * result + streamKeys.hashCode(); result = 31 * result + streamKeys.hashCode();
result = 31 * result + (customCacheKey == null ? 0 : customCacheKey.hashCode());
result = 31 * result + subtitles.hashCode(); result = 31 * result + subtitles.hashCode();
result = 31 * result + (tag == null ? 0 : tag.hashCode()); result = 31 * result + (tag == null ? 0 : tag.hashCode());
return result; return result;
...@@ -674,6 +723,11 @@ public final class MediaItem { ...@@ -674,6 +723,11 @@ public final class MediaItem {
this.clippingProperties = clippingProperties; this.clippingProperties = clippingProperties;
} }
/** Returns a {@link Builder} initialized with the values of this instance. */
public Builder buildUpon() {
return new Builder(this);
}
@Override @Override
public boolean equals(@Nullable Object obj) { public boolean equals(@Nullable Object obj) {
if (this == obj) { if (this == obj) {
......
...@@ -142,6 +142,14 @@ public class MediaItemTest { ...@@ -142,6 +142,14 @@ public class MediaItemTest {
} }
@Test @Test
public void builderSetCustomCacheKey_setsCustomCacheKey() {
MediaItem mediaItem =
new MediaItem.Builder().setSourceUri(URI_STRING).setCustomCacheKey("key").build();
assertThat(mediaItem.playbackProperties.customCacheKey).isEqualTo("key");
}
@Test
public void builderSetStreamKeys_setsStreamKeys() { public void builderSetStreamKeys_setsStreamKeys() {
List<StreamKey> streamKeys = new ArrayList<>(); List<StreamKey> streamKeys = new ArrayList<>();
streamKeys.add(new StreamKey(1, 0, 0)); streamKeys.add(new StreamKey(1, 0, 0));
...@@ -267,4 +275,40 @@ public class MediaItemTest { ...@@ -267,4 +275,40 @@ public class MediaItemTest {
assertThat(mediaItem.mediaMetadata).isEqualTo(mediaMetadata); assertThat(mediaItem.mediaMetadata).isEqualTo(mediaMetadata);
} }
@Test
public void buildUpon_equalsToOriginal() {
MediaItem mediaItem =
new MediaItem.Builder()
.setClipEndPositionMs(1000)
.setClipRelativeToDefaultPosition(true)
.setClipRelativeToLiveWindow(true)
.setClipStartPositionMs(100)
.setClipStartsAtKeyFrame(true)
.setCustomCacheKey("key")
.setDrmUuid(C.WIDEVINE_UUID)
.setDrmLicenseUri(URI_STRING + "/license")
.setDrmLicenseRequestHeaders(
Collections.singletonMap("Referer", "http://www.google.com"))
.setDrmMultiSession(true)
.setDrmPlayClearContentWithoutKey(true)
.setDrmSessionForClearTypes(Collections.singletonList(C.TRACK_TYPE_AUDIO))
.setMediaId("mediaId")
.setMediaMetadata(new MediaMetadata.Builder().setTitle("title").build())
.setMimeType(MimeTypes.APPLICATION_MP4)
.setSourceUri(URI_STRING)
.setStreamKeys(Collections.singletonList(new StreamKey(1, 0, 0)))
.setSubtitles(
Collections.singletonList(
new MediaItem.Subtitle(
Uri.parse(URI_STRING + "/en"),
MimeTypes.APPLICATION_TTML,
/* language= */ "en")))
.setTag(new Object())
.build();
MediaItem copy = mediaItem.buildUpon().build();
assertThat(copy).isEqualTo(mediaItem);
}
} }
...@@ -95,13 +95,10 @@ public final class ProgressiveMediaSource extends BaseMediaSource ...@@ -95,13 +95,10 @@ public final class ProgressiveMediaSource extends BaseMediaSource
} }
/** /**
* Sets the custom key that uniquely identifies the original stream. Used for cache indexing. * @deprecated Use {@link MediaItem.Builder#setCustomCacheKey(String)} and {@link
* The default value is {@code null}. * #createMediaSource(MediaItem)} instead.
*
* @param customCacheKey A custom key that uniquely identifies the original stream. Used for
* cache indexing.
* @return This factory, for convenience.
*/ */
@Deprecated
public Factory setCustomCacheKey(@Nullable String customCacheKey) { public Factory setCustomCacheKey(@Nullable String customCacheKey) {
this.customCacheKey = customCacheKey; this.customCacheKey = customCacheKey;
return this; return this;
...@@ -188,7 +185,9 @@ public final class ProgressiveMediaSource extends BaseMediaSource ...@@ -188,7 +185,9 @@ public final class ProgressiveMediaSource extends BaseMediaSource
extractorsFactory, extractorsFactory,
drmSessionManager, drmSessionManager,
loadErrorHandlingPolicy, loadErrorHandlingPolicy,
customCacheKey, mediaItem.playbackProperties.customCacheKey != null
? mediaItem.playbackProperties.customCacheKey
: customCacheKey,
continueLoadingCheckIntervalBytes, continueLoadingCheckIntervalBytes,
mediaItem.playbackProperties.tag != null ? mediaItem.playbackProperties.tag : tag); mediaItem.playbackProperties.tag != null ? mediaItem.playbackProperties.tag : tag);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment