From 7b663eea2fcc49b0c9eb6cc5ab43a63b56ce102b Mon Sep 17 00:00:00 2001 From: tonihei Date: Tue, 15 Aug 2023 17:39:59 +0100 Subject: [PATCH] Remove MediaPeriodId from common module It was moved there temporarily to support another temporary move of ExoPlaybackException. See . Since then, ExoPlaybackException has been moved back to ExoPlayer and we can do the same with MediaPeriodId, which only makes sense in the context of the ExoPlayer module. PiperOrigin-RevId: 557159381 --- .../media3/common/AdPlaybackState.java | 10 +- .../androidx/media3/common/MediaPeriodId.java | 195 ------------------ .../media3/exoplayer/DefaultLoadControl.java | 2 +- .../exoplayer/ExoPlaybackException.java | 2 +- .../media3/exoplayer/LoadControl.java | 2 +- .../analytics/DefaultAnalyticsCollector.java | 2 +- .../media3/exoplayer/source/MediaSource.java | 159 +++++++++++--- .../source/ads/ServerSideAdInsertionUtil.java | 2 +- 8 files changed, 142 insertions(+), 232 deletions(-) delete mode 100644 libraries/common/src/main/java/androidx/media3/common/MediaPeriodId.java diff --git a/libraries/common/src/main/java/androidx/media3/common/AdPlaybackState.java b/libraries/common/src/main/java/androidx/media3/common/AdPlaybackState.java index 2e5c97b4df..41e60f5d26 100644 --- a/libraries/common/src/main/java/androidx/media3/common/AdPlaybackState.java +++ b/libraries/common/src/main/java/androidx/media3/common/AdPlaybackState.java @@ -1000,14 +1000,8 @@ public final class AdPlaybackState implements Bundleable { * Appends a live postroll placeholder ad group to the ad playback state. * *

Adding such a placeholder is only required for periods of server side ad insertion live - * streams. - * - *

When building the media period queue, it sets {@link MediaPeriodId#nextAdGroupIndex} of a - * content period to the index of the placeholder. However, the placeholder will not produce a - * period in the media period queue. This only happens when an actual ad group is inserted at the - * given {@code nextAdGroupIndex}. In this case the newly inserted ad group will be used to insert - * an ad period into the media period queue following the content period with the given {@link - * MediaPeriodId#nextAdGroupIndex}. + * streams. A player is not expected to play this placeholder. It is only used to indicate that + * another ad group with this ad group index will be inserted in the future. * *

See {@link #endsWithLivePostrollPlaceHolder()} also. * diff --git a/libraries/common/src/main/java/androidx/media3/common/MediaPeriodId.java b/libraries/common/src/main/java/androidx/media3/common/MediaPeriodId.java deleted file mode 100644 index 343d01e253..0000000000 --- a/libraries/common/src/main/java/androidx/media3/common/MediaPeriodId.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package androidx.media3.common; - -import androidx.annotation.Nullable; -import androidx.media3.common.util.UnstableApi; - -/** - * Identifies a specific playback of a {@link Timeline.Period}. - * - *

A {@link Timeline.Period} can be played multiple times, for example if it is repeated. Each - * instances of this class identifies a specific playback of a {@link Timeline.Period}. - * - *

In ExoPlayer's implementation, {@link MediaPeriodId} identifies a {@code MediaPeriod}. - */ -// TODO(b/172315872) Should be final, but subclassed in MediaSource for backward-compatibility. -@UnstableApi -public class MediaPeriodId { - - /** The unique id of the timeline period. */ - public final Object periodUid; - - /** - * If the media period is in an ad group, the index of the ad group in the period. {@link - * C#INDEX_UNSET} otherwise. - */ - public final int adGroupIndex; - - /** - * If the media period is in an ad group, the index of the ad in its ad group in the period. - * {@link C#INDEX_UNSET} otherwise. - */ - public final int adIndexInAdGroup; - - /** - * The sequence number of the window in the buffered sequence of windows this media period is part - * of. {@link C#INDEX_UNSET} if the media period id is not part of a buffered sequence of windows. - */ - public final long windowSequenceNumber; - - /** - * The index of the next ad group to which the media period's content is clipped, or {@link - * C#INDEX_UNSET} if there is no following ad group or if this media period is an ad. - */ - public final int nextAdGroupIndex; - - /** - * Creates a media period identifier for a period which is not part of a buffered sequence of - * windows. - * - * @param periodUid The unique id of the timeline period. - */ - public MediaPeriodId(Object periodUid) { - this(periodUid, /* windowSequenceNumber= */ C.INDEX_UNSET); - } - - /** - * Creates a media period identifier for the specified period in the timeline. - * - * @param periodUid The unique id of the timeline period. - * @param windowSequenceNumber The sequence number of the window in the buffered sequence of - * windows this media period is part of. - */ - public MediaPeriodId(Object periodUid, long windowSequenceNumber) { - this( - periodUid, - /* adGroupIndex= */ C.INDEX_UNSET, - /* adIndexInAdGroup= */ C.INDEX_UNSET, - windowSequenceNumber, - /* nextAdGroupIndex= */ C.INDEX_UNSET); - } - - /** - * Creates a media period identifier for the specified clipped period in the timeline. - * - * @param periodUid The unique id of the timeline period. - * @param windowSequenceNumber The sequence number of the window in the buffered sequence of - * windows this media period is part of. - * @param nextAdGroupIndex The index of the next ad group to which the media period's content is - * clipped. - */ - public MediaPeriodId(Object periodUid, long windowSequenceNumber, int nextAdGroupIndex) { - this( - periodUid, - /* adGroupIndex= */ C.INDEX_UNSET, - /* adIndexInAdGroup= */ C.INDEX_UNSET, - windowSequenceNumber, - nextAdGroupIndex); - } - - /** - * Creates a media period identifier that identifies an ad within an ad group at the specified - * timeline period. - * - * @param periodUid The unique id of the timeline period that contains the ad group. - * @param adGroupIndex The index of the ad group. - * @param adIndexInAdGroup The index of the ad in the ad group. - * @param windowSequenceNumber The sequence number of the window in the buffered sequence of - * windows this media period is part of. - */ - public MediaPeriodId( - Object periodUid, int adGroupIndex, int adIndexInAdGroup, long windowSequenceNumber) { - this( - periodUid, - adGroupIndex, - adIndexInAdGroup, - windowSequenceNumber, - /* nextAdGroupIndex= */ C.INDEX_UNSET); - } - - /** Copy constructor for inheritance. */ - // TODO(b/172315872) Delete when client have migrated from MediaSource.MediaPeriodId - protected MediaPeriodId(MediaPeriodId mediaPeriodId) { - this.periodUid = mediaPeriodId.periodUid; - this.adGroupIndex = mediaPeriodId.adGroupIndex; - this.adIndexInAdGroup = mediaPeriodId.adIndexInAdGroup; - this.windowSequenceNumber = mediaPeriodId.windowSequenceNumber; - this.nextAdGroupIndex = mediaPeriodId.nextAdGroupIndex; - } - - private MediaPeriodId( - Object periodUid, - int adGroupIndex, - int adIndexInAdGroup, - long windowSequenceNumber, - int nextAdGroupIndex) { - this.periodUid = periodUid; - this.adGroupIndex = adGroupIndex; - this.adIndexInAdGroup = adIndexInAdGroup; - this.windowSequenceNumber = windowSequenceNumber; - this.nextAdGroupIndex = nextAdGroupIndex; - } - - /** Returns a copy of this period identifier but with {@code newPeriodUid} as its period uid. */ - public MediaPeriodId copyWithPeriodUid(Object newPeriodUid) { - return periodUid.equals(newPeriodUid) - ? this - : new MediaPeriodId( - newPeriodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, nextAdGroupIndex); - } - - /** Returns a copy of this period identifier with a new {@code windowSequenceNumber}. */ - public MediaPeriodId copyWithWindowSequenceNumber(long windowSequenceNumber) { - return this.windowSequenceNumber == windowSequenceNumber - ? this - : new MediaPeriodId( - periodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, nextAdGroupIndex); - } - - /** Returns whether this period identifier identifies an ad in an ad group in a period. */ - public boolean isAd() { - return adGroupIndex != C.INDEX_UNSET; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) { - return true; - } - if (!(obj instanceof MediaPeriodId)) { - return false; - } - - MediaPeriodId periodId = (MediaPeriodId) obj; - return periodUid.equals(periodId.periodUid) - && adGroupIndex == periodId.adGroupIndex - && adIndexInAdGroup == periodId.adIndexInAdGroup - && windowSequenceNumber == periodId.windowSequenceNumber - && nextAdGroupIndex == periodId.nextAdGroupIndex; - } - - @Override - public int hashCode() { - int result = 17; - result = 31 * result + periodUid.hashCode(); - result = 31 * result + adGroupIndex; - result = 31 * result + adIndexInAdGroup; - result = 31 * result + (int) windowSequenceNumber; - result = 31 * result + nextAdGroupIndex; - return result; - } -} diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultLoadControl.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultLoadControl.java index 5f12704a75..6b385d7cbb 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultLoadControl.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/DefaultLoadControl.java @@ -21,12 +21,12 @@ import static java.lang.Math.min; import androidx.annotation.Nullable; import androidx.media3.common.C; -import androidx.media3.common.MediaPeriodId; import androidx.media3.common.Timeline; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.Log; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; +import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; import androidx.media3.exoplayer.source.TrackGroupArray; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; import androidx.media3.exoplayer.upstream.Allocator; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlaybackException.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlaybackException.java index f8eeb6d9d8..923eb4d454 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlaybackException.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/ExoPlaybackException.java @@ -30,12 +30,12 @@ import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.C.FormatSupport; import androidx.media3.common.Format; -import androidx.media3.common.MediaPeriodId; import androidx.media3.common.PlaybackException; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.source.MediaSource; +import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; import java.io.IOException; import java.lang.annotation.Documented; import java.lang.annotation.Retention; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/LoadControl.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/LoadControl.java index a03e6e45e4..cdf68c2f82 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/LoadControl.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/LoadControl.java @@ -16,11 +16,11 @@ package androidx.media3.exoplayer; import androidx.media3.common.C; -import androidx.media3.common.MediaPeriodId; import androidx.media3.common.Timeline; import androidx.media3.common.TrackGroup; import androidx.media3.common.util.UnstableApi; import androidx.media3.exoplayer.source.MediaPeriod; +import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; import androidx.media3.exoplayer.source.TrackGroupArray; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; import androidx.media3.exoplayer.upstream.Allocator; diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/analytics/DefaultAnalyticsCollector.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/analytics/DefaultAnalyticsCollector.java index 0c34eb9183..70dc3b9fdd 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/analytics/DefaultAnalyticsCollector.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/analytics/DefaultAnalyticsCollector.java @@ -991,7 +991,7 @@ public class DefaultAnalyticsCollector implements AnalyticsCollector { if (error instanceof ExoPlaybackException) { ExoPlaybackException exoError = (ExoPlaybackException) error; if (exoError.mediaPeriodId != null) { - return generateEventTime(new MediaPeriodId(exoError.mediaPeriodId)); + return generateEventTime(exoError.mediaPeriodId); } } return generateCurrentPlayerMediaPeriodEventTime(); diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSource.java index 7343739c02..c25a07b53c 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSource.java @@ -131,51 +131,162 @@ public interface MediaSource { void onSourceInfoRefreshed(MediaSource source, Timeline timeline); } - // TODO(b/172315872) Delete when all clients have been migrated to base class. - /** - * Identifier for a {@link MediaPeriod}. - * - *

Extends for backward-compatibility {@link androidx.media3.common.MediaPeriodId}. - */ + /** Identifier for a {@link MediaPeriod}. */ @UnstableApi - final class MediaPeriodId extends androidx.media3.common.MediaPeriodId { + final class MediaPeriodId { - /** See {@link androidx.media3.common.MediaPeriodId#MediaPeriodId(Object)}. */ + /** The unique id of the timeline period. */ + public final Object periodUid; + + /** + * If the media period is in an ad group, the index of the ad group in the period. {@link + * C#INDEX_UNSET} otherwise. + */ + public final int adGroupIndex; + + /** + * If the media period is in an ad group, the index of the ad in its ad group in the period. + * {@link C#INDEX_UNSET} otherwise. + */ + public final int adIndexInAdGroup; + + /** + * The sequence number of the window in the buffered sequence of windows this media period is + * part of. {@link C#INDEX_UNSET} if the media period id is not part of a buffered sequence of + * windows. + */ + public final long windowSequenceNumber; + + /** + * The index of the next ad group to which the media period's content is clipped, or {@link + * C#INDEX_UNSET} if there is no following ad group or if this media period is an ad. + */ + public final int nextAdGroupIndex; + + /** + * Creates a media period identifier for a period which is not part of a buffered sequence of + * windows. + * + * @param periodUid The unique id of the timeline period. + */ public MediaPeriodId(Object periodUid) { - super(periodUid); + this(periodUid, /* windowSequenceNumber= */ C.INDEX_UNSET); } - /** See {@link androidx.media3.common.MediaPeriodId#MediaPeriodId(Object, long)}. */ + /** + * Creates a media period identifier for the specified period in the timeline. + * + * @param periodUid The unique id of the timeline period. + * @param windowSequenceNumber The sequence number of the window in the buffered sequence of + * windows this media period is part of. + */ public MediaPeriodId(Object periodUid, long windowSequenceNumber) { - super(periodUid, windowSequenceNumber); + this( + periodUid, + /* adGroupIndex= */ C.INDEX_UNSET, + /* adIndexInAdGroup= */ C.INDEX_UNSET, + windowSequenceNumber, + /* nextAdGroupIndex= */ C.INDEX_UNSET); } - /** See {@link androidx.media3.common.MediaPeriodId#MediaPeriodId(Object, long, int)}. */ + /** + * Creates a media period identifier for the specified clipped period in the timeline. + * + * @param periodUid The unique id of the timeline period. + * @param windowSequenceNumber The sequence number of the window in the buffered sequence of + * windows this media period is part of. + * @param nextAdGroupIndex The index of the next ad group to which the media period's content is + * clipped. + */ public MediaPeriodId(Object periodUid, long windowSequenceNumber, int nextAdGroupIndex) { - super(periodUid, windowSequenceNumber, nextAdGroupIndex); + this( + periodUid, + /* adGroupIndex= */ C.INDEX_UNSET, + /* adIndexInAdGroup= */ C.INDEX_UNSET, + windowSequenceNumber, + nextAdGroupIndex); } - /** See {@link androidx.media3.common.MediaPeriodId#MediaPeriodId(Object, int, int, long)}. */ + /** + * Creates a media period identifier that identifies an ad within an ad group at the specified + * timeline period. + * + * @param periodUid The unique id of the timeline period that contains the ad group. + * @param adGroupIndex The index of the ad group. + * @param adIndexInAdGroup The index of the ad in the ad group. + * @param windowSequenceNumber The sequence number of the window in the buffered sequence of + * windows this media period is part of. + */ public MediaPeriodId( Object periodUid, int adGroupIndex, int adIndexInAdGroup, long windowSequenceNumber) { - super(periodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber); + this( + periodUid, + adGroupIndex, + adIndexInAdGroup, + windowSequenceNumber, + /* nextAdGroupIndex= */ C.INDEX_UNSET); } - /** Wraps an {@link androidx.media3.common.MediaPeriodId} into a MediaPeriodId. */ - public MediaPeriodId(androidx.media3.common.MediaPeriodId mediaPeriodId) { - super(mediaPeriodId); + private MediaPeriodId( + Object periodUid, + int adGroupIndex, + int adIndexInAdGroup, + long windowSequenceNumber, + int nextAdGroupIndex) { + this.periodUid = periodUid; + this.adGroupIndex = adGroupIndex; + this.adIndexInAdGroup = adIndexInAdGroup; + this.windowSequenceNumber = windowSequenceNumber; + this.nextAdGroupIndex = nextAdGroupIndex; } - /** See {@link androidx.media3.common.MediaPeriodId#copyWithPeriodUid(Object)}. */ - @Override + /** Returns a copy of this period identifier but with {@code newPeriodUid} as its period uid. */ public MediaPeriodId copyWithPeriodUid(Object newPeriodUid) { - return new MediaPeriodId(super.copyWithPeriodUid(newPeriodUid)); + return periodUid.equals(newPeriodUid) + ? this + : new MediaPeriodId( + newPeriodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, nextAdGroupIndex); } - /** See {@link androidx.media3.common.MediaPeriodId#copyWithWindowSequenceNumber(long)}. */ - @Override + /** Returns a copy of this period identifier with a new {@code windowSequenceNumber}. */ public MediaPeriodId copyWithWindowSequenceNumber(long windowSequenceNumber) { - return new MediaPeriodId(super.copyWithWindowSequenceNumber(windowSequenceNumber)); + return this.windowSequenceNumber == windowSequenceNumber + ? this + : new MediaPeriodId( + periodUid, adGroupIndex, adIndexInAdGroup, windowSequenceNumber, nextAdGroupIndex); + } + + /** Returns whether this period identifier identifies an ad in an ad group in a period. */ + public boolean isAd() { + return adGroupIndex != C.INDEX_UNSET; + } + + @Override + public boolean equals(@Nullable Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof MediaPeriodId)) { + return false; + } + + MediaPeriodId periodId = (MediaPeriodId) obj; + return periodUid.equals(periodId.periodUid) + && adGroupIndex == periodId.adGroupIndex + && adIndexInAdGroup == periodId.adIndexInAdGroup + && windowSequenceNumber == periodId.windowSequenceNumber + && nextAdGroupIndex == periodId.nextAdGroupIndex; + } + + @Override + public int hashCode() { + int result = 17; + result = 31 * result + periodUid.hashCode(); + result = 31 * result + adGroupIndex; + result = 31 * result + adIndexInAdGroup; + result = 31 * result + (int) windowSequenceNumber; + result = 31 * result + nextAdGroupIndex; + return result; } } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java index 53e3f814ba..ce80a23072 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ads/ServerSideAdInsertionUtil.java @@ -21,12 +21,12 @@ import static java.lang.Math.max; import androidx.annotation.CheckResult; import androidx.media3.common.AdPlaybackState; import androidx.media3.common.C; -import androidx.media3.common.MediaPeriodId; import androidx.media3.common.Player; import androidx.media3.common.Timeline; import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.Util; import androidx.media3.exoplayer.source.MediaPeriod; +import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; /** A static utility class with methods to work with server-side inserted ads. */ @UnstableApi