首页 > 解决方案 > HTML 视频缓冲冻结

问题描述

我正在制作自定义视频控件,我有一个@progress事件用于跟踪视频的缓冲量并更新进度条的宽度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>

如果您从头到尾播放视频并且不点击超出缓冲范围,这可以正常工作:

视频进度条工作

这也适用于用拇指擦洗。

但是,如果您单击超出缓冲范围,它会冻结:

视频进度条冻结

点击事件的代码:

<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;
},

起初我认为这将是 Vue 的反应性问题,因为我通过 props 传递缓冲区数据,但是,当我console.log(e.target.buffered.end(0))看到数据本身冻结在单击时的任何位置时。

有谁知道为什么会这样或我该如何解决?

标签: javascripthtmlvue.js

解决方案


问题是您正在使用end(0)which 将返回第一个 时间范围的结尾。

由于您已跳过视频的一部分,因此您有多个时间范围的buffered,但您将继续显示第一个(索引 0)部分。

要向前跳跃,您可以使用e.target.buffered.end(e.target.buffered.length - 1),但是由于时间范围是有序的,这并不总是适用于向后跳跃。您可能需要遍历时间范围并找到包含您在媒体中当前位置的时间范围。


推荐阅读