From 6f5206cd76533fbe66a12e84ac153f5248725e22 Mon Sep 17 00:00:00 2001 From: bachinger Date: Sun, 27 Feb 2022 15:18:03 +0000 Subject: [PATCH] Drop ads for which we don't have metadata when joining a live stream When a live stream is joined while ads are already playing, the LOADED event is missed and we don't have ad information for those ads in the ad group that are before the ad index at which we joined. This way we can clip the duration when we receive the LOADED event for the last ad in the group. This fixes the problem of the playback controls being hidden when content resumes after the ad group. #minor-release PiperOrigin-RevId: 431269627 (cherry picked from commit 8e8c59031c328e4c64a16193732078568712a632) --- .../ImaServerSideAdInsertionMediaSource.java | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java index 87499ea227..5f7dabeff1 100644 --- a/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java +++ b/libraries/exoplayer_ima/src/main/java/androidx/media3/exoplayer/ima/ImaServerSideAdInsertionMediaSource.java @@ -105,11 +105,7 @@ import java.util.Map; import org.checkerframework.checker.nullness.qual.EnsuresNonNull; import org.checkerframework.checker.nullness.qual.MonotonicNonNull; -/** - * MediaSource for IMA server side inserted ad streams. - * - *

TODO(bachinger) add code snippet from PlayerActivity - */ +/** MediaSource for IMA server side inserted ad streams. */ @UnstableApi public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSource { @@ -119,8 +115,6 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou * *

Apps can use the {@link ImaServerSideAdInsertionMediaSource.Factory} to customized the * {@link DefaultMediaSourceFactory} that is used to build a player: - * - *

TODO(bachinger) add code snippet from PlayerActivity */ public static final class Factory implements MediaSource.Factory { @@ -461,6 +455,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou @Nullable private IOException loadError; private @MonotonicNonNull Timeline contentTimeline; private AdPlaybackState adPlaybackState; + private int firstSeenAdIndexInAdGroup; private ImaServerSideAdInsertionMediaSource( MediaItem mediaItem, @@ -698,18 +693,21 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou return adPlaybackState; } - private static AdPlaybackState addLiveAdBreak( + private AdPlaybackState addLiveAdBreak( Ad ad, long currentPeriodPositionUs, AdPlaybackState adPlaybackState) { AdPodInfo adPodInfo = ad.getAdPodInfo(); long adDurationUs = secToUs(ad.getDuration()); int adIndexInAdGroup = adPodInfo.getAdPosition() - 1; - // TODO(b/208398934) Support seeking backwards. if (adIndexInAdGroup == 0 || adPlaybackState.adGroupCount == 1) { + firstSeenAdIndexInAdGroup = adIndexInAdGroup; + // Adjust count and ad index in case we joined the live stream within an ad group. + int adCount = adPodInfo.getTotalAds() - firstSeenAdIndexInAdGroup; + adIndexInAdGroup -= firstSeenAdIndexInAdGroup; // First ad of group. Create a new group with all ads. long[] adDurationsUs = updateAdDurationAndPropagate( - new long[adPodInfo.getTotalAds()], + new long[adCount], adIndexInAdGroup, adDurationUs, secToUs(adPodInfo.getMaxDuration())); @@ -721,6 +719,11 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou /* adDurationsUs...= */ adDurationsUs); } else { int adGroupIndex = adPlaybackState.adGroupCount - 2; + adIndexInAdGroup -= firstSeenAdIndexInAdGroup; + if (adPodInfo.getTotalAds() == adPodInfo.getAdPosition()) { + // Reset the ad index whe we are at the last ad in the group. + firstSeenAdIndexInAdGroup = 0; + } adPlaybackState = updateAdDurationInAdGroup(adGroupIndex, adIndexInAdGroup, adDurationUs, adPlaybackState); AdPlaybackState.AdGroup adGroup = adPlaybackState.getAdGroup(adGroupIndex); @@ -857,7 +860,7 @@ public final class ImaServerSideAdInsertionMediaSource extends CompositeMediaSou long positionInWindowUs = timeline.getPeriod(player.getCurrentPeriodIndex(), new Timeline.Period()) .positionInWindowUs; - long currentPeriodPosition = msToUs(player.getCurrentPosition()) - positionInWindowUs; + long currentPeriodPosition = msToUs(player.getContentPosition()) - positionInWindowUs; newAdPlaybackState = addLiveAdBreak( event.getAd(),