use of com.google.android.exoplayer2.testutil.FakeTimeline in project ExoPlayer by google.
the class ExoPlayerTest method play_playedSSAIPreMidPostRollsMultiPeriodWindow_contentPeriodTransitionsOnly.
@Test
public void play_playedSSAIPreMidPostRollsMultiPeriodWindow_contentPeriodTransitionsOnly() 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= */
Integer.MAX_VALUE, /* isAdPeriodFlags...= */
true, false, true, true, false, true, true, true);
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);
player.release();
ArgumentCaptor<Integer> playbackStateCaptor = ArgumentCaptor.forClass(Integer.class);
verify(listener, times(3)).onPlaybackStateChanged(playbackStateCaptor.capture());
assertThat(playbackStateCaptor.getAllValues()).containsExactly(2, 3, 4).inOrder();
verify(listener, times(3)).onPositionDiscontinuity(oldPositionArgumentCaptor.capture(), newPositionArgumentCaptor.capture(), reasonArgumentCaptor.capture());
assertThat(reasonArgumentCaptor.getAllValues()).containsExactly(0, 0, 0).inOrder();
List<PositionInfo> oldPositions = oldPositionArgumentCaptor.getAllValues();
List<PositionInfo> newPositions = newPositionArgumentCaptor.getAllValues();
// Auto discontinuity from the empty pre-roll period to the first content period.
assertThat(oldPositions.get(0).periodIndex).isEqualTo(0);
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(oldPositions.get(0).positionMs).isEqualTo(0);
assertThat(newPositions.get(0).periodIndex).isEqualTo(1);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).positionMs).isEqualTo(0);
// Auto discontinuity from the first content to the second content period.
assertThat(oldPositions.get(1).periodIndex).isEqualTo(1);
assertThat(oldPositions.get(1).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(1).periodIndex).isEqualTo(4);
assertThat(newPositions.get(1).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(1).positionMs).isEqualTo(1250);
// Auto discontinuity from the second content period to the last frame of the last ad period.
assertThat(oldPositions.get(2).periodIndex).isEqualTo(4);
assertThat(oldPositions.get(2).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(2).periodIndex).isEqualTo(7);
assertThat(newPositions.get(2).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(2).positionMs).isEqualTo(2500);
}
use of com.google.android.exoplayer2.testutil.FakeTimeline in project ExoPlayer by google.
the class ExoPlayerTest method removeMediaItems_removesPlayingPeriod_callsOnPositionDiscontinuity.
@Test
public void removeMediaItems_removesPlayingPeriod_callsOnPositionDiscontinuity() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
player.setMediaSources(ImmutableList.of(new FakeMediaSource(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
1, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
10 * C.MICROS_PER_SECOND))), new FakeMediaSource(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
2, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
8 * C.MICROS_PER_SECOND)))));
player.prepare();
TestPlayerRunHelper.playUntilPosition(player, /* mediaItemIndex= */
1, /* positionMs= */
5 * C.MILLIS_PER_SECOND);
player.removeMediaItem(/* index= */
1);
player.seekTo(/* positionMs= */
0);
TestPlayerRunHelper.playUntilPosition(player, /* mediaItemIndex= */
0, /* positionMs= */
2 * C.MILLIS_PER_SECOND);
// Removing the last item resets the position to 0 with an empty timeline.
player.removeMediaItem(0);
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
ArgumentCaptor<Player.PositionInfo> oldPosition = ArgumentCaptor.forClass(Player.PositionInfo.class);
ArgumentCaptor<Player.PositionInfo> newPosition = ArgumentCaptor.forClass(Player.PositionInfo.class);
InOrder inOrder = inOrder(listener);
inOrder.verify(listener).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
inOrder.verify(listener).onTimelineChanged(any(), eq(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
inOrder.verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_REMOVE));
inOrder.verify(listener).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_SEEK));
inOrder.verify(listener).onTimelineChanged(any(), eq(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
inOrder.verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_REMOVE));
List<Player.PositionInfo> oldPositions = oldPosition.getAllValues();
List<Player.PositionInfo> newPositions = newPosition.getAllValues();
assertThat(oldPositions.get(0).mediaItemIndex).isEqualTo(1);
assertThat(oldPositions.get(0).positionMs).isIn(Range.closed(4980L, 5000L));
assertThat(oldPositions.get(0).contentPositionMs).isIn(Range.closed(4980L, 5000L));
assertThat(newPositions.get(0).mediaItemIndex).isEqualTo(0);
assertThat(newPositions.get(0).positionMs).isEqualTo(0);
assertThat(newPositions.get(0).contentPositionMs).isEqualTo(0);
assertThat(oldPositions.get(1).mediaItemIndex).isEqualTo(0);
assertThat(oldPositions.get(1).positionMs).isIn(Range.closed(1980L, 2000L));
assertThat(oldPositions.get(1).contentPositionMs).isIn(Range.closed(1980L, 2000L));
assertThat(newPositions.get(1).windowUid).isNull();
assertThat(newPositions.get(1).mediaItemIndex).isEqualTo(0);
assertThat(newPositions.get(1).positionMs).isEqualTo(0);
assertThat(newPositions.get(1).contentPositionMs).isEqualTo(0);
player.release();
}
use of com.google.android.exoplayer2.testutil.FakeTimeline in project ExoPlayer by google.
the class ExoPlayerTest method seekTo_seekOverMidRoll_callsOnDiscontinuityCorrectly.
@Test
public void seekTo_seekOverMidRoll_callsOnDiscontinuityCorrectly() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
AdPlaybackState adPlaybackState = FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */
1, /* adGroupTimesUs...= */
2 * C.MICROS_PER_SECOND);
TimelineWindowDefinition adTimeline = new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
true, /* isDynamic= */
false, /* isLive= */
false, /* isPlaceholder= */
false, /* durationUs= */
10 * C.MICROS_PER_SECOND, /* defaultPositionUs= */
0, /* windowOffsetInFirstPeriodUs= */
0, adPlaybackState);
player.setMediaSource(new FakeMediaSource(new FakeTimeline(adTimeline)));
player.prepare();
TestPlayerRunHelper.playUntilPosition(player, /* mediaItemIndex= */
0, /* positionMs= */
1000);
player.seekTo(/* positionMs= */
8_000);
player.play();
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_ENDED);
ArgumentCaptor<Player.PositionInfo> oldPosition = ArgumentCaptor.forClass(Player.PositionInfo.class);
ArgumentCaptor<Player.PositionInfo> newPosition = ArgumentCaptor.forClass(Player.PositionInfo.class);
verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_SEEK));
verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT));
verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
verify(listener, never()).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_REMOVE));
verify(listener, never()).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_SKIP));
List<Player.PositionInfo> oldPositions = oldPosition.getAllValues();
List<Player.PositionInfo> newPositions = newPosition.getAllValues();
// SEEK behind mid roll
assertThat(oldPositions.get(0).mediaItemIndex).isEqualTo(0);
assertThat(oldPositions.get(0).positionMs).isIn(Range.closed(980L, 1_000L));
assertThat(oldPositions.get(0).contentPositionMs).isIn(Range.closed(980L, 1_000L));
assertThat(oldPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(oldPositions.get(0).adIndexInAdGroup).isEqualTo(-1);
assertThat(newPositions.get(0).mediaItemIndex).isEqualTo(0);
assertThat(newPositions.get(0).positionMs).isEqualTo(8_000);
assertThat(newPositions.get(0).contentPositionMs).isEqualTo(8_000);
assertThat(newPositions.get(0).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(0).adIndexInAdGroup).isEqualTo(-1);
// SEEK_ADJUSTMENT back to ad
assertThat(oldPositions.get(1).mediaItemIndex).isEqualTo(0);
assertThat(oldPositions.get(1).positionMs).isEqualTo(8_000);
assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(8_000);
assertThat(oldPositions.get(1).adGroupIndex).isEqualTo(-1);
assertThat(oldPositions.get(1).adIndexInAdGroup).isEqualTo(-1);
assertThat(newPositions.get(1).mediaItemIndex).isEqualTo(0);
assertThat(newPositions.get(1).positionMs).isEqualTo(0);
assertThat(newPositions.get(1).contentPositionMs).isEqualTo(8000);
assertThat(newPositions.get(1).adGroupIndex).isEqualTo(0);
assertThat(newPositions.get(1).adIndexInAdGroup).isEqualTo(0);
// AUTO_TRANSITION back to content
assertThat(oldPositions.get(2).mediaItemIndex).isEqualTo(0);
assertThat(oldPositions.get(2).positionMs).isEqualTo(5_000);
assertThat(oldPositions.get(2).contentPositionMs).isEqualTo(8_000);
assertThat(oldPositions.get(2).adGroupIndex).isEqualTo(0);
assertThat(oldPositions.get(2).adIndexInAdGroup).isEqualTo(0);
assertThat(newPositions.get(2).mediaItemIndex).isEqualTo(0);
assertThat(newPositions.get(2).positionMs).isEqualTo(8_000);
assertThat(newPositions.get(2).contentPositionMs).isEqualTo(8_000);
assertThat(newPositions.get(2).adGroupIndex).isEqualTo(-1);
assertThat(newPositions.get(2).adIndexInAdGroup).isEqualTo(-1);
player.release();
}
use of com.google.android.exoplayer2.testutil.FakeTimeline in project ExoPlayer by google.
the class ExoPlayerTest method readAheadToEndDoesNotResetRenderer.
/**
* Tests that the player does not unnecessarily reset renderers when playing a multi-period
* source.
*/
@Test
public void readAheadToEndDoesNotResetRenderer() throws Exception {
// Use sufficiently short periods to ensure the player attempts to read all at once.
TimelineWindowDefinition windowDefinition0 = new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
false, /* isDynamic= */
false, /* durationUs= */
100_000);
TimelineWindowDefinition windowDefinition1 = new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
1, /* isSeekable= */
false, /* isDynamic= */
false, /* durationUs= */
100_000);
TimelineWindowDefinition windowDefinition2 = new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
2, /* isSeekable= */
false, /* isDynamic= */
false, /* durationUs= */
100_000);
Timeline timeline = new FakeTimeline(windowDefinition0, windowDefinition1, windowDefinition2);
final FakeRenderer videoRenderer = new FakeRenderer(C.TRACK_TYPE_VIDEO);
FakeMediaClockRenderer audioRenderer = new FakeMediaClockRenderer(C.TRACK_TYPE_AUDIO) {
@Override
public long getPositionUs() {
// to advance.
return isCurrentStreamFinal() ? 30 : 0;
}
@Override
public void setPlaybackParameters(PlaybackParameters playbackParameters) {
}
@Override
public PlaybackParameters getPlaybackParameters() {
return PlaybackParameters.DEFAULT;
}
@Override
public boolean isEnded() {
return videoRenderer.isEnded();
}
};
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(videoRenderer, audioRenderer).build();
Player.Listener mockPlayerListener = mock(Player.Listener.class);
player.addListener(mockPlayerListener);
player.setMediaSource(new FakeMediaSource(timeline, ExoPlayerTestRunner.VIDEO_FORMAT, ExoPlayerTestRunner.AUDIO_FORMAT));
player.prepare();
player.play();
runUntilPlaybackState(player, Player.STATE_ENDED);
InOrder inOrder = inOrder(mockPlayerListener);
inOrder.verify(mockPlayerListener).onTimelineChanged(argThat(noUid(new FakeMediaSource.InitialTimeline(timeline))), eq(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
inOrder.verify(mockPlayerListener).onTimelineChanged(argThat(noUid(timeline)), eq(Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE));
inOrder.verify(mockPlayerListener, times(2)).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
assertThat(audioRenderer.positionResetCount).isEqualTo(1);
assertThat(videoRenderer.isEnded).isTrue();
assertThat(audioRenderer.isEnded).isTrue();
}
use of com.google.android.exoplayer2.testutil.FakeTimeline in project ExoPlayer by google.
the class ExoPlayerTest method prepareWhenAlreadyPreparedIsANoop.
@Test
public void prepareWhenAlreadyPreparedIsANoop() throws Exception {
Timeline timeline = new FakeTimeline();
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_READY).prepare().build();
ExoPlayerTestRunner exoPlayerTestRunner = new ExoPlayerTestRunner.Builder(context).setTimeline(timeline).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertPlaybackStatesEqual(Player.STATE_BUFFERING, Player.STATE_READY, Player.STATE_ENDED);
exoPlayerTestRunner.assertTimelinesSame(placeholderTimeline, timeline);
exoPlayerTestRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, /* media item set (masked timeline) */
Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
}
Aggregations