use of com.google.android.exoplayer2.source.ads.AdPlaybackState in project ExoPlayer by google.
the class ServerSideAdInsertionMediaSourceTest method playbackWithAdditionalAdsInAdGroup_playsSuccessfulWithoutRendererResets.
@Test
public void playbackWithAdditionalAdsInAdGroup_playsSuccessfulWithoutRendererResets() throws Exception {
Context context = ApplicationProvider.getApplicationContext();
AtomicReference<Object> periodUid = new AtomicReference<>();
CapturingRenderersFactory renderersFactory = new CapturingRenderersFactory(context);
ExoPlayer player = new ExoPlayer.Builder(context, renderersFactory).setClock(new FakeClock(/* isAutoAdvancing= */
true)).build();
player.setVideoSurface(new Surface(new SurfaceTexture(/* texName= */
1)));
PlaybackOutput playbackOutput = PlaybackOutput.register(player, renderersFactory);
AdPlaybackState firstAdPlaybackState = addAdGroupToAdPlaybackState(new AdPlaybackState(/* adsId= */
new Object()), /* fromPositionUs= */
0, /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
500_000);
AtomicReference<ServerSideAdInsertionMediaSource> mediaSourceRef = new AtomicReference<>();
mediaSourceRef.set(new ServerSideAdInsertionMediaSource(new DefaultMediaSourceFactory(context).createMediaSource(MediaItem.fromUri(TEST_ASSET)), /* adPlaybackStateUpdater= */
contentTimeline -> {
if (periodUid.get() == null) {
periodUid.set(checkNotNull(contentTimeline.getPeriod(/* periodIndex= */
0, new Timeline.Period(), /* setIds= */
true).uid));
mediaSourceRef.get().setAdPlaybackStates(ImmutableMap.of(periodUid.get(), firstAdPlaybackState));
}
return true;
}));
AnalyticsListener listener = mock(AnalyticsListener.class);
player.addAnalyticsListener(listener);
player.setMediaSource(mediaSourceRef.get());
player.prepare();
// Wait until playback is ready with first ad and then replace by 3 ads.
runUntilPlaybackState(player, Player.STATE_READY);
AdPlaybackState secondAdPlaybackState = firstAdPlaybackState.withAdCount(/* adGroupIndex= */
0, /* adCount= */
3).withAdDurationsUs(/* adGroupIndex= */
0, /* adDurationsUs...= */
50_000, 250_000, 200_000);
mediaSourceRef.get().setAdPlaybackStates(ImmutableMap.of(periodUid.get(), secondAdPlaybackState));
runUntilPendingCommandsAreFullyHandled(player);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
// Assert all samples have been played.
DumpFileAsserts.assertOutput(context, playbackOutput, TEST_ASSET_DUMP);
// Assert playback has been reported with ads: [ad0][ad1][ad2][content]
// 4*2(audio+video) format changes, 3 discontinuities between parts.
verify(listener, times(3)).onPositionDiscontinuity(any(), any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
verify(listener, times(8)).onDownstreamFormatChanged(any(), any());
// Assert renderers played through without reset (=decoders have been enabled only once).
verify(listener).onVideoEnabled(any(), any());
verify(listener).onAudioEnabled(any(), any());
// Assert playback progression was smooth (=no unexpected delays that cause audio to underrun)
verify(listener, never()).onAudioUnderrun(any(), anyInt(), anyLong(), anyLong());
}
use of com.google.android.exoplayer2.source.ads.AdPlaybackState in project ExoPlayer by google.
the class ServerSideAdInsertionUtilTest method addAdGroupToAdPlaybackState_insertsCorrectAdGroupData.
@Test
public void addAdGroupToAdPlaybackState_insertsCorrectAdGroupData() {
AdPlaybackState state = new AdPlaybackState(ADS_ID, /* adGroupTimesUs...= */
0, 1, C.TIME_END_OF_SOURCE).withRemovedAdGroupCount(2);
// stream: 0-- content --4300-- ad1 --4500-- content
// content timeline: 0-4300 - [ad1] - 4700-end
state = addAdGroupToAdPlaybackState(state, /* fromPositionUs= */
4300, /* contentResumeOffsetUs= */
400, /* adDurationsUs...= */
200);
assertThat(state).isEqualTo(new AdPlaybackState(ADS_ID, /* adGroupTimesUs...= */
0, 0, 4300, C.TIME_END_OF_SOURCE).withRemovedAdGroupCount(2).withAdCount(/* adGroupIndex= */
2, /* adCount= */
1).withIsServerSideInserted(/* adGroupIndex= */
2, /* isServerSideInserted= */
true).withContentResumeOffsetUs(/* adGroupIndex= */
2, /* contentResumeOffsetUs= */
400).withAdDurationsUs(/* adGroupIndex= */
2, /* adDurationsUs...= */
200));
// stream: 0-- content --2100-- ad1 --2400-- content --4300-- ad2 --4500-- content
// content timeline: 0-2100 - [ad1] - 2100-4000 - [ad2] - 4400-end
state = addAdGroupToAdPlaybackState(state, /* fromPositionUs= */
2100, /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
300);
assertThat(state).isEqualTo(new AdPlaybackState(ADS_ID, /* adGroupTimesUs...= */
0, 0, 2100, 4000, C.TIME_END_OF_SOURCE).withRemovedAdGroupCount(2).withAdCount(/* adGroupIndex= */
2, /* adCount= */
1).withAdCount(/* adGroupIndex= */
3, /* adCount= */
1).withIsServerSideInserted(/* adGroupIndex= */
2, /* isServerSideInserted= */
true).withIsServerSideInserted(/* adGroupIndex= */
3, /* isServerSideInserted= */
true).withContentResumeOffsetUs(/* adGroupIndex= */
3, /* contentResumeOffsetUs= */
400).withAdDurationsUs(/* adGroupIndex= */
2, /* adDurationsUs...= */
300).withAdDurationsUs(/* adGroupIndex= */
3, /* adDurationsUs...= */
200));
// stream: 0-- ad1 --100-- content --2100-- ad2 --2400-- content --4300-- ad3 --4500-- content
// content timeline: 0 - [ad1] - 50-2050 -[ad2] - 2050-3950 - [ad3] - 4350-end
state = addAdGroupToAdPlaybackState(state, /* fromPositionUs= */
0, /* contentResumeOffsetUs= */
50, /* adDurationsUs...= */
100);
assertThat(state).isEqualTo(new AdPlaybackState(ADS_ID, /* adGroupTimesUs...= */
0, 0, 0, 2050, 3950, C.TIME_END_OF_SOURCE).withRemovedAdGroupCount(2).withAdCount(/* adGroupIndex= */
2, /* adCount= */
1).withAdCount(/* adGroupIndex= */
3, /* adCount= */
1).withAdCount(/* adGroupIndex= */
4, /* adCount= */
1).withIsServerSideInserted(/* adGroupIndex= */
2, /* isServerSideInserted= */
true).withIsServerSideInserted(/* adGroupIndex= */
3, /* isServerSideInserted= */
true).withIsServerSideInserted(/* adGroupIndex= */
4, /* isServerSideInserted= */
true).withContentResumeOffsetUs(/* adGroupIndex= */
2, /* contentResumeOffsetUs= */
50).withContentResumeOffsetUs(/* adGroupIndex= */
4, /* contentResumeOffsetUs= */
400).withAdDurationsUs(/* adGroupIndex= */
2, /* adDurationsUs...= */
100).withAdDurationsUs(/* adGroupIndex= */
3, /* adDurationsUs...= */
300).withAdDurationsUs(/* adGroupIndex= */
4, /* adDurationsUs...= */
200));
// stream: 0-- ad1 --100-- c --2100-- ad2 --2400-- c --4300-- ad3 --4500-- c --5000-- ad4 --6000
// content timeline: 0 - [ad1] - 50-2050 -[ad2] - 2050-3950 - [ad3] - 4350-4850 - [ad4] - 4850
state = addAdGroupToAdPlaybackState(state, /* fromPositionUs= */
5000, /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
1000);
assertThat(state).isEqualTo(new AdPlaybackState(ADS_ID, /* adGroupTimesUs...= */
0, 0, 0, 2050, 3950, 4850, C.TIME_END_OF_SOURCE).withRemovedAdGroupCount(2).withAdCount(/* adGroupIndex= */
2, /* adCount= */
1).withAdCount(/* adGroupIndex= */
3, /* adCount= */
1).withAdCount(/* adGroupIndex= */
4, /* adCount= */
1).withAdCount(/* adGroupIndex= */
5, /* adCount= */
1).withIsServerSideInserted(/* adGroupIndex= */
2, /* isServerSideInserted= */
true).withIsServerSideInserted(/* adGroupIndex= */
3, /* isServerSideInserted= */
true).withIsServerSideInserted(/* adGroupIndex= */
4, /* isServerSideInserted= */
true).withIsServerSideInserted(/* adGroupIndex= */
5, /* isServerSideInserted= */
true).withContentResumeOffsetUs(/* adGroupIndex= */
2, /* contentResumeOffsetUs= */
50).withContentResumeOffsetUs(/* adGroupIndex= */
4, /* contentResumeOffsetUs= */
400).withAdDurationsUs(/* adGroupIndex= */
2, /* adDurationsUs...= */
100).withAdDurationsUs(/* adGroupIndex= */
3, /* adDurationsUs...= */
300).withAdDurationsUs(/* adGroupIndex= */
4, /* adDurationsUs...= */
200).withAdDurationsUs(/* adGroupIndex= */
5, /* adDurationsUs...= */
1000));
}
use of com.google.android.exoplayer2.source.ads.AdPlaybackState in project ExoPlayer by google.
the class ServerSideAdInsertionUtilTest method addAdGroupToAdPlaybackState_emptyLeadingAds_markedAsSkipped.
@Test
public void addAdGroupToAdPlaybackState_emptyLeadingAds_markedAsSkipped() {
AdPlaybackState state = new AdPlaybackState(ADS_ID);
state = addAdGroupToAdPlaybackState(state, /* fromPositionUs= */
0, /* contentResumeOffsetUs= */
50_000, /* adDurationsUs...= */
0, 0, 10_000, 40_000, 0);
AdPlaybackState.AdGroup adGroup = state.getAdGroup(/* adGroupIndex= */
0);
assertThat(adGroup.durationsUs[0]).isEqualTo(0);
assertThat(adGroup.states[0]).isEqualTo(AdPlaybackState.AD_STATE_SKIPPED);
assertThat(adGroup.durationsUs[1]).isEqualTo(0);
assertThat(adGroup.states[1]).isEqualTo(AdPlaybackState.AD_STATE_SKIPPED);
assertThat(adGroup.durationsUs[2]).isEqualTo(10_000);
assertThat(adGroup.states[2]).isEqualTo(AdPlaybackState.AD_STATE_UNAVAILABLE);
assertThat(adGroup.durationsUs[4]).isEqualTo(0);
assertThat(adGroup.states[4]).isEqualTo(AdPlaybackState.AD_STATE_UNAVAILABLE);
assertThat(stream(adGroup.durationsUs).sum()).isEqualTo(50_000);
}
use of com.google.android.exoplayer2.source.ads.AdPlaybackState in project ExoPlayer by google.
the class ServerSideAdInsertionUtilTest method getMediaPeriodPositionUsForContent_returnsCorrectPositions.
@Test
public void getMediaPeriodPositionUsForContent_returnsCorrectPositions() {
// stream: 0-- ad1 --200-- content --2100-- ad2 --2300-- content --4300-- ad3 --4500-- content
// content timeline: 0 - [ad1] - 100-2000 -[ad2] - 2000-4000 - [ad3] - 4400-end
AdPlaybackState state = new AdPlaybackState(ADS_ID, /* adGroupTimesUs...= */
0, 0, 0, 2000, 4000).withRemovedAdGroupCount(2).withAdCount(/* adGroupIndex= */
2, /* adCount= */
2).withAdCount(/* adGroupIndex= */
3, /* adCount= */
1).withAdCount(/* adGroupIndex= */
4, /* adCount= */
3).withContentResumeOffsetUs(/* adGroupIndex= */
2, /* contentResumeOffsetUs= */
100).withContentResumeOffsetUs(/* adGroupIndex= */
3, /* contentResumeOffsetUs= */
0).withContentResumeOffsetUs(/* adGroupIndex= */
4, /* contentResumeOffsetUs= */
400).withAdDurationsUs(/* adGroupIndex= */
2, /* adDurationsUs...= */
150, 50).withAdDurationsUs(/* adGroupIndex= */
3, /* adDurationsUs...= */
200).withAdDurationsUs(/* adGroupIndex= */
4, /* adDurationsUs...= */
50, 50, 100);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
0, /* nextAdGroupIndex= */
2, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
0, /* nextAdGroupIndex= */
3, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
0, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
100, /* nextAdGroupIndex= */
2, state)).isEqualTo(100);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
100, /* nextAdGroupIndex= */
3, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
100, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
200, /* nextAdGroupIndex= */
3, state)).isEqualTo(100);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
200, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(100);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2099, /* nextAdGroupIndex= */
3, state)).isEqualTo(1999);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2099, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(1999);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2100, /* nextAdGroupIndex= */
3, state)).isEqualTo(2000);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2100, /* nextAdGroupIndex= */
4, state)).isEqualTo(2000);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2100, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(2000);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2300, /* nextAdGroupIndex= */
3, state)).isEqualTo(2200);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2300, /* nextAdGroupIndex= */
4, state)).isEqualTo(2000);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
2300, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(2000);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
4299, /* nextAdGroupIndex= */
4, state)).isEqualTo(3999);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
4299, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(3999);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
4300, /* nextAdGroupIndex= */
4, state)).isEqualTo(4000);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
4300, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(4200);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
4500, /* nextAdGroupIndex= */
4, state)).isEqualTo(4200);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
4500, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(4400);
assertThat(getMediaPeriodPositionUsForContent(/* positionUs= */
4700, /* nextAdGroupIndex= */
C.INDEX_UNSET, state)).isEqualTo(4600);
}
use of com.google.android.exoplayer2.source.ads.AdPlaybackState in project ExoPlayer by google.
the class ServerSideAdInsertionUtilTest method getMediaPeriodPositionUsForAd_returnsCorrectPositions.
@Test
public void getMediaPeriodPositionUsForAd_returnsCorrectPositions() {
// stream: 0-- ad1 --200-- content --2100-- ad2 --2300-- content --4300-- ad3 --4500-- content
// content timeline: 0 - [ad1] - 100-2000 -[ad2] - 2000-4000 - [ad3] - 4400-end
AdPlaybackState state = new AdPlaybackState(ADS_ID, /* adGroupTimesUs...= */
0, 0, 0, 2000, 4000).withRemovedAdGroupCount(2).withAdCount(/* adGroupIndex= */
2, /* adCount= */
2).withAdCount(/* adGroupIndex= */
3, /* adCount= */
1).withAdCount(/* adGroupIndex= */
4, /* adCount= */
3).withContentResumeOffsetUs(/* adGroupIndex= */
2, /* contentResumeOffsetUs= */
100).withContentResumeOffsetUs(/* adGroupIndex= */
3, /* contentResumeOffsetUs= */
0).withContentResumeOffsetUs(/* adGroupIndex= */
4, /* contentResumeOffsetUs= */
400).withAdDurationsUs(/* adGroupIndex= */
2, /* adDurationsUs...= */
150, 50).withAdDurationsUs(/* adGroupIndex= */
3, /* adDurationsUs...= */
200).withAdDurationsUs(/* adGroupIndex= */
4, /* adDurationsUs...= */
50, 50, 100);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
0, /* adGroupIndex= */
2, /* adIndexInAdGroup= */
0, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
100, /* adGroupIndex= */
2, /* adIndexInAdGroup= */
0, state)).isEqualTo(100);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
100, /* adGroupIndex= */
2, /* adIndexInAdGroup= */
1, state)).isEqualTo(-50);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
200, /* adGroupIndex= */
2, /* adIndexInAdGroup= */
0, state)).isEqualTo(200);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
200, /* adGroupIndex= */
2, /* adIndexInAdGroup= */
1, state)).isEqualTo(50);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
300, /* adGroupIndex= */
2, /* adIndexInAdGroup= */
1, state)).isEqualTo(150);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
2000, /* adGroupIndex= */
3, /* adIndexInAdGroup= */
0, state)).isEqualTo(-100);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
2100, /* adGroupIndex= */
3, /* adIndexInAdGroup= */
0, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
2300, /* adGroupIndex= */
3, /* adIndexInAdGroup= */
0, state)).isEqualTo(200);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4300, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
0, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4300, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
1, state)).isEqualTo(-50);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4300, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
2, state)).isEqualTo(-100);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4400, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
0, state)).isEqualTo(100);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4400, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
1, state)).isEqualTo(50);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4400, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
2, state)).isEqualTo(0);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4500, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
1, state)).isEqualTo(150);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4500, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
2, state)).isEqualTo(100);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4700, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
1, state)).isEqualTo(350);
assertThat(getMediaPeriodPositionUsForAd(/* positionUs= */
4700, /* adGroupIndex= */
4, /* adIndexInAdGroup= */
2, state)).isEqualTo(300);
}
Aggregations