use of androidx.media3.exoplayer.source.MediaSource in project media by androidx.
the class ExoPlayerTest method clippedLoopedPeriodsArePlayedFully.
@Test
public void clippedLoopedPeriodsArePlayedFully() throws Exception {
long startPositionUs = 300_000;
long expectedDurationUs = 700_000;
MediaSource mediaSource = new ClippingMediaSource(new FakeMediaSource(), startPositionUs, startPositionUs + expectedDurationUs);
Clock clock = new FakeClock(/* isAutoAdvancing= */
true);
AtomicReference<Player> playerReference = new AtomicReference<>();
AtomicLong positionAtDiscontinuityMs = new AtomicLong(C.TIME_UNSET);
AtomicLong clockAtStartMs = new AtomicLong(C.TIME_UNSET);
AtomicLong clockAtDiscontinuityMs = new AtomicLong(C.TIME_UNSET);
Player.Listener playerListener = new Player.Listener() {
@Override
public void onPlaybackStateChanged(@Player.State int playbackState) {
if (playbackState == Player.STATE_READY && clockAtStartMs.get() == C.TIME_UNSET) {
clockAtStartMs.set(clock.elapsedRealtime());
}
}
@Override
public void onPositionDiscontinuity(@DiscontinuityReason int reason) {
if (reason == Player.DISCONTINUITY_REASON_AUTO_TRANSITION) {
positionAtDiscontinuityMs.set(playerReference.get().getCurrentPosition());
clockAtDiscontinuityMs.set(clock.elapsedRealtime());
}
}
};
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
playerReference.set(player);
player.addListener(playerListener);
}
}).pause().setRepeatMode(Player.REPEAT_MODE_ALL).waitForPlaybackState(Player.STATE_READY).playUntilPosition(/* mediaItemIndex= */
0, /* positionMs= */
1).playUntilStartOfMediaItem(/* mediaItemIndex= */
0).setRepeatMode(Player.REPEAT_MODE_OFF).play().build();
new ExoPlayerTestRunner.Builder(context).setClock(clock).setMediaSources(mediaSource).setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
assertThat(positionAtDiscontinuityMs.get()).isAtLeast(0L);
assertThat(clockAtDiscontinuityMs.get() - clockAtStartMs.get()).isAtLeast(Util.usToMs(expectedDurationUs));
}
use of androidx.media3.exoplayer.source.MediaSource in project media by androidx.
the class MediaSourceListTest method setMediaSources_mediaSourceListPrepared_notUsingLazyPreparation.
@Test
public void setMediaSources_mediaSourceListPrepared_notUsingLazyPreparation() {
ShuffleOrder.DefaultShuffleOrder shuffleOrder = new ShuffleOrder.DefaultShuffleOrder(/* length= */
2);
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> mediaSources = createFakeHoldersWithSources(/* useLazyPreparation= */
false, mockMediaSource1, mockMediaSource2);
mediaSourceList.prepare(/* mediaTransferListener= */
null);
mediaSourceList.setMediaSources(mediaSources, shuffleOrder);
// Verify sources are prepared.
verify(mockMediaSource1, times(1)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
verify(mockMediaSource2, times(1)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
// Set media items again. The second holder is re-used.
MediaSource mockMediaSource3 = mock(MediaSource.class);
when(mockMediaSource3.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
List<MediaSourceList.MediaSourceHolder> moreMediaSources = createFakeHoldersWithSources(/* useLazyPreparation= */
false, mockMediaSource3);
moreMediaSources.add(mediaSources.get(1));
mediaSourceList.setMediaSources(moreMediaSources, shuffleOrder);
// Expect removed holders and sources to be removed and released.
verify(mockMediaSource1, times(1)).releaseSource(any(MediaSource.MediaSourceCaller.class));
assertThat(mediaSources.get(0).isRemoved).isTrue();
// Expect re-used holder and source not to be removed but released.
verify(mockMediaSource2, times(1)).releaseSource(any(MediaSource.MediaSourceCaller.class));
assertThat(mediaSources.get(1).isRemoved).isFalse();
verify(mockMediaSource2, times(2)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
}
use of androidx.media3.exoplayer.source.MediaSource in project media by androidx.
the class MediaSourceListTest method prepareAndReprepareAfterRelease_expectSourcePreparationAfterMediaSourceListPrepare.
@Test
public void prepareAndReprepareAfterRelease_expectSourcePreparationAfterMediaSourceListPrepare() {
MediaSource mockMediaSource1 = mock(MediaSource.class);
when(mockMediaSource1.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
MediaSource mockMediaSource2 = mock(MediaSource.class);
when(mockMediaSource2.getMediaItem()).thenReturn(MINIMAL_MEDIA_ITEM);
mediaSourceList.setMediaSources(createFakeHoldersWithSources(/* useLazyPreparation= */
false, mockMediaSource1, mockMediaSource2), new ShuffleOrder.DefaultShuffleOrder(/* length= */
2));
// Verify prepare is called once on prepare.
verify(mockMediaSource1, times(0)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
verify(mockMediaSource2, times(0)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
mediaSourceList.prepare(/* mediaTransferListener= */
null);
assertThat(mediaSourceList.isPrepared()).isTrue();
// Verify prepare is called once on prepare.
verify(mockMediaSource1, times(1)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
verify(mockMediaSource2, times(1)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
mediaSourceList.release();
mediaSourceList.prepare(/* mediaTransferListener= */
null);
// Verify prepare is called a second time on re-prepare.
verify(mockMediaSource1, times(2)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
verify(mockMediaSource2, times(2)).prepareSource(any(MediaSource.MediaSourceCaller.class), /* mediaTransferListener= */
isNull(), any());
}
use of androidx.media3.exoplayer.source.MediaSource in project media by androidx.
the class ExoPlayerTest method pauseAtEndOfMediaItems_pausesPlaybackWhenEnded.
@Test
public void pauseAtEndOfMediaItems_pausesPlaybackWhenEnded() throws Exception {
TimelineWindowDefinition timelineWindowDefinition = new TimelineWindowDefinition(/* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
10 * C.MICROS_PER_SECOND);
MediaSource mediaSource = new FakeMediaSource(new FakeTimeline(timelineWindowDefinition));
AtomicInteger playbackStateAfterPause = new AtomicInteger(C.INDEX_UNSET);
AtomicLong positionAfterPause = new AtomicLong(C.TIME_UNSET);
AtomicInteger mediaItemIndexAfterPause = new AtomicInteger(C.INDEX_UNSET);
ActionSchedule actionSchedule = new ActionSchedule.Builder(TAG).waitForPlayWhenReady(true).waitForPlayWhenReady(false).executeRunnable(new PlayerRunnable() {
@Override
public void run(ExoPlayer player) {
playbackStateAfterPause.set(player.getPlaybackState());
mediaItemIndexAfterPause.set(player.getCurrentMediaItemIndex());
positionAfterPause.set(player.getContentPosition());
}
}).build();
new ExoPlayerTestRunner.Builder(context).setPauseAtEndOfMediaItems(true).setMediaSources(mediaSource).setActionSchedule(actionSchedule).build().start().blockUntilActionScheduleFinished(TIMEOUT_MS).blockUntilEnded(TIMEOUT_MS);
assertThat(playbackStateAfterPause.get()).isEqualTo(Player.STATE_ENDED);
assertThat(mediaItemIndexAfterPause.get()).isEqualTo(0);
assertThat(positionAfterPause.get()).isEqualTo(10_000);
}
use of androidx.media3.exoplayer.source.MediaSource in project media by androidx.
the class ExoPlayerTest method shortAdFollowedByUnpreparedAd_playbackDoesNotGetStuck.
@Test
public void shortAdFollowedByUnpreparedAd_playbackDoesNotGetStuck() throws Exception {
AdPlaybackState adPlaybackState = FakeTimeline.createAdPlaybackState(/* adsPerAdGroup= */
2, /* adGroupTimesUs...= */
0);
long shortAdDurationMs = 1_000;
adPlaybackState = adPlaybackState.withAdDurationsUs(new long[][] { { shortAdDurationMs, shortAdDurationMs } });
Timeline timeline = new FakeTimeline(new TimelineWindowDefinition(/* periodCount= */
1, /* id= */
0, /* isSeekable= */
true, /* isDynamic= */
false, /* durationUs= */
Util.msToUs(10000), adPlaybackState));
// Simulate the second ad not being prepared.
FakeMediaSource mediaSource = new FakeMediaSource(timeline, 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, FakeMediaPeriod.TrackDataFactory.singleSampleWithTimeUs(0), mediaSourceEventDispatcher, drmSessionManager, drmEventDispatcher, /* deferOnPrepared= */
id.adIndexInAdGroup == 1);
}
};
ExoPlayer player = new TestExoPlayerBuilder(context).build();
player.setMediaSource(mediaSource);
player.prepare();
player.play();
// The player is not stuck in the buffering state.
TestPlayerRunHelper.runUntilPlaybackState(player, Player.STATE_READY);
}
Aggregations