From 12f161520595750f7c71da7de2eb29c00cda8d1d Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Tue, 15 Dec 2020 10:36:34 +0000 Subject: [PATCH] Use MediaItem as ads identifier by default Issue: #3750 PiperOrigin-RevId: 347572122 --- .../google/android/exoplayer2/MediaItem.java | 58 +++++++++++-------- .../android/exoplayer2/MediaItemTest.java | 2 +- .../source/DefaultMediaSourceFactory.java | 5 +- 3 files changed, 38 insertions(+), 27 deletions(-) diff --git a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java index bf936cd5c35..12f1951f9fd 100644 --- a/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java +++ b/library/common/src/main/java/com/google/android/exoplayer2/MediaItem.java @@ -418,13 +418,13 @@ public Builder setSubtitles(@Nullable List subtitles) { /** * Sets the optional ad tag {@link Uri}. * - *

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. - * *

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. * + *

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. */ public Builder setAdTagUri(@Nullable String adTagUri) { @@ -434,34 +434,35 @@ public Builder setAdTagUri(@Nullable String adTagUri) { /** * Sets the optional ad tag {@link Uri}. * - *

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. - * *

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. * + *

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. */ 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. * - *

All ads media items in the playlist with the same ads identifier and loader will share the - * same ad playback state. - * *

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. * + *

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 adsId An opaque identifier for ad playback state associated with this item. Must be - * non-null if {@code adTagUri} is non-null. Ad loading and playback state is shared among - * all media items that have the same ads id (by {@link Object#equals(Object) equality}) and - * ads loader, so it is important to pass the same identifiers when constructing playlist - * items each time the player returns to the foreground. + * @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 + * Object#equals(Object) equality}) and ads loader, so it is important to pass the same + * identifiers when constructing playlist items each time the player returns to the + * foreground. */ public Builder setAdTagUri(@Nullable Uri adTagUri, @Nullable Object adsId) { this.adTagUri = adTagUri; @@ -576,7 +577,7 @@ public MediaItem build() { drmSessionForClearTypes, drmKeySetId) : null, - adTagUri != null ? new AdsConfiguration(adTagUri, checkNotNull(adsId)) : null, + adTagUri != null ? new AdsConfiguration(adTagUri, adsId) : null, streamKeys, customCacheKey, subtitles, @@ -700,19 +701,26 @@ public int hashCode() { /** Configuration for playing back linear ads with a media item. */ public static final class AdsConfiguration { + /** The ad tag URI to load. */ 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. * * @param adTagUri The ad tag URI to load. * @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 - * Object#equals(Object) equality}), so it is important to pass the same identifiers when - * constructing playlist items each time the player returns to the foreground. + * and playback state is shared among all media items that have the same ads ID (by {@link + * Object#equals(Object) equality}) and ads loader, so it is important to pass the same + * 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.adsId = adsId; } @@ -727,13 +735,13 @@ public boolean equals(@Nullable Object 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 public int hashCode() { int result = adTagUri.hashCode(); - result = 31 * result + adsId.hashCode(); + result = 31 * result + (adsId != null ? adsId.hashCode() : 0); return result; } } diff --git a/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java b/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java index 915462b27f0..0243fe50f47 100644 --- a/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java +++ b/library/common/src/test/java/com/google/android/exoplayer2/MediaItemTest.java @@ -282,7 +282,7 @@ public void builderSetAdTagUri_setsAdTagUri() { MediaItem mediaItem = new MediaItem.Builder().setUri(URI_STRING).setAdTagUri(adTagUri).build(); assertThat(mediaItem.playbackProperties.adsConfiguration.adTagUri).isEqualTo(adTagUri); - assertThat(mediaItem.playbackProperties.adsConfiguration.adsId).isEqualTo(adTagUri); + assertThat(mediaItem.playbackProperties.adsConfiguration.adsId).isNull(); } @Test diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java index c9fa011b467..c0b82781df6 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/DefaultMediaSourceFactory.java @@ -18,6 +18,7 @@ import static com.google.android.exoplayer2.util.Util.castNonNull; import android.content.Context; +import android.util.Pair; import android.util.SparseArray; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; @@ -411,7 +412,9 @@ private MediaSource maybeWrapWithAdsMediaSource(MediaItem mediaItem, MediaSource return new AdsMediaSource( mediaSource, new DataSpec(adsConfiguration.adTagUri), - adsConfiguration.adsId, + /* adsId= */ adsConfiguration.adsId != null + ? adsConfiguration.adsId + : Pair.create(mediaItem.mediaId, adsConfiguration.adTagUri), /* adMediaSourceFactory= */ this, adsLoader, adViewProvider);