diff --git a/RELEASENOTES.md b/RELEASENOTES.md index d8db5650070..62e985f98b5 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -47,6 +47,8 @@ ([#5807](https://github.com/google/ExoPlayer/pull/5807)). * TTML: Fix bitmap rendering ([#5633](https://github.com/google/ExoPlayer/pull/5633)). +* IMA: Fix ad pod index offset calculation without preroll + ([#5928](https://github.com/google/ExoPlayer/issues/5928)). * Add a `playWhenReady` flag to MediaSessionConnector.PlaybackPreparer methods to indicate whether a controller sent a play or only a prepare command. This allows to take advantage of decoder reuse with the MediaSessionConnector diff --git a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java index 1cdbac56b58..5a266c290dd 100644 --- a/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java +++ b/extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java @@ -1054,13 +1054,8 @@ private void startAdPlayback() { long contentPositionMs = player.getCurrentPosition(); int adGroupIndexForPosition = adPlaybackState.getAdGroupIndexForPositionUs(C.msToUs(contentPositionMs)); - if (adGroupIndexForPosition == 0) { - podIndexOffset = 0; - } else if (adGroupIndexForPosition == C.INDEX_UNSET) { - // There is no preroll and midroll pod indices start at 1. - podIndexOffset = -1; - } else /* adGroupIndexForPosition > 0 */ { - // Skip ad groups before the one at or immediately before the playback position. + if (adGroupIndexForPosition > 0 && adGroupIndexForPosition != C.INDEX_UNSET) { + // Skip any ad groups before the one at or immediately before the playback position. for (int i = 0; i < adGroupIndexForPosition; i++) { adPlaybackState = adPlaybackState.withSkippedAdGroup(i); } @@ -1070,9 +1065,18 @@ private void startAdPlayback() { long adGroupBeforeTimeUs = adGroupTimesUs[adGroupIndexForPosition - 1]; double midpointTimeUs = (adGroupForPositionTimeUs + adGroupBeforeTimeUs) / 2d; adsRenderingSettings.setPlayAdsAfterTime(midpointTimeUs / C.MICROS_PER_SECOND); + } - // We're removing one or more ads, which means that the earliest ad (if any) will be a - // midroll/postroll. Midroll pod indices start at 1. + // IMA indexes any remaining midroll ad pods from 1. A preroll (if present) has index 0. + // Store an index offset as we want to index all ads (including skipped ones) from 0. + if (adGroupIndexForPosition == 0 && adGroupTimesUs[0] == 0) { + // We are playing a preroll. + podIndexOffset = 0; + } else if (adGroupIndexForPosition == C.INDEX_UNSET) { + // There's no ad to play which means there's no preroll. + podIndexOffset = -1; + } else { + // We are playing a midroll and any ads before it were skipped. podIndexOffset = adGroupIndexForPosition - 1; }