use of androidx.media3.exoplayer.source.ConcatenatingMediaSource in project media by androidx.
the class ExoPlayerTest method setMediaSources_whenIdle_correctMaskingPlaybackState.
@Test
public void setMediaSources_whenIdle_correctMaskingPlaybackState() throws Exception {
final int[] maskingPlaybackStates = new int[4];
Arrays.fill(maskingPlaybackStates, C.INDEX_UNSET);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set empty media item with no seek.
player.setMediaSource(new ConcatenatingMediaSource());
maskingPlaybackStates[0] = player.getPlaybackState();
}
}).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set media item with an implicit seek to the current position.
player.setMediaSource(new FakeMediaSource());
maskingPlaybackStates[1] = player.getPlaybackState();
}
}).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set media item with an explicit seek.
player.setMediaSource(new FakeMediaSource(), /* startPositionMs= */
C.TIME_UNSET);
maskingPlaybackStates[2] = player.getPlaybackState();
}
}).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set empty media item with an explicit seek.
player.setMediaSource(new ConcatenatingMediaSource(), /* startPositionMs= */
C.TIME_UNSET);
maskingPlaybackStates[3] = player.getPlaybackState();
}
}).prepare().build();
ExoPlayerTestRunner exoPlayerTestRunner = new ExoPlayerTestRunner.Builder(context).skipSettingMediaSources().setActionSchedule(actionSchedule).build().start(/* doPrepare= */
false).blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
// Expect reset of masking to first media item.
exoPlayerTestRunner.assertPlaybackStatesEqual(Player.STATE_ENDED);
assertArrayEquals(new int[] { Player.STATE_IDLE, Player.STATE_IDLE, Player.STATE_IDLE, Player.STATE_IDLE }, maskingPlaybackStates);
exoPlayerTestRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED);
}
use of androidx.media3.exoplayer.source.ConcatenatingMediaSource in project media by androidx.
the class ExoPlayerTest method delegatingMediaSourceApproach.
@Test
public void delegatingMediaSourceApproach() throws Exception {
Timeline fakeTimeline = new FakeTimeline(new TimelineWindowDefinition(/* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
10_000_000));
final ConcatenatingMediaSource underlyingSource = new ConcatenatingMediaSource();
CompositeMediaSource<Void> delegatingMediaSource = new CompositeMediaSource<Void>() {
@Override
public void prepareSourceInternal(@Nullable TransferListener mediaTransferListener) {
super.prepareSourceInternal(mediaTransferListener);
underlyingSource.addMediaSource(new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT));
underlyingSource.addMediaSource(new FakeMediaSource(fakeTimeline, ExoPlayerTestRunner.VIDEO_FORMAT));
prepareChildSource(null, underlyingSource);
}
@Override
public MediaPeriod createPeriod(MediaPeriodId id, Allocator allocator, long startPositionUs) {
return underlyingSource.createPeriod(id, allocator, startPositionUs);
}
@Override
public void releasePeriod(MediaPeriod mediaPeriod) {
underlyingSource.releasePeriod(mediaPeriod);
}
@Override
protected void onChildSourceInfoRefreshed(Void id, MediaSource mediaSource, Timeline timeline) {
refreshSourceInfo(timeline);
}
@Override
public boolean isSingleWindow() {
return false;
}
@Override
public MediaItem getMediaItem() {
return underlyingSource.getMediaItem();
}
@Override
@Nullable
public Timeline getInitialTimeline() {
return Timeline.EMPTY;
}
};
int[] currentMediaItemIndices = new int[1];
long[] currentPlaybackPositions = new long[1];
long[] windowCounts = new long[1];
int seekToMediaItemIndex = 1;
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).seek(/* mediaItemIndex= */
1, /* positionMs= */
5000).waitForTimelineChanged(/* expectedTimeline= */
null, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
currentMediaItemIndices[0] = player.getCurrentMediaItemIndex();
currentPlaybackPositions[0] = player.getCurrentPosition();
windowCounts[0] = player.getCurrentTimeline().getWindowCount();
}
}).build();
ExoPlayerTestRunner exoPlayerTestRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(delegatingMediaSource).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
exoPlayerTestRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
assertArrayEquals(new long[] { 2 }, windowCounts);
assertArrayEquals(new int[] { seekToMediaItemIndex }, currentMediaItemIndices);
assertArrayEquals(new long[] { 5_000 }, currentPlaybackPositions);
}
use of androidx.media3.exoplayer.source.ConcatenatingMediaSource 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.exoplayer.source.ConcatenatingMediaSource 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.exoplayer.source.ConcatenatingMediaSource in project media by androidx.
the class ExoPlayerTest method setMediaSources_whenEnded_correctMaskingPlaybackState.
@Test
public void setMediaSources_whenEnded_correctMaskingPlaybackState() 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);
final int[] maskingPlaybackStates = new int[4];
Arrays.fill(maskingPlaybackStates, C.INDEX_UNSET);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlaybackState(Player.STATE_ENDED).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set empty media item with an implicit seek to the current position.
player.setMediaSource(new ConcatenatingMediaSource());
maskingPlaybackStates[0] = player.getPlaybackState();
}
}).waitForPlaybackState(Player.STATE_ENDED).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set empty media item with an explicit seek.
player.setMediaSource(new ConcatenatingMediaSource(), /* startPositionMs= */
C.TIME_UNSET);
maskingPlaybackStates[1] = player.getPlaybackState();
}
}).waitForPlaybackState(Player.STATE_ENDED).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set media item with an implicit seek to the current position.
player.setMediaSource(firstMediaSource);
maskingPlaybackStates[2] = player.getPlaybackState();
}
}).waitForPlaybackState(Player.STATE_READY).clearMediaItems().executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
// Set media item with an explicit seek.
player.setMediaSource(secondMediaSource, /* startPositionMs= */
C.TIME_UNSET);
maskingPlaybackStates[3] = player.getPlaybackState();
}
}).waitForPlaybackState(Player.STATE_ENDED).build();
ExoPlayerTestRunner exoPlayerTestRunner = new ExoPlayerTestRunner.Builder(context).setExpectedPlayerEndedCount(/* expectedPlayerEndedCount= */
3).setMediaSources(new ConcatenatingMediaSource()).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
// Expect reset of masking to first media item.
exoPlayerTestRunner.assertPlaybackStatesEqual(Player.STATE_ENDED, Player.STATE_BUFFERING, Player.STATE_READY, Player.STATE_ENDED, Player.STATE_BUFFERING, Player.STATE_READY, Player.STATE_ENDED);
assertArrayEquals(new int[] { Player.STATE_ENDED, Player.STATE_ENDED, Player.STATE_BUFFERING, Player.STATE_BUFFERING }, maskingPlaybackStates);
exoPlayerTestRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
}
Aggregations