Skip to content

feat(live): fastZap live-join profile for realtime raw-TS sources (#195)#197

Merged
superuser404notfound merged 1 commit into
mainfrom
feat/ae195-fast-live-join
Jul 22, 2026
Merged

feat(live): fastZap live-join profile for realtime raw-TS sources (#195)#197
superuser404notfound merged 1 commit into
mainfrom
feat/ae195-fast-live-join

Conversation

@superuser404notfound

@superuser404notfound superuser404notfound commented Jul 22, 2026

Copy link
Copy Markdown
Owner

Summary

Adds LoadOptions.liveJoinProfile with a .fastZap opt-in for low-latency live joins on realtime raw-TS sources (#195), designed so the AE#189 holdback contract stays fully intact.

Why the join was slow

AE#189 (5.18.5) gates the first live manifest on the live-edge holdback: the window must carry HOLD-BACK = 3 x TARGETDURATION of content before the first serve (RFC 8216bis floor; anything less puts AVPlayer's initial position in its own stall-danger zone and spams -16832). With the fixed 4 s cut target, TARGETDURATION never falls below 6 (the ceil(1.5 x cut) floor), so the holdback is always >= 18 s. A backlog-serving origin fills that at I/O speed, but a strict-realtime origin can only fill it in wall-clock time: 10-18 s of black on every zap, regardless of how short the source GOPs are.

The fix

Reducing HOLD-BACK below 3 x TARGETDURATION is not spec-legal and would resurrect the #189 failure mode, so the profile shrinks TARGETDURATION itself instead:

  • .fastZap cuts live segments at every keyframe past 0.5 s (instead of 4 s). Segments quantize to the source keyframe cadence, TARGETDURATION is driven by ceil(max EXTINF) (the real GOP length), and the holdback the join waits for shrinks proportionally.
  • The gate, the served HOLD-BACK = 3 x TD, and the shared TD derivation (LiveEdgePolicy) are byte-for-byte unchanged in both profiles; .standard remains the default and is behavior-identical to 5.18.7.
  • Long-GOP sources cannot be cut shorter than their GOP, so under .fastZap they degrade to .standard behavior automatically (verified: AE#189's 5.76 s segments produce TD=6 / 18 s holdback under both profiles).
  • The observed-cadence TD floor (Bursty-ingest detection trusts self-reported TARGETDURATION, not observed cadence -- LL-HLS blocking-reload stays enabled and stalls with -15410 #167) still dominates for bursty ingest origins, so fast join never trades away the raised patience bursty delivery requires.
  • The MP4 muxer's in-RAM interleaver cap (2 x cut target, Blu-ray ISO playback failed, audio bridge.feed failed at pkt #64) is floored at 8 s so a sub-second cut target cannot shrink it below typical TS A/V interleave skew.

Measured (aetherctl live --realtime --preroll 0, strict-realtime origin, 1080p50 H.264 GOP=1 s, 6 Mbps TS)

profile readyToPlay segments TD HOLD-BACK
.standard +20.0 s 4.0 s 6 18 s
.fastZap +2.05 s 1.0 s 1 3 s

Both runs play stably afterwards (25-35 s observed, clock advancing 1 s/s, no -16832 / -12888 / -15410).

aetherctl live gains --fast-zap and --preroll N (0 models a strict-realtime origin with no backlog burst) so the A/B is reproducible, plus timestamped logs and a JOIN metric.

Trade-off (documented on the option)

A smaller TARGETDURATION also tightens AVPlayer's unchanged-playlist patience and live-edge buffer, so an origin that stalls or bursts mid-stream rebuffers or errors more readily than under .standard. That is the explicit host opt-in the issue asks for: picture fast with a small chance of an early rebuffer, for zapping UX.

Tests

  • New Issue195FastLiveJoinTests (8) pin the profile mapping, TD/holdback math under fastZap, long-GOP degradation, cadence-floor dominance, startup cushion, window sizing, and the served playlist (TARGETDURATION:1, HOLD-BACK=3.000).
  • Issue189LiveEdgeHoldbackTests / Issue189ServedTargetDurationTests untouched and green.
  • Full suite green, tvOS-sim build clean (Swift 6 strict concurrency).

🤖 Generated with Claude Code

https://claude.ai/code/session_01NAPCg4tCDdSqkK6tPkNptw

LoadOptions.liveJoinProfile = .fastZap cuts live segments at every
keyframe past 0.5s instead of the standard 4s, so the served
TARGETDURATION collapses to the source GOP length and the AE#189
startup cushion (HOLD-BACK = 3 x TARGETDURATION, the RFC 8216bis
floor) shrinks with it: a short-GOP 1080p50 IPTV stream on a
strict-realtime origin reaches readyToPlay in ~2s instead of ~20s
(measured via aetherctl live --realtime --preroll 0). The holdback
contract itself is unchanged in both profiles, so long-GOP sources
quantize back to .standard behavior and the AE#189 -16832 guarantee
holds; the observed-cadence TD floor (#167) still dominates for
bursty ingest.

- LiveJoinProfile enum + LoadOptions.liveJoinProfile (default
  .standard, behavior-identical to 5.18.7)
- HLSVideoEngine.liveCutTargetSeconds threads the resolved cut target
  into the producer keyframe cut, LiveWindowSizing, LiveCadencePolicy,
  and the served TARGETDURATION floor
- MP4 muxer interleaver cap floored at 8s so a sub-second cut target
  cannot shrink it below typical TS A/V interleave skew
- aetherctl live: --fast-zap and --preroll N (0 = strict-realtime
  origin, no backlog burst) for reproducible A/B join-latency runs,
  plus timestamped logs and a JOIN metric
- Issue195FastLiveJoinTests pin profile mapping, TD/holdback math,
  long-GOP degradation, cadence-floor dominance, startup cushion,
  window sizing, and the served playlist

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NAPCg4tCDdSqkK6tPkNptw
@superuser404notfound
superuser404notfound merged commit a56a1d2 into main Jul 22, 2026
3 checks passed
@superuser404notfound
superuser404notfound deleted the feat/ae195-fast-live-join branch July 22, 2026 16:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant