5.1.0
AetherEngine 5.1.0 makes iOS quick app switches free for paused sessions (#127), from an iPhone report against a slow single-connection source. Additive API only (isSessionReady, backgroundTeardownGraceSeconds); every current caller is source-compatible.
Added
Paused-background grace window on iOS (#127)
A paused session used to tear down the moment the app backgrounded, so the single most common iPhone flow (pause, swipe to Home, come back 10-30 s later) paid a full pipeline rebuild: demuxer reopen, segment-plan scan, AVPlayer item reload, up to 30 s to readyToPlay on a slow single-connection source. The teardown is now deferred by backgroundTeardownGraceSeconds (default 15 s, 0 restores the immediate teardown), held under a UIBackgroundTask assertion. Returning to the foreground inside the window cancels the teardown and resumes on the live pipeline: no reload, no reconnect, instant resume.
Wedge-safety is fully preserved: the assertion keeps the app genuinely running for the whole window, at expiry the background action is re-evaluated (PiP can start and lock-screen play can resume mid-window) and the teardown runs before any idle suspension; the assertion's expiration handler is a synchronous backstop. Two deliberate scope points: a PLAYING session with background playback disabled still tears down immediately (its audio would keep sounding through the window), and tvOS keeps the unconditional immediate teardown. The step decision is a pure, unit-tested policy (backgroundStep).
Public isSessionReady (#127)
@Published engine flag, true once the active session's transport is ready to accept seeks and report real time (native path: AVPlayerItem readyToPlay; SW/audio hosts publish readiness at session start), false across every teardown including the background one. Hosts gate corrective actions (restore watchdogs, position clamps) on it instead of inferring readiness from currentTime being pinned at 0.
Fixed
Pre-ready host seeks no longer clamp to 0:00 (#127)
A host seek forwarded while the AVPlayer item was pre-ready (e.g. right after a background-teardown reload) clamped to 0 against empty seekable ranges and replaced load()'s own pending start-position seek, so playback restarted from the file head even though the producer was correctly anchored at the resume position. Such seeks are now deferred and the latest one replays once the item is ready. Seeks issued during .loading stay ignored by design (that guard protects against a scrub racing a concurrent stop/load).
Host adoption note
If your host reloads on foreground return, gate the reload on the session actually being torn down (playbackBackend == .none) rather than on state != .playing, otherwise the reload throws away exactly the rebuild the grace window avoided.
Thanks to @dlev02 for the excellent report: validated proposals, device logs, and a prototype direction for the grace window.