Track Selection in Offline Downloads
When downloading content with the Offline Video SDK, you can choose exactly which video, audio, and subtitle tracks to store locally. This is useful for:
- Reducing file size
- Selecting a specific language
- Including/excluding subtitles
- Downloading only the needed bitrate for offline playback
info
Track selection relies on two parts:
- Inspect available tracks with
getAvailableTracks(url)
- Pass selected track
id
s viaDownloadOptions.tracks
todownloadStream
See full API in the API Reference.
Step 1 - Inspect Available Tracks
Before starting a download, call getAvailableTracks(url)
to retrieve all available tracks in the manifest.
import { getAvailableTracks } from "@TheWidlarzGroup/react-native-video-stream-downloader";
const tracks = await getAvailableTracks("https://example.com/manifest.m3u8");
console.log(tracks);
You’ll get something like (IDs such as video_0
, audio_0
, text_1
, including uri
, bandwidth
, and resolution
):
{
"video": [
{
"id": "video_0",
"type": "video",
"uri": "https://example.cdn/hls/video/250kbit.m3u8",
"bandwidth": 258157,
"codecs": "avc1.4d400d",
"resolution": { "width": 422, "height": 180 },
"audioGroupId": "stereo",
"subtitlesGroupId": "subs",
"label": "422x180"
},
{
"id": "video_1",
"type": "video",
"uri": "https://example.cdn/hls/video/1000kbit.m3u8",
"bandwidth": 1048576,
"codecs": "avc1.4d401f",
"resolution": { "width": 960, "height": 540 },
"audioGroupId": "stereo",
"subtitlesGroupId": "subs",
"label": "960x540"
},
],
"audio": [
{
"id": "audio_0",
"type": "audio",
"uri": "https://example.cdn/hls/audio/stereo/en/128kbit.m3u8",
"groupId": "stereo",
"language": "en",
"name": "English",
"isDefault": true,
"autoSelect": true
},
],
"text": [
{
"id": "text_0",
"type": "text",
"uri": "https://example.cdn/hls/subtitles_en.m3u8",
"groupId": "subs",
"language": "en",
"name": "English",
"isDefault": true,
"forced": false,
"autoSelect": true
},
]
}
Step 2 - Choose the Tracks You Want
Example: choose a mid-quality video rendition (middle index), all audio, and all text tracks.
const selectedVideo = tracks.video?.[Math.floor(tracks.video.length / 2)];
const selectedTracks = {
video: selectedVideo ? [selectedVideo.id] : [],
text: tracks.text?.map((t) => t.id) || [],
audio: tracks.audio?.map((a) => a.id) || [],
};
We suggest exploring the example implementation in our Starter Kit.: react-native-offline-video-starter.
You can also:
- Filter audio by language
- Pick a single subtitle language
- Choose only one audio/video track for maximum size reduction
Step 3 - Pass Tracks to downloadStream()
import { downloadStream } from "@TheWidlarzGroup/react-native-video-stream-downloader";
await downloadStream("https://example.com/video.m3u8", {
tracks: selectedTracks,
});
This ensures the download includes only the selected tracks.
Example - Download Lowest Bitrate Only
const lowestVideo = tracks.video?.reduce((min, track) =>
track.bandwidth < min.bandwidth ? track : min
);
await downloadStream("https://example.com/video.m3u8", {
tracks: { video: [lowestVideo!.id] },
});
Notes
- Not selecting any tracks defaults to all available tracks (or use
includeAllTracks: true
). - Track IDs are manifest-specific - always call
getAvailableTracks
before downloading.