mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-10 13:15:25 +03:00
Simplify dynamic video player
This commit is contained in:
parent
e8a6a99b46
commit
2e4ec3c02d
@ -201,15 +201,8 @@ function PreviewVideoPlayer({
|
||||
// canvas to cover preview transition
|
||||
|
||||
const canvasRef = useRef<HTMLCanvasElement | null>(null);
|
||||
const [videoWidth, videoHeight] = useMemo(() => {
|
||||
if (!previewRef.current) {
|
||||
return [0, 0];
|
||||
}
|
||||
const [videoSize, setVideoSize] = useState<number[]>([0, 0]);
|
||||
|
||||
return [previewRef.current.videoWidth, previewRef.current.videoHeight];
|
||||
// we know the video size will be known on load
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [loaded]);
|
||||
// handle switching sources
|
||||
|
||||
useEffect(() => {
|
||||
@ -218,9 +211,12 @@ function PreviewVideoPlayer({
|
||||
}
|
||||
|
||||
if (canvasRef.current) {
|
||||
canvasRef.current
|
||||
.getContext("2d")
|
||||
?.drawImage(previewRef.current, 0, 0, videoWidth, videoHeight);
|
||||
const context = canvasRef.current.getContext("2d");
|
||||
|
||||
if (context) {
|
||||
context.drawImage(previewRef.current, 0, 0, videoSize[0], videoSize[1]);
|
||||
}
|
||||
|
||||
setHasCanvas(true);
|
||||
}
|
||||
|
||||
@ -235,7 +231,7 @@ function PreviewVideoPlayer({
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`relative w-full rounded-2xl bg-black overflow-hidden ${className ?? ""} ${onClick ? "cursor-pointer" : ""}`}
|
||||
className={`relative rounded-2xl bg-black overflow-hidden ${onClick ? "cursor-pointer" : ""} ${className ?? ""}`}
|
||||
onClick={onClick}
|
||||
>
|
||||
{currentHourFrame && (
|
||||
@ -246,9 +242,9 @@ function PreviewVideoPlayer({
|
||||
)}
|
||||
<canvas
|
||||
ref={canvasRef}
|
||||
width={videoWidth}
|
||||
height={videoHeight}
|
||||
className={`absolute h-full left-1/2 -translate-x-1/2 ${!loaded && hasCanvas ? "" : "hidden"}`}
|
||||
width={videoSize[0]}
|
||||
height={videoSize[1]}
|
||||
className={`h-full absolute left-1/2 -translate-x-1/2 ${!loaded && hasCanvas ? "" : "hidden"}`}
|
||||
/>
|
||||
<video
|
||||
ref={previewRef}
|
||||
@ -269,8 +265,15 @@ function PreviewVideoPlayer({
|
||||
previewRef.current?.pause();
|
||||
}
|
||||
|
||||
if (previewRef.current && startTime && currentPreview) {
|
||||
previewRef.current.currentTime = startTime - currentPreview.start;
|
||||
if (previewRef.current) {
|
||||
setVideoSize([
|
||||
previewRef.current.videoWidth,
|
||||
previewRef.current.videoHeight,
|
||||
]);
|
||||
|
||||
if (startTime && currentPreview) {
|
||||
previewRef.current.currentTime = startTime - currentPreview.start;
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
|
||||
@ -41,26 +41,6 @@ export default function DynamicVideoPlayer({
|
||||
const apiHost = useApiHost();
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
// playback behavior
|
||||
|
||||
const grow = useMemo(() => {
|
||||
if (!config) {
|
||||
return "aspect-video";
|
||||
}
|
||||
|
||||
const aspectRatio =
|
||||
config.cameras[camera].detect.width /
|
||||
config.cameras[camera].detect.height;
|
||||
|
||||
if (aspectRatio > 2) {
|
||||
return "";
|
||||
} else if (aspectRatio < 16 / 9) {
|
||||
return isDesktop ? "" : "aspect-tall";
|
||||
} else {
|
||||
return "aspect-video";
|
||||
}
|
||||
}, [camera, config]);
|
||||
|
||||
// controlling playback
|
||||
|
||||
const playerRef = useRef<HTMLVideoElement | null>(null);
|
||||
@ -169,9 +149,9 @@ export default function DynamicVideoPlayer({
|
||||
}, [controller, recordings]);
|
||||
|
||||
return (
|
||||
<div className={`w-full relative ${className ?? ""}`}>
|
||||
<>
|
||||
<HlsVideoPlayer
|
||||
className={isDesktop ? `w-full ${grow}` : "max-h-[50dvh]"}
|
||||
className={isDesktop ? `w-full ${className}` : "max-h-[50dvh]"}
|
||||
videoRef={playerRef}
|
||||
visible={!(isScrubbing || isLoading)}
|
||||
currentSource={source}
|
||||
@ -195,7 +175,7 @@ export default function DynamicVideoPlayer({
|
||||
)}
|
||||
</HlsVideoPlayer>
|
||||
<PreviewPlayer
|
||||
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${isDesktop ? `w-full ${grow}` : "max-h-[50dvh]"}`}
|
||||
className={`${isScrubbing || isLoading ? "visible" : "hidden"} ${isDesktop ? `w-full ${className}` : "max-h-[50dvh]"}`}
|
||||
camera={camera}
|
||||
timeRange={timeRange}
|
||||
cameraPreviews={cameraPreviews}
|
||||
@ -205,6 +185,6 @@ export default function DynamicVideoPlayer({
|
||||
setPreviewController(previewController);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
@ -194,23 +194,36 @@ export function RecordingView({
|
||||
|
||||
// motion timeline data
|
||||
|
||||
const getCameraAspect = useCallback(
|
||||
(cam: string) => {
|
||||
if (!config) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const camera = config.cameras[cam];
|
||||
|
||||
if (!camera) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return camera.detect.width / camera.detect.height;
|
||||
},
|
||||
[config],
|
||||
);
|
||||
|
||||
const mainCameraAspect = useMemo(() => {
|
||||
if (!config) {
|
||||
const aspectRatio = getCameraAspect(mainCamera);
|
||||
|
||||
if (!aspectRatio) {
|
||||
return "normal";
|
||||
}
|
||||
|
||||
const aspectRatio =
|
||||
config.cameras[mainCamera].detect.width /
|
||||
config.cameras[mainCamera].detect.height;
|
||||
|
||||
if (aspectRatio > 2) {
|
||||
} else if (aspectRatio > 2) {
|
||||
return "wide";
|
||||
} else if (aspectRatio < 16 / 9) {
|
||||
return "tall";
|
||||
} else {
|
||||
return "normal";
|
||||
}
|
||||
}, [config, mainCamera]);
|
||||
}, [getCameraAspect, mainCamera]);
|
||||
|
||||
const grow = useMemo(() => {
|
||||
if (isMobile) {
|
||||
@ -335,8 +348,8 @@ export function RecordingView({
|
||||
key={mainCamera}
|
||||
className={
|
||||
isDesktop
|
||||
? `flex justify-center mb-5 ${mainCameraAspect == "tall" ? "h-full" : "w-[78%]"}`
|
||||
: `w-full ${mainCameraAspect == "wide" ? "" : "aspect-video"}`
|
||||
? `flex justify-center mb-5 ${mainCameraAspect == "tall" ? "h-[90%]" : mainCameraAspect == "wide" ? "w-full" : "w-[78%]"}`
|
||||
: `w-full ${mainCameraAspect == "wide" ? "aspect-wide" : "aspect-video"}`
|
||||
}
|
||||
>
|
||||
<DynamicVideoPlayer
|
||||
@ -367,13 +380,18 @@ export function RecordingView({
|
||||
{allCameras.map((cam) => {
|
||||
if (cam !== mainCamera) {
|
||||
return (
|
||||
<div key={cam}>
|
||||
<div
|
||||
key={cam}
|
||||
className={`${mainCameraAspect == "wide" ? "h-full flex-grow" : ""}`}
|
||||
style={{
|
||||
aspectRatio:
|
||||
mainCameraAspect == "wide"
|
||||
? undefined
|
||||
: getCameraAspect(cam),
|
||||
}}
|
||||
>
|
||||
<PreviewPlayer
|
||||
className={
|
||||
mainCameraAspect == "tall"
|
||||
? "size-full"
|
||||
: "size-full"
|
||||
}
|
||||
className="h-full"
|
||||
camera={cam}
|
||||
timeRange={currentTimeRange}
|
||||
cameraPreviews={allPreviews ?? []}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user