Commit e961c1b5 by tonihei Committed by christosts

Update media controller position before pausing.

We stop estimating new position when pausing until we
receive a new position from the player. However, this
means that we will continue to return a possible stale
previous position. Updating the current position before
pausing solves this issue.

PiperOrigin-RevId: 503153982
parent 2cb4e3d7
...@@ -129,7 +129,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; ...@@ -129,7 +129,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
@Nullable private TextureView videoTextureView; @Nullable private TextureView videoTextureView;
private Size surfaceSize; private Size surfaceSize;
@Nullable private IMediaSession iSession; @Nullable private IMediaSession iSession;
private long lastReturnedCurrentPositionMs; private long currentPositionMs;
private long lastSetPlayWhenReadyCalledTimeMs; private long lastSetPlayWhenReadyCalledTimeMs;
@Nullable private PlayerInfo pendingPlayerInfo; @Nullable private PlayerInfo pendingPlayerInfo;
@Nullable private BundlingExclusions pendingBundlingExclusions; @Nullable private BundlingExclusions pendingBundlingExclusions;
...@@ -175,7 +175,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; ...@@ -175,7 +175,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
? null ? null
: new SessionServiceConnection(connectionHints); : new SessionServiceConnection(connectionHints);
flushCommandQueueHandler = new FlushCommandQueueHandler(applicationLooper); flushCommandQueueHandler = new FlushCommandQueueHandler(applicationLooper);
lastReturnedCurrentPositionMs = C.TIME_UNSET; currentPositionMs = C.TIME_UNSET;
lastSetPlayWhenReadyCalledTimeMs = C.TIME_UNSET; lastSetPlayWhenReadyCalledTimeMs = C.TIME_UNSET;
} }
...@@ -582,32 +582,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; ...@@ -582,32 +582,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
@Override @Override
public long getCurrentPosition() { public long getCurrentPosition() {
boolean receivedUpdatedPositionInfo = maybeUpdateCurrentPositionMs();
lastSetPlayWhenReadyCalledTimeMs < playerInfo.sessionPositionInfo.eventTimeMs; return currentPositionMs;
if (!playerInfo.isPlaying) {
if (receivedUpdatedPositionInfo || lastReturnedCurrentPositionMs == C.TIME_UNSET) {
lastReturnedCurrentPositionMs = playerInfo.sessionPositionInfo.positionInfo.positionMs;
}
return lastReturnedCurrentPositionMs;
}
if (!receivedUpdatedPositionInfo && lastReturnedCurrentPositionMs != C.TIME_UNSET) {
// Need an updated current position in order to make a new position estimation
return lastReturnedCurrentPositionMs;
}
long elapsedTimeMs =
(getInstance().getTimeDiffMs() != C.TIME_UNSET)
? getInstance().getTimeDiffMs()
: SystemClock.elapsedRealtime() - playerInfo.sessionPositionInfo.eventTimeMs;
long estimatedPositionMs =
playerInfo.sessionPositionInfo.positionInfo.positionMs
+ (long) (elapsedTimeMs * playerInfo.playbackParameters.speed);
if (playerInfo.sessionPositionInfo.durationMs != C.TIME_UNSET) {
estimatedPositionMs = min(estimatedPositionMs, playerInfo.sessionPositionInfo.durationMs);
}
lastReturnedCurrentPositionMs = estimatedPositionMs;
return lastReturnedCurrentPositionMs;
} }
@Override @Override
...@@ -1966,7 +1942,8 @@ import org.checkerframework.checker.nullness.qual.NonNull; ...@@ -1966,7 +1942,8 @@ import org.checkerframework.checker.nullness.qual.NonNull;
return; return;
} }
// Stop estimating content position until a new positionInfo arrives from the player // Update position and then stop estimating until a new positionInfo arrives from the player.
maybeUpdateCurrentPositionMs();
lastSetPlayWhenReadyCalledTimeMs = SystemClock.elapsedRealtime(); lastSetPlayWhenReadyCalledTimeMs = SystemClock.elapsedRealtime();
PlayerInfo playerInfo = PlayerInfo playerInfo =
this.playerInfo.copyWithPlayWhenReady( this.playerInfo.copyWithPlayWhenReady(
...@@ -2726,6 +2703,34 @@ import org.checkerframework.checker.nullness.qual.NonNull; ...@@ -2726,6 +2703,34 @@ import org.checkerframework.checker.nullness.qual.NonNull;
return playerInfo; return playerInfo;
} }
private void maybeUpdateCurrentPositionMs() {
boolean receivedUpdatedPositionInfo =
lastSetPlayWhenReadyCalledTimeMs < playerInfo.sessionPositionInfo.eventTimeMs;
if (!playerInfo.isPlaying) {
if (receivedUpdatedPositionInfo || currentPositionMs == C.TIME_UNSET) {
currentPositionMs = playerInfo.sessionPositionInfo.positionInfo.positionMs;
}
return;
}
if (!receivedUpdatedPositionInfo && currentPositionMs != C.TIME_UNSET) {
// Need an updated current position in order to make a new position estimation
return;
}
long elapsedTimeMs =
(getInstance().getTimeDiffMs() != C.TIME_UNSET)
? getInstance().getTimeDiffMs()
: SystemClock.elapsedRealtime() - playerInfo.sessionPositionInfo.eventTimeMs;
long estimatedPositionMs =
playerInfo.sessionPositionInfo.positionInfo.positionMs
+ (long) (elapsedTimeMs * playerInfo.playbackParameters.speed);
if (playerInfo.sessionPositionInfo.durationMs != C.TIME_UNSET) {
estimatedPositionMs = min(estimatedPositionMs, playerInfo.sessionPositionInfo.durationMs);
}
currentPositionMs = estimatedPositionMs;
}
private Period getPeriodWithNewWindowIndex(Timeline timeline, int periodIndex, int windowIndex) { private Period getPeriodWithNewWindowIndex(Timeline timeline, int periodIndex, int windowIndex) {
Period period = new Period(); Period period = new Period();
timeline.getPeriod(periodIndex, period); timeline.getPeriod(periodIndex, period);
......
...@@ -888,6 +888,37 @@ public class MediaControllerTest { ...@@ -888,6 +888,37 @@ public class MediaControllerTest {
} }
@Test @Test
public void getCurrentPosition_afterPause_returnsCorrectPosition() throws Exception {
long testCurrentPosition = 100L;
PlaybackParameters testPlaybackParameters = new PlaybackParameters(/* speed= */ 2.0f);
long testTimeDiff = 50L;
Bundle playerConfig =
new RemoteMediaSession.MockPlayerConfigBuilder()
.setPlaybackState(Player.STATE_READY)
.setPlayWhenReady(true)
.setCurrentPosition(testCurrentPosition)
.setDuration(10_000L)
.setPlaybackParameters(testPlaybackParameters)
.build();
remoteSession.setPlayer(playerConfig);
MediaController controller = controllerTestRule.createController(remoteSession.getToken());
long currentPositionMs =
threadTestRule
.getHandler()
.postAndSync(
() -> {
controller.setTimeDiffMs(testTimeDiff);
controller.pause();
return controller.getCurrentPosition();
});
long expectedCurrentPositionMs =
testCurrentPosition + (long) (testTimeDiff * testPlaybackParameters.speed);
assertThat(currentPositionMs).isEqualTo(expectedCurrentPositionMs);
}
@Test
public void getContentPosition_whenPlayingAd_doesNotAdvance() throws Exception { public void getContentPosition_whenPlayingAd_doesNotAdvance() throws Exception {
long testContentPosition = 100L; long testContentPosition = 100L;
Bundle playerConfig = Bundle playerConfig =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment