diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaPeriod.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaPeriod.java index 751ce3feea..1744873ab4 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaPeriod.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaPeriod.java @@ -26,6 +26,7 @@ import androidx.media3.common.util.Util; import androidx.media3.decoder.DecoderInputBuffer; import androidx.media3.exoplayer.FormatHolder; import androidx.media3.exoplayer.SeekParameters; +import androidx.media3.exoplayer.source.ClippingMediaSource.IllegalClippingException; import androidx.media3.exoplayer.trackselection.ExoTrackSelection; import java.io.IOException; import org.checkerframework.checker.nullness.compatqual.NullableType; @@ -45,6 +46,7 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb private long pendingInitialDiscontinuityPositionUs; /* package */ long startUs; /* package */ long endUs; + @Nullable private IllegalClippingException clippingError; /** * Creates a new clipping media period that provides a clipped view of the specified {@link @@ -81,6 +83,16 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb this.endUs = endUs; } + /** + * Sets a clipping error detected by the media source so that it can be thrown as a period error + * at the next opportunity. + * + * @param clippingError The clipping error. + */ + public void setClippingError(IllegalClippingException clippingError) { + this.clippingError = clippingError; + } + @Override public void prepare(MediaPeriod.Callback callback, long positionUs) { this.callback = callback; @@ -89,6 +101,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public void maybeThrowPrepareError() throws IOException { + if (clippingError != null) { + throw clippingError; + } mediaPeriod.maybeThrowPrepareError(); } @@ -221,6 +236,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public void onPrepared(MediaPeriod mediaPeriod) { + if (clippingError != null) { + return; + } Assertions.checkNotNull(callback).onPrepared(this); } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java index 405fa1fc59..b798b969d2 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/ClippingMediaSource.java @@ -278,6 +278,11 @@ public final class ClippingMediaSource extends CompositeMediaSource { clippingTimeline = new ClippingTimeline(timeline, windowStartUs, windowEndUs); } catch (IllegalClippingException e) { clippingError = e; + // The clipping error won't be propagated while we have existing MediaPeriods. Setting the + // error at the MediaPeriods ensures it will be thrown as soon as possible. + for (int i = 0; i < mediaPeriods.size(); i++) { + mediaPeriods.get(i).setClippingError(clippingError); + } return; } refreshSourceInfo(clippingTimeline);