Sideload external subtitles
Learn how to register, select, and render external subtitle files that are not in the HLS manifest in the FastPix iOS Player.
The FastPix iOS Player SDK can play a subtitle file that is not in the manifest: a .vtt or .srt file side-loaded from your own storage, alongside an asset you cannot re-package. The SDK supports two formats, WebVTT and SubRip. SubRip files are converted to WebVTT on the device and reported as srt_converted, so a timing problem can be traced back to the conversion step.
External tracks appear in getSubtitleTracks() alongside in-manifest tracks and are selected with the same setSubtitleTrack(trackId:). External cues always arrive through the onSubtitleCueChange callback, so your app renders them itself. For the shared subtitle workflow, see Switch subtitle tracks.
Register an external subtitle
Register the track after prepare(playbackID:playbackOptions:). The subtitle manager is created during player setup, so registering before it exists fails with .playerNotPrepared.
Registration is synchronous and performs no I/O. It answers only what can be decided from the descriptor you pass. Questions that need the file bytes, such as whether the file exists or contains readable cues, are answered later through the delegate when the track is first selected.
Unregister and inspect tracks
Registering re-publishes onSubtitlesLoaded(tracks:), so a track registered after the manifest has already loaded still appears in your menu. Unregistering the track that is currently rendering stops its cue stream and fires onSubtitleChange(track: nil).
Declare the format explicitly
The SDK infers the format from the URL’s path extension only. The query string is not read as a statement about the file’s format. A signed URL such as …/en.vtt?token=ey… is inferred correctly, but …/subtitles?file=en.srt is not, so you must declare the format.
Handle external subtitle events
Conform to FastPixSubtitleTrackDelegate to receive load reports, load failures, and rendering limitations:
The same list is queryable at any time, which makes a “subtitles vanished on AirPlay” report answerable in one line:
Bound the fetching window
Control how far ahead and behind the playhead the SDK fetches and retains cues:
FastPixExternalSubtitleTrack model
FastPixSubtitleFileFormat and FastPixSubtitleIngestFormat
FastPixExternalSubtitleRegistrationError
Decidable from the descriptor alone, reported synchronously at the call site. Every case has an explanation.
FastPixExternalSubtitleLoadFailure
Needs the file bytes, so it is reported asynchronously when the track is first selected.
FastPixExternalSubtitleLoadReport
FastPixExternalSubtitleLimitation
Two convenience lists are published: FastPixExternalSubtitleLimitation.hostRendering (the first three) and .externalTrack (all four).
Note:
registerExternalSubtitle(_:)performs no I/O and returns synchronously. It does not stat the file, including for afile://URL, which can point at an iCloud Drive path wherefileExistsblocks on a download. Existence at registration would also say nothing about existence at selection.- An external track has exactly one possible renderer. The SDK selects
.hostfor it regardless ofsubtitleRenderer, because AVFoundation renders legible tracks that exist in the asset and a side-loaded file does not. ImplementonSubtitleCueChange(information:)to see anything.- For in-manifest tracks the renderer is yours to choose.
subtitleRendererdefaults to.avFoundation, which draws inside the player’s own surface and does not emit the cue stream; set.hostto receive cues instead. Do not do both, or a host ends up rendering every subtitle twice.sourceIDis yours to choose precisely so it can be stable across app launches. An SDK-generated ID would change on every relaunch, and a host persisting the viewer’s choice would never find the track again.isDefaultdoes not auto-select. A side-loaded default would override the stream’s ownDEFAULT=YESrendition without you having asked for that.- The composite ID (
external:<sourceID>:<language>) exists so that two tracks in the same language are addressable separately. Legacy language-only IDs passed tosetSubtitleTrack(trackId:)still resolve.
Frequently asked questions
What subtitle file formats can I sideload into the FastPix iOS Player?
You can sideload WebVTT (.vtt) and SubRip (.srt) files. SubRip files are converted to WebVTT on the device and reported with the ingest format srt_converted, so a timing problem can be traced back to the conversion step. The SDK infers the format from the URL’s path extension, or you can set format: explicitly when the URL has no usable extension.
Why are my external subtitles not showing up in the FastPix iOS Player?
An external track has exactly one possible renderer, so the SDK renders it through the host, not AVFoundation. You must set the subtitleTrackDelegate and implement onSubtitleCueChange(information:) to draw the cues yourself. Also register the track after prepare(playbackID:playbackOptions:); registering earlier fails with .playerNotPrepared.
Can I sideload a subtitle file stored locally on the device?
Yes. The url on FastPixExternalSubtitleTrack accepts http, https, and file schemes. Registration performs no I/O and does not check that the file exists, including for a file:// URL, so a missing or unreadable file is reported asynchronously through onExternalSubtitleLoadFailed(sourceID:failure:) when the track is first selected.
Why do my external subtitles disappear during AirPlay or Picture in Picture?
Host-rendered cues are drawn into a sibling view, and AirPlay, external displays, and Picture in Picture move the player’s video surface rather than your view hierarchy. The SDK reports this through onSubtitleRenderingLimitations(_:), and the current limitations are queryable at any time with subtitleRenderingLimitations.