From 0085a7e761130b6a00d17546463e7e8c67fd0669 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Fri, 23 Aug 2019 16:16:07 +0100 Subject: [PATCH] Defer adsManager.init until the timeline has loaded If the app seeks after we get an ads manager but before the player exposes the timeline with ads, we would end up expecting to play a preroll even after the seek request arrived. This caused the player to get stuck. Wait until a non-empty timeline has been exposed via onTimelineChanged before initializing IMA (at which point it can start polling the player position). Seek requests are not handled while an ad is playing. PiperOrigin-RevId: 265058325 --- .../exoplayer2/ext/ima/ImaAdsLoader.java | 20 +++++++++++-------- .../exoplayer2/ext/ima/ImaAdsLoaderTest.java | 3 ++- 2 files changed, 14 insertions(+), 9 deletions(-) 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 f5ec9f120d..335f8374dd 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 @@ -338,6 +338,7 @@ public final class ImaAdsLoader private int lastVolumePercentage; private AdsManager adsManager; + private boolean initializedAdsManager; private AdLoadException pendingAdLoadError; private Timeline timeline; private long contentDurationMs; @@ -613,8 +614,8 @@ public final class ImaAdsLoader adsManager.resume(); } } else if (adsManager != null) { - // Ads have loaded but the ads manager is not initialized. - startAdPlayback(); + adPlaybackState = new AdPlaybackState(getAdGroupTimesUs(adsManager.getAdCuePoints())); + updateAdPlaybackState(); } else { // Ads haven't loaded yet, so request them. requestAds(adViewGroup); @@ -688,7 +689,8 @@ public final class ImaAdsLoader if (player != null) { // If a player is attached already, start playback immediately. try { - startAdPlayback(); + adPlaybackState = new AdPlaybackState(getAdGroupTimesUs(adsManager.getAdCuePoints())); + updateAdPlaybackState(); } catch (Exception e) { maybeNotifyInternalError("onAdsManagerLoaded", e); } @@ -968,6 +970,10 @@ public final class ImaAdsLoader if (contentDurationUs != C.TIME_UNSET) { adPlaybackState = adPlaybackState.withContentDurationUs(contentDurationUs); } + if (!initializedAdsManager && adsManager != null) { + initializedAdsManager = true; + initializeAdsManager(); + } onPositionDiscontinuity(Player.DISCONTINUITY_REASON_INTERNAL); } @@ -1041,7 +1047,7 @@ public final class ImaAdsLoader // Internal methods. - private void startAdPlayback() { + private void initializeAdsManager() { AdsRenderingSettings adsRenderingSettings = imaFactory.createAdsRenderingSettings(); adsRenderingSettings.setEnablePreloading(ENABLE_PRELOADING); adsRenderingSettings.setMimeTypes(supportedMimeTypes); @@ -1056,10 +1062,9 @@ public final class ImaAdsLoader adsRenderingSettings.setUiElements(adUiElements); } - // Set up the ad playback state, skipping ads based on the start position as required. + // Skip ads based on the start position as required. long[] adGroupTimesUs = getAdGroupTimesUs(adsManager.getAdCuePoints()); - adPlaybackState = new AdPlaybackState(adGroupTimesUs); - long contentPositionMs = player.getCurrentPosition(); + long contentPositionMs = player.getContentPosition(); int adGroupIndexForPosition = adPlaybackState.getAdGroupIndexForPositionUs(C.msToUs(contentPositionMs)); if (adGroupIndexForPosition > 0 && adGroupIndexForPosition != C.INDEX_UNSET) { @@ -1093,7 +1098,6 @@ public final class ImaAdsLoader pendingContentPositionMs = contentPositionMs; } - // Start ad playback. adsManager.init(adsRenderingSettings); updateAdPlaybackState(); if (DEBUG) { diff --git a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java index 1e1935c63a..4b2020a7d5 100644 --- a/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java +++ b/extensions/ima/src/test/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoaderTest.java @@ -143,7 +143,8 @@ public class ImaAdsLoaderTest { assertThat(adsLoaderListener.adPlaybackState) .isEqualTo( new AdPlaybackState(/* adGroupTimesUs= */ 0) - .withAdDurationsUs(PREROLL_ADS_DURATIONS_US)); + .withAdDurationsUs(PREROLL_ADS_DURATIONS_US) + .withContentDurationUs(CONTENT_DURATION_US)); } @Test