如何将缓冲区时间范围数据从 HTML5 视频播放器引用映射到进度条?

How to Map the Buffer TimeRange Data From an HTML5 Video Player Ref to a Progress Bar?

我基本上只是想从默认 HTML5 视频播放器或 YouTube 上的类似播放器中模拟缓冲栏。

我正在制作自定义 JSX HTML5 视频播放器控制栏,但卡住了,因为我不确定如何 get/use 来自 videoRef 的缓冲进度数据对象。似乎我应该使用视频参考中的缓冲区 end() 函数和 TimeRanges 对象,但我还没有看到任何关于如何使用它来计算缓冲区栏的示例或文档.

问题:如何使用视频播放器 videoRef 中的缓冲区对象并将数据映射到自定义视频控制栏的缓冲区进度条?

我是否以某种方式检测到流缓冲区的进度,是否有某种事件?

示例代码:

export default function App() {
  const videoRef = React.useRef();
  const [videoProgress, setVideoProgress] = useState(0);
  const [videoBufferProgress, setVideoBufferProgress] = useState(0);
  const [videoTime, setVideoTime] = useState(0);

  //updates the video progress bar 1-100%, works fine
  function updateTime() {
    setVideoProgress(
      (videoRef.current.currentTime / videoRef.current.duration) * 100
    );
    setVideoTime(videoRef.current.currentTime);
  }

  //get buffer information so that I can use it to fill the buffer progress bar, it doesnt work rn
  function updateBuffer() {
    //setVideoBufferProgress()
    console.log(videoRef.current.buffered.end(0));
  }

  useEffect(() => {
    videoRef.current.addEventListener("loadeddata", () => updateBuffer());
    videoRef.current.addEventListener("timeupdate", () => updateTime());

    return () => {
      videoRef.current.removeEventListener("loadeddata", () => updateBuffer());
      videoRef.current.removeEventListener("timeupdate", () => updateTime());
    };
  }, []);

  return (
    <div>
      <video ref={videoRef}>
        <source src={`/api/video/stream/480/624593ba5a88168159a56169`} type="video/mp4"/>
      </video>
      <div>
        //video timeline bar, this works fine
        <ProgressBar
          now={videoProgress}
        />
        //video buffer bar, this doesnt work
        <ProgressBar
          now={videoBufferProgress}
        />
      </div>
    </div>
  );
}

我明白了。您只需监听 progress 事件。

function updateBuffer() {
    setVideoBufferProgress((videoRef.current.buffered.end(0) / videoRef.current.duration) * 100); //provides the last second of the video that has been loaded/buffered
}

//use the progress event to update the buffer for when new data is loaded
useEffect(() => {
  videoRef.current &&
    videoRef.current.addEventListener("loadeddata", () => updateBuffer());
  videoRef.current &&
    videoRef.current.addEventListener("progress", () => updateBuffer());
  videoRef.current &&
    videoRef.current.addEventListener("timeupdate", () => updateTime());
}, [videoRef.current]);