fix live camera initial resolution

add resize observer from frigate
This commit is contained in:
NlightN22 2025-03-17 02:09:51 +07:00
parent 99bb90a6c4
commit e55a3d3439
3 changed files with 77 additions and 2 deletions

View File

@ -0,0 +1,69 @@
import { MutableRefObject, useEffect, useMemo, useState } from "react";
type RefType = MutableRefObject<Element | null> | Window;
export function useResizeObserver(...refs: RefType[]) {
const [dimensions, setDimensions] = useState<
{ width: number; height: number; x: number; y: number }[]
>(
new Array(refs.length).fill({
width: 0,
height: 0,
x: -Infinity,
y: -Infinity,
}),
);
const resizeObserver = useMemo(
() =>
new ResizeObserver((entries) => {
window.requestAnimationFrame(() => {
setDimensions((prevDimensions) => {
const newDimensions = entries.map((entry) => entry.contentRect);
if (
JSON.stringify(prevDimensions) !== JSON.stringify(newDimensions)
) {
return newDimensions;
}
return prevDimensions;
});
});
}),
[],
);
useEffect(() => {
refs.forEach((ref) => {
if (ref instanceof Window) {
resizeObserver.observe(document.body);
} else if (ref.current) {
resizeObserver.observe(ref.current);
}
});
return () => {
refs.forEach((ref) => {
if (ref instanceof Window) {
resizeObserver.unobserve(document.body);
} else if (ref.current) {
resizeObserver.unobserve(ref.current);
}
});
};
}, [refs, resizeObserver]);
if (dimensions.length == refs.length) {
return dimensions;
} else {
const items = [...dimensions];
for (let i = dimensions.length; i < refs.length; i++) {
items.push({
width: 0,
height: 0,
x: -Infinity,
y: -Infinity,
});
}
return items;
}
}

View File

@ -8,9 +8,11 @@ import OverlayCogwheelLoader from '../shared/components/loaders/OverlayCogwheelL
import Player from '../widgets/Player'; import Player from '../widgets/Player';
import CameraPageHeader from '../widgets/header/CameraPageHeader'; import CameraPageHeader from '../widgets/header/CameraPageHeader';
import RetryErrorPage from './RetryErrorPage'; import RetryErrorPage from './RetryErrorPage';
import { LegacyRef, useRef } from 'react';
const LiveCameraPage = () => { const LiveCameraPage = () => {
const { t } = useTranslation() const { t } = useTranslation()
const containerRef = useRef<HTMLDivElement | null>(null)
let { id: cameraId } = useParams<'id'>() let { id: cameraId } = useParams<'id'>()
if (!cameraId) throw Error('Camera id does not exist') if (!cameraId) throw Error('Camera id does not exist')
@ -25,12 +27,13 @@ const LiveCameraPage = () => {
return ( return (
<Flex w='100%' h='100%' justify='center' align='center' direction='column'> <Flex ref={containerRef} w='100%' h='100%' justify='center' align='center' direction='column'>
<CameraPageHeader camera={camera} editButton /> <CameraPageHeader camera={camera} editButton />
<Player <Player
camera={camera} camera={camera}
useWebGL={true} useWebGL={true}
preferredLiveMode='jsmpeg' preferredLiveMode='jsmpeg'
containerRef={containerRef}
/> />
</Flex> </Flex>
); );

View File

@ -5,6 +5,8 @@ import { useEffect, useMemo, useRef, useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { cn } from "../../utils/class.merge"; import { cn } from "../../utils/class.merge";
import { PlayerStatsType } from "../../../types/live"; import { PlayerStatsType } from "../../../types/live";
import { isProduction } from "../../env.const";
import { useResizeObserver } from "../../../hooks/resize-observer";
type JSMpegPlayerProps = { type JSMpegPlayerProps = {
url: string; url: string;
@ -52,7 +54,8 @@ const JSMpegPlayer = (
[containerRef, containerRef.current, internalContainerRef], [containerRef, containerRef.current, internalContainerRef],
); );
const { height: containerHeight, width: containerWidth } = useViewportSize() const [{ width: containerWidth, height: containerHeight }] =
useResizeObserver(selectedContainerRef);
const stretch = true; const stretch = true;
const aspectRatio = width / height; const aspectRatio = width / height;