Search in sources :

Example 26 with FakeTimeline

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();
}
Also used : Listener(androidx.media3.common.Player.Listener) Player(androidx.media3.common.Player) InOrder(org.mockito.InOrder) FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) FakeTimeline(androidx.media3.test.utils.FakeTimeline) TimelineWindowDefinition(androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition) PositionInfo(androidx.media3.common.Player.PositionInfo) TestExoPlayerBuilder(androidx.media3.test.utils.TestExoPlayerBuilder) Test(org.junit.Test)

Example 27 with FakeTimeline

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();
}
Also used : Listener(androidx.media3.common.Player.Listener) Player(androidx.media3.common.Player) InOrder(org.mockito.InOrder) FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) FakeTimeline(androidx.media3.test.utils.FakeTimeline) ConcatenatingMediaSource(androidx.media3.exoplayer.source.ConcatenatingMediaSource) TimelineWindowDefinition(androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition) PositionInfo(androidx.media3.common.Player.PositionInfo) TestExoPlayerBuilder(androidx.media3.test.utils.TestExoPlayerBuilder) Test(org.junit.Test)

Example 28 with FakeTimeline

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);
}
Also used : FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) ActionSchedule(androidx.media3.test.utils.ActionSchedule) PlayerRunnable(androidx.media3.test.utils.ActionSchedule.PlayerRunnable) TestExoPlayerBuilder(androidx.media3.test.utils.TestExoPlayerBuilder) Timeline(androidx.media3.common.Timeline) NoUidTimeline(androidx.media3.test.utils.NoUidTimeline) FakeTimeline(androidx.media3.test.utils.FakeTimeline) SinglePeriodTimeline(androidx.media3.exoplayer.source.SinglePeriodTimeline) FakeTimeline(androidx.media3.test.utils.FakeTimeline) TimelineWindowDefinition(androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition) ConcatenatingMediaSource(androidx.media3.exoplayer.source.ConcatenatingMediaSource) ExoPlayerTestRunner(androidx.media3.test.utils.ExoPlayerTestRunner) Test(org.junit.Test)

Example 29 with FakeTimeline

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);
}
Also used : Timeline(androidx.media3.common.Timeline) NoUidTimeline(androidx.media3.test.utils.NoUidTimeline) FakeTimeline(androidx.media3.test.utils.FakeTimeline) SinglePeriodTimeline(androidx.media3.exoplayer.source.SinglePeriodTimeline) CompositeMediaSource(androidx.media3.exoplayer.source.CompositeMediaSource) ClippingMediaSource(androidx.media3.exoplayer.source.ClippingMediaSource) FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) MaskingMediaSource(androidx.media3.exoplayer.source.MaskingMediaSource) ServerSideAdInsertionMediaSource(androidx.media3.exoplayer.source.ads.ServerSideAdInsertionMediaSource) FakeAdaptiveMediaSource(androidx.media3.test.utils.FakeAdaptiveMediaSource) ConcatenatingMediaSource(androidx.media3.exoplayer.source.ConcatenatingMediaSource) MediaSource(androidx.media3.exoplayer.source.MediaSource) FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) ActionSchedule(androidx.media3.test.utils.ActionSchedule) PlayerRunnable(androidx.media3.test.utils.ActionSchedule.PlayerRunnable) FakeTimeline(androidx.media3.test.utils.FakeTimeline) TestExoPlayerBuilder(androidx.media3.test.utils.TestExoPlayerBuilder) ExoPlayerTestRunner(androidx.media3.test.utils.ExoPlayerTestRunner) Test(org.junit.Test)

Example 30 with FakeTimeline

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);
}
Also used : FakeMediaSource(androidx.media3.test.utils.FakeMediaSource) ActionSchedule(androidx.media3.test.utils.ActionSchedule) PlayerRunnable(androidx.media3.test.utils.ActionSchedule.PlayerRunnable) IOException(java.io.IOException) Timeline(androidx.media3.common.Timeline) NoUidTimeline(androidx.media3.test.utils.NoUidTimeline) FakeTimeline(androidx.media3.test.utils.FakeTimeline) SinglePeriodTimeline(androidx.media3.exoplayer.source.SinglePeriodTimeline) FakeTimeline(androidx.media3.test.utils.FakeTimeline) ExoPlayerTestRunner(androidx.media3.test.utils.ExoPlayerTestRunner) Test(org.junit.Test)

Aggregations

FakeTimeline (androidx.media3.test.utils.FakeTimeline)242 Test (org.junit.Test)240 Timeline (androidx.media3.common.Timeline)171 FakeMediaSource (androidx.media3.test.utils.FakeMediaSource)159 TestExoPlayerBuilder (androidx.media3.test.utils.TestExoPlayerBuilder)136 SinglePeriodTimeline (androidx.media3.exoplayer.source.SinglePeriodTimeline)118 TimelineWindowDefinition (androidx.media3.test.utils.FakeTimeline.TimelineWindowDefinition)117 NoUidTimeline (androidx.media3.test.utils.NoUidTimeline)117 ActionSchedule (androidx.media3.test.utils.ActionSchedule)98 ExoPlayerTestRunner (androidx.media3.test.utils.ExoPlayerTestRunner)87 MediaPeriodId (androidx.media3.exoplayer.source.MediaSource.MediaPeriodId)69 AdPlaybackState (androidx.media3.common.AdPlaybackState)63 ConcatenatingMediaSource (androidx.media3.exoplayer.source.ConcatenatingMediaSource)62 PlayerRunnable (androidx.media3.test.utils.ActionSchedule.PlayerRunnable)60 MediaSource (androidx.media3.exoplayer.source.MediaSource)57 Player (androidx.media3.common.Player)51 ServerSideAdInsertionMediaSource (androidx.media3.exoplayer.source.ads.ServerSideAdInsertionMediaSource)50 ClippingMediaSource (androidx.media3.exoplayer.source.ClippingMediaSource)49 CompositeMediaSource (androidx.media3.exoplayer.source.CompositeMediaSource)49 MaskingMediaSource (androidx.media3.exoplayer.source.MaskingMediaSource)49