You might have noticed that with some browsers, before 2018, the standard implementation of the video element did not let the user choose the subtitle language. Now, recent browsers offers a menu to choose the track to display.
However, before it was available, it was easy to implement this feature using the Track API.
In the example below, we added two buttons below the video to enable/disable subtitles/captions and let you choose which track you prefer:
HTML code:
<html lang="en">
<head>
<meta charset=utf-8>
<title>HTML5 Video player with a choose subtitle feature</title>
</head>
<body onload="init()">
<section id="all">
<h1>Using the track API to extract the content of webVTT files in <code><track></code> elements</h1>
<p>Click on the buttons under the video to extract the english or german
subtitles</p>
<p>Look at the HTML and JS code.</p>
<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" default>
<track label="Deutsch subtitles" kind="subtitles" srclang="de"
src="https://mainline.i3s.unice.fr/mooc/elephants-dream-subtitles-de.vtt">
<track label="English chapters" kind="chapters" srclang="en"
src="https://mainline.i3s.unice.fr/mooc/elephants-dream-chapters-en.vtt">
</video>
<h3>Current track: <span id="currentLang"></span></h3>
<div id="langButtonDiv"></div>
</section>
</body>
</html>
CSS code:
#all {
background-color: lightgrey;
border-radius:10px;
padding: 20px;
border:1px solid;
}
JS code:
let langButtonDiv, currentLangSpan, video;
function init() {
langButtonDiv = document.querySelector("#langButtonDiv");
currentLangSpan = document.querySelector("#currentLang");
video = document.querySelector("#myVideo");
console.log("Number of tracks = " + video.textTracks.length);
// Updates the display of the current track activated
currentLangSpan.innerHTML = activeTrack();
// Build the buttons for choosing a track
buildButtons();
}
function activeTrack() {
for (let i = 0; i < video.textTracks.length; i++) {
if(video.textTracks[i].mode === 'showing') {
return video.textTracks[i].label + " (" + video.textTracks[i].language + ")";
}
}
return "no subtitles/caption selected";
}
function buildButtons() {
if (video.textTracks) {
// for each track, create a button
for (let i = 0; i < video.textTracks.length; i++) {
// We create buttons only for the caption and subtitle tracks
let track = video.textTracks[i];
if((track.kind !== "subtitles") && (track.kind !== "captions")) continue;
createButton(video.textTracks[i]);
}
}
}
function createButton(track) {
let b = document.createElement("button");
b.value=track.label;
b.setAttribute("lang", track.language);
b.addEventListener('click', (e) => {
// check which track is the track with the language we're
// looking for
var lang = e.target.getAttribute('lang');
for (var i = 0; i < video.textTracks.length; i++) {
if (video.textTracks[i].language == lang) {
video.textTracks[i].mode = 'showing';
} else {
video.textTracks[i].mode = 'hidden';
}
}
// update the span so that it displays the new active track
currentLangSpan.innerHTML = activeTrack();
});
b.appendChild(document.createTextNode(track.label));
langButtonDiv.appendChild(b);
}
If you are interested in building a complete custom video player, MDN offers an online tutorial with further information about styling and integrating a "CC" button
The MDN documentation on Web Video Text Tracks Format (WebVTT)