Hi, in this video I will show you how we can work with the track elements from JavaScript, just to know which track has been loaded and which track is active.
For that, we will manipulate different properties of the HTML track element from JavaScript.
The first thing I am going to do is to add a small div at the end of the document for displaying the different track statuses.
I added a div here called trackStatusesDiv with a heading... I am going to add some CSS to visualize this area.
So like that, we will have the description of the track here.
I added a border and some margins and so on.
From JavaScript, we can not do anything before the page has been loaded, so I am adding a window.onload listener, and all the treatments will be in this function.
So the first thing I am going to do is get these track elementshere... and I am going to get them in a variable called htmlTracks.
So how can I get them?
I'm going to stop the automatic refresh on JSBin for the moment.
So, querySelectorAll is a function that will return a collection with all the tracks, an array with all the tracks,all the HTML elements.
So there, I am going to call a function called displayTrackStatusesthat I write here.
I will first iterate on these tracks and display in the console the different values.
So we are doing a loop.
I will first just display something in the console.
I am going to add a current track, it will be easier.
So, I can write currentTrack.label for example, that will display the value of the different attributes.
This is just for checking that my code is OK.
So I open the console, I have got one error...
So if I click here "Run with JS" I can see that it's working.
What I can display is the label, I can also display the kind... you remember the kind: subtitles, subtitles, chapters for the different tracks subtitles, subtitles and chapters and I can also display the language with srclang.
So English, Deutsch (for German).
I can also display what is called the status.
It is readyState, this is a property you can use only from JavaScript.
It says that for track number 1, the value is 0, for track number 2 is 2, for track number 3, it's 0.
2 means that the track is loaded and 0 means that the track is not available.
So we've got the first track, the English subtitles are not available: status readyState 0 and we've got the German subtitles that have been loaded because is has the default attribute, and we showed that in Google Chrome the track with the default attribute is loaded when the page is loaded.
So this is how we can consult the different statuses of a track from JavaScript.
I am going to copy and paste some code for just displaying this in a nicer way here.
So, this is how we can display the different statuses and I can add a button that will call this just to refresh the different statuses.
Let's add a button, we call it refresh, and when we click on it, we will call displayTrackStatuses.
If I click here... just checking there is no error…it will refresh this thing.
So now I am going to try this code with Safari;because you remember Safari has a menu for changing the different tracks.
I prepared that already, so here I can start playing the same video that has Deutsch subtitles loaded by default, you can see that here.
If I choose English subtitles now, and I refreshtrack statuses: you can see that the English subtitles are loaded now and the Deutsch subtitlesare also available.
So, we are going to use these different attributes for forcing some tracks to load programmatically from JavaScript and this will enable us to make a sort of menu for choosing the different tracks.
I will explain that in a next video.
Let's go back to our example. Below is the HTML code:
<video id="myVideo" preload="metadata" controls crossOrigin="anonymous">
<source src="https://...../elephants-dream-medium.mp4" type="video/mp4">
<source src="https://...../elephants-dream-medium.webm" type="video/webm">
<track label="English subtitles" kind="subtitles" srclang="en"
src="https://...../elephants-dream-subtitles-en.vtt" >
<track label="Deutsch subtitles" kind="subtitles" srclang="de"
src="https://...../elephants-dream-subtitles-de.vtt" default>
<track label="English chapters" kind="chapters" srclang="en"
src="https://...../elephants-dream-chapters-en.vtt">
</video>
<div id="trackStatusesDiv">
<h3>HTML track descriptions</h3>
</div>
This example defines three <track> elements. From JavaScript, we can manipulate these elements as "HTML elements" - we will call them the "HTML views" of tracks.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Using HTML views of tracks</title>
</head>
<body>
<video id="myVideo" preload="metadata" controls crossOrigin="anonymous">
<source src="https://mainline.i3s.unice.fr/mooc/elephants-dream-medium.mp4" type="video/mp4">
<source src="https://mainline.i3s.unice.fr/mooc/elephants-dream-medium.webm" type="video/webm">
<track label="English subtitles" kind="subtitles" srclang="en"
src="https://mainline.i3s.unice.fr/mooc/elephants-dream-subtitles-en.vtt" >
<track label="Deutsch subtitles" kind="subtitles" srclang="de"
src="https://mainline.i3s.unice.fr/mooc/elephants-dream-subtitles-de.vtt" default>
<track label="English chapters" kind="chapters" srclang="en"
src="https://mainline.i3s.unice.fr/mooc/elephants-dream-chapters-en.vtt">
</video>
<p>
<button onclick=displayTrackStatuses()>Refresh track statuses</button>
<div id="trackStatusesDiv">
<h3>HTML track descriptions</h3>
</div>
</body>
</html>
Here is the JavaScript source code:
var video, htmlTracks;
var trackStatusesDiv;
window.onload = function() {
// called when the page has been loaded
video = document.querySelector("#myVideo");
trackStatusesDiv = document.querySelector("#trackStatusesDiv");
// Get the tracks as HTML elements
htmlTracks = document.querySelectorAll("track");
// displays their statuses in a div under the video
displayTrackStatuses(htmlTracks);
};
function displayTrackStatuses(htmlTracks) {
// displays track info
for(var i = 0; i < htmlTracks.length; i++) {
var currentHtmlTrack = htmlTracks[i];
var label = "<li>label = " + currentHtmlTrack.label + "</li>";
var kind = "<li>kind = " + currentHtmlTrack.kind + "</li>";
var lang = "<li>lang = " + currentHtmlTrack.srclang + "</li>";
var readyState = "<li>readyState = "
+ currentHtmlTrack.readyState + "</li>"
trackStatusesDiv.innerHTML += "<li><b>Track:" + i + ":</b></li>"
+ "<ul>" + label + kind + lang + readyState + "</ul>";
}
}
The code is rather straightforward:
We cannot access any HTML element before the page has been loaded. This is why we do all the work in the window.onload listener,
Line 7: we get a pointer to the div with id=trackStatusesDiv, that will be used to display track statuses,
Line 10: we get all the track elements in the document. They are HTML track elements,
Line 13: we call a function that will build some HTML to display the track status in the div we got from line 7.
Lines 16-29: we iterate on the HTML tracks, and for each track we get the label, the kind and the srclang attribute values. Notice, at line 24, the use of the readyState attribute, only used from JavaScript, that will give the current HTML track state.
You can see on the screenshot (or from the JSBin example) that the German subtitle file has been loaded, and that none of the other tracks have been loaded.
0 = NONE ; the text track's cues have not been obtained
1 = LOADING ; the text track is loading with no errors yet. Further cues can still be added to the track by the parser
2 = LOADED ; the text track has been loaded with no errors
3 = ERROR ; the text track was enabled, but when the user agent attempted to obtain it, something failed. Some or all of the cues are likely missing and will not be obtained
Now, it's time to look at the twin brother of an HTML track: the corresponding TextTrack object!