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;
import com.google.android.exoplayer2.demo.Sample.UriSample;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException;
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.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory;
......@@ -473,7 +472,12 @@ public class PlayerActivity extends AppCompatActivity
.getDownloadTracker()
.getDownloadRequest(mediaItem.playbackProperties.sourceUri);
if (downloadRequest != null) {
return DownloadHelper.createMediaSource(downloadRequest, dataSourceFactory);
mediaItem =
mediaItem
.buildUpon()
.setStreamKeys(downloadRequest.streamKeys)
.setCustomCacheKey(downloadRequest.customCacheKey)
.build();
}
return mediaSourceFactory
.setDrmHttpDataSourceFactory(drmDataSourceFactory)
......
......@@ -69,17 +69,47 @@ public final class MediaItem {
private boolean drmPlayClearContentWithoutKey;
private List<Integer> drmSessionForClearTypes;
private List<StreamKey> streamKeys;
@Nullable private String customCacheKey;
private List<Subtitle> subtitles;
@Nullable private Object tag;
@Nullable private MediaMetadata mediaMetadata;
/** Creates a builder. */
public Builder() {
streamKeys = Collections.emptyList();
subtitles = Collections.emptyList();
clipEndPositionMs = C.TIME_END_OF_SOURCE;
drmSessionForClearTypes = Collections.emptyList();
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 {
}
/**
* 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.
*
* <p>{@code null} or an empty {@link List} can be used for a reset.
......@@ -352,6 +393,7 @@ public final class MediaItem {
drmSessionForClearTypes)
: null,
streamKeys,
customCacheKey,
subtitles,
tag);
mediaId = mediaId != null ? mediaId : sourceUri.toString();
......@@ -461,6 +503,9 @@ public final class MediaItem {
/** Optional stream keys by which the manifest is filtered. */
public final List<StreamKey> streamKeys;
/** Optional custom cache key (only used for progressive streams). */
@Nullable public final String customCacheKey;
/** Optional subtitles to be sideloaded. */
public final List<Subtitle> subtitles;
......@@ -476,12 +521,14 @@ public final class MediaItem {
@Nullable String mimeType,
@Nullable DrmConfiguration drmConfiguration,
List<StreamKey> streamKeys,
@Nullable String customCacheKey,
List<Subtitle> subtitles,
@Nullable Object tag) {
this.sourceUri = sourceUri;
this.mimeType = mimeType;
this.drmConfiguration = drmConfiguration;
this.streamKeys = streamKeys;
this.customCacheKey = customCacheKey;
this.subtitles = subtitles;
this.tag = tag;
}
......@@ -500,6 +547,7 @@ public final class MediaItem {
&& Util.areEqual(mimeType, other.mimeType)
&& Util.areEqual(drmConfiguration, other.drmConfiguration)
&& streamKeys.equals(other.streamKeys)
&& Util.areEqual(customCacheKey, other.customCacheKey)
&& subtitles.equals(other.subtitles)
&& Util.areEqual(tag, other.tag);
}
......@@ -510,6 +558,7 @@ public final class MediaItem {
result = 31 * result + (mimeType == null ? 0 : mimeType.hashCode());
result = 31 * result + (drmConfiguration == null ? 0 : drmConfiguration.hashCode());
result = 31 * result + streamKeys.hashCode();
result = 31 * result + (customCacheKey == null ? 0 : customCacheKey.hashCode());
result = 31 * result + subtitles.hashCode();
result = 31 * result + (tag == null ? 0 : tag.hashCode());
return result;
......@@ -674,6 +723,11 @@ public final class MediaItem {
this.clippingProperties = clippingProperties;
}
/** Returns a {@link Builder} initialized with the values of this instance. */
public Builder buildUpon() {
return new Builder(this);
}
@Override
public boolean equals(@Nullable Object obj) {
if (this == obj) {
......
......@@ -142,6 +142,14 @@ public class MediaItemTest {
}
@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() {
List<StreamKey> streamKeys = new ArrayList<>();
streamKeys.add(new StreamKey(1, 0, 0));
......@@ -267,4 +275,40 @@ public class MediaItemTest {
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
}
/**
* Sets the custom key that uniquely identifies the original stream. Used for cache indexing.
* The default value is {@code null}.
*
* @param customCacheKey A custom key that uniquely identifies the original stream. Used for
* cache indexing.
* @return This factory, for convenience.
* @deprecated Use {@link MediaItem.Builder#setCustomCacheKey(String)} and {@link
* #createMediaSource(MediaItem)} instead.
*/
@Deprecated
public Factory setCustomCacheKey(@Nullable String customCacheKey) {
this.customCacheKey = customCacheKey;
return this;
......@@ -188,7 +185,9 @@ public final class ProgressiveMediaSource extends BaseMediaSource
extractorsFactory,
drmSessionManager,
loadErrorHandlingPolicy,
customCacheKey,
mediaItem.playbackProperties.customCacheKey != null
? mediaItem.playbackProperties.customCacheKey
: customCacheKey,
continueLoadingCheckIntervalBytes,
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