Skip to content Skip to sidebar Skip to footer

HTML 5 Video: Playing Multiple "clips" With Javascript

I'm having a problem with HTML Video and JavaScript so have written some simple code to demonstrate. There is one video which contains three 'clips' all five seconds long (obviousl

Solution 1:

I don't know what Chrome bug you are talking about, but for cleaner code, you might be interested in the #t=start[,end] Media Fragment, which will allow you to set a time range directly as the source of your <video>:

onclick =e=> {
  const data = e.target.dataset;
  if(!data.start) return;
  vid.src = vid.src.split('#')[0] +
    '#t=' + data.start + ',' + data.end;
  // url.vid#t=start,end
  vid.play();
}
<button data-start="5" data-end="10">play [5,10]</button>
<button data-start="35" data-end="40">play [35,40]</button>
<button data-start="00:01:25" data-end="00:01:30">play [00:01:25,00:01:30]</button>
<video id="vid" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" muted></video>

Now if you really wish to go the way you were going, then you'll have change your code a bit.

Never add a new event listener from an user-generated event.

Add it once, and only trigger semaphores / update variables from user events.

So we first add the timeupdate event on our <video>, then if no user generated event did happen, we exit early. Otherwise, we check for a variable that is accessible to both our event listeners (here called next_stop) if we should pause or not.

Then, in the buttons event listeners, we update the <video>'scurrentTime, request it to play and update next_stop.

The two event listeners can interact thanks to the shared next_stop variable, but no more conflicts.

let next_stop = Infinity; // a variable shared by both event listeners

// add the event listeners only once
vid.addEventListener('timeupdate', handleTimeupdate, {passive: true});
document.addEventListener('click', handleClick);

function handleTimeupdate(evt) {
  // not set? exit early
  if(!isFinite(next_stop)) return;
  // a single action
  if(this.currentTime > next_stop) {
    this.pause();
    // if you want to disable the range once it's done
    // e.g to allow default controls interactions
//    next_stop = Infinity;
  }
}

function handleClick(evt) {
  const times = parseTime(evt.target);
  if(!times) return;
  // update the video's current time  
  vid.currentTime = times.start;
  // update the shared variable
  next_stop = times.end;
  // start playing if needed
  if(vid.paused) {
    vid.play();
  }
}

function parseTime(target) {
  const data = target.dataset;
  if(!data || !data.start) return null;
  return {start: +data.start, end: +data.end};
}
<button data-start="5" data-end="10">play [5,10]</button>
<button data-start="35" data-end="40">play [35,40]</button>
<button data-start="85" data-end="90">play [00:01:25,00:01:30]</button>
<video id="vid" src="https://upload.wikimedia.org/wikipedia/commons/transcoded/2/22/Volcano_Lava_Sample.webm/Volcano_Lava_Sample.webm.360p.webm" controls></video>

Post a Comment for "HTML 5 Video: Playing Multiple "clips" With Javascript"