Use MediaItem as ads identifier by default

Issue: #3750
PiperOrigin-RevId: 347572122
This commit is contained in:
andrewlewis 2020-12-15 10:36:34 +00:00 committed by Christos Tsilopoulos
parent 0633778c70
commit 12f1615205
3 changed files with 38 additions and 27 deletions

View File

@ -418,13 +418,13 @@ public final class MediaItem {
/** /**
* Sets the optional ad tag {@link Uri}. * Sets the optional ad tag {@link Uri}.
* *
* <p>All ads media items in the playlist with the same ad tag URI and loader will share the
* same ad playback state. To resume ad playback when recreating the playlist on returning from
* the background, pass the same ad tag URI.
*
* <p>If {@link #setUri} is passed a non-null {@code uri}, the ad tag URI is used to create a * <p>If {@link #setUri} is passed a non-null {@code uri}, the ad tag URI is used to create a
* {@link PlaybackProperties} object. Otherwise it will be ignored. * {@link PlaybackProperties} object. Otherwise it will be ignored.
* *
* <p>Media items in the playlist with the same ad tag URI, media ID and ads loader will share
* the same ad playback state. To resume ad playback when recreating the playlist on returning
* from the background, pass media items with the same ad tag URIs and media IDs to the player.
*
* @param adTagUri The ad tag URI to load. * @param adTagUri The ad tag URI to load.
*/ */
public Builder setAdTagUri(@Nullable String adTagUri) { public Builder setAdTagUri(@Nullable String adTagUri) {
@ -434,34 +434,35 @@ public final class MediaItem {
/** /**
* Sets the optional ad tag {@link Uri}. * Sets the optional ad tag {@link Uri}.
* *
* <p>All ads media items in the playlist with the same ad tag URI and loader will share the
* same ad playback state. To resume ad playback when recreating the playlist on returning from
* the background, pass the same ad tag URI.
*
* <p>If {@link #setUri} is passed a non-null {@code uri}, the ad tag URI is used to create a * <p>If {@link #setUri} is passed a non-null {@code uri}, the ad tag URI is used to create a
* {@link PlaybackProperties} object. Otherwise it will be ignored. * {@link PlaybackProperties} object. Otherwise it will be ignored.
* *
* <p>Media items in the playlist with the same ad tag URI, media ID and ads loader will share
* the same ad playback state. To resume ad playback when recreating the playlist on returning
* from the background, pass media items with the same ad tag URIs and media IDs to the player.
*
* @param adTagUri The ad tag URI to load. * @param adTagUri The ad tag URI to load.
*/ */
public Builder setAdTagUri(@Nullable Uri adTagUri) { public Builder setAdTagUri(@Nullable Uri adTagUri) {
return setAdTagUri(adTagUri, /* adsId= */ adTagUri); return setAdTagUri(adTagUri, /* adsId= */ null);
} }
/** /**
* Sets the optional ad tag {@link Uri} and ads identifier. * Sets the optional ad tag {@link Uri} and ads identifier.
* *
* <p>All ads media items in the playlist with the same ads identifier and loader will share the
* same ad playback state.
*
* <p>If {@link #setUri} is passed a non-null {@code uri}, the ad tag URI is used to create a * <p>If {@link #setUri} is passed a non-null {@code uri}, the ad tag URI is used to create a
* {@link PlaybackProperties} object. Otherwise it will be ignored. * {@link PlaybackProperties} object. Otherwise it will be ignored.
* *
* <p>Media items in the playlist that have the same ads identifier and ads loader share the
* same ad playback state. To resume ad playback when recreating the playlist on returning from
* the background, pass the same ads IDs to the player.
*
* @param adTagUri The ad tag URI to load. * @param adTagUri The ad tag URI to load.
* @param adsId An opaque identifier for ad playback state associated with this item. Must be * @param adsId An opaque identifier for ad playback state associated with this item. Ad loading
* non-null if {@code adTagUri} is non-null. Ad loading and playback state is shared among * and playback state is shared among all media items that have the same ads ID (by {@link
* all media items that have the same ads id (by {@link Object#equals(Object) equality}) and * Object#equals(Object) equality}) and ads loader, so it is important to pass the same
* ads loader, so it is important to pass the same identifiers when constructing playlist * identifiers when constructing playlist items each time the player returns to the
* items each time the player returns to the foreground. * foreground.
*/ */
public Builder setAdTagUri(@Nullable Uri adTagUri, @Nullable Object adsId) { public Builder setAdTagUri(@Nullable Uri adTagUri, @Nullable Object adsId) {
this.adTagUri = adTagUri; this.adTagUri = adTagUri;
@ -576,7 +577,7 @@ public final class MediaItem {
drmSessionForClearTypes, drmSessionForClearTypes,
drmKeySetId) drmKeySetId)
: null, : null,
adTagUri != null ? new AdsConfiguration(adTagUri, checkNotNull(adsId)) : null, adTagUri != null ? new AdsConfiguration(adTagUri, adsId) : null,
streamKeys, streamKeys,
customCacheKey, customCacheKey,
subtitles, subtitles,
@ -700,19 +701,26 @@ public final class MediaItem {
/** Configuration for playing back linear ads with a media item. */ /** Configuration for playing back linear ads with a media item. */
public static final class AdsConfiguration { public static final class AdsConfiguration {
/** The ad tag URI to load. */
public final Uri adTagUri; public final Uri adTagUri;
public final Object adsId; /**
* An opaque identifier for ad playback state associated with this item, or {@code null} if the
* combination of the {@link MediaItem.Builder#setMediaId(String) media ID} and {@link #adTagUri
* ad tag URI} should be used as the ads identifier.
*/
@Nullable public final Object adsId;
/** /**
* Creates an ads configuration with the given ad tag URI and ads identifier. * Creates an ads configuration with the given ad tag URI and ads identifier.
* *
* @param adTagUri The ad tag URI to load. * @param adTagUri The ad tag URI to load.
* @param adsId An opaque identifier for ad playback state associated with this item. Ad loading * @param adsId An opaque identifier for ad playback state associated with this item. Ad loading
* and playback state is shared among all media items that have the same ads id (by {@link * and playback state is shared among all media items that have the same ads ID (by {@link
* Object#equals(Object) equality}), so it is important to pass the same identifiers when * Object#equals(Object) equality}) and ads loader, so it is important to pass the same
* constructing playlist items each time the player returns to the foreground. * identifiers when constructing playlist items each time the player returns to the
* foreground.
*/ */
private AdsConfiguration(Uri adTagUri, Object adsId) { private AdsConfiguration(Uri adTagUri, @Nullable Object adsId) {
this.adTagUri = adTagUri; this.adTagUri = adTagUri;
this.adsId = adsId; this.adsId = adsId;
} }
@ -727,13 +735,13 @@ public final class MediaItem {
} }
AdsConfiguration other = (AdsConfiguration) obj; AdsConfiguration other = (AdsConfiguration) obj;
return adTagUri.equals(other.adTagUri) && adsId.equals(other.adsId); return adTagUri.equals(other.adTagUri) && Util.areEqual(adsId, other.adsId);
} }
@Override @Override
public int hashCode() { public int hashCode() {
int result = adTagUri.hashCode(); int result = adTagUri.hashCode();
result = 31 * result + adsId.hashCode(); result = 31 * result + (adsId != null ? adsId.hashCode() : 0);
return result; return result;
} }
} }

View File

@ -282,7 +282,7 @@ public class MediaItemTest {
MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).setAdTagUri(adTagUri).build(); MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).setAdTagUri(adTagUri).build();
assertThat(mediaItem.playbackProperties.adsConfiguration.adTagUri).isEqualTo(adTagUri); assertThat(mediaItem.playbackProperties.adsConfiguration.adTagUri).isEqualTo(adTagUri);
assertThat(mediaItem.playbackProperties.adsConfiguration.adsId).isEqualTo(adTagUri); assertThat(mediaItem.playbackProperties.adsConfiguration.adsId).isNull();
} }
@Test @Test

View File

@ -18,6 +18,7 @@ package com.google.android.exoplayer2.source;
import static com.google.android.exoplayer2.util.Util.castNonNull; import static com.google.android.exoplayer2.util.Util.castNonNull;
import android.content.Context; import android.content.Context;
import android.util.Pair;
import android.util.SparseArray; import android.util.SparseArray;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
@ -411,7 +412,9 @@ public final class DefaultMediaSourceFactory implements MediaSourceFactory {
return new AdsMediaSource( return new AdsMediaSource(
mediaSource, mediaSource,
new DataSpec(adsConfiguration.adTagUri), new DataSpec(adsConfiguration.adTagUri),
adsConfiguration.adsId, /* adsId= */ adsConfiguration.adsId != null
? adsConfiguration.adsId
: Pair.create(mediaItem.mediaId, adsConfiguration.adTagUri),
/* adMediaSourceFactory= */ this, /* adMediaSourceFactory= */ this,
adsLoader, adsLoader,
adViewProvider); adViewProvider);