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 71bc048902..3be28e1b84 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 @@ -40,6 +40,7 @@ import com.google.ads.interactivemedia.v3.api.AdsRequest; import com.google.ads.interactivemedia.v3.api.CompanionAdSlot; import com.google.ads.interactivemedia.v3.api.ImaSdkFactory; import com.google.ads.interactivemedia.v3.api.ImaSdkSettings; +import com.google.ads.interactivemedia.v3.api.UiElement; import com.google.ads.interactivemedia.v3.api.player.ContentProgressProvider; import com.google.ads.interactivemedia.v3.api.player.VideoAdPlayer; import com.google.ads.interactivemedia.v3.api.player.VideoProgressUpdate; @@ -67,8 +68,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** Loads ads using the IMA SDK. All methods are called on the main thread. */ public final class ImaAdsLoader @@ -91,8 +94,10 @@ public final class ImaAdsLoader private @Nullable ImaSdkSettings imaSdkSettings; private @Nullable AdEventListener adEventListener; + private @Nullable Set adUiElements; private int vastLoadTimeoutMs; private int mediaLoadTimeoutMs; + private int mediaBitrate; private boolean focusSkipButtonWhenAvailable; private ImaFactory imaFactory; @@ -105,6 +110,7 @@ public final class ImaAdsLoader this.context = Assertions.checkNotNull(context); vastLoadTimeoutMs = TIMEOUT_UNSET; mediaLoadTimeoutMs = TIMEOUT_UNSET; + mediaBitrate = BITRATE_UNSET; focusSkipButtonWhenAvailable = true; imaFactory = new DefaultImaFactory(); } @@ -135,6 +141,18 @@ public final class ImaAdsLoader return this; } + /** + * Sets the ad UI elements to be rendered by the IMA SDK. + * + * @param adUiElements The ad UI elements to be rendered by the IMA SDK. + * @return This builder, for convenience. + * @see AdsRenderingSettings#setUiElements(Set) + */ + public Builder setAdUiElements(Set adUiElements) { + this.adUiElements = new HashSet<>(Assertions.checkNotNull(adUiElements)); + return this; + } + /** * Sets the VAST load timeout, in milliseconds. * @@ -143,7 +161,7 @@ public final class ImaAdsLoader * @see AdsRequest#setVastLoadTimeout(float) */ public Builder setVastLoadTimeoutMs(int vastLoadTimeoutMs) { - Assertions.checkArgument(vastLoadTimeoutMs >= 0); + Assertions.checkArgument(vastLoadTimeoutMs > 0); this.vastLoadTimeoutMs = vastLoadTimeoutMs; return this; } @@ -156,11 +174,24 @@ public final class ImaAdsLoader * @see AdsRenderingSettings#setLoadVideoTimeout(int) */ public Builder setMediaLoadTimeoutMs(int mediaLoadTimeoutMs) { - Assertions.checkArgument(mediaLoadTimeoutMs >= 0); + Assertions.checkArgument(mediaLoadTimeoutMs > 0); this.mediaLoadTimeoutMs = mediaLoadTimeoutMs; return this; } + /** + * Sets the media maximum recommended bitrate for ads, in bps. + * + * @param bitrate The media maximum recommended bitrate for ads, in bps. + * @return This builder, for convenience. + * @see AdsRenderingSettings#setBitrateKbps(int) + */ + public Builder setMaxMediaBitrate(int bitrate) { + Assertions.checkArgument(bitrate > 0); + this.mediaBitrate = bitrate; + return this; + } + /** * Sets whether to focus the skip button (when available) on Android TV devices. The default * setting is {@code true}. @@ -197,7 +228,9 @@ public final class ImaAdsLoader null, vastLoadTimeoutMs, mediaLoadTimeoutMs, + mediaBitrate, focusSkipButtonWhenAvailable, + adUiElements, adEventListener, imaFactory); } @@ -217,7 +250,9 @@ public final class ImaAdsLoader adsResponse, vastLoadTimeoutMs, mediaLoadTimeoutMs, + mediaBitrate, focusSkipButtonWhenAvailable, + adUiElements, adEventListener, imaFactory); } @@ -247,6 +282,7 @@ public final class ImaAdsLoader private static final long MAXIMUM_PRELOAD_DURATION_MS = 8000; private static final int TIMEOUT_UNSET = -1; + private static final int BITRATE_UNSET = -1; /** The state of ad playback. */ @Documented @@ -271,6 +307,8 @@ public final class ImaAdsLoader private final int vastLoadTimeoutMs; private final int mediaLoadTimeoutMs; private final boolean focusSkipButtonWhenAvailable; + private final int mediaBitrate; + private final @Nullable Set adUiElements; private final @Nullable AdEventListener adEventListener; private final ImaFactory imaFactory; private final Timeline.Period period; @@ -357,7 +395,9 @@ public final class ImaAdsLoader /* adsResponse= */ null, /* vastLoadTimeoutMs= */ TIMEOUT_UNSET, /* mediaLoadTimeoutMs= */ TIMEOUT_UNSET, + /* mediaBitrate= */ BITRATE_UNSET, /* focusSkipButtonWhenAvailable= */ true, + /* adUiElements= */ null, /* adEventListener= */ null, /* imaFactory= */ new DefaultImaFactory()); } @@ -382,7 +422,9 @@ public final class ImaAdsLoader /* adsResponse= */ null, /* vastLoadTimeoutMs= */ TIMEOUT_UNSET, /* mediaLoadTimeoutMs= */ TIMEOUT_UNSET, + /* mediaBitrate= */ BITRATE_UNSET, /* focusSkipButtonWhenAvailable= */ true, + /* adUiElements= */ null, /* adEventListener= */ null, /* imaFactory= */ new DefaultImaFactory()); } @@ -394,7 +436,9 @@ public final class ImaAdsLoader @Nullable String adsResponse, int vastLoadTimeoutMs, int mediaLoadTimeoutMs, + int mediaBitrate, boolean focusSkipButtonWhenAvailable, + @Nullable Set adUiElements, @Nullable AdEventListener adEventListener, ImaFactory imaFactory) { Assertions.checkArgument(adTagUri != null || adsResponse != null); @@ -402,7 +446,9 @@ public final class ImaAdsLoader this.adsResponse = adsResponse; this.vastLoadTimeoutMs = vastLoadTimeoutMs; this.mediaLoadTimeoutMs = mediaLoadTimeoutMs; + this.mediaBitrate = mediaBitrate; this.focusSkipButtonWhenAvailable = focusSkipButtonWhenAvailable; + this.adUiElements = adUiElements; this.adEventListener = adEventListener; this.imaFactory = imaFactory; if (imaSdkSettings == null) { @@ -950,7 +996,13 @@ public final class ImaAdsLoader if (mediaLoadTimeoutMs != TIMEOUT_UNSET) { adsRenderingSettings.setLoadVideoTimeout(mediaLoadTimeoutMs); } + if (mediaBitrate != BITRATE_UNSET) { + adsRenderingSettings.setBitrateKbps(mediaBitrate / 1000); + } adsRenderingSettings.setFocusSkipButtonWhenAvailable(focusSkipButtonWhenAvailable); + if (adUiElements != null) { + adsRenderingSettings.setUiElements(adUiElements); + } // Set up the ad playback state, skipping ads based on the start position as required. long[] adGroupTimesUs = getAdGroupTimesUs(adsManager.getAdCuePoints());