use of com.google.android.exoplayer2.testutil.TestExoPlayerBuilder in project ExoPlayer by google.
the class ExoPlayerTest method setMediaSources_removesPlayingPeriod_callsOnPositionDiscontinuity.
@Test
public void setMediaSources_removesPlayingPeriod_callsOnPositionDiscontinuity() throws Exception {
FakeMediaSource secondMediaSource = new FakeMediaSource(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
2, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
15 * C.MICROS_PER_SECOND)));
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
player.setMediaSource(new FakeMediaSource(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
1, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
10 * C.MICROS_PER_SECOND))));
player.prepare();
TestPlayerRunHelper.playUntilPosition(player, /* mediaItemIndex= */
0, /* positionMs= */
5 * C.MILLIS_PER_SECOND);
player.setMediaSources(ImmutableList.of(secondMediaSource, secondMediaSource));
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);
InOrder inOrder = inOrder(listener);
inOrder.verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_REMOVE));
inOrder.verify(listener).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
List<Player.PositionInfo> oldPositions = oldPosition.getAllValues();
List<Player.PositionInfo> newPositions = newPosition.getAllValues();
assertThat(oldPositions.get(0).mediaItemIndex).isEqualTo(0);
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);
player.release();
}
use of com.google.android.exoplayer2.testutil.TestExoPlayerBuilder 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.testutil.TestExoPlayerBuilder in project ExoPlayer by google.
the class ExoPlayerTest method resettingMediaSourcesGivesFreshSourceInfo.
@Test
public void resettingMediaSourcesGivesFreshSourceInfo() throws Exception {
FakeRenderer renderer = new FakeRenderer(C.TRACK_TYPE_VIDEO);
Timeline firstTimeline = new FakeTimeline(new TimelineWindowDefinition(/* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
1_000_000_000));
MediaSource firstSource = new FakeMediaSource(firstTimeline, ExoPlayerTestRunner.VIDEO_FORMAT);
AtomicBoolean secondSourcePrepared = new AtomicBoolean();
MediaSource secondSource = new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
@Override
public synchronized void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);
secondSourcePrepared.set(true);
}
};
Timeline thirdTimeline = new FakeTimeline();
MediaSource thirdSource = new FakeMediaSource(thirdTimeline, ExoPlayerTestRunner.VIDEO_FORMAT);
ExoPlayer player = new TestExoPlayerBuilder(context).setRenderers(renderer).build();
Player.Listener mockPlayerListener = mock(Player.Listener.class);
player.addListener(mockPlayerListener);
player.setMediaSource(firstSource);
player.prepare();
player.play();
runUntilTimelineChanged(player);
player.setMediaSource(secondSource);
runMainLooperUntil(secondSourcePrepared::get);
player.setMediaSource(thirdSource);
runUntilPlaybackState(player, Player.STATE_ENDED);
// The first source's preparation completed with a real timeline. When the second source was
// prepared, it immediately exposed a placeholder timeline, but the source info refresh from the
// second source was suppressed as we replace it with the third source before the update
// arrives.
InOrder inOrder = inOrder(mockPlayerListener);
inOrder.verify(mockPlayerListener).onTimelineChanged(argThat(noUid(placeholderTimeline)), eq(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
inOrder.verify(mockPlayerListener).onTimelineChanged(argThat(noUid(firstTimeline)), eq(Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE));
inOrder.verify(mockPlayerListener).onTimelineChanged(argThat(noUid(placeholderTimeline)), eq(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
inOrder.verify(mockPlayerListener).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_REMOVE));
inOrder.verify(mockPlayerListener).onTimelineChanged(argThat(noUid(placeholderTimeline)), eq(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED));
inOrder.verify(mockPlayerListener).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_REMOVE));
inOrder.verify(mockPlayerListener).onTimelineChanged(argThat(noUid(thirdTimeline)), eq(Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE));
inOrder.verify(mockPlayerListener).onTracksChanged(eq(new TrackGroupArray(new TrackGroup(ExoPlayerTestRunner.VIDEO_FORMAT))), any());
assertThat(renderer.isEnded).isTrue();
}
use of com.google.android.exoplayer2.testutil.TestExoPlayerBuilder 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);
}
use of com.google.android.exoplayer2.testutil.TestExoPlayerBuilder in project ExoPlayer by google.
the class ExoPlayerTest method repeatMode_windowTransition_callsOnPositionDiscontinuityAndOnMediaItemTransition.
@Test
public void repeatMode_windowTransition_callsOnPositionDiscontinuityAndOnMediaItemTransition() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
FakeMediaSource secondMediaSource = new FakeMediaSource(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
2, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
20 * C.MICROS_PER_SECOND)));
player.addListener(listener);
player.setMediaSource(new FakeMediaSource(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
1, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
10 * C.MICROS_PER_SECOND))));
player.setRepeatMode(Player.REPEAT_MODE_ONE);
player.prepare();
player.play();
TestPlayerRunHelper.runUntilPositionDiscontinuity(player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
player.setRepeatMode(Player.REPEAT_MODE_ALL);
player.play();
TestPlayerRunHelper.runUntilPositionDiscontinuity(player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
player.addMediaSource(secondMediaSource);
player.seekTo(/* mediaItemIndex= */
1, /* positionMs= */
C.TIME_UNSET);
player.play();
TestPlayerRunHelper.runUntilPositionDiscontinuity(player, Player.DISCONTINUITY_REASON_AUTO_TRANSITION);
player.setRepeatMode(Player.REPEAT_MODE_OFF);
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);
InOrder inOrder = inOrder(listener);
// Expect media item transition for repeat mode ONE to be attributed to
// DISCONTINUITY_REASON_REPEAT.
inOrder.verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
Player.PositionInfo oldPositionInfo = oldPosition.getValue();
Player.PositionInfo newPositionInfo = newPosition.getValue();
assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid);
assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex);
assertThat(oldPositionInfo.mediaItemIndex).isEqualTo(newPositionInfo.mediaItemIndex);
assertThat(oldPositionInfo.mediaItem.localConfiguration.tag).isEqualTo(1);
assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(10_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000);
assertThat(newPositionInfo.positionMs).isEqualTo(0);
assertThat(newPositionInfo.contentPositionMs).isEqualTo(0);
inOrder.verify(listener).onMediaItemTransition(any(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT));
// Expect media item transition for repeat mode ALL with a single item to be attributed to
// DISCONTINUITY_REASON_REPEAT.
inOrder.verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
oldPositionInfo = oldPosition.getValue();
newPositionInfo = newPosition.getValue();
assertThat(oldPositionInfo.periodUid).isEqualTo(newPositionInfo.periodUid);
assertThat(oldPositionInfo.periodIndex).isEqualTo(newPositionInfo.periodIndex);
assertThat(oldPositionInfo.mediaItemIndex).isEqualTo(newPositionInfo.mediaItemIndex);
assertThat(oldPositionInfo.mediaItem.localConfiguration.tag).isEqualTo(1);
assertThat(oldPositionInfo.windowUid).isEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(10_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(10_000);
assertThat(newPositionInfo.positionMs).isEqualTo(0);
assertThat(newPositionInfo.contentPositionMs).isEqualTo(0);
inOrder.verify(listener).onMediaItemTransition(any(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_REPEAT));
// Expect media item transition for repeat mode ALL with more than one item which is attributed
// to DISCONTINUITY_REASON_AUTO_TRANSITION not DISCONTINUITY_REASON_REPEAT.
inOrder.verify(listener).onPositionDiscontinuity(oldPosition.capture(), newPosition.capture(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
oldPositionInfo = oldPosition.getValue();
newPositionInfo = newPosition.getValue();
assertThat(oldPositionInfo.mediaItemIndex).isEqualTo(1);
assertThat(oldPositionInfo.mediaItem.localConfiguration.tag).isEqualTo(2);
assertThat(oldPositionInfo.windowUid).isNotEqualTo(newPositionInfo.windowUid);
assertThat(oldPositionInfo.positionMs).isEqualTo(20_000);
assertThat(oldPositionInfo.contentPositionMs).isEqualTo(20_000);
assertThat(newPositionInfo.positionMs).isEqualTo(0);
assertThat(newPositionInfo.mediaItemIndex).isEqualTo(0);
inOrder.verify(listener).onMediaItemTransition(any(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_AUTO));
// Last auto transition from media item 0 to media item 1 not caused by repeat mode.
inOrder.verify(listener).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
inOrder.verify(listener).onMediaItemTransition(any(), eq(Player.MEDIA_ITEM_TRANSITION_REASON_AUTO));
// No more callbacks called.
inOrder.verify(listener, never()).onPositionDiscontinuity(any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
inOrder.verify(listener, never()).onMediaItemTransition(any(), anyInt());
player.release();
}
Aggregations