Commit 0085a7e7 by andrewlewis Committed by Oliver Woodman

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
parent 7cefb56e
......@@ -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) {
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment