Skip to content

Commit

Permalink
Update media controller position before pausing.
Browse files Browse the repository at this point in the history
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
(cherry picked from commit e961c1b)
  • Loading branch information
tonihei authored and christosts committed Jan 25, 2023
1 parent 5b18c2d commit 28e3780
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
@Nullable private TextureView videoTextureView;
private Size surfaceSize;
@Nullable private IMediaSession iSession;
private long lastReturnedCurrentPositionMs;
private long currentPositionMs;
private long lastSetPlayWhenReadyCalledTimeMs;
@Nullable private PlayerInfo pendingPlayerInfo;
@Nullable private BundlingExclusions pendingBundlingExclusions;
Expand Down Expand Up @@ -175,7 +175,7 @@ public MediaControllerImplBase(
? null
: new SessionServiceConnection(connectionHints);
flushCommandQueueHandler = new FlushCommandQueueHandler(applicationLooper);
lastReturnedCurrentPositionMs = C.TIME_UNSET;
currentPositionMs = C.TIME_UNSET;
lastSetPlayWhenReadyCalledTimeMs = C.TIME_UNSET;
}

Expand Down Expand Up @@ -582,32 +582,8 @@ public long getDuration() {

@Override
public long getCurrentPosition() {
boolean receivedUpdatedPositionInfo =
lastSetPlayWhenReadyCalledTimeMs < playerInfo.sessionPositionInfo.eventTimeMs;
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;
maybeUpdateCurrentPositionMs();
return currentPositionMs;
}

@Override
Expand Down Expand Up @@ -1966,7 +1942,8 @@ private void setPlayWhenReady(
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();
PlayerInfo playerInfo =
this.playerInfo.copyWithPlayWhenReady(
Expand Down Expand Up @@ -2726,6 +2703,34 @@ private PlayerInfo maskTimelineAndPositionInfo(
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) {
Period period = new Period();
timeline.getPeriod(periodIndex, period);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,37 @@ public void getCurrentPosition_whenPlaying_advances() throws Exception {
assertThat(currentPositionMs).isEqualTo(expectedCurrentPositionMs);
}

@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 {
long testContentPosition = 100L;
Expand Down

0 comments on commit 28e3780

Please sign in to comment.