Dan Knights
Dan Knights

Reputation: 8368

HTML video buffering freeze

I'm making custom video controls, I have a @progress event which is used to track how much the video has buffered and update the width of a progress bar div:

<video @progress="videoBuffer($event)">
videoBuffer(e) {
  if (e.target.buffered.length === 1)
    // videoBuffered passed as props to the controls
    this.videoBuffered = (e.target.buffered.end(0) / e.target.duration) * 100;
},
<div
  class="dk__video-buffered"
  :style="{ maxWidth: videoBuffered + '%' }"
></div>

This works fine if you play the video from start to finish and don't click past the buffered range:

Video progress bar working

This also works when scrubbing with the thumb.

However, if you click past the buffered range, it freezes:

Video progress bar freezing

Code for the click event:

<div
  class="dk__video-track-container"
  @click="trackTime($event)"
>
  <div class="dk__video-track">
    <div
      class="dk__video-played"
      :style="{ width: playedWidth + '%' }"
    ></div>
    <div
      class="dk__video-buffered"
      :style="{ maxWidth: videoBuffered + '%' }"
    ></div>
  </div>
</div>
trackTime(e) {
  // Set the videos time on click
  this.video.currentTime =
    (e.offsetX / e.target.offsetParent.offsetWidth) * this.videoDuration;
},

At first I thought this would be an issue with Vue's reactivity as I'm passing the buffer data through props, but, when I console.log(e.target.buffered.end(0)) I can see that the data itself freezes on whatever position it was at when clicked.

Does anyone have any idea why this is or how I can work around it?

Upvotes: 0

Views: 883

Answers (1)

DBS
DBS

Reputation: 9959

The problem is that you are using end(0) which will return the end of the first time range.

Since you have skipped a part of the video, you have multiple time range's buffered, but you will continue displaying the first (index 0) section.

To jump forwards, you could use e.target.buffered.end(e.target.buffered.length - 1), however since time range's are ordered, this will not always work for jumping backwards. You may need to iterate through the time-range's and find the one which contains your current position in the media.

Upvotes: 2

Related Questions