137 lines
4.0 KiB
TypeScript
137 lines
4.0 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||
/* eslint-disable react-hooks/exhaustive-deps */
|
||
import { useEffect, useRef, useState } from "react";
|
||
import {
|
||
Config,
|
||
AllSettings,
|
||
PixelStreaming,
|
||
LatencyTestResults,
|
||
} from "@epicgames-ps/lib-pixelstreamingfrontend-ue5.3";
|
||
import { Trans } from "react-i18next";
|
||
|
||
export interface PixelStreamingWrapperProps {
|
||
initialSettings?: Partial<AllSettings>;
|
||
onVideoInitialized?: () => void;
|
||
}
|
||
|
||
export const PixelStreamingWrapper = ({
|
||
initialSettings,
|
||
onVideoInitialized,
|
||
}: PixelStreamingWrapperProps) => {
|
||
// A reference to parent div element that the Pixel Streaming library attaches into:
|
||
const videoParent = useRef<HTMLDivElement>(null);
|
||
|
||
// Pixel streaming library instance is stored into this state variable after initialization:
|
||
const [_pixelStreaming, setPixelStreaming] = useState<PixelStreaming>();
|
||
|
||
// A boolean state variable that determines if the Click to play overlay is shown:
|
||
const [_clickToPlayVisible, setClickToPlayVisible] = useState(false);
|
||
|
||
const [, setLatencyTestResult] = useState<LatencyTestResults>();
|
||
const [isVideoInitialized, setIsVideoInitialized] = useState(false);
|
||
|
||
// Run on component mount:
|
||
useEffect(() => {
|
||
if (videoParent.current) {
|
||
// Attach Pixel Streaming library to videoParent element:
|
||
const config = new Config({ initialSettings });
|
||
const streaming = new PixelStreaming(config, {
|
||
videoElementParent: videoParent.current,
|
||
});
|
||
|
||
document.getElementById("hiddenInput")?.remove();
|
||
document.getElementById("editTextButton")?.remove();
|
||
|
||
// register a playStreamRejected handler to show Click to play overlay if needed:
|
||
streaming.addEventListener("playStreamRejected", () => {
|
||
setClickToPlayVisible(true);
|
||
});
|
||
|
||
streaming.addEventListener("videoInitialized", () => {
|
||
onVideoInitialized && onVideoInitialized();
|
||
setIsVideoInitialized(true);
|
||
});
|
||
|
||
streaming.addEventListener("latencyTestResult", (e) => {
|
||
setLatencyTestResult(e.data.latencyTimings);
|
||
// console.log("Data", e.data.latencyTimings);
|
||
});
|
||
|
||
// setInterval(() => {
|
||
// streaming.requestLatencyTest();
|
||
// }, 500);
|
||
|
||
// Save the library instance into component state so that it can be accessed later:
|
||
setPixelStreaming(streaming);
|
||
|
||
// Clean up on component unmount:
|
||
return () => {
|
||
try {
|
||
streaming.disconnect();
|
||
} catch {
|
||
//
|
||
}
|
||
};
|
||
}
|
||
}, []);
|
||
|
||
return (
|
||
<div
|
||
style={{
|
||
width: "100%",
|
||
height: "100%",
|
||
position: "relative",
|
||
}}
|
||
>
|
||
<div
|
||
ref={videoParent}
|
||
style={{
|
||
width: "100%",
|
||
height: "100%",
|
||
}}
|
||
/>
|
||
{!isVideoInitialized && (
|
||
<div className="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center">
|
||
<p className="flex items-center gap-4">
|
||
<span>
|
||
<img
|
||
src="/icons/Loader.png"
|
||
alt=""
|
||
className="animate-spin w-6 h-6"
|
||
/>
|
||
</span>
|
||
<Trans i18nKey="streamBuffering">Буферизация потока</Trans>
|
||
</p>
|
||
</div>
|
||
)}
|
||
|
||
{/* {clickToPlayVisible && (
|
||
<div
|
||
style={{
|
||
position: "absolute",
|
||
top: 0,
|
||
left: 0,
|
||
width: "100%",
|
||
height: "100%",
|
||
display: "flex",
|
||
alignItems: "center",
|
||
justifyContent: "center",
|
||
cursor: "pointer",
|
||
color: "#fff",
|
||
}}
|
||
onClick={() => {
|
||
pixelStreaming?.play();
|
||
setClickToPlayVisible(false);
|
||
}}
|
||
>
|
||
<div className="bg-gradient rounded px-4 py-2 opacity-95 hover:opacity-100 transition-opacity">
|
||
<p>
|
||
<Trans i18nKey="clickToContinue">Нажмите, чтобы продолжить</Trans>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
)} */}
|
||
</div>
|
||
);
|
||
};
|