Skip to content

5.4.1

Choose a tag to compare

@superuser404notfound superuser404notfound released this 17 Jul 04:10

Patch release: native seeks are hard-bounded at their 8 s budget, and sparse-cache interior holes recover immediately instead of waiting on a producer that can never fill them.

Fixed

  • A native seek can no longer suspend the caller past its 8 s budget (#129). The old deadline path retried the seek with an unbounded await, so repeated source stalls could leave seek(to:) suspended for 40+ s. The deadline now reconciles the public clock to AVPlayer's rendered frame and returns to the caller; the original AVPlayer seek stays alive as the recovery intent. If that seek lands later, the engine settles the public clock from the rendered frame, re-anchors subtitles once, and reconciles transport state after the fact. Both orderings of the completion/deadline race on the MainActor are handled, and the landing evidence distinguishes a genuine late landing from a short seek whose unchanged pre-seek frame already sits inside the landed window.

  • Deadline recovery restarts only a genuinely starved producer (#129). A healthy-but-slow producer that is already filling toward the target keeps its progress; restarting it threw away useful work and could evict the target's segments from retention.

  • Interior sparse-cache holes no longer burn a wait the producer can never fill (#129). After scrubbing, retained cache bands leave interior holes inside the stored min/max index range, and the fetch path waited 2 s on every one before restarting. Residency inside the range is not proof the segment exists; the fetch now waits only when the active producer's forward march actually covers the requested index, and restarts immediately otherwise.

  • A starved seek landing with a paused timeControlStatus and playing intent no longer latches paused. The seek finalize now reconciles transport from live AVPlayer status: an external AVKit / MediaRemote play or pause issued during the seek wins, while the bounded stall-recovery window reasserts play over a spurious pause. The #122 guarantee is unchanged: a paused scrub still lands paused and is never reasserted into playback.

Thanks to @thatcube for the fix, including device verification with network-backed media on a real Apple TV.

Compatibility

No public API changes. Behavior note: a seek that cannot land within 8 s now returns with the clock reconciled to the rendered position instead of keeping the caller suspended; the pending seek then completes asynchronously when the source recovers, so hosts may observe the playhead bounce back before jumping to the target on heavily stalled sources.