FEAT: Integrated the live stream video

This commit is contained in:
white
2025-02-12 15:04:56 +00:00
parent c95f2c95f8
commit 1eff005dec

View File

@@ -1,61 +1,64 @@
import React, { useEffect, useRef } from "react"; import React, { useEffect, useRef } from "react";
import { useParams } from "react-router-dom";
import videojs from "video.js"; import videojs from "video.js";
import type Player from "video.js/dist/types/player";
import "video.js/dist/video-js.css"; import "video.js/dist/video-js.css";
interface VideoPlayerProps { const VideoPlayer: React.FC = () => {
streamId: number; const { streamerName } = useParams<{ streamerName: string }>(); // Get streamerName from URL
}
const VideoPlayer: React.FC<VideoPlayerProps> = ({ streamId }) => {
const videoRef = useRef<HTMLDivElement>(null); const videoRef = useRef<HTMLDivElement>(null);
const playerRef = useRef<Player | null>(null); const playerRef = useRef<videojs.Player | null>(null);
useEffect(() => { useEffect(() => {
// Makes sure Video.js player is only initialized once if (!videoRef.current || !streamerName) return;
if (!playerRef.current && videoRef.current) {
const streamUrl = `http://localhost:8080/stream/${streamerName}/index.m3u8`; // Updated URL with streamerName
if (!playerRef.current) {
const videoElement = document.createElement("video"); const videoElement = document.createElement("video");
videoElement.classList.add( videoElement.classList.add("video-js", "vjs-big-play-centered", "w-full", "h-full");
"video-js", videoElement.setAttribute("playsinline", "true");
"vjs-big-play-centered",
"w-full",
"h-full",
);
videoRef.current.appendChild(videoElement); videoRef.current.appendChild(videoElement);
playerRef.current = videojs(videoElement, { playerRef.current = videojs(videoElement, {
controls: true, controls: true,
autoplay: true,
muted: true,
fluid: true, fluid: true,
responsive: true, responsive: true,
// autoplay: true, liveui: true,
loop: true,
aspectRatio: "16:9",
sources: [ sources: [
{ {
src: `/images/sample_game_video.mp4`, src: streamUrl,
// type: "application/x-mpegURL", type: "application/x-mpegURL",
type: "video/mp4",
}, },
], ],
}); });
// Handle stream errors & retry
playerRef.current.on("error", () => {
console.error(`Stream failed to load: ${streamUrl}`);
setTimeout(() => {
console.log("Retrying stream...");
playerRef.current?.src({ src: streamUrl, type: "application/x-mpegURL" });
playerRef.current?.play();
}, 5000);
});
} else {
playerRef.current.src({ src: streamUrl, type: "application/x-mpegURL" });
playerRef.current.play();
} }
// Dispose the Video.js player when the component unmounts
return () => { return () => {
if (playerRef.current) { if (playerRef.current) {
playerRef.current.dispose(); playerRef.current.dispose();
playerRef.current = null; playerRef.current = null;
} }
}; };
}, [streamId]); }, [streamerName]);
return ( return (
<div <div className="min-w-[65vw] w-full h-full flex justify-center items-center bg-gray-900 rounded-lg">
id="video-container" <div ref={videoRef} className="w-full max-w-[80vw] self-center" />
className="min-w-[65vw] w-full h-full flex justify-center items-center bg-gray-900 rounded-lg"
style={{ gridArea: "1 / 1 / 2 / 2" }}
>
<div ref={videoRef} id="video-player" className="w-full max-w-[80vw] self-center" />
</div> </div>
); );
}; };