Skip to content

Commit 6ee0171

Browse files
committed
fix: recover contiguous live media gaps
1 parent 967aab3 commit 6ee0171

3 files changed

Lines changed: 10 additions & 5 deletions

File tree

‎src/main/kotlin/dev/typetype/server/services/SabrLivePlayback.kt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,13 @@ internal fun SabrSessionHolder.isFutureLiveRequest(request: SabrSegmentRequest):
108108
internal fun SabrSessionHolder.isHistoricalLiveRequest(request: SabrSegmentRequest): Boolean {
109109
if (request.isInitializationSegment) return false
110110
val live = livePlaybackSnapshot()?.takeIf { it.active } ?: return false
111+
val observed = observedMediaSegment(request.format) ?: return false
112+
val requestEndMs = playbackSegmentEndMs(request.format, request.sequenceNumber)
113+
if (requestEndMs < live.headTimeMs - LIVE_HISTORICAL_REQUEST_TOLERANCE_MS) return true
111114
lastServedSequence(request.format)?.let { lastServed ->
112115
if (request.sequenceNumber in lastServed..lastServed + LIVE_FUTURE_SEGMENT_TOLERANCE) return false
113116
}
114-
val observed = observedMediaSegment(request.format) ?: return false
115-
if (request.sequenceNumber < observed.header.sequenceNumber) return true
116-
val requestEndMs = playbackSegmentEndMs(request.format, request.sequenceNumber)
117-
return requestEndMs < live.headTimeMs - LIVE_HISTORICAL_REQUEST_TOLERANCE_MS
117+
return request.sequenceNumber < observed.header.sequenceNumber
118118
}
119119

120120
internal fun SabrSessionHolder.liveRetryAfterMs(blockedRequests: List<SabrSegmentRequest> = emptyList()): Long =

‎src/test/kotlin/dev/typetype/server/services/SabrLiveFutureRequestTest.kt‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package dev.typetype.server.services
33
import io.mockk.every
44
import io.mockk.mockk
55
import org.junit.jupiter.api.Assertions.assertFalse
6+
import org.junit.jupiter.api.Assertions.assertTrue
67
import org.junit.jupiter.api.Test
78
import org.schabi.newpipe.extractor.services.youtube.sabr.SabrMediaHeader
89
import org.schabi.newpipe.extractor.services.youtube.sabr.SabrMediaSegment
@@ -63,8 +64,11 @@ class SabrLiveFutureRequestTest {
6364
lastRequestAt = Instant.EPOCH,
6465
)
6566
holder.observeMediaSegment(segment(audio.itag, 3_889, 7_776_000L))
67+
holder.setLastServedSequence(audio.itag, 3_889)
68+
val request = SabrSegmentRequest.media(audio, 3_890)
6669

67-
assertFalse(holder.isFutureLiveRequest(SabrSegmentRequest.media(audio, 3_890)))
70+
assertFalse(holder.isFutureLiveRequest(request))
71+
assertTrue(holder.isHistoricalLiveRequest(request))
6872
}
6973

7074
private fun format(itag: Int): YoutubeSabrFormat = mockk {

‎src/test/kotlin/dev/typetype/server/services/SabrSeekRepositionPumpTest.kt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ class SabrSeekRepositionPumpTest {
196196
every { session.pumpOnceStreamingForDemand(any(), request) } returns mockk(relaxed = true)
197197
val holder = holder(session, audio, video)
198198
holder.observeMediaSegment(mediaSegment(video.itag, sequence = 3_076))
199+
holder.setLastServedSequence(video.itag, 3_076)
199200
holder.requestSegmentDemand(request)
200201
assertFalse(holder.isFutureLiveRequest(request))
201202
assertEquals(DEFAULT_PLAYBACK_RETRY_MS, holder.liveRetryAfterMs(listOf(request)))

0 commit comments

Comments
 (0)