Skip to content

AetherEngine 5.17.0

Choose a tag to compare

@superuser404notfound superuser404notfound released this 21 Jul 07:15

Live remote-HLS: reroute HEVC-in-MPEG-TS masters onto the ingest path (#168 follow-up)

Symptom

A live channel whose master playlist advertises HEVC (CODECS="hvc1.2.2.L153.B0,mp4a.40.2") but delivers MPEG-TS segments (.ts, no EXT-X-MAP) stayed black with audio playing on the nativeRemoteHLS bypass. The 5.16.1 retest log settled the diagnosis: asset.load(tracks) -> count=0, the audio item track appears at readyToPlay, and a video item track is never built, neither at readyToPlay nor seconds later.

Root cause

Per the HLS Authoring Spec, AVFoundation supports HEVC only in fMP4 carriage. For HEVC-in-TS, AVPlayer accepts the master, plays the audio, and silently never creates the video track. That also starves the 5.16.1 fix: with no video track there is no CMFormatDescription to read a dynamic range from and nothing to program display criteria for. The identical stream plays on the loopback path because the ingest remuxes TS to fMP4.

Fix

  • On live nativeRemoteHLS sessions the engine arms a carriage watchdog at readyToPlay: it polls item.tracks at a 0.5 s cadence for 4 s and takes advertisement evidence from AVURLAsset.variants, AVFoundation's own already-fetched master parse, so there is no second origin connect past IPTV tokens or WAFs.
  • When the master advertises a video rendition and AVPlayer never builds a video item track, the engine transparently reroutes the session onto the loopback ingest path (HLSLiveIngestReader remuxes TS to fMP4). The rerouted session runs the full probe and display-criteria handshake, so HDR channels also get their panel switch.
  • HLSLiveIngestReader now carries LoadOptions.httpHeaders on every playlist, segment, and AES-key fetch (the companion audio reader inherits them), so header-enforcing IPTV origins (Referer / User-Agent / Authorization, #119) accept the rerouted ingest. New public initializer: HLSLiveIngestReader(playlistURL:httpHeaders:).
  • New LoadOptions.nativeRemoteHLSIngestFallback (default true) opts out of the reroute.

Guards

  • Live-only: VOD remote HLS is the AE#154 reroute target, so no reroute ping-pong is possible.
  • Audio-only masters (radio channels) disarm immediately; masters without variant evidence (media-playlist-direct URLs) wait out the grace and disarm without firing, keeping their working AVPlayer session.
  • Dead origins never reach readyToPlay, so the watchdog never arms on them; a generation check drops verdicts outrun by a newer load()/stop().

Expected log signals on the reproducing channel

[NativeAVPlayerHost] #N master advertises video (1 variant(s)) but AVPlayer built no video track after grace; HEVC-in-MPEG-TS carriage suspected (#168)
[AetherEngine] #168: nativeRemoteHLS built no video track for a master that advertises video; rerouting onto the live-ingest loopback path (TS -> fMP4 remux)

Tests

14 new unit tests (watchdog verdict matrix, variant advertisement mapper, arm gate, LoadOptions default, ingest request header contract). Full suite: 344 XCTest + 872 Swift Testing, 0 failures. CI green on macOS test, iOS Simulator, and tvOS Simulator builds.

Thanks to @kskchaitanya1993 for the precise 5.16.1 retest log that isolated the track-build rejection branch, and for validating the reroute approach host-side.