Add a setting for enabling continuous playback

Issue: #3750
PiperOrigin-RevId: 346079830
This commit is contained in:
andrewlewis 2020-12-07 14:32:25 +00:00 committed by Ian Baker
parent dd782ef9b4
commit 6796c4d01c
5 changed files with 76 additions and 0 deletions

View file

@ -45,6 +45,8 @@
([#3750](https://github.com/google/ExoPlayer/issues/3750)).
* Fix a condition where playback can get stuck before an empty ad
([#8205](https://github.com/google/ExoPlayer/issues/8205)).
* Add `ImaAdsLoader.Builder.setEnableContinuousPlayback` for setting
whether to request ads for continuous playback.
* Metadata retriever:
* Parse Google Photos HEIC motion photos metadata.
* FFmpeg extension:

View file

@ -517,6 +517,9 @@ import java.util.Map;
}
pendingAdRequestContext = new Object();
request.setUserRequestContext(pendingAdRequestContext);
if (configuration.enableContinuousPlayback != null) {
request.setContinuousPlayback(configuration.enableContinuousPlayback);
}
if (configuration.vastLoadTimeoutMs != TIMEOUT_UNSET) {
request.setVastLoadTimeout(configuration.vastLoadTimeoutMs);
}

View file

@ -114,6 +114,7 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
@Nullable private List<String> adMediaMimeTypes;
@Nullable private Set<UiElement> adUiElements;
@Nullable private Collection<CompanionAdSlot> companionAdSlots;
@Nullable private Boolean enableContinuousPlayback;
private long adPreloadTimeoutMs;
private int vastLoadTimeoutMs;
private int mediaLoadTimeoutMs;
@ -235,6 +236,20 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
return this;
}
/**
* Sets whether to enable continuous playback. Pass {@code true} if content videos will be
* played continuously, similar to a TV broadcast. This setting may modify the ads request but
* does not affect ad playback behavior. The requested value is unknown by default.
*
* @param enableContinuousPlayback Whether to enable continuous playback.
* @return This builder, for convenience.
* @see AdsRequest#setContinuousPlayback(boolean)
*/
public Builder setEnableContinuousPlayback(boolean enableContinuousPlayback) {
this.enableContinuousPlayback = enableContinuousPlayback;
return this;
}
/**
* Sets the duration in milliseconds for which the player must buffer while preloading an ad
* group before that ad group is skipped and marked as having failed to load. Pass {@link
@ -354,6 +369,7 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
focusSkipButtonWhenAvailable,
playAdBeforeStartPosition,
mediaBitrate,
enableContinuousPlayback,
adMediaMimeTypes,
adUiElements,
companionAdSlots,

View file

@ -89,6 +89,7 @@ import java.util.Set;
public final boolean focusSkipButtonWhenAvailable;
public final boolean playAdBeforeStartPosition;
public final int mediaBitrate;
@Nullable public final Boolean enableContinuousPlayback;
@Nullable public final List<String> adMediaMimeTypes;
@Nullable public final Set<UiElement> adUiElements;
@Nullable public final Collection<CompanionAdSlot> companionAdSlots;
@ -105,6 +106,7 @@ import java.util.Set;
boolean focusSkipButtonWhenAvailable,
boolean playAdBeforeStartPosition,
int mediaBitrate,
@Nullable Boolean enableContinuousPlayback,
@Nullable List<String> adMediaMimeTypes,
@Nullable Set<UiElement> adUiElements,
@Nullable Collection<CompanionAdSlot> companionAdSlots,
@ -119,6 +121,7 @@ import java.util.Set;
this.focusSkipButtonWhenAvailable = focusSkipButtonWhenAvailable;
this.playAdBeforeStartPosition = playAdBeforeStartPosition;
this.mediaBitrate = mediaBitrate;
this.enableContinuousPlayback = enableContinuousPlayback;
this.adMediaMimeTypes = adMediaMimeTypes;
this.adUiElements = adUiElements;
this.companionAdSlots = companionAdSlots;

View file

@ -19,6 +19,7 @@ import static androidx.test.core.app.ApplicationProvider.getApplicationContext;
import static com.google.android.exoplayer2.ext.ima.ImaUtil.getAdGroupTimesUsForCuePoints;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyDouble;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doAnswer;
@ -1128,6 +1129,57 @@ public final class ImaAdsLoaderTest {
.isEqualTo(new AdPlaybackState(secondAdsId, /* adGroupTimesUs...= */ 0));
}
@Test
public void buildWithDefaultEnableContinuousPlayback_doesNotSetAdsRequestProperty() {
imaAdsLoader =
new ImaAdsLoader.Builder(getApplicationContext())
.setImaFactory(mockImaFactory)
.setImaSdkSettings(mockImaSdkSettings)
.build();
imaAdsLoader.setPlayer(fakePlayer);
adsMediaSource =
new AdsMediaSource(
new FakeMediaSource(CONTENT_TIMELINE),
TEST_DATA_SPEC,
TEST_ADS_ID,
new DefaultMediaSourceFactory((Context) getApplicationContext()),
imaAdsLoader,
adViewProvider);
when(mockAdsManager.getAdCuePoints()).thenReturn(PREROLL_CUE_POINTS_SECONDS);
imaAdsLoader.setSupportedContentTypes(C.TYPE_OTHER);
imaAdsLoader.start(
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
verify(mockAdsRequest, never()).setContinuousPlayback(anyBoolean());
}
@Test
public void buildWithEnableContinuousPlayback_setsAdsRequestProperty() {
imaAdsLoader =
new ImaAdsLoader.Builder(getApplicationContext())
.setEnableContinuousPlayback(true)
.setImaFactory(mockImaFactory)
.setImaSdkSettings(mockImaSdkSettings)
.build();
imaAdsLoader.setPlayer(fakePlayer);
adsMediaSource =
new AdsMediaSource(
new FakeMediaSource(CONTENT_TIMELINE),
TEST_DATA_SPEC,
TEST_ADS_ID,
new DefaultMediaSourceFactory((Context) getApplicationContext()),
imaAdsLoader,
adViewProvider);
when(mockAdsManager.getAdCuePoints()).thenReturn(PREROLL_CUE_POINTS_SECONDS);
imaAdsLoader.setSupportedContentTypes(C.TYPE_OTHER);
imaAdsLoader.start(
adsMediaSource, TEST_DATA_SPEC, TEST_ADS_ID, adViewProvider, adsLoaderListener);
verify(mockAdsRequest).setContinuousPlayback(true);
}
private void setupMocks() {
ArgumentCaptor<Object> userRequestContextCaptor = ArgumentCaptor.forClass(Object.class);
doNothing().when(mockAdsRequest).setUserRequestContext(userRequestContextCaptor.capture());