Skip to content Skip to sidebar Skip to footer

How To Start Preloading Multiple Parts/chapters Of A Same Video

I want to preload various chapters of the same video. So that when someone jumps to a new chapter there's no buffering. For example if first chapter starts from 00:00 and the next

Solution 1:

You could try this approach, but I'm not sure it's the best one :

  • Use the canplay event. It will fire when enough data is loaded (a few frames).

  • Each time it fires, go to your next chapter and wait until it fires again.

  • Do so until you loaded all chapters, then remove the event and set its video's currentTime to 0.

Javascript:

var chapters = [50, 100, 200, 300];
var j = 0;
var vid = document.querySelector('video');

vid.addEventListener('canplay', canplay);

function canplay() {
  if (j < chapters.length)
    this.currentTime = chapters[j++];
  else {
    this.removeEventListener('canplay', canplay);
    this.currentTime = 0;
  }
}

Please note that when you change the currentTime, there will still be a little time for browser to buffer images, even preloaded.

var chapters = [50, 100, 200, 300];
var j = 0;
var vid = document.querySelector('video');

vid.addEventListener('canplay', canplay);

function canplay() {
  if (j < chapters.length)
    this.currentTime = chapters[j++];
  else {
    this.removeEventListener('canplay', canplay);
    this.currentTime = 0;
    // remove the condom
    var c = document.querySelector('#condom');
    c.parentNode.removeChild(c);
    showLinks();
  }
}

function showLinks() {
  var links = document.querySelector('#links');
  links.innerHTML = "";
  for (var i = 0; i < chapters.length; i++) {
    var c = document.createElement('a');
    c.href = "#";
    // add an attribute to store the chapter time
    c.chapter = chapters[i];
    c.addEventListener('click', function(e) {
      e.preventDefault();
      // set the video to our time
      vid.currentTime = this.chapter;
    });
    c.innerHTML = 'chapter' + i;
    links.appendChild(c);
  }
}
html,body{ margin:0 }
a { margin:.5em; }
#condom{ position:absolute; top:0; left:0; height:170px; width:303px; z-index:9999; background:rgba(255,255,255, 0.7); text-align:center; }
#condom>span{ position:relative;  top:50%; transform:translateY(-50%); }
<video controls="true" preload="auto" height="170">
  <source type="video/ogg" src="http://media.w3.org/2010/05/bunny/movie.ogv">
  <source type="video/mp4" src="http://media.w3.org/2010/05/bunny/movie.mp4">
</video>
<div id="links"></div>
<div id="condom"><span>Your video is loading</span></div>

Pros : It does what you ask.

Cons : you will have to wait a bunch of time before it's first loaded.

Possible workaround, use two videos, one playable right now, and the other one, with chapters, going to replace the first one :

var chapters = [50, 100, 200, 300];
var j = 0;
var vid = document.querySelector('#withChapters');
var first = document.querySelector("#first");
vid.addEventListener('canplay', canplay);

function canplay() {
  if (j < chapters.length)
    this.currentTime = chapters[j++];
  else {
    this.removeEventListener('canplay', canplay);
    // We're not playing the first video ?
    if (first.paused) {
      // set us to its current position
      this.currentTime = first.currentTime;
      // remove the old one and let's replace it
      first.parentNode.removeChild(first);
      this.style.display = "block";
    }//else we'll do it later
    //anyway, show the links now
    showLinks();
  }
}

function showLinks() {
  var links = document.querySelector('#links');
  links.innerHTML = "";
  for (var i = 0; i < chapters.length; i++) {
    var c = document.createElement('a');
    c.className = "chapter_links";
    c.href = "#";
    // add an attribute to store the chapter time
    c.chapter = chapters[i];
    c.addEventListener('click', function(e) {
      e.preventDefault();
      // set the video to our time
      vid.currentTime = this.chapter;
      // he's still there?
      if (first) {
        // And he's playing ? so are we
        if (!first.paused) vid.play();
        // anyway, now is "later"
        first.parentNode.removeChild(first);
        vid.style.display = "block";
      }
    });
    c.innerHTML = 'chapter' + i;
    links.appendChild(c);
  }
}
a { margin: .5em; }
<video id="first" controls preload="auto" height="170">
  <source type="video/ogg" src="http://media.w3.org/2010/05/bunny/movie.ogv">
  <source type="video/mp4" src="http://media.w3.org/2010/05/bunny/movie.mp4">
</video>
<video id="withChapters" style="display:none" controls preload="auto" height="170">
  <source type="video/ogg" src="http://media.w3.org/2010/05/bunny/movie.ogv">
  <source type="video/mp4" src="http://media.w3.org/2010/05/bunny/movie.mp4">
</video>
<div id="links">Please wait while chapters are loading ...</div>

pros: solved the problem of first snippet.

cons: since you'll be loading two videos at the same time, the loading of chapters will take even more time, and the playing of the first video may suffer from this.


Post a Comment for "How To Start Preloading Multiple Parts/chapters Of A Same Video"