Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<html lang="en">
<head>
  <meta charset=utf-8>
  <title>Video player with chapter menu</title>
</head>
<body>
  <section id="all">
    <h1>Using JSON to describe chapter markers</h1>
    This example uses a WebVTT file with kind=chapters, that contains JSON cues for associating images and chapter marker descriptions.
    <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-JSON.vtt">
    </video>    
    <h2>Chapter menu</h2>
    <div id="chapterMenu"></div>
  </section>
</body>
</html>
 
#all {
  background-color: lightgrey;
  border-radius:10px;
  padding: 20px;
  border:1px solid;
  display:inline-block;
  /*height:500px;*/
  margin:30px;
  width:90%;
}
#myVideo {
  border-radius:10px;
  border:1px solid;
    display: block;
    margin-right: 2.85714%;
    width: 100%;
    background-color: black;
    position: relative;
  box-shadow: 5px 5px 5px grey;
}
#chapterMenuSection {
  background-color: lightgrey;
  border-radius:10px;
  padding: 20px;
  border:1px solid;
  display:inline-block;
  margin:0px 30px 30px 30px;
  width:90%;
}
figure.img {
  margin: 2px;
  float: left;
}
figcaption.desc {
  text-align: center;
  font-weight: normal;
  margin: 2px;
}
.thumb {
  height: 75px;
  border: 1px solid #000;
  margin: 10px 5px 0 0;
  box-shadow: 5px 5px 5px grey;
  transition: all 0.5s;
}
.thumb:hover {
    box-shadow: 5px 5px 5px black;
}
 
var video, chapterMenuDiv;
var tracks, trackElems, tracksURLs = [];
window.onload = function() {
  console.log("init");
  // when the page is loaded
  video = document.querySelector("#myVideo");
  chapterMenuDiv = document.querySelector("#chapterMenu");
  
  // 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;
  }
  
  // The tracks as JS objects
  tracks = video.textTracks;
  
  buildChapterMenu('en', 'chapters');
};
function buildChapterMenu(lang, kind) {
    // Locate the track with language = lang and kind="chapters"
  for(var i = 0; i < tracks.length; i++) {
    // current track
    var track = tracks[i];
    var trackAsHtmlElem = trackElems[i];
  
    if((track.language === lang) && (track.kind === kind)) {
      // the track must be active if we want to highlight the 
      // current chapter while the video is playing
      track.mode="showing"; 
      if(trackAsHtmlElem.readyState === 2) {
        // the track has already been loaded
        displayChapterMarkers(track);
      } else {
        displayChapterMarkersAfterTrackLoaded(trackAsHtmlElem, track);
      }
    }
  } 
}
function displayChapterMarkers(track) {
    var cues = track.cues;
  
    // We should not see the cues on the video.
    track.mode="hidden";
  
    // Iterate on cues
      for(var i=0, len = cues.length; i < len; i++) {
        var cue = cues[i];
        //addCueListeners(cue);
        var cueObject = JSON.parse(cue.text);
        var description = cueObject.description;
        var imageFileName = cueObject.image;
        var imageURL = "https://mainline.i3s.unice.fr/mooc/" + imageFileName;
        
        // add an image to the menu
        var figure = document.createElement('figure');
        figure.classList.add("img");
        
        figure.innerHTML = "<img onclick='jumpTo(" + cue.startTime + ");'  class='thumb' src='" + imageURL + "'><figcaption class='desc'>" + description + "</figcaption></figure>";
        chapterMenuDiv.insertBefore(figure, null);
      }
  }
function displayChapterMarkersAfterTrackLoaded(trackElem, track) {
  // Create a listener that will be called only when the track has
  // been loaded
  trackElem.addEventListener('load', function(e) {
      console.log("chapter track loaded");
      displayChapterMarkers(track);
   });
}
function jumpTo(time) {
  video.currentTime = time;
  video.play();
}
Output 300px

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
AuroreDechampspro
0viewers