Bin
2025-12-17 dcf780a91c16b6be28635b6e2e0e702060ee19f2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { useCallback, useRef, useEffect } from "react";
import { SYNC_WINDOW } from "../mixins/Syncable";
 
export const useUpdateBuffering = (
  mediaRef: React.RefObject<HTMLMediaElement> | React.MutableRefObject<HTMLMediaElement | undefined>,
  onBufferingChange: (isBuffering: boolean) => void,
) => {
  const timeoutRef = useRef<number | null>(null);
  const bufferingStartedTime = useRef<number | null>(null);
 
  const updateBuffering = useCallback(() => {
    if (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }
 
    const mediaEl = mediaRef.current;
    if (!mediaEl) return;
 
    const shouldWaitForSyncWindow =
      bufferingStartedTime.current !== null && Date.now() - bufferingStartedTime.current < SYNC_WINDOW;
    const isBuffering = mediaEl.networkState === mediaEl.NETWORK_LOADING || shouldWaitForSyncWindow;
 
    if (isBuffering) {
      onBufferingChange(true);
      bufferingStartedTime.current = bufferingStartedTime.current ?? Date.now();
      timeoutRef.current = window.setTimeout(updateBuffering, 16);
    } else {
      onBufferingChange(false);
    }
  }, [mediaRef, onBufferingChange]);
 
  useEffect(() => {
    return () => {
      if (timeoutRef.current) {
        clearTimeout(timeoutRef.current);
      }
    };
  }, []);
 
  return updateBuffering;
};