import type { Track } from './Track';
import type { TextTrackCue } from './TextTrackCue';
export type TextTrackType = 'srt' | 'ttml' | 'webvtt' | 'cea608' | '';
export type TextTrackKind = 'subtitles' | 'captions' | 'descriptions' | 'chapters' | 'metadata' | 'thumbnails';
export type TextTrackMode = 'disabled' | 'showing';
export interface TextTrack extends Track {
/**
* The kind of the text track, represented by a value from the following list:
*
- `'subtitles'`: The track contains subtitles.
*
- `'captions'`: The track contains closed captions, a translation of dialogue and sound effects.
*
- `'descriptions'`: The track contains descriptions, a textual description of the video.
*
- `'chapters'`: The track contains chapter titles.
*
- `'metadata'`: The track contains metadata. This track will not serve display purposes.
*/
readonly kind: TextTrackKind;
/**
* The label of the text track.
*/
label: string;
/**
* The language of the text track.
*/
readonly language: string;
/**
* The identifier of the text track.
*
* @remarks
*
- This identifier can be used to distinguish between related tracks, e.g. tracks in the same list.
*/
readonly id: string;
/**
* A unique identifier of the text track.
*
* @remarks
*
- This identifier is unique across tracks of a THEOplayer instance and can be used to distinguish between tracks.
*/
readonly uid: number;
/**
* The mode of the text track, represented by a value from the following list:
*
- `'disabled'`: The track is disabled.
*
- `'showing'`: The track is showing.
*/
mode: TextTrackMode;
/**
* The content type of the text track.
*/
readonly type: TextTrackType;
/**
* The list of cues of the track.
*
* @remarks
*
- If the {@link TextTrack.mode} is `'disabled'`, this property is `null`.
*/
cues: TextTrackCue[] | null;
/**
* The source of the text track.
*/
readonly src: string;
/**
* Indicates whether the track contains Forced Narrative cues.
* This may only be true for subtitle tracks where
*
- For DASH: the corresponding AdaptationSet contains a child Role with its value attribute equal to `'forced_subtitle'`
*
- For HLS: the corresponding #EXT-X-MEDIA tag contains the attributes TYPE=SUBTITLES and FORCED=YES (not supported yet)
*/
readonly forced: boolean;
}
/**
* Retain renderable tracks.
* https://html.spec.whatwg.org/multipage/embedded-content.html#text-track-showing
*/
export function filterRenderableTracks(textTracks: TextTrack[] | undefined): TextTrack[] | undefined {
return textTracks && textTracks.filter((textTrack) => textTrack.kind === 'subtitles' || textTrack.kind === 'captions');
}
/**
* Retain first thumbnail track encountered in the textTracks list.
*/
export function filterThumbnailTracks(textTracks: TextTrack[] | undefined): TextTrack | undefined {
return textTracks && textTracks.find(isThumbnailTrack);
}
/**
* Query whether a track is a valid thumbnail track.
*/
export function isThumbnailTrack(textTrack: TextTrack | undefined): boolean {
return !!textTrack && (textTrack.kind === 'thumbnails' || (textTrack.kind === 'metadata' && textTrack.label === 'thumbnails'));
}
export function hasTextTrack(textTrackList: TextTrack[], textTrack: TextTrack): boolean {
return !!(textTrackList && textTrack && textTrackList.find((t) => t.uid === textTrack.uid));
}
export function removeTextTrack(textTrackList: TextTrack[], textTrack: TextTrack): TextTrack[] {
return textTrackList && textTrack ? textTrackList.filter((t) => t.uid !== textTrack.uid) : textTrackList;
}
export function addTextTrack(textTrackList: TextTrack[], textTrack: TextTrack): TextTrack[] {
return textTrackList && textTrack && !hasTextTrack(textTrackList, textTrack) ? [...textTrackList, textTrack] : textTrackList;
}
export function hasTextTrackCue(textTrack: TextTrack, cue: TextTrackCue): boolean {
return !!(textTrack.cues && cue && textTrack.cues.find((c) => cue.uid === c.uid));
}
export function removeTextTrackCue(textTrack: TextTrack, cue: TextTrackCue) {
if (textTrack && textTrack.cues && cue && !hasTextTrackCue(textTrack, cue)) {
textTrack.cues = textTrack.cues.filter((c) => c.uid !== cue.uid);
}
}
export function addTextTrackCue(textTrack: TextTrack, cue: TextTrackCue) {
if (textTrack && textTrack.cues && cue && !hasTextTrackCue(textTrack, cue)) {
textTrack.cues.push(cue);
}
}
export function findTextTrackByUid(textTracks: TextTrack[], uid: number): TextTrack | undefined {
return textTracks.find((t) => t.uid === uid);
}