feat: add buffering spinner to VideoPlayer component

This commit is contained in:
2026-03-11 22:06:10 +01:00
parent 2caad1670d
commit 62549faffa

View File

@@ -1,5 +1,6 @@
import { forwardRef, useEffect, useRef } from "react";
import { forwardRef, useEffect, useRef, useState } from "react";
import Hls from "hls.js";
import { Loader2 } from "lucide-react";
export interface SubtitleTrack {
id: number;
@@ -34,6 +35,7 @@ const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
) => {
const internalRef = useRef<HTMLVideoElement | null>(null);
const hlsRef = useRef<Hls | null>(null);
const [isBuffering, setIsBuffering] = useState(true);
const setRef = (el: HTMLVideoElement | null) => {
internalRef.current = el;
@@ -55,6 +57,7 @@ const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
hlsRef.current?.destroy();
hlsRef.current = null;
onSubtitleTracksChange?.([]);
setIsBuffering(true);
const isHls = src.includes(".m3u8");
@@ -117,9 +120,18 @@ const VideoPlayer = forwardRef<HTMLVideoElement, VideoPlayerProps>(
ref={setRef}
poster={poster}
playsInline
onPlaying={() => setIsBuffering(false)}
onWaiting={() => setIsBuffering(true)}
onError={onStreamError}
className="h-full w-full object-contain"
/>
{/* Buffering spinner — shown until frames are actually rendering */}
{isBuffering && (
<div className="pointer-events-none absolute inset-0 flex items-center justify-center">
<Loader2 className="h-10 w-10 animate-spin text-zinc-500" />
</div>
)}
</div>
);
},