Reported over Discord by the author of Snappier IPTV, who embeds the engine: is there a plan for preloading / caching of VOD content, in the shape KSPlayer offers as an addon?
Half of that already exists, and the half that does not is the half the request is actually about.
What the engine does today
On the VOD paths the engine owns, bytes are already cached on disk for the life of the session:
Two limits follow from where that state lives:
What is missing
There is no way to warm anything before load(). Every session starts cold, and a cold open is not free: measured against a 300 ms origin, a non-fast-start MP4 costs two to three sequential round trips before the first sample read, and on a slow origin the first byte of the data connection is the whole perceived start time (#281 and the layout matrix that came out of it). For a host whose UI knows what is next (the next episode, the item under the cursor), those seconds are spendable in advance and are not being spent.
Shape under consideration
A source-level byte prewarm rather than a segment-level one:
- A URL-keyed, process-wide store of resident spans, beside
SourceContentLengthCache and SuffixRangeSupport, which are already exactly this shape.
- A public call that fills it for a URL the engine is not playing: the head span, the trailing object where the layout has one, and a bounded run of media bytes.
AVIOReader consults it on open, at the same place it consults the retained spans today, so a later load() of that URL adopts the bytes and skips the round trips.
Route-independent across the paths the engine owns (loopback native, software host, side demuxers), and by construction not applicable to nativeRemoteHLS, where the engine issues no requests.
Two things it has to get right:
Explicitly out of scope here: persistence across app launches, and offline download. Those are a different feature with a different lifetime and a different disk contract, and are not needed for the reported case.
Reported over Discord by the author of Snappier IPTV, who embeds the engine: is there a plan for preloading / caching of VOD content, in the shape KSPlayer offers as an addon?
Half of that already exists, and the half that does not is the half the request is actually about.
What the engine does today
On the VOD paths the engine owns, bytes are already cached on disk for the life of the session:
SegmentCache: a sliding window with a backward retention budget, so a seek back into watched content is a hit and never reaches the origin again (Loopback-HLS: a single backward seek on heavy 4K can wedge the segment producer (video stalls, audio continues -> A/V desync) #93, Forward-buffer window: 150-segment ceiling silently caps an "unbounded pre-buffer" host option (#102 follow-up) #207). Forward depth is the host's to set throughLoadOptions.forwardBufferSegments, up to the whole source, bounded bymin(2 GiB, a quarter of free space)with the cap relaxed when the host opts into a large window (configurable forward-buffer window (LoadOptions.forwardBufferSegments) #102, Forward-buffer window: 150-segment ceiling silently caps an "unbounded pre-buffer" host option (#102 follow-up) #207).ResidentSpankeeps the head and a speculative tail span so the box-chain walk of a non-fast-start MP4 does not pay a round trip for bytes the reader already had (VOD cold-start pays a mandatory sequential head→tail→re-anchor round trip on non-fast-start MP4 sources — request for parallel fetch or moov-offset hint #281).Two limits follow from where that state lives:
<tmp>/aether-segments/<uuid>/, flock-held and swept when the session ends (SegmentCache.init's stale-session sweep deletes a concurrent >1h session's directory — the age check has no liveness half #451). Nothing survives the item, let alone the app.nativeRemoteHLSbypass AVPlayer fetches the URL itself, so there is no loopback and no cache at all. That is the route an IPTV host takes for an m3u8; a progressive VOD URL (mkv / mp4) takes the loopback path and gets everything above.What is missing
There is no way to warm anything before
load(). Every session starts cold, and a cold open is not free: measured against a 300 ms origin, a non-fast-start MP4 costs two to three sequential round trips before the first sample read, and on a slow origin the first byte of the data connection is the whole perceived start time (#281 and the layout matrix that came out of it). For a host whose UI knows what is next (the next episode, the item under the cursor), those seconds are spendable in advance and are not being spent.Shape under consideration
A source-level byte prewarm rather than a segment-level one:
SourceContentLengthCacheandSuffixRangeSupport, which are already exactly this shape.AVIOReaderconsults it on open, at the same place it consults the retained spans today, so a laterload()of that URL adopts the bytes and skips the round trips.Route-independent across the paths the engine owns (loopback native, software host, side demuxers), and by construction not applicable to
nativeRemoteHLS, where the engine issues no requests.Two things it has to get right:
Explicitly out of scope here: persistence across app launches, and offline download. Those are a different feature with a different lifetime and a different disk contract, and are not needed for the reported case.