HTML5 huge Video Playlist

This is an example how a video playlist for single and long video could look like. Just edit the ul list to place more entry points.

by scurrilus

HTML

<video width="400" controls id="myvideo">
  <source src="https://download.media.tagesschau.de/video/2018/0218/TV-20180218-1908-2701.websm.h264.mp4" type="video/mp4">
  Your browser does not support HTML5 video.
</video>

<ul>
  <li data-duration="0:0">Intro</li>
  <li data-duration="0:12">Begrüßung</li>
  <li data-duration="0:20">Peter Taubert zieht sich zurück</li>
  <li data-duration="4:47">SPD Mitglieder Votum - Interview</li>
  <li data-duration="6:26">Flüchtlingsintegration</li>
  <li data-duration="10:12">Irgendwas in der Mitte</li>
  <li data-duration="12:21">Etwas Anderes in der Mitte</li>
  <li data-duration="14:10">Flüchtlingsintegration - Interview</li>
  <li data-duration="18:55">Abmoderation</li>
</ul>

SCSS

.capture-active {
  color: #cc0000;
}

video {
  float: left;
}

ul {
  background: #f3f3f3;
  box-sizing: border-box;
  float: left;
  margin: 0;
  padding: 1em;
  height: 225px;
  overflow-y: auto;
  width: 400px;
}

li {
  border-left: 2px solid;
  cursor: pointer;
  font-family: Arial;
  line-height: 1.5em;
  list-style: none;
  margin-bottom: 0.25em;
  padding-left: 1em;
  transition: all 0.25s;

  &:hover {
    color: #666;
  }
}

JavaScript

const video = document.getElementById("myvideo");
const listItem = document.getElementsByTagName('li');
let videoTimer = "";

/* Time Calculation from ul list data-duration value */
timeCaluculation = function(inputTime) {
  const datasetDuration = inputTime.split(":");
  const calcTime = String(parseInt(datasetDuration[0]) * 60 + parseInt(datasetDuration[1]));
  return calcTime;
}

/* Place time at the end of listItem description. Jump to ul list data-duration value given time on click.*/
for (var i = 0; i < listItem.length; i++) {
  listItem[i].append(" - (" + listItem[i].dataset.duration + "s)");

  listItem[i].addEventListener('click', function(e) {
    video.currentTime = timeCaluculation(this.dataset.duration);
    video.play();
    listStyling();
  }, false);
}

/* List active Capture styling */
function listStyling() {
  const activeClass = "capture-active";
  for (var i = 0; i < listItem.length; i++) {
    listItem[i].classList.remove(activeClass);

    if (video.currentTime > timeCaluculation(listItem[i].dataset.duration)) {
      if (i > 0) {
        listItem[i - 1].classList.remove(activeClass);
      }

      if (i < listItem.length - 1) {
        listItem[i + 1].classList.remove(activeClass);
      }

      listItem[i].classList.add(activeClass);
    }
  }
}

/* Video Events */
video.onpause = function() {
  clearInterval(videoTimer);
}

video.onplaying = function() {
  clearInterval(videoTimer);
  videoTimer = setInterval(listStyling, 100);
};