I'm working on a page with a video player in which I'm trying to show vtt captions and get information from the cues in the <track> element.
Here's what's relevant for the player in HTML:
<div class="video">
<video id="vid">
<source src="Video.mp4" type="video/mp4">
<track kind="subtitles" src="Captions.vtt" srclang="en">
</video>
</div>
I had something like this in my JavaScript first, just to see what I was getting before manipulating anything in code.
var trackObject = $('track')[0].track;
trackObject.mode = 'showing';
console.log('Track cues:');
console.log(trackObject.cues);
console.log(trackObject.cues[0]);
The change to the mode attribute is done there because, if I set default to the <track> element in HTML, then the video doesn't appear in many browsers. Still don't know why.
What this prints to the console is the following:
However, when I expand the TextTrackCueList, I do see the cues:
This has only made sense to me if I assume that the cues have loaded into the element, but the length attribute hasn't been updated. But I still don't know what's that length I'm seeing at the end of the list, which shows the actual number of cues.
I haven't found any kind of load event on the text track, so this is what I did to make sure I can get the cues:
var trackObject = $('track')[0].track;
trackObject.mode = 'showing';
var waitForCues = setInterval(function() {
if (trackObject.cues.length > 0) {
var cueList = getTracks(trackObject)
// ...Do some processing with the cues...
clearInterval(waitForCues);
}
}, 40);
Why does this happen with the length attribute of the track element? How can I get rid of that waiting for the length to be greater than 0?
As an HTMLMediaElement, the <track> element supports the same global load and error events that any other HTMLElement does, so you can listen for those to determine whether your VTT is ready for business or not.
mytrack.addEventListener(`load`, evt => {
console.log(`good to go`);
const { track } = mytrack;
// force this track to become active so we can get the cues:
track.mode = "showing";
const { cues } = track;
console.log(`${cues.length} cues found`);
});
mytrack.addEventListener(`error`, evt => {
console.log(`yeah that's a problem`);
});
<video controls>
<source src="https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4" type="video/mp4">
<track
id="mytrack"
kind="captions"
src="data:text/plain;charset=utf-8,WEBVTT%0A%0A00%3A00%3A00.500%20--%3E%2000%3A00%3A02.000%0AThe%20Web%20is%20always%20changing%0A%0A00%3A00%3A02.500%20--%3E%2000%3A00%3A04.300%0Aand%20the%20way%20we%20access%20it%20is%20changing"
srclang="en"
label="English"
default="default">
>
</video>