Video player with clickable transcript

by murgiaMarco

HTML

<section id="all">
  <h1>Using the track API to extract the content of webVTT files in <code>&lt;track&gt;</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>
  <p>

    <button disabled id="buttonEnglish" onclick="loadTranscript('en');">
      Display English transcript
    </button>

    <button disabled id="buttonDeutsch" onclick="loadTranscript('de');">
      Display Deutsch transcript
    </button>

  </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">
    <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>
  <div id="transcript"></div>
</section>

CSS

#all {
  background-color: lightgrey;
  border-radius: 10px;
  padding: 20px;
  border: 1px solid;
  display: inline-block;
  /*height:500px;*/
  margin: 30px;
  width: 90%;
}

.cues {
  color: blue;
}

.cues:hover {
  text-decoration: underline;
}

.cues.current {
  color: black;
  font-weight: bold;
}

#myVideo {
  display: block;
  float: left;
  margin-right: 2.85714%;
  width: 65.71429%;
  background-color: black;
  position: relative;
}

#transcript {
  padding: 10px;
  border: 1px solid;
  float: left;
  max-height: 225px;
  overflow: auto;
  width: 25%;
  margin: 0;
  font-size: 14px;
  list-style: none;
}

JavaScript

var video, transcriptDiv;
var tracks, trackElems, tracksURLs = [];
var buttonEnglish, buttonDeutsch;

window.onload = function() {
  console.log("init");
  // when the page is loaded
  video = document.querySelector("#myVideo");
  transcriptDiv = document.querySelector("#transcript");
  
  // The tracks as HTML elements
  trackElems = document.querySelectorAll("track");
  for(var i = 0; i < trackElems.length; i++) {
    var currentTrackElem = trackElems[i];
    tracksURLs[i] = currentTrackElem.src;
  }
  
  buttonEnglish = document.querySelector("#buttonEnglish");
  buttonDeutsch = document.querySelector("#buttonDeutsch");
  
  // we enable the buttons and show transcript
  buttonEnglish.disabled = false;
  buttonDeutsch.disabled = false;
    
  // The tracks as JS objects
  tracks = video.textTracks;
};

function loadTranscript(lang) {
  // clear current transcript
  clearTranscriptDiv();
  
  // set all track mode to disabled. We will only activate the
  // one whose content will be displayed as transcript
  disableAllTracks();
  
  // Locate the track with language = lang
  for(var i = 0; i < tracks.length; i++) {
    // current track
    var track = tracks[i];
    var trackAsHtmlElem = trackElems[i];
  
    if((track.language === lang) && (track.kind !== "chapters")) {
      track.mode="showing";

      if(trackAsHtmlElem.readyState === 2) {
        // the track has already been loaded
        displayCues(track);
      } else {
        displayCuesAfterTrackLoaded(trackAsHtmlElem, track);
      }
      
/*      FOR FIREFOX....
        track.addEventListener("cuechange", function(e) {
           var cue = this.activeCues[0];
           console.log("cue change");
           var transcriptText = document.getElementById(cue.id);
           transcriptText.classList.add("current");
      });
      */
    }
  } 
}
  

function displayCuesAfterTrackLoaded(trackElem, track) {
  // Create a listener that will be called only when the track has
  // been loaded
 ...