Skip to content

Sequential EVENT startup: the playlist is held for 2 published durations (= 3 segment opens) and the spacing scan spends the origin's non-replayable prefix #370

Description

@tschuegy

Symptom

On a slow or stalling origin, a sequential-origin session (AetherEngine 6.25.1, tvOS 26.6, Xtream timeshift .ts) never starts: AVPlayer's first /media.m3u8 GET is held for the full 30 s startup wait and the asset load times out (NSURLError -1008 / CoreMedia -12884) even though two segments were already produced and ~12 s of media sat on disk:

[HLSSegmentProducer] seg-0.m4s captured (2336504 B)
[HLSSegmentProducer] #65 ledger seg-1 base=0 itemAxis=6.000s sourceStart=32076.800s planSource=32074.800s drift=2.000s shift=32070.800s
[HLSSegmentProducer] seg-1.m4s captured (2308798 B)
... 30 s later ...
[NativeAVPlayerHost] #8 asset.load(duration) failed: NSURLErrorDomain/-1008 ... underlying=CoreMediaErrorDomain/-12884
[HLSLocalServer] media.m3u8 tail: ... #EXTINF:6.000, / seg0.mp4
[HLSLocalServer] -> 200 /media.m3u8 bytes=176

Cause — two compounding startup costs

  1. The gate demands 2 published durations, which takes 3 ledger opens. waitForSequentialStartupSegments reuses LiveEdgePolicy.minStartupSegments = 2, a live sliding-window constant (its doc comment guards against -12888 on a window whose holdback can't fit). On the append-only EVENT playlist a segment's EXTINF only becomes final when the next segment's ledger opens (real duration = nextStart − start), so N published durations require N+1 segment opens: the gate effectively waits for ~3 segments ≈ 12-18 s of media through a possibly-throttled origin. A one-segment EVENT playlist is legal HLS, and this playlist already carries the refresh counter tag that defeats AVPlayer's unchanged-playlist patience — the live rationale does not apply.
  2. The keyframe-spacing scan spends the origin's prefix before the pump even starts. For the uniform-stride fallback plan, measureKeyframeSpacing first seeks — a silent no-op on a non-seekable sequential pb — then consumes up to 20 000 packets / 30 s of content from the single byte-0-only connection. Those bytes never reach the pump, so the session starts late and silently drops the archive's first GOP(s). Both field cases ended in max(4.0, measured) = the 4 s floor anyway (measured 0.480 s and 2.000 s), so the scan bought nothing.

Proposed fix (PR follows)

Not proposed: publishing a segment before its successor opens. The append playlist exists because plan-EXTINF lies, published EVENT entries must not mutate, and capture/duration-known already coincide at the earliest knowable moment — the lag is inherent; the fix is to stop demanding two of them before serving.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions