diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 773921155e..32ab94035b 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -21,6 +21,13 @@ AdPlaybackState>)` by adding a timeline parameter that contains the periods with the UIDs used as keys in the map. This is required to avoid concurrency issues with multi-period live streams. + * Deprecate `EventDispatcher.withParameters(int windowIndex, @Nullable + MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs)` and + `BaseMediaSource.createEventDispatcher(..., long mediaTimeOffsetMs)`. + The variant of the methods without the `mediaTimeOffsetUs` can be called + instead. Note that even for the deprecated variants, the offset is not + anymore added to `startTimeUs` and `endTimeUs` of the `MediaLoadData` + objects that are dispatched by the dispatcher. * Audio: * Fix bug where some playbacks fail when tunneling is enabled and `AudioProcessors` are active, e.g. for gapless trimming @@ -52,6 +59,8 @@ * DASH: * Fix handling of empty segment timelines ([#11014](https://github.com/google/ExoPlayer/issues/11014)). + * Remove the media time offset from `MediaLoadData.startTimeMs` and + `MediaLoadData.endTimeMs` for multi period DASH streams. * RTSP: * Retry with TCP if RTSP Setup with UDP fails with RTSP Error 461 UnsupportedTransport diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BaseMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BaseMediaSource.java index 3fb3b9d4cd..a2b0d46096 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BaseMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/BaseMediaSource.java @@ -101,37 +101,46 @@ public abstract class BaseMediaSource implements MediaSource { */ protected final MediaSourceEventListener.EventDispatcher createEventDispatcher( @Nullable MediaPeriodId mediaPeriodId) { - return eventDispatcher.withParameters( - /* windowIndex= */ 0, mediaPeriodId, /* mediaTimeOffsetMs= */ 0); + return eventDispatcher.withParameters(/* windowIndex= */ 0, mediaPeriodId); } /** * Returns a {@link MediaSourceEventListener.EventDispatcher} which dispatches all events to the - * registered listeners with the specified {@link MediaPeriodId} and time offset. - * - * @param mediaPeriodId The {@link MediaPeriodId} to be reported with the events. - * @param mediaTimeOffsetMs The offset to be added to all media times, in milliseconds. - * @return An event dispatcher with pre-configured media period id and time offset. - */ - protected final MediaSourceEventListener.EventDispatcher createEventDispatcher( - MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs) { - Assertions.checkNotNull(mediaPeriodId); - return eventDispatcher.withParameters(/* windowIndex= */ 0, mediaPeriodId, mediaTimeOffsetMs); - } - - /** - * Returns a {@link MediaSourceEventListener.EventDispatcher} which dispatches all events to the - * registered listeners with the specified window index, {@link MediaPeriodId} and time offset. + * registered listeners with the specified window index and {@link MediaPeriodId}. * * @param windowIndex The timeline window index to be reported with the events. * @param mediaPeriodId The {@link MediaPeriodId} to be reported with the events. May be null, if * the events do not belong to a specific media period. - * @param mediaTimeOffsetMs The offset to be added to all media times, in milliseconds. - * @return An event dispatcher with pre-configured media period id and time offset. + * @return An event dispatcher with pre-configured media period id. */ + protected final MediaSourceEventListener.EventDispatcher createEventDispatcher( + int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + return eventDispatcher.withParameters(windowIndex, mediaPeriodId); + } + + /** + * Note: The {@code mediaTimeOffsetMs} passed to this method is ignored and not added to media + * times in any way. + * + * @deprecated Use {@link #createEventDispatcher(MediaPeriodId)} instead. + */ + @Deprecated + protected final MediaSourceEventListener.EventDispatcher createEventDispatcher( + MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs) { + Assertions.checkNotNull(mediaPeriodId); + return eventDispatcher.withParameters(/* windowIndex= */ 0, mediaPeriodId); + } + + /** + * Note: The {@code mediaTimeOffsetMs} passed to this method is ignored and not added to media + * times in any way. + * + * @deprecated Use {@link #createEventDispatcher(int, MediaPeriodId)} instead. + */ + @Deprecated protected final MediaSourceEventListener.EventDispatcher createEventDispatcher( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs) { - return eventDispatcher.withParameters(windowIndex, mediaPeriodId, mediaTimeOffsetMs); + return eventDispatcher.withParameters(windowIndex, mediaPeriodId); } /** diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/CompositeMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/CompositeMediaSource.java index 7ce915d86a..1aa0c50499 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/CompositeMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/CompositeMediaSource.java @@ -357,8 +357,7 @@ public abstract class CompositeMediaSource extends BaseMediaSource { int windowIndex = getWindowIndexForChildWindowIndex(id, childWindowIndex); if (mediaSourceEventDispatcher.windowIndex != windowIndex || !Util.areEqual(mediaSourceEventDispatcher.mediaPeriodId, mediaPeriodId)) { - mediaSourceEventDispatcher = - createEventDispatcher(windowIndex, mediaPeriodId, /* mediaTimeOffsetMs= */ 0); + mediaSourceEventDispatcher = createEventDispatcher(windowIndex, mediaPeriodId); } if (drmEventDispatcher.windowIndex != windowIndex || !Util.areEqual(drmEventDispatcher.mediaPeriodId, mediaPeriodId)) { diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSourceEventListener.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSourceEventListener.java index 624b79967e..5cb2ea15b1 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSourceEventListener.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSourceEventListener.java @@ -16,6 +16,7 @@ package androidx.media3.exoplayer.source; import static androidx.media3.common.util.Util.postOrRun; +import static androidx.media3.common.util.Util.usToMs; import android.os.Handler; import androidx.annotation.CheckResult; @@ -26,7 +27,6 @@ import androidx.media3.common.Format; import androidx.media3.common.Player; import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; -import androidx.media3.common.util.Util; import androidx.media3.exoplayer.source.MediaSource.MediaPeriodId; import java.io.IOException; import java.util.concurrent.CopyOnWriteArrayList; @@ -152,26 +152,22 @@ public interface MediaSourceEventListener { @Nullable public final MediaPeriodId mediaPeriodId; private final CopyOnWriteArrayList listenerAndHandlers; - private final long mediaTimeOffsetMs; /** Creates an event dispatcher. */ public EventDispatcher() { this( /* listenerAndHandlers= */ new CopyOnWriteArrayList<>(), /* windowIndex= */ 0, - /* mediaPeriodId= */ null, - /* mediaTimeOffsetMs= */ 0); + /* mediaPeriodId= */ null); } private EventDispatcher( CopyOnWriteArrayList listenerAndHandlers, int windowIndex, - @Nullable MediaPeriodId mediaPeriodId, - long mediaTimeOffsetMs) { + @Nullable MediaPeriodId mediaPeriodId) { this.listenerAndHandlers = listenerAndHandlers; this.windowIndex = windowIndex; this.mediaPeriodId = mediaPeriodId; - this.mediaTimeOffsetMs = mediaTimeOffsetMs; } /** @@ -180,14 +176,24 @@ public interface MediaSourceEventListener { * * @param windowIndex The timeline window index to be reported with the events. * @param mediaPeriodId The {@link MediaPeriodId} to be reported with the events. - * @param mediaTimeOffsetMs The offset to be added to all media times, in milliseconds. * @return A view of the event dispatcher with the pre-configured parameters. */ @CheckResult + public EventDispatcher withParameters(int windowIndex, @Nullable MediaPeriodId mediaPeriodId) { + return new EventDispatcher(listenerAndHandlers, windowIndex, mediaPeriodId); + } + + /** + * Note: The {@code mediaTimeOffsetMs} passed to this method is ignored and not added to media + * times in any way. + * + * @deprecated Use {@link #withParameters(int, MediaPeriodId)} instead. + */ + @Deprecated + @CheckResult public EventDispatcher withParameters( int windowIndex, @Nullable MediaPeriodId mediaPeriodId, long mediaTimeOffsetMs) { - return new EventDispatcher( - listenerAndHandlers, windowIndex, mediaPeriodId, mediaTimeOffsetMs); + return new EventDispatcher(listenerAndHandlers, windowIndex, mediaPeriodId); } /** @@ -246,8 +252,8 @@ public interface MediaSourceEventListener { trackFormat, trackSelectionReason, trackSelectionData, - adjustMediaTime(mediaStartTimeUs), - adjustMediaTime(mediaEndTimeUs))); + usToMs(mediaStartTimeUs), + usToMs(mediaEndTimeUs))); } /** Dispatches {@link #onLoadStarted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ @@ -291,8 +297,8 @@ public interface MediaSourceEventListener { trackFormat, trackSelectionReason, trackSelectionData, - adjustMediaTime(mediaStartTimeUs), - adjustMediaTime(mediaEndTimeUs))); + usToMs(mediaStartTimeUs), + usToMs(mediaEndTimeUs))); } /** Dispatches {@link #onLoadCompleted(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ @@ -337,8 +343,8 @@ public interface MediaSourceEventListener { trackFormat, trackSelectionReason, trackSelectionData, - adjustMediaTime(mediaStartTimeUs), - adjustMediaTime(mediaEndTimeUs))); + usToMs(mediaStartTimeUs), + usToMs(mediaEndTimeUs))); } /** Dispatches {@link #onLoadCanceled(int, MediaPeriodId, LoadEventInfo, MediaLoadData)}. */ @@ -397,8 +403,8 @@ public interface MediaSourceEventListener { trackFormat, trackSelectionReason, trackSelectionData, - adjustMediaTime(mediaStartTimeUs), - adjustMediaTime(mediaEndTimeUs)), + usToMs(mediaStartTimeUs), + usToMs(mediaEndTimeUs)), error, wasCanceled); } @@ -431,8 +437,8 @@ public interface MediaSourceEventListener { /* trackFormat= */ null, C.SELECTION_REASON_ADAPTIVE, /* trackSelectionData= */ null, - adjustMediaTime(mediaStartTimeUs), - adjustMediaTime(mediaEndTimeUs))); + usToMs(mediaStartTimeUs), + usToMs(mediaEndTimeUs))); } /** Dispatches {@link #onUpstreamDiscarded(int, MediaPeriodId, MediaLoadData)}. */ @@ -460,7 +466,7 @@ public interface MediaSourceEventListener { trackFormat, trackSelectionReason, trackSelectionData, - adjustMediaTime(mediaTimeUs), + usToMs(mediaTimeUs), /* mediaEndTimeMs= */ C.TIME_UNSET)); } @@ -474,11 +480,6 @@ public interface MediaSourceEventListener { } } - private long adjustMediaTime(long mediaTimeUs) { - long mediaTimeMs = Util.usToMs(mediaTimeUs); - return mediaTimeMs == C.TIME_UNSET ? C.TIME_UNSET : mediaTimeOffsetMs + mediaTimeMs; - } - private static final class ListenerAndHandler { public Handler handler; diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/offline/DownloadHelperTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/offline/DownloadHelperTest.java index 477763d395..8d49f4f7ab 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/offline/DownloadHelperTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/offline/DownloadHelperTest.java @@ -517,8 +517,7 @@ public class DownloadHelperTest { trackGroupArrays[periodIndex], allocator, TEST_TIMELINE.getWindow(0, new Timeline.Window()).positionInFirstPeriodUs, - new EventDispatcher() - .withParameters(/* windowIndex= */ 0, id, /* mediaTimeOffsetMs= */ 0)) { + new EventDispatcher().withParameters(/* windowIndex= */ 0, id)) { @Override public List getStreamKeys(List trackSelections) { List result = new ArrayList<>(); diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/MergingMediaPeriodTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/MergingMediaPeriodTest.java index 2ef9252c64..58e6e97f3c 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/MergingMediaPeriodTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/MergingMediaPeriodTest.java @@ -246,10 +246,7 @@ public final class MergingMediaPeriodTest { new FakeMediaPeriodWithSelectionParameters( new TrackGroupArray(trackGroups), new EventDispatcher() - .withParameters( - /* windowIndex= */ i, - new MediaPeriodId(/* periodUid= */ i), - /* mediaTimeOffsetMs= */ 0), + .withParameters(/* windowIndex= */ i, new MediaPeriodId(/* periodUid= */ i)), /* trackDataFactory= */ (unusedFormat, unusedMediaPeriodId) -> ImmutableList.of( oneByteSample(definition.singleSampleTimeUs, C.BUFFER_FLAG_KEY_FRAME), diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/ProgressiveMediaPeriodTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/ProgressiveMediaPeriodTest.java index a6931c3164..bd3836b4ad 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/ProgressiveMediaPeriodTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/source/ProgressiveMediaPeriodTest.java @@ -69,7 +69,7 @@ public final class ProgressiveMediaPeriodTest { .withParameters(/* windowIndex= */ 0, mediaPeriodId), new DefaultLoadErrorHandlingPolicy(), new MediaSourceEventListener.EventDispatcher() - .withParameters(/* windowIndex= */ 0, mediaPeriodId, /* mediaTimeOffsetMs= */ 0), + .withParameters(/* windowIndex= */ 0, mediaPeriodId), sourceInfoRefreshListener, new DefaultAllocator(/* trimOnReset= */ true, C.DEFAULT_BUFFER_SEGMENT_SIZE), /* customCacheKey= */ null, diff --git a/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java b/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java index 00a96572a8..0e8f472732 100644 --- a/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java +++ b/libraries/exoplayer_dash/src/main/java/androidx/media3/exoplayer/dash/DashMediaSource.java @@ -469,8 +469,7 @@ public final class DashMediaSource extends BaseMediaSource { @Override public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) { int periodIndex = (Integer) id.periodUid - firstPeriodId; - MediaSourceEventListener.EventDispatcher periodEventDispatcher = - createEventDispatcher(id, manifest.getPeriod(periodIndex).startMs); + MediaSourceEventListener.EventDispatcher periodEventDispatcher = createEventDispatcher(id); DrmSessionEventListener.EventDispatcher drmEventDispatcher = createDrmEventDispatcher(id); DashMediaPeriod mediaPeriod = new DashMediaPeriod( diff --git a/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DashMediaPeriodTest.java b/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DashMediaPeriodTest.java index e7c836c0dc..4b201c2467 100644 --- a/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DashMediaPeriodTest.java +++ b/libraries/exoplayer_dash/src/test/java/androidx/media3/exoplayer/dash/DashMediaPeriodTest.java @@ -216,7 +216,7 @@ public final class DashMediaPeriodTest { .withParameters(/* windowIndex= */ 0, mediaPeriodId), mock(LoadErrorHandlingPolicy.class), new MediaSourceEventListener.EventDispatcher() - .withParameters(/* windowIndex= */ 0, mediaPeriodId, /* mediaTimeOffsetMs= */ 0), + .withParameters(/* windowIndex= */ 0, mediaPeriodId), /* elapsedRealtimeOffsetMs= */ 0, mock(LoaderErrorThrower.class), mock(Allocator.class), diff --git a/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsMediaPeriodTest.java b/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsMediaPeriodTest.java index ed2afa8107..6bbf3799cf 100644 --- a/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsMediaPeriodTest.java +++ b/libraries/exoplayer_hls/src/test/java/androidx/media3/exoplayer/hls/HlsMediaPeriodTest.java @@ -89,7 +89,7 @@ public final class HlsMediaPeriodTest { .withParameters(/* windowIndex= */ 0, mediaPeriodId), mock(LoadErrorHandlingPolicy.class), new MediaSourceEventListener.EventDispatcher() - .withParameters(/* windowIndex= */ 0, mediaPeriodId, /* mediaTimeOffsetMs= */ 0), + .withParameters(/* windowIndex= */ 0, mediaPeriodId), mock(Allocator.class), mock(CompositeSequenceableLoaderFactory.class), /* allowChunklessPreparation= */ true, diff --git a/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/SsMediaPeriodTest.java b/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/SsMediaPeriodTest.java index 5b94223ca9..e4b8d355cd 100644 --- a/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/SsMediaPeriodTest.java +++ b/libraries/exoplayer_smoothstreaming/src/test/java/androidx/media3/exoplayer/smoothstreaming/SsMediaPeriodTest.java @@ -72,7 +72,7 @@ public class SsMediaPeriodTest { .withParameters(/* windowIndex= */ 0, mediaPeriodId), mock(LoadErrorHandlingPolicy.class), new MediaSourceEventListener.EventDispatcher() - .withParameters(/* windowIndex= */ 0, mediaPeriodId, /* mediaTimeOffsetMs= */ 0), + .withParameters(/* windowIndex= */ 0, mediaPeriodId), mock(LoaderErrorThrower.class), mock(Allocator.class)); }; diff --git a/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaSource.java b/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaSource.java index 8a9cc508a6..a5150ac58c 100644 --- a/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaSource.java +++ b/libraries/test_utils/src/main/java/androidx/media3/test/utils/FakeMediaSource.java @@ -239,7 +239,7 @@ public class FakeMediaSource extends BaseMediaSource { Assertions.checkArgument(periodIndex != C.INDEX_UNSET); Period period = timeline.getPeriod(periodIndex, new Period()); MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher = - createEventDispatcher(period.windowIndex, id, period.getPositionInWindowMs()); + createEventDispatcher(period.windowIndex, id); DrmSessionEventListener.EventDispatcher drmEventDispatcher = createDrmEventDispatcher(period.windowIndex, id); MediaPeriod mediaPeriod =