HLS.js provides comprehensive multi-track support for audio and subtitles with dynamic switching capabilities.
Manage audio track selection and switching.
interface Hls {
/** All available audio tracks including non-selectable ones (read-only) */
readonly allAudioTracks: MediaPlaylist[];
/** Selectable audio tracks (read-only) */
readonly audioTracks: MediaPlaylist[];
/** Currently selected audio track index */
audioTrack: number;
/**
* Set audio track with advanced options
* @param option - Audio track or selection criteria
* @returns Selected audio track or null
*/
setAudioOption(option: MediaPlaylist | AudioSelectionOption): MediaPlaylist | null;
}Usage Examples:
const hls = new Hls();
// Wait for manifest parsing
hls.on(Hls.Events.MANIFEST_PARSED, () => {
console.log("Available audio tracks:", hls.audioTracks.length);
// List all audio tracks
hls.audioTracks.forEach((track, index) => {
console.log(`Audio ${index}: ${track.name} (${track.lang})`);
});
// Select audio track by index
hls.audioTrack = 1;
// Select by language preference
const spanishTrack = hls.setAudioOption({ lang: "es" });
if (spanishTrack) {
console.log("Selected Spanish audio:", spanishTrack.name);
}
});
// Listen for audio track changes
hls.on(Hls.Events.AUDIO_TRACK_SWITCHING, (event, data) => {
console.log(`Switching to audio track ${data.id}: ${data.name}`);
});
hls.on(Hls.Events.AUDIO_TRACK_SWITCHED, (event, data) => {
console.log(`Audio track switched to ${data.id}`);
});Manage subtitle track selection and display.
interface Hls {
/** All available subtitle tracks (read-only) */
readonly allSubtitleTracks: MediaPlaylist[];
/** Selectable subtitle tracks (read-only) */
readonly subtitleTracks: MediaPlaylist[];
/** Currently selected subtitle track index (-1 for none) */
subtitleTrack: number;
/** Whether subtitles are displayed */
subtitleDisplay: boolean;
/**
* Set subtitle track with advanced options
* @param option - Subtitle track or selection criteria
* @returns Selected subtitle track or null
*/
setSubtitleOption(option: MediaPlaylist | SubtitleSelectionOption): MediaPlaylist | null;
}Usage Examples:
const hls = new Hls();
// Wait for manifest parsing
hls.on(Hls.Events.MANIFEST_PARSED, () => {
console.log("Available subtitle tracks:", hls.subtitleTracks.length);
// List all subtitle tracks
hls.subtitleTracks.forEach((track, index) => {
console.log(`Subtitle ${index}: ${track.name} (${track.lang})`);
});
// Select subtitle track
hls.subtitleTrack = 0;
hls.subtitleDisplay = true;
// Select by language
const frenchSubs = hls.setSubtitleOption({ lang: "fr" });
if (frenchSubs) {
console.log("Selected French subtitles:", frenchSubs.name);
hls.subtitleDisplay = true;
}
// Disable subtitles
hls.subtitleTrack = -1;
hls.subtitleDisplay = false;
});
// Listen for subtitle track changes
hls.on(Hls.Events.SUBTITLE_TRACK_SWITCH, (event, data) => {
console.log(`Subtitle track switched to ${data.id}`);
});
// Listen for subtitle data
hls.on(Hls.Events.CUES_PARSED, (event, data) => {
console.log("Subtitle cues parsed:", data.cues.length);
});Access tracks organized by groups and renditions.
// Get audio tracks by group
const audioTracks = hls.allAudioTracks.filter(track =>
track.groupId === "audio-group-1"
);
// Get tracks with specific characteristics
const accessibleTracks = hls.subtitleTracks.filter(track =>
track.characteristics?.includes("public.accessibility.describes-video")
);Events for monitoring track changes and loading.
// Audio track events
hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, (event, data: {
audioTracks: MediaPlaylist[]
}) => {
// Called when audio tracks are updated
});
hls.on(Hls.Events.AUDIO_TRACK_SWITCHING, (event, data: {
id: number,
type?: string,
url?: string
}) => {
// Called when starting to switch audio tracks
});
hls.on(Hls.Events.AUDIO_TRACK_SWITCHED, (event, data: {
id: number
}) => {
// Called when audio track switch is complete
});
hls.on(Hls.Events.AUDIO_TRACK_LOADING, (event, data: {
id: number,
url: string
}) => {
// Called when loading audio track playlist
});
hls.on(Hls.Events.AUDIO_TRACK_LOADED, (event, data: {
id: number,
details: LevelDetails,
stats: LoadStats
}) => {
// Called when audio track playlist is loaded
});
// Subtitle track events
hls.on(Hls.Events.SUBTITLE_TRACKS_UPDATED, (event, data: {
subtitleTracks: MediaPlaylist[]
}) => {
// Called when subtitle tracks are updated
});
hls.on(Hls.Events.SUBTITLE_TRACK_SWITCH, (event, data: {
id: number,
type?: string,
url?: string
}) => {
// Called when subtitle track is switched
});
hls.on(Hls.Events.SUBTITLE_TRACK_LOADING, (event, data: {
id: number,
url: string
}) => {
// Called when loading subtitle track
});
hls.on(Hls.Events.SUBTITLE_TRACK_LOADED, (event, data: {
id: number,
details: LevelDetails,
stats: LoadStats
}) => {
// Called when subtitle track is loaded
});
hls.on(Hls.Events.CUES_PARSED, (event, data: {
type: string,
cues: any[],
track: string
}) => {
// Called when subtitle cues are parsed
});interface MediaPlaylist {
/** Unique track ID */
readonly id: number;
/** Track name/title */
readonly name: string;
/** Language code (e.g., "en", "es") */
readonly lang: string | undefined;
/** Associated language for accessibility */
readonly assocLang: string | undefined;
/** Track characteristics */
readonly characteristics: string | undefined;
/** Audio channel configuration */
readonly channels: string | undefined;
/** Playlist URI */
readonly uri: string;
/** Group ID for track grouping */
readonly groupId: string | undefined;
/** Track type */
readonly type: string;
/** Whether track is default */
readonly default: boolean;
/** Whether track is forced */
readonly forced: boolean;
/** Codec information */
readonly codec: string | undefined;
}
interface AudioSelectionOption {
/** Language preference */
lang?: string;
/** Track name/title preference */
name?: string;
/** Group ID preference */
groupId?: string;
/** Characteristics requirement */
characteristics?: string;
/** Channels requirement */
channels?: string;
}
interface SubtitleSelectionOption {
/** Language preference */
lang?: string;
/** Track name/title preference */
name?: string;
/** Group ID preference */
groupId?: string;
/** Characteristics requirement */
characteristics?: string;
/** Whether forced subtitles only */
forced?: boolean;
}
interface VideoSelectionOption {
/** Video width requirement */
width?: number;
/** Video height requirement */
height?: number;
/** Bitrate requirement */
bitrate?: number;
/** Codec requirement */
codec?: string;
}