Reputation: 8368
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:
This also works when scrubbing with the thumb.
However, if you click past the buffered range, it freezes:
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
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