Table of contents
Part 1: Upload
Part 2: Playback
Reference
FastPix lets you attach multiple subtitle files and audio files to a single video. Subtitle tracks can be included at the time of upload or added afterward. Audio tracks can only be added after the video has been created. This section covers the full workflow.
Before you begin, make sure you have the following ready:
TokenID:SecretKey and base64-encode the result for Basic Auth.Supported formats:
If your file URL requires authentication (login, token, etc.), FastPix cannot fetch it and the track will fail. For S3, use a pre-signed URL with a generous expiry window.
If your subtitle files are ready when you upload the video, you can attach them in the same API call by listing them in the inputs array alongside the video. Audio tracks cannot be included at upload time and must be added separately after the video is created (see Method 2).
Endpoint: POST https://api.fastpix.com/v1/on-demand
What’s happening here: You’re creating a single media asset that contains one video and three subtitle tracks (English, Spanish, Hindi). FastPix processes all of them together and attaches the subtitle tracks to the video automatically.
Input parameters for each subtitle track:
Response:
NOTE:
Save each track’s
idfrom the response. You’ll need thesetrackIdvalues if you want to update or remove individual tracks later.
This also works with the Direct Upload endpoint. Include your subtitle tracks inside the pushMediaSettings object. See the direct upload docs for the exact payload structure.
Once a video is uploaded, you can add both subtitle and audio tracks at any time using the tracks endpoint. This is also the only way to add audio tracks, since they cannot be included at upload time. Call the endpoint once per track.
Endpoint: POST https://api.fastpix.com/v1/on-demand/{mediaId}/tracks
Add a subtitle track:
Add an audio track:
There is no limit on the number of tracks per video. Call this endpoint once for each language or audio variant you want to add.
Response (audio track example):
SAVE THIS
Save
data.idas thetrackId. Audio tracks are registered but not immediately ready. Wait for thevideo.media.track.readywebhook before serving to viewers.
FastPix processes tracks asynchronously. After your API call returns, the track is queued for processing. You should listen for webhook events to know when tracks are ready for playback.
Key webhook events:
Production pattern:
trackId in your database with status "processing".video.media.track.ready on your webhook endpoint.trackId and update the status to "ready".Register your webhook endpoint in the FastPix dashboard under Settings → Webhooks. FastPix sends a POST request to your endpoint for each event.
Update a track (fix a typo, swap the file, correct the language tag):
Delete a track:
NOTE:
Track deletion is permanent and cannot be undone. Double-check you have the correct
trackIdbefore sending the request.
Once your tracks are processed and ready, the FastPix Player handles track switching automatically. This section covers how playback works on web, Android, and iOS.
The core idea is the same across all platforms: the FastPix Player reads the HLS manifest, detects all attached subtitle and audio tracks, and presents them as selectable options in the player UI. You don’t need to write custom track-switching logic.
The FastPix web player is a custom HTML element (<fastpix-player>) that handles everything out of the box.
CDN:
NPM:
See the installation guide for all options.
All subtitle and audio tracks attached to that playbackId appear automatically in the player UI:
If you add tracks after the video is already being played:
When tracks are added dynamically to a video that viewers are currently watching, enable cache busting to ensure the player fetches the updated HLS manifest:
This appends a unique query parameter to the manifest URL, forcing the browser and CDN to serve the latest version instead of a cached copy.
For videos with a private access policy, pass a signed JWT token:
Track switching works identically for private and public videos. The token authenticates access to the stream; once the player loads the manifest, all tracks are available.
The following example shows a fully functional page that goes beyond the default player UI. It wires up custom audio and subtitle track buttons, renders a styled subtitle overlay driven entirely by your own code, polls for subtitle tracks after the manifest is parsed, keeps buttons in sync as tracks change, and supports forward/backward seek controls. It’s a starting point you can drop into any HTML page and extend.
Key points about the example above:
hide-native-subtitles suppresses the player’s built-in subtitle layer so the custom-subtitle overlay is the only thing rendering subtitle text. Without this attribute, cue text would appear twice.default-audio-track / default-subtitle-track accept a track label (case-insensitive) and set the initially active track when the player loads. If the label doesn’t match any track in the manifest, the player falls back to the manifest default.fastpixtracksready is the correct entry point for all track work. Never call getAudioTracks() or getSubtitleTracks() before this event fires.fastpixtracksready is intentional — subtitle textTracks register slightly later than audio tracks. Polling getSubtitleTracks() for a short window catches them reliably.setAudioTrack() and setSubtitleTrack() take a label string, not a numeric id. The id field in the TrackInfo object is an internal index and must not be used for switching or persistence.onclick. fastpixsubtitlecue may not fire again for several seconds after subtitles are turned off, so relying on the cue handler to clear the overlay causes a visible delay.For a step-by-step breakdown of each part of this implementation — including how to persist user language preferences across sessions — see Build a custom track switcher UI.
For the complete reference — all methods, properties, events, attributes, and additional usage examples — see the Audio & Subtitle Tracks API reference in the FastPix web player repository.
React integration
To see how this track switcher and custom subtitle overlay are integrated in a React app (for example, a vertical shorts feed with a track menu and subtitle pill), see FastPix React Shorts Demo. That repo uses the same APIs (getAudioTracks, setAudioTrack, getSubtitleTracks, setSubtitleTrack, fastpixtracksready, fastpixsubtitlecue, and others), mounts the player with document.createElement('fastpix-player') in useEffect, and shows React patterns for refs, cleanup, and feed-level state. Clone it, run npm install and npm run dev, then replace the feed playback IDs with your own multi-track assets.
For a full deep dive on how the player detects and renders subtitle and audio tracks, see Manage audio and subtitles.
The FastPix Android Player SDK is built on Media3/ExoPlayer. It automatically detects subtitle and audio tracks from the HLS manifest and supports on-the-fly switching with no additional track-switching code required.
In your app-level build.gradle (or build.gradle.kts for Kotlin DSL):
In your settings.gradle (or settings.gradle.kts), add the GitHub Maven repository. You’ll need a GitHub Personal Access Token (PAT) to access the private Maven package.
Note: Load credentials from
local.propertiesto avoid hardcoding secrets in your source files.
Click Sync Now after adding the repository.
The SDK discovers audio tracks from the HLS manifest and fires callbacks when they’re available:
To switch to a specific audio track:
NOTE:
If a seek is in progress, the SDK defers the track switch until the seek completes.
To set a preferred default audio track that applies automatically when tracks become available:
To switch to a specific subtitle track or disable subtitles:
To set a preferred default subtitle track:
Note: Use BCP-47 or ISO language names such as
"English","Spanish","Hindi", or"French". Default track preferences apply automatically when tracks become available and never override a manual selection. If the preferred language isn’t present in the stream, the player retains its current selection.
For videos with a private access policy, pass a signed JWT token via playbackToken:
Track switching works identically for private and public videos.
For the full Android SDK reference, see FastPix player for Android.
The FastPix iOS Player SDK wraps AVPlayer and AVPlayerViewController. It auto-detects subtitle and audio tracks from the HLS manifest and supports dynamic audio track switching.
1. Install via Swift Package Manager:
In Xcode: File → Add Packages → enter the repository URL: https://github.com/FastPix/iOS-player
2. Import and set up playback:
3. Audio and subtitle track switching:
The player dynamically detects all available audio tracks from the HLS manifest. Users can switch audio tracks through the player’s built-in interface without restarting the stream. Subtitle tracks detected from the manifest are displayed automatically during playback.
For secure playback:
The iOS SDK also supports tvOS with the same API surface. See the tvOS setup guide for setup details.
Full SDK reference: FastPix player for iOS
Regardless of platform, the FastPix Player follows the same flow:
playbackId, the player constructs the HLS stream URL and fetches the manifest. The manifest contains metadata entries for each subtitle and audio track, including language, name, and URI.Can I upload a video with subtitle tracks in a single API call?
Yes. Include subtitle files in the inputs array alongside your video when calling POST /v1/on-demand. Each subtitle item needs type: "subtitle", a public url, and a languageCode. Audio tracks cannot be included at upload time and must be added separately via the tracks endpoint after the video is created.
Is there a limit on the number of tracks per video?
There is no stated limit. You can add as many subtitle and audio tracks as you need.
What if I add tracks to a video that viewers are currently watching?
On web, enable enable-cache-busting on the player to force a manifest refresh. On mobile, the next time the player loads the stream, it will pick up the new tracks.
How do I know my tracks are ready for playback?
Listen for the video.media.track.ready webhook. For audio tracks, there’s also a video.media.track.created event that fires earlier (registered but still processing). Don’t serve the track until you receive ready.
What language code format should I use?
BCP 47. Simple codes like en, es, fr, de, ja, hi work for most cases. For regional variants, use en-US, pt-BR, zh-TW, etc.