Home Reference Source

src/utils/texttrack-utils.ts

  1. export function sendAddTrackEvent(track: TextTrack, videoEl: HTMLMediaElement) {
  2. let event: Event;
  3. try {
  4. event = new Event('addtrack');
  5. } catch (err) {
  6. // for IE11
  7. event = document.createEvent('Event');
  8. event.initEvent('addtrack', false, false);
  9. }
  10. (event as any).track = track;
  11. videoEl.dispatchEvent(event);
  12. }
  13.  
  14. export function clearCurrentCues(track: TextTrack) {
  15. if (track?.cues) {
  16. // When track.mode is disabled, track.cues will be null.
  17. // To guarantee the removal of cues, we need to temporarily
  18. // change the mode to hidden
  19. if (track.mode === 'disabled') {
  20. track.mode = 'hidden';
  21. }
  22. while (track.cues.length > 0) {
  23. track.removeCue(track.cues[0]);
  24. }
  25. }
  26. }
  27.  
  28. // Find first cue starting after given time.
  29. // Modified version of binary search O(log(n)).
  30. function getFirstCueIndexAfterTime(
  31. cues: TextTrackCueList | TextTrackCue[],
  32. time: number
  33. ): number {
  34. // If first cue starts after time, start there
  35. if (time < cues[0].startTime) {
  36. return 0;
  37. }
  38. // If the last cue ends before time there is no overlap
  39. if (time > cues[cues.length - 1].endTime) {
  40. return -1;
  41. }
  42.  
  43. let left = 0;
  44. let right = cues.length - 1;
  45.  
  46. while (left <= right) {
  47. const mid = Math.floor((right + left) / 2);
  48.  
  49. if (time < cues[mid].startTime) {
  50. right = mid - 1;
  51. } else if (time > cues[mid].startTime) {
  52. left = mid + 1;
  53. } else {
  54. // If it's not lower or higher, it must be equal.
  55. return mid;
  56. }
  57. }
  58. // At this point, left and right have swapped.
  59. // No direct match was found, left or right element must be the closest. Check which one has the smallest diff.
  60. return cues[left].startTime - time < time - cues[right].startTime
  61. ? left
  62. : right;
  63. }
  64.  
  65. export function getCuesInRange(
  66. cues: TextTrackCueList | TextTrackCue[],
  67. start: number,
  68. end: number
  69. ): TextTrackCue[] {
  70. const cuesFound: TextTrackCue[] = [];
  71. const firstCueInRange = getFirstCueIndexAfterTime(cues, start);
  72. if (firstCueInRange > -1) {
  73. for (let i = firstCueInRange, len = cues.length; i < len; i++) {
  74. const cue = cues[i];
  75. if (cue.startTime >= start && cue.endTime <= end) {
  76. cuesFound.push(cue);
  77. } else if (cue.startTime > end) {
  78. return cuesFound;
  79. }
  80. }
  81. }
  82. return cuesFound;
  83. }