6.3.0 - External subtitle tracks can address a container's Nth stream
An external subtitle URL does not have to be a sidecar. It can be a container holding several subtitle streams, and a track can now name which one it means.
Added
-
ExternalSubtitleTrack.sourceStreamIndex, an absoluteAVStreamindex inside the container at the track'surl. A host that registers one track per embedded stream of the same MKV (English, English SDH, Spanish) previously got three selectable tracks all rendering the same cues:SubtitleDecoder.decodeFilestopped at the container's firstAVMEDIA_TYPE_SUBTITLEstream and the descriptor carried no index to say otherwise (#266).The index is absolute, matching the convention that embedded track ids are stream indices, not an ordinal over the subtitle streams.
nilkeeps decoding the container's first subtitle stream, so every existing registration behaves exactly as before. An index that is out of range or names a non-subtitle stream throwsSubtitleDecoderError.streamIndexNotSubtitlerather than falling back, because a silent fallback would be indistinguishable from leaving the field nil, which is the behaviour the index exists to escape.Honoured on both selection channels, primary and the companion secondary track, and on the native WebVTT rendition fill for load-declared tracks. Note that
TrackInfo.codecis still derived from the URL extension, so a container URL reportssubrip; a host driving a styled ASS renderer should setformatHint: "ass"on such tracks. Requested by edde746.
Changed
-
External tracks sharing a container are filled from a single pass over it. Each load-declared external track used to get its own whole-file read, so three tracks pointing at one MKV meant three full downloads at load. Discarding the unwanted streams would not have helped: a Matroska demuxer reads every discarded byte anyway, so only a single pass actually saves the bytes. Tracks sharing a URL and headers are now decoded together, one stream decoder per requested stream, each with its own timing anchor, ASS play resolution and open-composition bookkeeping.
A pass covering several streams fails as a whole, so a failure retries the targets individually and one host-side index mistake cannot blank the container's other tracks. A store that still could not be filled stays unfinished rather than serving a complete but blank rendition.
SubtitleDecoder.decodeFilegained a variant taking several stream indices and returning positionally, so a caller maps results back onto its own targets without having to resolve what anilentry became.
Upgrading
.package(url: "https://github.com/superuser404notfound/AetherEngine", from: "6.3.0")Source-compatible. ExternalSubtitleTrack's new field is the last initializer parameter and defaults to nil, which is the pre-6.3.0 behaviour, so existing registrations need no change. Hosts that resolve external subtitles from a container URL can now register one track per stream instead of one track per file.