download
raw
4.62 kB
import { logger } from './logger';
export function sendAddTrackEvent(track: TextTrack, videoEl: HTMLMediaElement) {
let event: Event;
try {
event = new Event('addtrack');
} catch (err) {
// for IE11
event = document.createEvent('Event');
event.initEvent('addtrack', false, false);
}
(event as any).track = track;
videoEl.dispatchEvent(event);
}
export function addCueToTrack(track: TextTrack, cue: VTTCue) {
// Sometimes there are cue overlaps on segmented vtts so the same
// cue can appear more than once in different vtt files.
// This avoid showing duplicated cues with same timecode and text.
const mode = track.mode;
if (mode === 'disabled') {
track.mode = 'hidden';
}
if (track.cues && !track.cues.getCueById(cue.id)) {
try {
track.addCue(cue);
if (!track.cues.getCueById(cue.id)) {
throw new Error(`addCue is failed for: ${cue}`);
}
} catch (err) {
logger.debug(`[texttrack-utils]: ${err}`);
try {
const textTrackCue = new (self.TextTrackCue as any)(
cue.startTime,
cue.endTime,
cue.text,
);
textTrackCue.id = cue.id;
track.addCue(textTrackCue);
} catch (err2) {
logger.debug(
`[texttrack-utils]: Legacy TextTrackCue fallback failed: ${err2}`,
);
}
}
}
if (mode === 'disabled') {
track.mode = mode;
}
}
export function clearCurrentCues(
track: TextTrack,
enterHandler?: (e?: Event) => void,
) {
// When track.mode is disabled, track.cues will be null.
// To guarantee the removal of cues, we need to temporarily
// change the mode to hidden
const mode = track.mode;
if (mode === 'disabled') {
track.mode = 'hidden';
}
if (track.cues) {
for (let i = track.cues.length; i--; ) {
if (enterHandler) {
track.cues[i].removeEventListener('enter', enterHandler);
}
track.removeCue(track.cues[i]);
}
}
if (mode === 'disabled') {
track.mode = mode;
}
}
export function removeCuesInRange(
track: TextTrack,
start: number,
end: number,
predicate?: (cue: TextTrackCue) => boolean,
) {
const mode = track.mode;
if (mode === 'disabled') {
track.mode = 'hidden';
}
if (track.cues && track.cues.length > 0) {
const cues = getCuesInRange(track.cues, start, end);
for (let i = 0; i < cues.length; i++) {
if (!predicate || predicate(cues[i])) {
track.removeCue(cues[i]);
}
}
}
if (mode === 'disabled') {
track.mode = mode;
}
}
// Find first cue starting at or after given time.
// Modified version of binary search O(log(n)).
function getFirstCueIndexFromTime(
cues: TextTrackCueList | TextTrackCue[],
time: number,
): number {
// If first cue starts at or after time, start there
if (time <= cues[0].startTime) {
return 0;
}
// If the last cue ends before time there is no overlap
const len = cues.length - 1;
if (time > cues[len].endTime) {
return -1;
}
let left = 0;
let right = len;
let mid;
while (left <= right) {
mid = Math.floor((right + left) / 2);
if (time < cues[mid].startTime) {
right = mid - 1;
} else if (time > cues[mid].startTime && left < len) {
left = mid + 1;
} else {
// If it's not lower or higher, it must be equal.
return mid;
}
}
// At this point, left and right have swapped.
// No direct match was found, left or right element must be the closest. Check which one has the smallest diff.
return cues[left].startTime - time < time - cues[right].startTime
? left
: right;
}
export function getCuesInRange(
cues: TextTrackCueList | TextTrackCue[],
start: number,
end: number,
): TextTrackCue[] {
const cuesFound: TextTrackCue[] = [];
const firstCueInRange = getFirstCueIndexFromTime(cues, start);
if (firstCueInRange > -1) {
for (let i = firstCueInRange, len = cues.length; i < len; i++) {
const cue = cues[i];
if (cue.startTime >= start && cue.endTime <= end) {
cuesFound.push(cue);
} else if (cue.startTime > end) {
return cuesFound;
}
}
}
return cuesFound;
}
export function filterSubtitleTracks(
textTrackList: TextTrackList,
): TextTrack[] {
const tracks: TextTrack[] = [];
for (let i = 0; i < textTrackList.length; i++) {
const track = textTrackList[i];
// Edge adds a track without a label; we don't want to use it
if (
(track.kind === 'subtitles' || track.kind === 'captions') &&
track.label
) {
tracks.push(textTrackList[i]);
}
}
return tracks;
}

Xet Storage Details

Size:
4.62 kB
·
Xet hash:
2039a4cb431c979c478c3371398de845e5ef908751026170e76d88242951b089

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.