fix(android): effectiveDuration uses desiredIdx so duration tracks the displayed title
android / Build + lint + test (push) Successful in 4m2s
android / Build + lint + test (push) Successful in 4m2s
This commit is contained in:
@@ -462,6 +462,8 @@ class PlayerController @Inject constructor(
|
|||||||
upnpActive,
|
upnpActive,
|
||||||
remoteState.durationMs,
|
remoteState.durationMs,
|
||||||
player.duration,
|
player.duration,
|
||||||
|
desiredIdx = idx,
|
||||||
|
controllerIdx = idx,
|
||||||
),
|
),
|
||||||
bufferedPositionMs = player.bufferedPosition.coerceAtLeast(0),
|
bufferedPositionMs = player.bufferedPosition.coerceAtLeast(0),
|
||||||
playbackError = player.playerError?.message,
|
playbackError = player.playerError?.message,
|
||||||
@@ -525,7 +527,13 @@ class PlayerController @Inject constructor(
|
|||||||
val desiredIdx = desiredQueueIndex(controller, upnpActive)
|
val desiredIdx = desiredQueueIndex(controller, upnpActive)
|
||||||
val current = uiStateInternal.value
|
val current = uiStateInternal.value
|
||||||
val newPos = effectivePosition.coerceAtLeast(0)
|
val newPos = effectivePosition.coerceAtLeast(0)
|
||||||
val newDur = effectiveDuration(upnpActive, remoteState.durationMs, controller.duration)
|
val newDur = effectiveDuration(
|
||||||
|
upnpActive,
|
||||||
|
remoteState.durationMs,
|
||||||
|
controller.duration,
|
||||||
|
desiredIdx = desiredIdx,
|
||||||
|
controllerIdx = controller.currentMediaItemIndex,
|
||||||
|
)
|
||||||
val newBuf = controller.bufferedPosition.coerceAtLeast(0)
|
val newBuf = controller.bufferedPosition.coerceAtLeast(0)
|
||||||
// Track adjustments are forward-only AND suppressed while a user
|
// Track adjustments are forward-only AND suppressed while a user
|
||||||
// transport press is pending Sonos confirmation. Together those keep
|
// transport press is pending Sonos confirmation. Together those keep
|
||||||
@@ -691,11 +699,22 @@ class PlayerController @Inject constructor(
|
|||||||
* until the first SOAP poll lands.
|
* until the first SOAP poll lands.
|
||||||
*/
|
*/
|
||||||
@Suppress("ReturnCount") // 3-tier fallback reads cleanest as a ladder of early returns
|
@Suppress("ReturnCount") // 3-tier fallback reads cleanest as a ladder of early returns
|
||||||
private fun effectiveDuration(upnpActive: Boolean, remoteMs: Long, localMs: Long): Long {
|
private fun effectiveDuration(
|
||||||
|
upnpActive: Boolean,
|
||||||
|
remoteMs: Long,
|
||||||
|
localMs: Long,
|
||||||
|
desiredIdx: Int,
|
||||||
|
controllerIdx: Int,
|
||||||
|
): Long {
|
||||||
if (upnpActive && remoteMs > 0) return remoteMs
|
if (upnpActive && remoteMs > 0) return remoteMs
|
||||||
if (localMs > 0) return localMs
|
// Tier 2 (wrapped player's probed duration) only valid when the
|
||||||
val idx = mediaController?.currentMediaItemIndex ?: 0
|
// wrapped player is on the same track we're trying to show. After a
|
||||||
val ref = queueRefs.getOrNull(idx) ?: return 0
|
// Sonos natural advance the polling tick updates desiredIdx from
|
||||||
|
// Sonos's truth while controllerIdx is briefly stale -- using the
|
||||||
|
// wrapped player's duration here would surface the old track's
|
||||||
|
// length under the new track's title.
|
||||||
|
if (localMs > 0 && controllerIdx == desiredIdx) return localMs
|
||||||
|
val ref = queueRefs.getOrNull(desiredIdx) ?: return 0
|
||||||
return ref.durationSec.toLong() * MS_PER_SECOND
|
return ref.durationSec.toLong() * MS_PER_SECOND
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user