use of androidx.media3.test.utils.ExoPlayerTestRunner 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.test.utils.ExoPlayerTestRunner in project media by androidx.
the class ExoPlayerTest method resetPlaylistWithPreviousPosition.
@Test
public void resetPlaylistWithPreviousPosition() throws Exception {
Object firstWindowId = new Object();
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
firstWindowId));
Timeline firstExpectedMaskingTimeline = new MaskingMediaSource.PlaceholderTimeline(FakeTimeline.FAKE_MEDIA_ITEM.buildUpon().setTag(firstWindowId).build());
Object secondWindowId = new Object();
Timeline secondTimeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
secondWindowId));
Timeline secondExpectedMaskingTimeline = new MaskingMediaSource.PlaceholderTimeline(FakeTimeline.FAKE_MEDIA_ITEM.buildUpon().setTag(secondWindowId).build());
MediaSource secondSource = new FakeMediaSource(secondTimeline);
AtomicLong positionAfterReprepare = new AtomicLong();
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).pause().waitForPlaybackState(Player.STATE_READY).playUntilPosition(/* mediaItemIndex= */
0, /* positionMs= */
2000).setMediaSources(/* mediaItemIndex= */
0, /* positionMs= */
2000, secondSource).waitForTimelineChanged(secondTimeline, /* expectedReason */
Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
positionAfterReprepare.set(player.getCurrentPosition());
}
}).play().build();
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context).setTimeline(timeline).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
testRunner.assertTimelinesSame(firstExpectedMaskingTimeline, timeline, secondExpectedMaskingTimeline, secondTimeline);
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE, Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
assertThat(positionAfterReprepare.get()).isAtLeast(2000L);
}
use of androidx.media3.test.utils.ExoPlayerTestRunner in project media by androidx.
the class ExoPlayerTest method timelineUpdateDropsPrebufferedPeriods.
@Test
public void timelineUpdateDropsPrebufferedPeriods() throws Exception {
Timeline timeline1 = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
1), new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
2));
final Timeline timeline2 = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
1), new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
3));
final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, ExoPlayerTestRunner.VIDEO_FORMAT);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).pause().waitForPlaybackState(Player.STATE_READY).playUntilPosition(/* mediaItemIndex= */
0, /* positionMs= */
Util.usToMs(TimelineWindowDefinition.DEFAULT_WINDOW_DURATION_US)).executeRunnable(() -> mediaSource.setNewSourceInfo(timeline2)).waitForTimelineChanged(timeline2, /* expectedReason */
Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE).play().build();
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(mediaSource).setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE, Player.TIMELINE_CHANGE_REASON_SOURCE_UPDATE);
testRunner.assertPlayedPeriodIndices(0, 1);
// Assert that the second period was re-created from the new timeline.
assertThat(mediaSource.getCreatedMediaPeriods()).hasSize(3);
assertThat(mediaSource.getCreatedMediaPeriods().get(0).periodUid).isEqualTo(timeline1.getUidOfPeriod(/* periodIndex= */
0));
assertThat(mediaSource.getCreatedMediaPeriods().get(1).periodUid).isEqualTo(timeline1.getUidOfPeriod(/* periodIndex= */
1));
assertThat(mediaSource.getCreatedMediaPeriods().get(2).periodUid).isEqualTo(timeline2.getUidOfPeriod(/* periodIndex= */
1));
assertThat(mediaSource.getCreatedMediaPeriods().get(1).windowSequenceNumber).isGreaterThan(mediaSource.getCreatedMediaPeriods().get(0).windowSequenceNumber);
assertThat(mediaSource.getCreatedMediaPeriods().get(2).windowSequenceNumber).isGreaterThan(mediaSource.getCreatedMediaPeriods().get(1).windowSequenceNumber);
}
use of androidx.media3.test.utils.ExoPlayerTestRunner 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.test.utils.ExoPlayerTestRunner in project media by androidx.
the class ExoPlayerTest method infiniteLoading_withSmallAllocations_oomIsPreventedByLoadControl_andThrowsStuckBufferingIllegalStateException.
@Test
public void infiniteLoading_withSmallAllocations_oomIsPreventedByLoadControl_andThrowsStuckBufferingIllegalStateException() {
DefaultLoadControl loadControl = new DefaultLoadControl.Builder().setTargetBufferBytes(10 * C.DEFAULT_BUFFER_SEGMENT_SIZE).build();
// Return no end of stream signal to prevent playback from ending.
FakeMediaPeriod.TrackDataFactory trackDataWithoutEos = (format, periodId) -> ImmutableList.of();
MediaSource continuouslyAllocatingMediaSource = new FakeMediaSource(new FakeTimeline(), ExoPlayerTestRunner.VIDEO_FORMAT) {
@Override
protected MediaPeriod createMediaPeriod(MediaPeriodId id, TrackGroupArray trackGroupArray, Allocator allocator, MediaSourceEventListener.EventDispatcher mediaSourceEventDispatcher, DrmSessionManager drmSessionManager, DrmSessionEventListener.EventDispatcher drmEventDispatcher, @Nullable TransferListener transferListener) {
return new FakeMediaPeriod(trackGroupArray, allocator, trackDataWithoutEos, mediaSourceEventDispatcher, drmSessionManager, drmEventDispatcher, /* deferOnPrepared= */
false) {
private final List<Allocation> allocations = new ArrayList<>();
private Callback callback;
@Override
public synchronized void prepare(Callback callback, long positionUs) {
this.callback = callback;
super.prepare(callback, positionUs);
}
@Override
public long getBufferedPositionUs() {
// Pretend not to make loading progress, so that continueLoading keeps being called.
return 0;
}
@Override
public long getNextLoadPositionUs() {
// Pretend not to make loading progress, so that continueLoading keeps being called.
return 0;
}
@Override
public boolean continueLoading(long positionUs) {
allocations.add(allocator.allocate());
callback.onContinueLoadingRequested(this);
return true;
}
};
}
};
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder(context).setMediaSources(continuouslyAllocatingMediaSource).setLoadControl(loadControl).build();
ExoPlaybackException exception = assertThrows(ExoPlaybackException.class, () -> testRunner.start().blockUntilEnded(TIMEOUT_MS));
assertThat(exception.type).isEqualTo(ExoPlaybackException.TYPE_UNEXPECTED);
assertThat(exception.getUnexpectedException()).isInstanceOf(IllegalStateException.class);
}
Aggregations