"use client"; import { useEffect, useRef, useState } from "react"; import styles from "./VideoPlayer.module.scss"; interface VideoPlayerProps { mpd: string; m3u8: string; poster?: string; autoPlay?: boolean; } export default function VideoPlayer({ mpd, m3u8, poster, autoPlay = false, }: VideoPlayerProps) { const videoRef = useRef(null); const [isLoading, setIsLoading] = useState(true); const [hasError, setHasError] = useState(false); const [showPlayButton, setShowPlayButton] = useState(true); useEffect(() => { const video = videoRef.current; if (!video) return; // eslint-disable-next-line @typescript-eslint/no-explicit-any let shakaPlayer: any; // eslint-disable-next-line @typescript-eslint/no-explicit-any let hls: any; let cleanup = false; const initPlayer = async () => { try { setIsLoading(true); setHasError(false); // eslint-disable-next-line no-console console.log("[VideoPlayer] Initializing player..."); // eslint-disable-next-line no-console console.log("[VideoPlayer] DASH URL:", mpd); // eslint-disable-next-line no-console console.log("[VideoPlayer] HLS URL:", m3u8); // iOS/Safari - нативный HLS if (video.canPlayType("application/vnd.apple.mpegurl")) { // eslint-disable-next-line no-console console.log("[VideoPlayer] Using native HLS support"); video.src = m3u8; setIsLoading(false); return; } // DASH через Shaka (предпочтительно для Android/Desktop) try { // eslint-disable-next-line no-console console.log("[VideoPlayer] Trying Shaka Player for DASH..."); const shaka = await import("shaka-player/dist/shaka-player.compiled.js"); if (cleanup) return; shakaPlayer = new shaka.default.Player(video); shakaPlayer.configure({ streaming: { bufferingGoal: 20, rebufferingGoal: 2, lowLatencyMode: false, }, manifest: { dash: { ignoreMinBufferTime: true, }, }, }); await shakaPlayer.load(mpd); // eslint-disable-next-line no-console console.log("[VideoPlayer] Shaka Player loaded successfully"); setIsLoading(false); return; } catch (e) { // eslint-disable-next-line no-console console.warn("[VideoPlayer] Shaka failed, fallback to HLS.js", e); } // Запасной вариант - HLS.js try { // eslint-disable-next-line no-console console.log("[VideoPlayer] Trying HLS.js..."); const Hls = (await import("hls.js")).default; if (cleanup) return; if (Hls.isSupported()) { hls = new Hls({ maxBufferLength: 30, debug: false, }); hls.loadSource(m3u8); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, () => { // eslint-disable-next-line no-console console.log("[VideoPlayer] HLS.js manifest parsed"); setIsLoading(false); }); hls.on( Hls.Events.ERROR, // eslint-disable-next-line @typescript-eslint/no-explicit-any (_event: any, data: any) => { // eslint-disable-next-line no-console console.error("[VideoPlayer] HLS.js error:", data); if (data.fatal) { setHasError(true); setIsLoading(false); } }, ); return; } } catch (e) { // eslint-disable-next-line no-console console.warn("[VideoPlayer] HLS.js failed", e); } // Совсем запасной - прямой src // eslint-disable-next-line no-console console.log("[VideoPlayer] Using direct video src"); video.src = m3u8; setIsLoading(false); } catch (error) { // eslint-disable-next-line no-console console.error("[VideoPlayer] Fatal error:", error); setHasError(true); setIsLoading(false); } }; initPlayer(); return () => { cleanup = true; try { shakaPlayer?.destroy(); } catch { // Ignore cleanup errors } try { hls?.destroy(); } catch { // Ignore cleanup errors } }; }, [mpd, m3u8, autoPlay]); const handlePlay = async () => { const video = videoRef.current; if (!video) return; try { // Убеждаемся что звук включен video.muted = false; await video.play(); setShowPlayButton(false); // eslint-disable-next-line no-console console.log("[VideoPlayer] Started playing with sound"); } catch (error) { // eslint-disable-next-line no-console console.error("[VideoPlayer] Play failed:", error); } }; const handleVideoPlay = () => { setShowPlayButton(false); }; const handleVideoPause = () => { // Пауза через нативные контролы }; return (
{isLoading && !hasError && (
)} {hasError && (

Unable to load video

Please check your connection and try again

)} {!isLoading && !hasError && showPlayButton && ( )}
); }