use of androidx.media3.test.utils.FakeTimeline in project media by androidx.
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 androidx.media3.test.utils.FakeTimeline in project media by androidx.
the class ExoPlayerTest method concatenatingMediaSourceRemoveMediaSource_removesPlayingPeriod_callsOnPositionDiscontinuity.
@Test
public void concatenatingMediaSourceRemoveMediaSource_removesPlayingPeriod_callsOnPositionDiscontinuity() throws Exception {
ExoPlayer player = new TestExoPlayerBuilder(context).build();
Player.Listener listener = mock(Player.Listener.class);
player.addListener(listener);
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource(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))), new FakeMediaSource(new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
2, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
6 * C.MICROS_PER_SECOND))));
player.addMediaSource(concatenatingMediaSource);
player.prepare();
TestPlayerRunHelper.playUntilPosition(player, /* mediaItemIndex= */
1, /* positionMs= */
5 * C.MILLIS_PER_SECOND);
concatenatingMediaSource.removeMediaSource(1);
TestPlayerRunHelper.runUntilPendingCommandsAreFullyHandled(player);
concatenatingMediaSource.removeMediaSource(1);
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(any(), any(), eq(Player.DISCONTINUITY_REASON_AUTO_TRANSITION));
inOrder.verify(listener, times(2)).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(1);
assertThat(newPositions.get(0).positionMs).isEqualTo(0);
assertThat(newPositions.get(0).contentPositionMs).isEqualTo(0);
assertThat(oldPositions.get(1).mediaItemIndex).isEqualTo(1);
assertThat(oldPositions.get(1).positionMs).isEqualTo(0);
assertThat(oldPositions.get(1).contentPositionMs).isEqualTo(0);
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 androidx.media3.test.utils.FakeTimeline in project media by androidx.
the class ExoPlayerTest method seekToIndexWithEmptyMultiWindowMediaSource.
@Test
public void seekToIndexWithEmptyMultiWindowMediaSource() throws Exception {
Timeline fakeTimeline = new FakeTimeline(new TimelineWindowDefinition(/* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
10_000_000));
ConcatenatingMediaSource concatenatingMediaSource = new ConcatenatingMediaSource(/* isAtomic= */
false);
int[] currentMediaItemIndices = new int[2];
long[] currentPlaybackPositions = new long[2];
long[] windowCounts = new long[2];
int seekToMediaItemIndex = 1;
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_ENDED).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
currentMediaItemIndices[0] = player.getCurrentMediaItemIndex();
currentPlaybackPositions[0] = player.getCurrentPosition();
windowCounts[0] = player.getCurrentTimeline().getWindowCount();
}
}).executeRunnable(() -> concatenatingMediaSource.addMediaSources(Arrays.asList(new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT), new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT)))).waitForTimelineChanged().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
currentMediaItemIndices[1] = player.getCurrentMediaItemIndex();
currentPlaybackPositions[1] = player.getCurrentPosition();
windowCounts[1] = player.getCurrentTimeline().getWindowCount();
}
}).build();
new ExoPlayerTestRunner.Builder(context).setMediaSources(concatenatingMediaSource).initialSeek(seekToMediaItemIndex, 5000).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
assertArrayEquals(new long[] { 0, 2 }, windowCounts);
assertArrayEquals(new int[] { seekToMediaItemIndex, seekToMediaItemIndex }, currentMediaItemIndices);
assertArrayEquals(new long[] { 5_000, 5_000 }, currentPlaybackPositions);
}
use of androidx.media3.test.utils.FakeTimeline in project media by androidx.
the class ExoPlayerTest method removeMediaItems_currentItemRemovedThatIsTheLast_correctMasking.
@Test
public void removeMediaItems_currentItemRemovedThatIsTheLast_correctMasking() throws Exception {
Timeline firstTimeline = new FakeTimeline(/* windowCount= */
1, 1L);
MediaSource firstMediaSource = new FakeMediaSource(firstTimeline);
Timeline secondTimeline = new FakeTimeline(/* windowCount= */
1, 2L);
MediaSource secondMediaSource = new FakeMediaSource(secondTimeline);
Timeline thirdTimeline = new FakeTimeline(/* windowCount= */
1, 3L);
MediaSource thirdMediaSource = new FakeMediaSource(thirdTimeline);
Timeline fourthTimeline = new FakeTimeline(/* windowCount= */
1, 3L);
MediaSource fourthMediaSource = new FakeMediaSource(fourthTimeline);
final int[] currentMediaItemIndices = new int[9];
Arrays.fill(currentMediaItemIndices, C.INDEX_UNSET);
final int[] maskingPlaybackStates = new int[4];
Arrays.fill(maskingPlaybackStates, C.INDEX_UNSET);
final long[] currentPositions = new long[3];
Arrays.fill(currentPositions, C.TIME_UNSET);
final long[] bufferedPositions = new long[3];
Arrays.fill(bufferedPositions, C.TIME_UNSET);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_READY).waitForPendingPlayerCommands().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Expect the current media item index to be 2 after seek.
currentMediaItemIndices[0] = player.getCurrentMediaItemIndex();
currentPositions[0] = player.getCurrentPosition();
bufferedPositions[0] = player.getBufferedPosition();
player.removeMediaItem(/* index= */
2);
// Expect the current media item index to be 0
// (default position of timeline after not finding subsequent period).
currentMediaItemIndices[1] = player.getCurrentMediaItemIndex();
// Transition to ENDED.
maskingPlaybackStates[0] = player.getPlaybackState();
currentPositions[1] = player.getCurrentPosition();
bufferedPositions[1] = player.getBufferedPosition();
}
}).waitForPlaybackState(Player.STATE_ENDED).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Expects the current media item index still on 0.
currentMediaItemIndices[2] = player.getCurrentMediaItemIndex();
// Insert an item at begin when the playlist is not empty.
player.addMediaSource(/* index= */
0, thirdMediaSource);
// Expects the current media item index to be (0 + 1) after insertion at begin.
currentMediaItemIndices[3] = player.getCurrentMediaItemIndex();
// Remains in ENDED.
maskingPlaybackStates[1] = player.getPlaybackState();
currentPositions[2] = player.getCurrentPosition();
bufferedPositions[2] = player.getBufferedPosition();
}
}).waitForTimelineChanged().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
currentMediaItemIndices[4] = player.getCurrentMediaItemIndex();
// Implicit seek to the current media item index, which is out of bounds in new
// timeline.
player.setMediaSource(fourthMediaSource, /* resetPosition= */
false);
// 0 after reset.
currentMediaItemIndices[5] = player.getCurrentMediaItemIndex();
// Invalid seek, so we remain in ENDED.
maskingPlaybackStates[2] = player.getPlaybackState();
}
}).waitForTimelineChanged().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
currentMediaItemIndices[6] = player.getCurrentMediaItemIndex();
// Explicit seek to (0, C.TIME_UNSET). Player transitions to BUFFERING.
player.setMediaSource(fourthMediaSource, /* startPositionMs= */
5000);
// 0 after explicit seek.
currentMediaItemIndices[7] = player.getCurrentMediaItemIndex();
// Transitions from ENDED to BUFFERING after explicit seek.
maskingPlaybackStates[3] = player.getPlaybackState();
}
}).waitForTimelineChanged().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Check whether actual media item index is equal masking index from above.
currentMediaItemIndices[8] = player.getCurrentMediaItemIndex();
}
}).build();
ExoPlayerTestRunner exoPlayerTestRunner = new ExoPlayerTestRunner.Builder(context).initialSeek(/* mediaItemIndex= */
2, /* positionMs= */
C.TIME_UNSET).setExpectedPlayerEndedCount(2).setMediaSources(firstMediaSource, secondMediaSource, thirdMediaSource).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
// Expect reset of masking to first media item.
exoPlayerTestRunner.assertPlaybackStatesEqual(Player.STATE_BUFFERING, // Ready after initial prepare.
Player.STATE_READY, // ended after removing current media item index
Player.STATE_ENDED, // buffers after set items with seek
Player.STATE_BUFFERING, Player.STATE_READY, Player.STATE_ENDED);
assertArrayEquals(new int[] { // ended after removing current media item index
Player.STATE_ENDED, // adding items does not change state
Player.STATE_ENDED, // set items with seek to current position.
Player.STATE_ENDED, Player.STATE_BUFFERING }, // buffers after set items with seek
maskingPlaybackStates);
assertArrayEquals(new int[] { 2, 0, 0, 1, 1, 0, 0, 0, 0 }, currentMediaItemIndices);
assertThat(currentPositions[0]).isEqualTo(0);
assertThat(currentPositions[1]).isEqualTo(0);
assertThat(currentPositions[2]).isEqualTo(0);
assertThat(bufferedPositions[0]).isGreaterThan(0);
assertThat(bufferedPositions[1]).isEqualTo(0);
assertThat(bufferedPositions[2]).isEqualTo(0);
}
use of androidx.media3.test.utils.FakeTimeline in project media by androidx.
the class ExoPlayerTest method seekAfterPlaybackError.
@Test
public void seekAfterPlaybackError() throws Exception {
final Timeline timeline = new FakeTimeline(/* windowCount= */
2);
final long[] positionHolder = { C.TIME_UNSET, C.TIME_UNSET, C.TIME_UNSET };
final int[] mediaItemIndexHolder = { C.INDEX_UNSET, C.INDEX_UNSET, C.INDEX_UNSET };
final FakeMediaSource firstMediaSource = new FakeMediaSource(timeline);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).pause().waitForPlaybackState(Player.STATE_READY).playUntilPosition(/* mediaItemIndex= */
1, /* positionMs= */
500).throwPlaybackException(ExoPlaybackException.createForSource(new IOException(), PlaybackException.ERROR_CODE_IO_UNSPECIFIED)).waitForPlaybackState(Player.STATE_IDLE).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Position while in error state
positionHolder[0] = player.getCurrentPosition();
mediaItemIndexHolder[0] = player.getCurrentMediaItemIndex();
}
}).seek(/* mediaItemIndex= */
0, /* positionMs= */
C.TIME_UNSET).waitForPendingPlayerCommands().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Position while in error state
positionHolder[1] = player.getCurrentPosition();
mediaItemIndexHolder[1] = player.getCurrentMediaItemIndex();
}
}).prepare().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Position after prepare.
positionHolder[2] = player.getCurrentPosition();
mediaItemIndexHolder[2] = player.getCurrentMediaItemIndex();
}
}).play().build();
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(firstMediaSource).setActionSchedule(actionSchedule).build();
assertThrows(ExoPlaybackException.class, () -> testRunner.start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS));
assertThat(positionHolder[0]).isAtLeast(500L);
assertThat(positionHolder[1]).isEqualTo(0L);
assertThat(positionHolder[2]).isEqualTo(0L);
assertThat(mediaItemIndexHolder[0]).isEqualTo(1);
assertThat(mediaItemIndexHolder[1]).isEqualTo(0);
assertThat(mediaItemIndexHolder[2]).isEqualTo(0);
}
Aggregations