diff --git a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java index 464bf497fe..10cc75de32 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaPeriod.java @@ -21,6 +21,7 @@ import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.FormatHolder; import com.google.android.exoplayer2.SeekParameters; import com.google.android.exoplayer2.decoder.DecoderInputBuffer; +import com.google.android.exoplayer2.source.ClippingMediaSource.IllegalClippingException; import com.google.android.exoplayer2.trackselection.ExoTrackSelection; import com.google.android.exoplayer2.util.Assertions; import com.google.android.exoplayer2.util.MimeTypes; @@ -42,6 +43,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 @@ -78,6 +80,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; @@ -86,6 +98,9 @@ public final class ClippingMediaPeriod implements MediaPeriod, MediaPeriod.Callb @Override public void maybeThrowPrepareError() throws IOException { + if (clippingError != null) { + throw clippingError; + } mediaPeriod.maybeThrowPrepareError(); } @@ -218,6 +233,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/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java index f86b81760d..ab62cca0c5 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/source/ClippingMediaSource.java @@ -276,6 +276,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);