mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Handle !resetPosition as initial seek position.
The flag in ExoPlayer.prepare is documented as keeping the current window index and window position. We are currently using the current period UID and period position instead. This causes problems when the media source is changed but the position is not reset. Using the initial seek position instead ensures we actually use the window index and position. Issue:#5520 PiperOrigin-RevId: 236101024
This commit is contained in:
parent
377e550d0f
commit
2ae07936ba
@ -64,6 +64,9 @@
|
||||
([#5179](https://github.com/google/ExoPlayer/issues/5179)).
|
||||
* Fix issue with `TimelineQueueNavigator` not publishing the queue in shuffled
|
||||
order when in shuffle mode.
|
||||
* Fix issue where not resetting the position for a new `MediaSource` in calls to
|
||||
`ExoPlayer.prepare` causes an `IndexOutOfBoundsException`
|
||||
([#5520](https://github.com/google/ExoPlayer/issues/5520)).
|
||||
|
||||
### 2.9.6 ###
|
||||
|
||||
|
@ -436,6 +436,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
private void prepareInternal(MediaSource mediaSource, boolean resetPosition, boolean resetState) {
|
||||
pendingPrepareCount++;
|
||||
if (!resetPosition && pendingInitialSeekPosition == null && !playbackInfo.timeline.isEmpty()) {
|
||||
playbackInfo.timeline.getPeriodByUid(playbackInfo.periodId.periodUid, period);
|
||||
long windowPositionUs = playbackInfo.positionUs + period.getPositionInWindowUs();
|
||||
pendingInitialSeekPosition =
|
||||
new SeekPosition(Timeline.EMPTY, period.windowIndex, windowPositionUs);
|
||||
}
|
||||
resetInternal(
|
||||
/* resetRenderers= */ false, /* releaseMediaSource= */ true, resetPosition, resetState);
|
||||
loadControl.onPrepared();
|
||||
|
@ -1124,6 +1124,45 @@ public final class ExoPlayerTest {
|
||||
testRunner.assertPlayedPeriodIndices(0, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReprepareAndKeepPositionWithNewMediaSource() throws Exception {
|
||||
Timeline timeline =
|
||||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ new Object()));
|
||||
Timeline secondTimeline =
|
||||
new FakeTimeline(
|
||||
new TimelineWindowDefinition(/* periodCount= */ 1, /* id= */ new Object()));
|
||||
MediaSource secondSource = new FakeMediaSource(secondTimeline, /* manifest= */ null);
|
||||
AtomicLong positionAfterReprepare = new AtomicLong();
|
||||
ActionSchedule actionSchedule =
|
||||
new ActionSchedule.Builder("testReprepareAndKeepPositionWithNewMediaSource")
|
||||
.pause()
|
||||
.waitForPlaybackState(Player.STATE_READY)
|
||||
.playUntilPosition(/* windowIndex= */ 0, /* positionMs= */ 2000)
|
||||
.prepareSource(secondSource, /* resetPosition= */ false, /* resetState= */ true)
|
||||
.waitForTimelineChanged(secondTimeline)
|
||||
.executeRunnable(
|
||||
new PlayerRunnable() {
|
||||
@Override
|
||||
public void run(SimpleExoPlayer player) {
|
||||
positionAfterReprepare.set(player.getCurrentPosition());
|
||||
}
|
||||
})
|
||||
.play()
|
||||
.build();
|
||||
ExoPlayerTestRunner testRunner =
|
||||
new ExoPlayerTestRunner.Builder()
|
||||
.setTimeline(timeline)
|
||||
.setActionSchedule(actionSchedule)
|
||||
.build(context)
|
||||
.start()
|
||||
.blockUntilActionScheduleFinished(TIMEOUT_MS)
|
||||
.blockUntilEnded(TIMEOUT_MS);
|
||||
|
||||
testRunner.assertTimelinesEqual(timeline, Timeline.EMPTY, secondTimeline);
|
||||
assertThat(positionAfterReprepare.get()).isAtLeast(2000L);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopDuringPreparationOverwritesPreparation() throws Exception {
|
||||
Timeline timeline = new FakeTimeline(/* windowCount= */ 1);
|
||||
|
Loading…
x
Reference in New Issue
Block a user