Home Reference Source

src/utils/cues.ts

  1. import { fixLineBreaks } from './vttparser';
  2. import { CaptionScreen, Row } from './cea-608-parser';
  3.  
  4. export interface CuesInterface {
  5. newCue (track: TextTrack | null, startTime: number, endTime: number, captionScreen: CaptionScreen): VTTCue[]
  6. }
  7.  
  8. interface VTTCue extends TextTrackCue {
  9. new(start: number, end: number, cueText: string): VTTCue
  10. line: number
  11. align: string
  12. position: number
  13. }
  14.  
  15. export function newCue (track: TextTrack | null, startTime: number, endTime: number, captionScreen: CaptionScreen): VTTCue[] {
  16. const result: VTTCue[] = [];
  17. let row: Row;
  18. // the type data states this is VTTCue, but it can potentially be a TextTrackCue on old browsers
  19. let cue: VTTCue;
  20. let indenting: boolean;
  21. let indent: number;
  22. let text: string;
  23. let VTTCue: VTTCue = (window as any).VTTCue as VTTCue || TextTrackCue;
  24.  
  25. for (let r = 0; r < captionScreen.rows.length; r++) {
  26. row = captionScreen.rows[r];
  27. indenting = true;
  28. indent = 0;
  29. text = '';
  30.  
  31. if (!row.isEmpty()) {
  32. for (let c = 0; c < row.chars.length; c++) {
  33. if (row.chars[c].uchar.match(/\s/) && indenting) {
  34. indent++;
  35. } else {
  36. text += row.chars[c].uchar;
  37. indenting = false;
  38. }
  39. }
  40. // To be used for cleaning-up orphaned roll-up captions
  41. row.cueStartTime = startTime;
  42.  
  43. // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
  44. if (startTime === endTime) {
  45. endTime += 0.0001;
  46. }
  47.  
  48. cue = new VTTCue(startTime, endTime, fixLineBreaks(text.trim()));
  49.  
  50. if (indent >= 16) {
  51. indent--;
  52. } else {
  53. indent++;
  54. }
  55.  
  56. // VTTCue.line get's flakey when using controls, so let's now include line 13&14
  57. // also, drop line 1 since it's to close to the top
  58. if (navigator.userAgent.match(/Firefox\//)) {
  59. cue.line = r + 1;
  60. } else {
  61. cue.line = (r > 7 ? r - 2 : r + 1);
  62. }
  63.  
  64. cue.align = 'left';
  65. // Clamp the position between 0 and 100 - if out of these bounds, Firefox throws an exception and captions break
  66. cue.position = Math.max(0, Math.min(100, 100 * (indent / 32)));
  67. result.push(cue);
  68. if (track) {
  69. track.addCue(cue);
  70. }
  71. }
  72. }
  73. return result;
  74. }