diff --git a/RELEASENOTES.md b/RELEASENOTES.md index cb6dbe6f28..8c72f05c24 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -25,6 +25,8 @@ getters. * Deprecate `HttpDataSource.Factory.getDefaultRequestProperties` and add `HttpDataSource.Factory.setDefaultRequestProperties` instead. + * Fix playback issues after seeking during an ad + ([#8349](https://github.com/google/ExoPlayer/issues/8349)) * Track selection: * Add option to specify multiple preferred audio or text languages. * Forward `Timeline` and `MediaPeriodId` to `TrackSelection.Factory`. diff --git a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java index 9e5a8b2409..109faff7f2 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerImpl.java @@ -613,8 +613,10 @@ import java.util.concurrent.TimeoutException; // general because the midroll ad preceding the seek destination must be played before the // content position can be played, if a different ad is playing at the moment. Log.w(TAG, "seekTo ignored because an ad is playing"); - playbackInfoUpdateListener.onPlaybackInfoUpdate( - new ExoPlayerImplInternal.PlaybackInfoUpdate(playbackInfo)); + ExoPlayerImplInternal.PlaybackInfoUpdate playbackInfoUpdate = + new ExoPlayerImplInternal.PlaybackInfoUpdate(this.playbackInfo); + playbackInfoUpdate.incrementPendingOperationAcks(1); + playbackInfoUpdateListener.onPlaybackInfoUpdate(playbackInfoUpdate); return; } @Player.State diff --git a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java index add4783648..bb93811e10 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/ExoPlayerTest.java @@ -4490,6 +4490,42 @@ public final class ExoPlayerTest { assertThat(totalBufferedDurationMs[1]).isEqualTo(adDurationMs); } + // https://github.com/google/ExoPlayer/issues/8349 + @Test + public void seekTo_whilePlayingAd_doesntBlockFutureUpdates() throws Exception { + long contentDurationMs = 10_000; + long adDurationMs = 4_000; + AdPlaybackState adPlaybackState = + new AdPlaybackState(/* adsId= */ new Object(), /* adGroupTimesUs...= */ 0) + .withAdCount(/* adGroupIndex= */ 0, /* adCount= */ 1) + .withAdUri(/* adGroupIndex= */ 0, /* adIndexInAdGroup= */ 0, Uri.EMPTY); + long[][] durationsUs = new long[1][]; + durationsUs[0] = new long[] {C.msToUs(adDurationMs)}; + adPlaybackState = adPlaybackState.withAdDurationsUs(durationsUs); + Timeline adTimeline = + new FakeTimeline( + new TimelineWindowDefinition( + /* periodCount= */ 1, + /* id= */ 0, + /* isSeekable= */ true, + /* isDynamic= */ false, + /* durationUs= */ C.msToUs(contentDurationMs), + adPlaybackState)); + FakeMediaSource adsMediaSource = new FakeMediaSource(adTimeline); + + SimpleExoPlayer player = new TestExoPlayerBuilder(context).build(); + player.setMediaSource(adsMediaSource); + player.pause(); + player.prepare(); + runUntilPlaybackState(player, Player.STATE_READY); + + player.seekTo(0, 8000); + player.play(); + + // This times out if playback info updates after the seek are blocked. + runUntilPlaybackState(player, Player.STATE_ENDED); + } + @Test public void becomingNoisyIgnoredIfBecomingNoisyHandlingIsDisabled() throws Exception { CountDownLatch becomingNoisyHandlingDisabled = new CountDownLatch(1);