3

I'm trying to see if I need to import a VTT parser or if it's possible for me to get HTML from <track src="transcript.vtt" />. It seems like the browser support exists already for parsing HTML to show atop a video but I can't find a way to access it outside of a video.

how could I achieve something like this:

<div>
  <random-video-player></random-video-player>
  <track src="transcript.vtt" />
  <div id="transcript" >
     // show my VTT cues
  </div>
</div>


@ViewChild('track') track: HTMLTrackElement;
track.cues.foreach(cue => {
   var cueHtmlSpecial = addSpecialAttributes(cue);
   document.getElementById("transcript").appendChild(cueHtmlSpecial)
});

I found a package that more or less should work as I need but wondered if a package was actually necessary. https://github.com/plussub/srt-vtt-parser

azulBonnet
  • 831
  • 4
  • 14
  • 31

1 Answers1

4

If you really only want to parse Web-VTT then no, you don't need an extra library.
The Web-VTT API indeed already offers almost all you need.

To extract the VTTCues from a .vtt file, you'll need a <video> element, but it doesn't have to be connected to the DOM and doesn't have to point to an actual media file, so all that gets downloaded is the .vtt file:

const getCues = (url) => {
  // we need a <video> element, but it can stay disconnected
  // it also doesn't need to point to an actual media
  const vid = document.createElement("video");
  const track = document.createElement("track");
  track.default = true;
  vid.append(track);
  return new Promise((res, rej) => {
    track.onload = (evt) => res([...vid.textTracks[0].cues]);
    track.onerror = (evt) => rej("invalid url");
    track.src = url;
  });
};
(async () => {
  const url = getVTTURL();
  const cues = await getCues(url);
  // for the demo we log only a few properties from the VTTCue object
  console.log(cues.map(({text, startTime, endTime}) => ({text, startTime, endTime})));
})().catch(console.error);


// only for this demo, we build a full .vtt file on the fly
// and return an URL that points to this file.
function getVTTURL() {
  let vttText = `WEBVTT`;
  for( let i=0; i<35; i++ ) {
    const t1 = (i + '').padStart(2 , '0');
    const t2 = ((i+1) + '').padStart(2 , '0');
    vttText += `
      00:00:${t1}.000 --> 00:00:${t2}.000
      Test${i}`
  }
  const vttBlob = new Blob([vttText], {
    type: 'text/plain'
  });
  return URL.createObjectURL(vttBlob);
}
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • There's also: The [getCueAsHTML()](https://developer.mozilla.org/en-US/docs/Web/API/VTTCue/getCueAsHTML) method of the VTTCue interface returns a DocumentFragment containing the cue content. – azulBonnet Mar 24 '22 at 16:12
  • Note that Safari on iOS will not load the track if subtitles are disabled in the native video player. This is a global setting and might cause random issues that are hard to find. Setting the track kind to `kind="metadata"` should fix this unexpected behavior. – Andreas Riedmüller Mar 28 '23 at 11:59
  • Also you might want to add `vid.crossOrigin = "anonymous";` to fix CORS issues if the VTT file is on another domain. – Andreas Riedmüller Mar 28 '23 at 12:05