use of com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_beyondSSAIMidRolls_seekAdjustedAndRequestedContentPositionKept.
@Test
public void seekTo_beyondSSAIMidRolls_seekAdjustedAndRequestedContentPositionKept() throws Exception {
ArgumentCaptor<PositionInfo> oldPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<Integer> reasonArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
FakeTimeline adTimeline = FakeTimeline.createMultiPeriodAdTimeline("windowId", /* numberOfPlayedAds= */
0, /* isAdPeriodFlags...= */
false, true, true, false);
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.pause();
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
player.seekTo(/* positionMs= */
4000);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
verify(listener, times(6)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(1, 2, 0, 0, 0, 0).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// seek discontinuities
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).periodIndex).isEqualTo(3);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).positionMs).isEqualTo(4000);
// seek adjustment
assertThat(oldPositions.get(1).periodIndex).isEqualTo(3);
assertThat(oldPositions.get(1).adGroupIndex).isEqualTo(-1);
assertThat(oldPositions.get(1).positionMs).isEqualTo(4000);
assertThat(newPositions.get(1).periodIndex).isEqualTo(1);
assertThat(newPositions.get(1).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(1).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(1).positionMs).isEqualTo(0);
assertThat(newPositions.get(1).contentPositionMs).isEqualTo(4000);
// auto transition from ad to end of period
assertThat(oldPositions.get(2).periodIndex).isEqualTo(1);
assertThat(oldPositions.get(2).adGroupIndex).isEqualTo(0);
assertThat(oldPositions.get(2).adIndexInAdGroup).isEqualTo(0);
assertThat(oldPositions.get(2).positionMs).isEqualTo(2500);
assertThat(oldPositions.get(2).contentPositionMs).isEqualTo(4000);
assertThat(newPositions.get(2).periodIndex).isEqualTo(1);
assertThat(newPositions.get(2).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(2).positionMs).isEqualTo(2500);
// auto transition to next ad period
assertThat(oldPositions.get(3).periodIndex).isEqualTo(1);
assertThat(oldPositions.get(3).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(3).periodIndex).isEqualTo(2);
assertThat(newPositions.get(3).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(3).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(3).contentPositionMs).isEqualTo(4000);
// auto transition from ad to end of period
assertThat(oldPositions.get(4).periodIndex).isEqualTo(2);
assertThat(oldPositions.get(4).adGroupIndex).isEqualTo(0);
assertThat(oldPositions.get(4).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(4).periodIndex).isEqualTo(2);
assertThat(newPositions.get(4).adGroupIndex).isEqualTo(-1);
// auto transition to final content period with seek position
assertThat(oldPositions.get(5).periodIndex).isEqualTo(2);
assertThat(oldPositions.get(5).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(5).periodIndex).isEqualTo(3);
assertThat(newPositions.get(5).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(5).contentPositionMs).isEqualTo(4000);
}
use of com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource in project ExoPlayer by google.
the class ExoPlayerTest method play_playedSSAIPreMidPostRollsSinglePeriodWindow_noDiscontinuities.
@Test
public void play_playedSSAIPreMidPostRollsSinglePeriodWindow_noDiscontinuities() throws Exception {
AdPlaybackState adPlaybackState = addAdGroupToAdPlaybackState(new AdPlaybackState("adsId"), /* fromPositionUs= */
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
C.MICROS_PER_SECOND);
adPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US + (3 * C.MICROS_PER_SECOND), /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
C.MICROS_PER_SECOND);
adPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US + (5 * C.MICROS_PER_SECOND), /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
C.MICROS_PER_SECOND);
adPlaybackState = addAdGroupToAdPlaybackState(adPlaybackState, /* fromPositionUs= */
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US + (9 * C.MICROS_PER_SECOND), /* contentResumeOffsetUs= */
0, /* adDurationsUs...= */
C.MICROS_PER_SECOND);
adPlaybackState = adPlaybackState.withPlayedAd(/* adGroupIndex= */
0, /* adIndexInAdGroup+ */
0);
adPlaybackState = adPlaybackState.withPlayedAd(/* adGroupIndex= */
1, /* adIndexInAdGroup+ */
0);
adPlaybackState = adPlaybackState.withPlayedAd(/* adGroupIndex= */
2, /* adIndexInAdGroup+ */
0);
adPlaybackState = adPlaybackState.withPlayedAd(/* adGroupIndex= */
3, /* adIndexInAdGroup+ */
0);
FakeTimeline adTimeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, "windowId", /* isSeekable= */
true, /* isDynamic= */
false, /* isLive= */
false, /* isPlaceholder= */
false, /* durationUs= */
DEFAULT_WINDOW_DURATION_US, /* defaultPositionUs= */
0, /* windowOffsetInFirstPeriodUs= */
DEFAULT_WINDOW_OFFSET_IN_FIRST_PERIOD_US, /* adPlaybackStates= */
ImmutableList.of(adPlaybackState), MediaItem.EMPTY));
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline, ExoPlayerTestRunner.AUDIO_FORMAT), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.prepare();
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
long finalPositionMs = player.getCurrentPosition();
player.release();
assertThat(finalPositionMs).isEqualTo(6000);
verify(listener, never()).onPositionDiscontinuity(any(), any(), anyInt());
ArgumentCaptor<Integer> playbackStateCaptor = ArgumentCaptor.forClass(Integer.class);
verify(listener, times(3)).onPlaybackStateChanged(playbackStateCaptor.capture());
assertThat(playbackStateCaptor.getAllValues()).containsExactly(2, 3, 4).inOrder();
}
use of com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_toPlayedSAIMidRolls_requestedContentPositionNotPropagatedIntoAds.
@Test
public void seekTo_toPlayedSAIMidRolls_requestedContentPositionNotPropagatedIntoAds() throws Exception {
ArgumentCaptor<PositionInfo> oldPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<Integer> reasonArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
FakeTimeline adTimeline = FakeTimeline.createMultiPeriodAdTimeline("windowId", /* numberOfPlayedAds= */
2, /* isAdPeriodFlags...= */
false, true, true, false);
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.pause();
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
player.seekTo(2500);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
verify(listener, times(1)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(1).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// seek discontinuity
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
// TODO(bachinger): Incorrect masking. Skipped played prerolls not taken into account by masking
assertThat(newPositions.get(0).periodIndex).isEqualTo(1);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
}
use of com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_beyondSSAIMidRollsConsecutiveContentPeriods_seekAdjusted.
@Test
public void seekTo_beyondSSAIMidRollsConsecutiveContentPeriods_seekAdjusted() throws Exception {
ArgumentCaptor<PositionInfo> oldPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<Integer> reasonArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
FakeTimeline adTimeline = FakeTimeline.createMultiPeriodAdTimeline("windowId", /* numberOfPlayedAds= */
0, /* isAdPeriodFlags...= */
false, true, false, false);
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.pause();
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
player.seekTo(/* positionMs= */
7000);
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
verify(listener, times(5)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(1, 2, 0, 0, 0).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// seek
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).periodIndex).isEqualTo(3);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).positionMs).isEqualTo(7000);
// seek adjustment
assertThat(oldPositions.get(1).periodIndex).isEqualTo(3);
assertThat(oldPositions.get(1).adGroupIndex).isEqualTo(-1);
assertThat(oldPositions.get(1).positionMs).isEqualTo(7000);
assertThat(newPositions.get(1).periodIndex).isEqualTo(1);
assertThat(newPositions.get(1).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(1).positionMs).isEqualTo(0);
}
use of com.google.android.exoplayer2.source.ads.ServerSideAdInsertionMediaSource in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_beforeSSAIMidRolls_requestedContentPositionNotPropagatedIntoAds.
@Test
public void seekTo_beforeSSAIMidRolls_requestedContentPositionNotPropagatedIntoAds() throws Exception {
ArgumentCaptor<PositionInfo> oldPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<PositionInfo> newPositionArgumentCaptor = ArgumentCaptor.forClass(PositionInfo.class);
ArgumentCaptor<Integer> reasonArgumentCaptor = ArgumentCaptor.forClass(Integer.class);
FakeTimeline adTimeline = FakeTimeline.createMultiPeriodAdTimeline("windowId", /* numberOfPlayedAds= */
0, /* isAdPeriodFlags...= */
false, true, true, false);
Listener listener = mock(Listener.class);
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.addListener(listener);
AtomicReference<ServerSideAdInsertionMediaSource> sourceReference = new AtomicReference<>();
sourceReference.set(new ServerSideAdInsertionMediaSource(new FakeMediaSource(adTimeline), contentTimeline -> {
sourceReference.get().setAdPlaybackStates(adTimeline.getAdPlaybackStates(/* windowIndex= */
0));
return true;
}));
player.setMediaSource(sourceReference.get());
player.pause();
player.prepare();
runUntilPlaybackState(player, Player.STATE_READY);
player.play();
player.seekTo(1600);
runUntilPlaybackState(player, Player.STATE_ENDED);
player.release();
verify(listener, times(6)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(1, 0, 0, 0, 0, 0).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// seek discontinuity
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(newPositions.get(0).periodIndex).isEqualTo(0);
assertThat(newPositions.get(0).positionMs).isEqualTo(1600);
assertThat(newPositions.get(0).contentPositionMs).isEqualTo(1600);
// auto discontinuities through ads has correct content position that is not the seek position.
assertThat(newPositions.get(1).periodIndex).isEqualTo(1);
assertThat(newPositions.get(1).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(1).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(1).positionMs).isEqualTo(0);
assertThat(newPositions.get(1).contentPositionMs).isEqualTo(2500);
assertThat(newPositions.get(2).contentPositionMs).isEqualTo(2500);
assertThat(newPositions.get(3).contentPositionMs).isEqualTo(2500);
assertThat(newPositions.get(4).contentPositionMs).isEqualTo(2500);
// Content resumes at expected position that is not the seek position.
assertThat(newPositions.get(5).periodIndex).isEqualTo(3);
assertThat(newPositions.get(5).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(5).positionMs).isEqualTo(2500);
assertThat(newPositions.get(5).contentPositionMs).isEqualTo(2500);
}
Aggregations