mirror of
https://github.com/samsonjs/media.git
synced 2026-04-27 15:07:40 +00:00
Remove potential flakiness from ExoPlayerTest caused by multi-threading.
Some tests in ExoPlayerTest issue commands to the player from the test thread while the player is actively playing media (playWhenReady=true). Due to the indeterminate time taken to enqueue the commands on the playback thread, they may arrive when the player already proceeded to another window or finished playback. To ensure the tests are always deterministic, this change pauses playback in the tests where this may happen before issuing the commands. Also, for tests where we need to wait for a new window before issuing the next command, a new action is added which allows to play until a specified position. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=182535096
This commit is contained in:
parent
24f866e788
commit
4ba17bb690
3 changed files with 295 additions and 90 deletions
|
|
@ -252,23 +252,31 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED,
|
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED,
|
||||||
Player.TIMELINE_CHANGE_REASON_RESET, Player.TIMELINE_CHANGE_REASON_PREPARED);
|
Player.TIMELINE_CHANGE_REASON_RESET, Player.TIMELINE_CHANGE_REASON_PREPARED);
|
||||||
testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT)));
|
testRunner.assertTrackGroupsEqual(new TrackGroupArray(new TrackGroup(Builder.VIDEO_FORMAT)));
|
||||||
assertEquals(1, renderer.formatReadCount);
|
|
||||||
assertEquals(1, renderer.bufferReadCount);
|
|
||||||
assertTrue(renderer.isEnded);
|
assertTrue(renderer.isEnded);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testRepeatModeChanges() throws Exception {
|
public void testRepeatModeChanges() throws Exception {
|
||||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 3);
|
Timeline timeline = new FakeTimeline(/* windowCount= */ 3);
|
||||||
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testRepeatMode") // 0 -> 1
|
ActionSchedule actionSchedule =
|
||||||
.waitForPositionDiscontinuity().setRepeatMode(Player.REPEAT_MODE_ONE) // 1 -> 1
|
new ActionSchedule.Builder("testRepeatMode")
|
||||||
.waitForPositionDiscontinuity().setRepeatMode(Player.REPEAT_MODE_OFF) // 1 -> 2
|
.pause()
|
||||||
.waitForPositionDiscontinuity().setRepeatMode(Player.REPEAT_MODE_ONE) // 2 -> 2
|
.waitForTimelineChanged(timeline)
|
||||||
.waitForPositionDiscontinuity().setRepeatMode(Player.REPEAT_MODE_ALL) // 2 -> 0
|
.playUntilStartOfWindow(/* windowIndex= */ 1)
|
||||||
.waitForPositionDiscontinuity().setRepeatMode(Player.REPEAT_MODE_ONE) // 0 -> 0
|
.setRepeatMode(Player.REPEAT_MODE_ONE)
|
||||||
.waitForPositionDiscontinuity() // 0 -> 0
|
.playUntilStartOfWindow(/* windowIndex= */ 1)
|
||||||
.waitForPositionDiscontinuity().setRepeatMode(Player.REPEAT_MODE_OFF) // 0 -> end
|
.setRepeatMode(Player.REPEAT_MODE_OFF)
|
||||||
.build();
|
.playUntilStartOfWindow(/* windowIndex= */ 2)
|
||||||
|
.setRepeatMode(Player.REPEAT_MODE_ONE)
|
||||||
|
.playUntilStartOfWindow(/* windowIndex= */ 2)
|
||||||
|
.setRepeatMode(Player.REPEAT_MODE_ALL)
|
||||||
|
.playUntilStartOfWindow(/* windowIndex= */ 0)
|
||||||
|
.setRepeatMode(Player.REPEAT_MODE_ONE)
|
||||||
|
.playUntilStartOfWindow(/* windowIndex= */ 0)
|
||||||
|
.playUntilStartOfWindow(/* windowIndex= */ 0)
|
||||||
|
.setRepeatMode(Player.REPEAT_MODE_OFF)
|
||||||
|
.play()
|
||||||
|
.build();
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline).setRenderers(renderer).setActionSchedule(actionSchedule)
|
.setTimeline(timeline).setRenderers(renderer).setActionSchedule(actionSchedule)
|
||||||
.build().start().blockUntilEnded(TIMEOUT_MS);
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
@ -298,12 +306,18 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(false,
|
ConcatenatingMediaSource mediaSource = new ConcatenatingMediaSource(false,
|
||||||
new FakeShuffleOrder(3), fakeMediaSources);
|
new FakeShuffleOrder(3), fakeMediaSources);
|
||||||
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
FakeRenderer renderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testShuffleModeEnabled")
|
ActionSchedule actionSchedule =
|
||||||
.setRepeatMode(Player.REPEAT_MODE_ALL).waitForPositionDiscontinuity() // 0 -> 1
|
new ActionSchedule.Builder("testShuffleModeEnabled")
|
||||||
.setShuffleModeEnabled(true).waitForPositionDiscontinuity() // 1 -> 0
|
.pause()
|
||||||
.waitForPositionDiscontinuity().waitForPositionDiscontinuity() // 0 -> 2 -> 1
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
.setShuffleModeEnabled(false).setRepeatMode(Player.REPEAT_MODE_OFF) // 1 -> 2 -> end
|
.setRepeatMode(Player.REPEAT_MODE_ALL)
|
||||||
.build();
|
.playUntilStartOfWindow(/* windowIndex= */ 1)
|
||||||
|
.setShuffleModeEnabled(true)
|
||||||
|
.playUntilStartOfWindow(/* windowIndex= */ 1)
|
||||||
|
.setShuffleModeEnabled(false)
|
||||||
|
.setRepeatMode(Player.REPEAT_MODE_OFF)
|
||||||
|
.play()
|
||||||
|
.build();
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
||||||
.setMediaSource(mediaSource).setRenderers(renderer).setActionSchedule(actionSchedule)
|
.setMediaSource(mediaSource).setRenderers(renderer).setActionSchedule(actionSchedule)
|
||||||
.build().start().blockUntilEnded(TIMEOUT_MS);
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
@ -446,8 +460,13 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
return mediaPeriod;
|
return mediaPeriod;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testSeekDiscontinuityAdjust")
|
ActionSchedule actionSchedule =
|
||||||
.waitForPlaybackState(Player.STATE_READY).seek(10).build();
|
new ActionSchedule.Builder("testSeekDiscontinuityAdjust")
|
||||||
|
.pause()
|
||||||
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
|
.seek(10)
|
||||||
|
.play()
|
||||||
|
.build();
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder().setMediaSource(mediaSource)
|
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder().setMediaSource(mediaSource)
|
||||||
.setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
|
.setActionSchedule(actionSchedule).build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_SEEK,
|
testRunner.assertPositionDiscontinuityReasonsEqual(Player.DISCONTINUITY_REASON_SEEK,
|
||||||
|
|
@ -551,14 +570,19 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||||
final FakeTrackSelector trackSelector = new FakeTrackSelector();
|
final FakeTrackSelector trackSelector = new FakeTrackSelector();
|
||||||
ActionSchedule disableTrackAction = new ActionSchedule.Builder("testChangeTrackSelection")
|
ActionSchedule disableTrackAction =
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
new ActionSchedule.Builder("testChangeTrackSelection")
|
||||||
.executeRunnable(new Runnable() {
|
.pause()
|
||||||
@Override
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
public void run() {
|
.executeRunnable(
|
||||||
trackSelector.setRendererDisabled(0, true);
|
new Runnable() {
|
||||||
}
|
@Override
|
||||||
}).build();
|
public void run() {
|
||||||
|
trackSelector.setRendererDisabled(0, true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.play()
|
||||||
|
.build();
|
||||||
|
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setMediaSource(mediaSource)
|
.setMediaSource(mediaSource)
|
||||||
|
|
@ -590,14 +614,19 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
FakeRenderer videoRenderer = new FakeRenderer(Builder.VIDEO_FORMAT);
|
||||||
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
FakeRenderer audioRenderer = new FakeRenderer(Builder.AUDIO_FORMAT);
|
||||||
final FakeTrackSelector trackSelector = new FakeTrackSelector(/* reuse track selection */ true);
|
final FakeTrackSelector trackSelector = new FakeTrackSelector(/* reuse track selection */ true);
|
||||||
ActionSchedule disableTrackAction = new ActionSchedule.Builder("testReuseTrackSelection")
|
ActionSchedule disableTrackAction =
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
new ActionSchedule.Builder("testReuseTrackSelection")
|
||||||
.executeRunnable(new Runnable() {
|
.pause()
|
||||||
@Override
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
public void run() {
|
.executeRunnable(
|
||||||
trackSelector.setRendererDisabled(0, true);
|
new Runnable() {
|
||||||
}
|
@Override
|
||||||
}).build();
|
public void run() {
|
||||||
|
trackSelector.setRendererDisabled(0, true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.play()
|
||||||
|
.build();
|
||||||
|
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setMediaSource(mediaSource)
|
.setMediaSource(mediaSource)
|
||||||
|
|
@ -625,15 +654,20 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
Timeline timeline1 = new FakeTimeline(new TimelineWindowDefinition(false, false, 100000));
|
Timeline timeline1 = new FakeTimeline(new TimelineWindowDefinition(false, false, 100000));
|
||||||
final Timeline timeline2 = new FakeTimeline(new TimelineWindowDefinition(false, false, 20000));
|
final Timeline timeline2 = new FakeTimeline(new TimelineWindowDefinition(false, false, 20000));
|
||||||
final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, null, Builder.VIDEO_FORMAT);
|
final FakeMediaSource mediaSource = new FakeMediaSource(timeline1, null, Builder.VIDEO_FORMAT);
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testDynamicTimelineChangeReason")
|
ActionSchedule actionSchedule =
|
||||||
.waitForTimelineChanged(timeline1)
|
new ActionSchedule.Builder("testDynamicTimelineChangeReason")
|
||||||
.executeRunnable(new Runnable() {
|
.pause()
|
||||||
@Override
|
.waitForTimelineChanged(timeline1)
|
||||||
public void run() {
|
.executeRunnable(
|
||||||
mediaSource.setNewSourceInfo(timeline2, null);
|
new Runnable() {
|
||||||
}
|
@Override
|
||||||
})
|
public void run() {
|
||||||
.build();
|
mediaSource.setNewSourceInfo(timeline2, null);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.waitForTimelineChanged(timeline2)
|
||||||
|
.play()
|
||||||
|
.build();
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
||||||
.setMediaSource(mediaSource).setActionSchedule(actionSchedule)
|
.setMediaSource(mediaSource).setActionSchedule(actionSchedule)
|
||||||
.build().start().blockUntilEnded(TIMEOUT_MS);
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
@ -655,13 +689,17 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||||
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT)
|
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT)
|
||||||
);
|
);
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testRepreparationWithShuffle")
|
ActionSchedule actionSchedule =
|
||||||
// Wait for first preparation and enable shuffling. Plays period 0.
|
new ActionSchedule.Builder("testRepreparationWithShuffle")
|
||||||
.waitForPlaybackState(Player.STATE_READY).setShuffleModeEnabled(true)
|
// Wait for first preparation and enable shuffling. Plays period 0.
|
||||||
// Reprepare with second media source (keeping state, but with position reset).
|
.pause()
|
||||||
// Plays period 1 and 0 because of the reversed fake shuffle order.
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
.prepareSource(secondMediaSource, /* resetPosition= */ true, /* resetState= */ false)
|
.setShuffleModeEnabled(true)
|
||||||
.build();
|
// Reprepare with second media source (keeping state, but with position reset).
|
||||||
|
// Plays period 1 and 0 because of the reversed fake shuffle order.
|
||||||
|
.prepareSource(secondMediaSource, /* resetPosition= */ true, /* resetState= */ false)
|
||||||
|
.play()
|
||||||
|
.build();
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
||||||
.setMediaSource(firstMediaSource).setActionSchedule(actionSchedule)
|
.setMediaSource(firstMediaSource).setActionSchedule(actionSchedule)
|
||||||
.build().start().blockUntilEnded(TIMEOUT_MS);
|
.build().start().blockUntilEnded(TIMEOUT_MS);
|
||||||
|
|
@ -715,54 +753,96 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
|
|
||||||
public void testStopDoesNotResetPosition() throws Exception {
|
public void testStopDoesNotResetPosition() throws Exception {
|
||||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testStopDoesNotResetPosition")
|
final long[] positionHolder = new long[1];
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
ActionSchedule actionSchedule =
|
||||||
.stop()
|
new ActionSchedule.Builder("testStopDoesNotResetPosition")
|
||||||
.build();
|
.pause()
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
.setTimeline(timeline)
|
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 50)
|
||||||
.setActionSchedule(actionSchedule)
|
.stop()
|
||||||
.build()
|
.executeRunnable(
|
||||||
.start()
|
new PlayerRunnable() {
|
||||||
.blockUntilEnded(TIMEOUT_MS);
|
@Override
|
||||||
|
public void run(SimpleExoPlayer player) {
|
||||||
|
positionHolder[0] = player.getCurrentPosition();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
ExoPlayerTestRunner testRunner =
|
||||||
|
new ExoPlayerTestRunner.Builder()
|
||||||
|
.setTimeline(timeline)
|
||||||
|
.setActionSchedule(actionSchedule)
|
||||||
|
.build()
|
||||||
|
.start()
|
||||||
|
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
||||||
|
.blockUntilEnded(TIMEOUT_MS);
|
||||||
testRunner.assertTimelinesEqual(timeline);
|
testRunner.assertTimelinesEqual(timeline);
|
||||||
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
|
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
|
||||||
testRunner.assertNoPositionDiscontinuities();
|
testRunner.assertNoPositionDiscontinuities();
|
||||||
|
assertTrue(positionHolder[0] >= 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStopWithoutResetDoesNotResetPosition() throws Exception {
|
public void testStopWithoutResetDoesNotResetPosition() throws Exception {
|
||||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testStopWithoutResetDoesNotReset")
|
final long[] positionHolder = new long[1];
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
ActionSchedule actionSchedule =
|
||||||
.stop(/* reset= */ false)
|
new ActionSchedule.Builder("testStopWithoutResetDoesNotReset")
|
||||||
.build();
|
.pause()
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
.setTimeline(timeline)
|
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 50)
|
||||||
.setActionSchedule(actionSchedule)
|
.stop(/* reset= */ false)
|
||||||
.build()
|
.executeRunnable(
|
||||||
.start()
|
new PlayerRunnable() {
|
||||||
.blockUntilEnded(TIMEOUT_MS);
|
@Override
|
||||||
|
public void run(SimpleExoPlayer player) {
|
||||||
|
positionHolder[0] = player.getCurrentPosition();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
ExoPlayerTestRunner testRunner =
|
||||||
|
new ExoPlayerTestRunner.Builder()
|
||||||
|
.setTimeline(timeline)
|
||||||
|
.setActionSchedule(actionSchedule)
|
||||||
|
.build()
|
||||||
|
.start()
|
||||||
|
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
||||||
|
.blockUntilEnded(TIMEOUT_MS);
|
||||||
testRunner.assertTimelinesEqual(timeline);
|
testRunner.assertTimelinesEqual(timeline);
|
||||||
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
|
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED);
|
||||||
testRunner.assertNoPositionDiscontinuities();
|
testRunner.assertNoPositionDiscontinuities();
|
||||||
|
assertTrue(positionHolder[0] >= 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStopWithResetDoesResetPosition() throws Exception {
|
public void testStopWithResetDoesResetPosition() throws Exception {
|
||||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||||
ActionSchedule actionSchedule = new ActionSchedule.Builder("testStopWithResetDoesReset")
|
final long[] positionHolder = new long[1];
|
||||||
.waitForPlaybackState(Player.STATE_READY)
|
ActionSchedule actionSchedule =
|
||||||
.stop(/* reset= */ true)
|
new ActionSchedule.Builder("testStopWithResetDoesReset")
|
||||||
.build();
|
.pause()
|
||||||
ExoPlayerTestRunner testRunner = new ExoPlayerTestRunner.Builder()
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
.setTimeline(timeline)
|
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 50)
|
||||||
.setActionSchedule(actionSchedule)
|
.stop(/* reset= */ true)
|
||||||
.build()
|
.executeRunnable(
|
||||||
.start()
|
new PlayerRunnable() {
|
||||||
.blockUntilEnded(TIMEOUT_MS);
|
@Override
|
||||||
|
public void run(SimpleExoPlayer player) {
|
||||||
|
positionHolder[0] = player.getCurrentPosition();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
ExoPlayerTestRunner testRunner =
|
||||||
|
new ExoPlayerTestRunner.Builder()
|
||||||
|
.setTimeline(timeline)
|
||||||
|
.setActionSchedule(actionSchedule)
|
||||||
|
.build()
|
||||||
|
.start()
|
||||||
|
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
||||||
|
.blockUntilEnded(TIMEOUT_MS);
|
||||||
testRunner.assertTimelinesEqual(timeline, Timeline.EMPTY);
|
testRunner.assertTimelinesEqual(timeline, Timeline.EMPTY);
|
||||||
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED,
|
testRunner.assertTimelineChangeReasonsEqual(Player.TIMELINE_CHANGE_REASON_PREPARED,
|
||||||
Player.TIMELINE_CHANGE_REASON_RESET);
|
Player.TIMELINE_CHANGE_REASON_RESET);
|
||||||
testRunner.assertNoPositionDiscontinuities();
|
testRunner.assertNoPositionDiscontinuities();
|
||||||
|
assertEquals(0, positionHolder[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStopWithoutResetReleasesMediaSource() throws Exception {
|
public void testStopWithoutResetReleasesMediaSource() throws Exception {
|
||||||
|
|
@ -1022,8 +1102,10 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(target, /* positionMs= */ 50)
|
.sendMessage(target, /* positionMs= */ 50)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1039,8 +1121,10 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForTimelineChanged(timeline)
|
.waitForTimelineChanged(timeline)
|
||||||
.sendMessage(target, /* positionMs= */ 50)
|
.sendMessage(target, /* positionMs= */ 50)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1057,9 +1141,11 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target80 = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target80 = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(target80, /* positionMs= */ 80)
|
.sendMessage(target80, /* positionMs= */ 80)
|
||||||
.sendMessage(target50, /* positionMs= */ 50)
|
.sendMessage(target50, /* positionMs= */ 50)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1078,9 +1164,11 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target2 = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target2 = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(target1, /* positionMs= */ 50)
|
.sendMessage(target1, /* positionMs= */ 50)
|
||||||
.sendMessage(target2, /* positionMs= */ 50)
|
.sendMessage(target2, /* positionMs= */ 50)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1098,8 +1186,10 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(target, /* positionMs= */ 50)
|
.sendMessage(target, /* positionMs= */ 50)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1120,11 +1210,13 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
long duration2Ms = timeline.getWindow(1, new Window()).getDurationMs();
|
long duration2Ms = timeline.getWindow(1, new Window()).getDurationMs();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(targetStartFirstPeriod, /* windowIndex= */ 0, /* positionMs= */ 0)
|
.sendMessage(targetStartFirstPeriod, /* windowIndex= */ 0, /* positionMs= */ 0)
|
||||||
.sendMessage(targetEndMiddlePeriod, /* windowIndex= */ 0, /* positionMs= */ duration1Ms)
|
.sendMessage(targetEndMiddlePeriod, /* windowIndex= */ 0, /* positionMs= */ duration1Ms)
|
||||||
.sendMessage(targetStartMiddlePeriod, /* windowIndex= */ 1, /* positionMs= */ 0)
|
.sendMessage(targetStartMiddlePeriod, /* windowIndex= */ 1, /* positionMs= */ 0)
|
||||||
.sendMessage(targetEndLastPeriod, /* windowIndex= */ 1, /* positionMs= */ duration2Ms)
|
.sendMessage(targetEndLastPeriod, /* windowIndex= */ 1, /* positionMs= */ duration2Ms)
|
||||||
|
.play()
|
||||||
// Add additional prepare at end and wait until it's processed to ensure that
|
// Add additional prepare at end and wait until it's processed to ensure that
|
||||||
// messages sent at end of playback are received before test ends.
|
// messages sent at end of playback are received before test ends.
|
||||||
.waitForPlaybackState(Player.STATE_ENDED)
|
.waitForPlaybackState(Player.STATE_ENDED)
|
||||||
|
|
@ -1193,9 +1285,11 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(target, /* positionMs= */ 50)
|
.sendMessage(target, /* positionMs= */ 50)
|
||||||
.seek(/* positionMs= */ 51)
|
.seek(/* positionMs= */ 51)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1211,9 +1305,11 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.sendMessage(target, /* positionMs= */ 50)
|
.sendMessage(target, /* positionMs= */ 50)
|
||||||
.waitForTimelineChanged(timeline)
|
.waitForTimelineChanged(timeline)
|
||||||
.seek(/* positionMs= */ 51)
|
.seek(/* positionMs= */ 51)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1229,9 +1325,11 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(target, /* positionMs= */ 50)
|
.sendMessage(target, /* positionMs= */ 50)
|
||||||
.setRepeatMode(Player.REPEAT_MODE_ALL)
|
.setRepeatMode(Player.REPEAT_MODE_ALL)
|
||||||
|
.play()
|
||||||
.waitForPositionDiscontinuity()
|
.waitForPositionDiscontinuity()
|
||||||
.setRepeatMode(Player.REPEAT_MODE_OFF)
|
.setRepeatMode(Player.REPEAT_MODE_OFF)
|
||||||
.build();
|
.build();
|
||||||
|
|
@ -1250,6 +1348,7 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(
|
.sendMessage(
|
||||||
target,
|
target,
|
||||||
|
|
@ -1257,8 +1356,10 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
/* positionMs= */ 50,
|
/* positionMs= */ 50,
|
||||||
/* deleteAfterDelivery= */ false)
|
/* deleteAfterDelivery= */ false)
|
||||||
.setRepeatMode(Player.REPEAT_MODE_ALL)
|
.setRepeatMode(Player.REPEAT_MODE_ALL)
|
||||||
.waitForPositionDiscontinuity()
|
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 1)
|
||||||
|
.playUntilStartOfWindow(/* windowIndex= */ 0)
|
||||||
.setRepeatMode(Player.REPEAT_MODE_OFF)
|
.setRepeatMode(Player.REPEAT_MODE_OFF)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1281,6 +1382,7 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForTimelineChanged(timeline)
|
.waitForTimelineChanged(timeline)
|
||||||
.sendMessage(target, /* positionMs= */ 50)
|
.sendMessage(target, /* positionMs= */ 50)
|
||||||
.executeRunnable(
|
.executeRunnable(
|
||||||
|
|
@ -1290,6 +1392,8 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
mediaSource.setNewSourceInfo(secondTimeline, null);
|
mediaSource.setNewSourceInfo(secondTimeline, null);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.waitForTimelineChanged(secondTimeline)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setMediaSource(mediaSource)
|
.setMediaSource(mediaSource)
|
||||||
|
|
@ -1306,8 +1410,10 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.waitForPlaybackState(Player.STATE_BUFFERING)
|
||||||
.sendMessage(target, /* windowIndex = */ 2, /* positionMs= */ 50)
|
.sendMessage(target, /* windowIndex = */ 2, /* positionMs= */ 50)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1324,8 +1430,10 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForTimelineChanged(timeline)
|
.waitForTimelineChanged(timeline)
|
||||||
.sendMessage(target, /* windowIndex = */ 2, /* positionMs= */ 50)
|
.sendMessage(target, /* windowIndex = */ 2, /* positionMs= */ 50)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setTimeline(timeline)
|
||||||
|
|
@ -1350,6 +1458,7 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
|
.pause()
|
||||||
.waitForTimelineChanged(timeline)
|
.waitForTimelineChanged(timeline)
|
||||||
.sendMessage(target, /* windowIndex = */ 1, /* positionMs= */ 50)
|
.sendMessage(target, /* windowIndex = */ 1, /* positionMs= */ 50)
|
||||||
.executeRunnable(
|
.executeRunnable(
|
||||||
|
|
@ -1361,6 +1470,7 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
})
|
})
|
||||||
.waitForTimelineChanged(secondTimeline)
|
.waitForTimelineChanged(secondTimeline)
|
||||||
.seek(/* windowIndex= */ 0, /* positionMs= */ 0)
|
.seek(/* windowIndex= */ 0, /* positionMs= */ 0)
|
||||||
|
.play()
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setMediaSource(mediaSource)
|
.setMediaSource(mediaSource)
|
||||||
|
|
@ -1373,23 +1483,30 @@ public final class ExoPlayerTest extends TestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSendMessagesNonLinearPeriodOrder() throws Exception {
|
public void testSendMessagesNonLinearPeriodOrder() throws Exception {
|
||||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 3);
|
Timeline fakeTimeline = new FakeTimeline(/* windowCount= */ 1);
|
||||||
|
MediaSource[] fakeMediaSources = {
|
||||||
|
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||||
|
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT),
|
||||||
|
new FakeMediaSource(fakeTimeline, null, Builder.VIDEO_FORMAT)
|
||||||
|
};
|
||||||
|
ConcatenatingMediaSource mediaSource =
|
||||||
|
new ConcatenatingMediaSource(false, new FakeShuffleOrder(3), fakeMediaSources);
|
||||||
PositionGrabbingMessageTarget target1 = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target1 = new PositionGrabbingMessageTarget();
|
||||||
PositionGrabbingMessageTarget target2 = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target2 = new PositionGrabbingMessageTarget();
|
||||||
PositionGrabbingMessageTarget target3 = new PositionGrabbingMessageTarget();
|
PositionGrabbingMessageTarget target3 = new PositionGrabbingMessageTarget();
|
||||||
ActionSchedule actionSchedule =
|
ActionSchedule actionSchedule =
|
||||||
new ActionSchedule.Builder("testSendMessages")
|
new ActionSchedule.Builder("testSendMessages")
|
||||||
.waitForPlaybackState(Player.STATE_BUFFERING)
|
.pause()
|
||||||
|
.waitForPlaybackState(Player.STATE_READY)
|
||||||
.sendMessage(target1, /* windowIndex = */ 0, /* positionMs= */ 50)
|
.sendMessage(target1, /* windowIndex = */ 0, /* positionMs= */ 50)
|
||||||
.sendMessage(target2, /* windowIndex = */ 1, /* positionMs= */ 50)
|
.sendMessage(target2, /* windowIndex = */ 1, /* positionMs= */ 50)
|
||||||
.sendMessage(target3, /* windowIndex = */ 2, /* positionMs= */ 50)
|
.sendMessage(target3, /* windowIndex = */ 2, /* positionMs= */ 50)
|
||||||
.waitForTimelineChanged(timeline)
|
.setShuffleModeEnabled(true)
|
||||||
.seek(/* windowIndex= */ 1, /* positionMs= */ 0)
|
.seek(/* windowIndex= */ 2, /* positionMs= */ 0)
|
||||||
.waitForPositionDiscontinuity()
|
.play()
|
||||||
.seek(/* windowIndex= */ 0, /* positionMs= */ 0)
|
|
||||||
.build();
|
.build();
|
||||||
new ExoPlayerTestRunner.Builder()
|
new ExoPlayerTestRunner.Builder()
|
||||||
.setTimeline(timeline)
|
.setMediaSource(mediaSource)
|
||||||
.setActionSchedule(actionSchedule)
|
.setActionSchedule(actionSchedule)
|
||||||
.build()
|
.build()
|
||||||
.start()
|
.start()
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.testutil;
|
package com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.ExoPlayer;
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.Player;
|
import com.google.android.exoplayer2.Player;
|
||||||
|
|
@ -411,7 +413,7 @@ public abstract class Action {
|
||||||
} else {
|
} else {
|
||||||
message.setPosition(positionMs);
|
message.setPosition(positionMs);
|
||||||
}
|
}
|
||||||
message.setHandler(new android.os.Handler());
|
message.setHandler(new Handler());
|
||||||
message.setDeleteAfterDelivery(deleteAfterDelivery);
|
message.setDeleteAfterDelivery(deleteAfterDelivery);
|
||||||
message.send();
|
message.send();
|
||||||
}
|
}
|
||||||
|
|
@ -441,6 +443,68 @@ public abstract class Action {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a play action to be executed, waits until the player reaches the specified position,
|
||||||
|
* and pauses the player again.
|
||||||
|
*/
|
||||||
|
public static final class PlayUntilPosition extends Action {
|
||||||
|
|
||||||
|
private final int windowIndex;
|
||||||
|
private final long positionMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tag A tag to use for logging.
|
||||||
|
* @param windowIndex The window index at which the player should be paused again.
|
||||||
|
* @param positionMs The position in that window at which the player should be paused again.
|
||||||
|
*/
|
||||||
|
public PlayUntilPosition(String tag, int windowIndex, long positionMs) {
|
||||||
|
super(tag, "PlayUntilPosition:" + windowIndex + "," + positionMs);
|
||||||
|
this.windowIndex = windowIndex;
|
||||||
|
this.positionMs = positionMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doActionAndScheduleNextImpl(
|
||||||
|
final SimpleExoPlayer player,
|
||||||
|
final MappingTrackSelector trackSelector,
|
||||||
|
final Surface surface,
|
||||||
|
final HandlerWrapper handler,
|
||||||
|
final ActionNode nextAction) {
|
||||||
|
// Schedule one message on the playback thread to pause the player immediately.
|
||||||
|
player
|
||||||
|
.createMessage(
|
||||||
|
new Target() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(int messageType, Object payload)
|
||||||
|
throws ExoPlaybackException {
|
||||||
|
player.setPlayWhenReady(/* playWhenReady= */ false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setPosition(windowIndex, positionMs)
|
||||||
|
.send();
|
||||||
|
// Schedule another message on this test thread to continue action schedule.
|
||||||
|
player
|
||||||
|
.createMessage(
|
||||||
|
new Target() {
|
||||||
|
@Override
|
||||||
|
public void handleMessage(int messageType, Object payload)
|
||||||
|
throws ExoPlaybackException {
|
||||||
|
nextAction.schedule(player, trackSelector, surface, handler);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setPosition(windowIndex, positionMs)
|
||||||
|
.setHandler(new Handler())
|
||||||
|
.send();
|
||||||
|
player.setPlayWhenReady(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doActionImpl(
|
||||||
|
SimpleExoPlayer player, MappingTrackSelector trackSelector, Surface surface) {
|
||||||
|
// Not triggered.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waits for {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)}.
|
* Waits for {@link Player.EventListener#onTimelineChanged(Timeline, Object, int)}.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ import com.google.android.exoplayer2.Timeline;
|
||||||
import com.google.android.exoplayer2.source.MediaSource;
|
import com.google.android.exoplayer2.source.MediaSource;
|
||||||
import com.google.android.exoplayer2.testutil.Action.ClearVideoSurface;
|
import com.google.android.exoplayer2.testutil.Action.ClearVideoSurface;
|
||||||
import com.google.android.exoplayer2.testutil.Action.ExecuteRunnable;
|
import com.google.android.exoplayer2.testutil.Action.ExecuteRunnable;
|
||||||
|
import com.google.android.exoplayer2.testutil.Action.PlayUntilPosition;
|
||||||
import com.google.android.exoplayer2.testutil.Action.PrepareSource;
|
import com.google.android.exoplayer2.testutil.Action.PrepareSource;
|
||||||
import com.google.android.exoplayer2.testutil.Action.Seek;
|
import com.google.android.exoplayer2.testutil.Action.Seek;
|
||||||
import com.google.android.exoplayer2.testutil.Action.SendMessages;
|
import com.google.android.exoplayer2.testutil.Action.SendMessages;
|
||||||
|
|
@ -229,6 +230,29 @@ public final class ActionSchedule {
|
||||||
return apply(new SetPlayWhenReady(tag, true));
|
return apply(new SetPlayWhenReady(tag, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a play action to be executed, waits until the player reaches the specified
|
||||||
|
* position, and pauses the player again.
|
||||||
|
*
|
||||||
|
* @param windowIndex The window index at which the player should be paused again.
|
||||||
|
* @param positionMs The position in that window at which the player should be paused again.
|
||||||
|
* @return The builder, for convenience.
|
||||||
|
*/
|
||||||
|
public Builder playUntilPosition(int windowIndex, long positionMs) {
|
||||||
|
return apply(new PlayUntilPosition(tag, windowIndex, positionMs));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedules a play action to be executed, waits until the player reaches the start of the
|
||||||
|
* specified window, and pauses the player again.
|
||||||
|
*
|
||||||
|
* @param windowIndex The window index at which the player should be paused again.
|
||||||
|
* @return The builder, for convenience.
|
||||||
|
*/
|
||||||
|
public Builder playUntilStartOfWindow(int windowIndex) {
|
||||||
|
return apply(new PlayUntilPosition(tag, windowIndex, /* positionMs= */ 0));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schedules a pause action to be executed.
|
* Schedules a pause action to be executed.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue