@@ -91,36 +91,47 @@ public class AudioNavigator<S : Configurable.Settings, P : Configurable.Preferen
91
91
.mapNotNull { it.duration }
92
92
.takeIf { it.size == readingOrder.items.size }
93
93
?.sum()
94
+
95
+ val coercedOffset =
96
+ playback.coerceOffset(currentItem.duration)
97
+
94
98
val totalProgression =
95
99
if (itemStartPosition == null ) {
96
100
null
97
101
} else {
98
- readingOrder.duration?.let { (itemStartPosition + playback.offset ) / it }
102
+ readingOrder.duration?.let { (itemStartPosition + coercedOffset ) / it }
99
103
}
100
104
101
105
val locator = requireNotNull(publication.locatorFromLink(link))
102
106
locator.copyWithLocations(
103
- fragments = listOf (" t=${playback.offset .inWholeSeconds} " ),
104
- progression = item.duration?.let { playback.offset / it },
107
+ fragments = listOf (" t=${coercedOffset .inWholeSeconds} " ),
108
+ progression = item.duration?.let { coercedOffset / it },
105
109
totalProgression = totalProgression
106
110
)
107
111
}
108
112
109
113
override val playback: StateFlow <Playback > =
110
114
audioEngine.playback.mapStateIn(coroutineScope) { playback ->
115
+ val itemDuration =
116
+ readingOrder.items[playback.index].duration
117
+
118
+ val coercedOffset =
119
+ playback.coerceOffset(itemDuration)
120
+
111
121
Playback (
112
122
playback.state.toState(),
113
123
playback.playWhenReady,
114
124
playback.index,
115
- playback.offset ,
125
+ coercedOffset ,
116
126
playback.buffered
117
127
)
118
128
}
119
129
120
130
override val location: StateFlow <Location > =
121
131
audioEngine.playback.mapStateIn(coroutineScope) {
122
132
val currentItem = readingOrder.items[it.index]
123
- Location (currentItem.href, it.offset)
133
+ val coercedOffset = it.coerceOffset(currentItem.duration)
134
+ Location (currentItem.href, coercedOffset)
124
135
}
125
136
126
137
override fun play () {
@@ -178,4 +189,11 @@ public class AudioNavigator<S : Configurable.Settings, P : Configurable.Preferen
178
189
is AudioEngine .State .Buffering -> State .Buffering
179
190
is AudioEngine .State .Failure -> State .Failure (error)
180
191
}
192
+
193
+ private fun AudioEngine.Playback.coerceOffset (duration : Duration ? ): Duration =
194
+ if (duration == null ) {
195
+ offset
196
+ } else {
197
+ offset.coerceAtMost(duration)
198
+ }
181
199
}
0 commit comments