mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-26 10:08:22 +03:00
Fix dashboard live rendering and rotated cover fitting
This commit is contained in:
parent
4721dd4ed0
commit
5aa80022ae
@ -94,6 +94,7 @@ export default function LivePlayer({
|
|||||||
const shouldRotateClockwise = applyDashboardTransforms && rotateClockwise;
|
const shouldRotateClockwise = applyDashboardTransforms && rotateClockwise;
|
||||||
|
|
||||||
const mediaViewportRef = useRef<HTMLDivElement | null>(null);
|
const mediaViewportRef = useRef<HTMLDivElement | null>(null);
|
||||||
|
const mediaContentRef = useRef<HTMLDivElement | null>(null);
|
||||||
const [{ width: viewportWidth, height: viewportHeight }] =
|
const [{ width: viewportWidth, height: viewportHeight }] =
|
||||||
useResizeObserver(mediaViewportRef);
|
useResizeObserver(mediaViewportRef);
|
||||||
|
|
||||||
@ -104,17 +105,54 @@ export default function LivePlayer({
|
|||||||
transforms.push("rotate(90deg)");
|
transforms.push("rotate(90deg)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// For a 90° rotation, the media box must use swapped viewport dimensions
|
if (!shouldRotateClockwise || !viewportWidth || !viewportHeight) {
|
||||||
// before rotating, otherwise the rotated content can under-fill one axis.
|
return {
|
||||||
const rotatedWidth = viewportHeight ? `${viewportHeight}px` : "100%";
|
transform: transforms.join(" "),
|
||||||
const rotatedHeight = viewportWidth ? `${viewportWidth}px` : "100%";
|
width: "100%",
|
||||||
|
height: "100%",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const sourceWidth = cameraConfig.detect.width || 1;
|
||||||
|
const sourceHeight = cameraConfig.detect.height || 1;
|
||||||
|
const rotatedAspect = sourceHeight / sourceWidth;
|
||||||
|
const containerAspect = viewportWidth / viewportHeight;
|
||||||
|
|
||||||
|
let renderedWidth = viewportWidth;
|
||||||
|
let renderedHeight = viewportHeight;
|
||||||
|
|
||||||
|
if (shouldFillContainer) {
|
||||||
|
if (rotatedAspect > containerAspect) {
|
||||||
|
renderedHeight = viewportHeight;
|
||||||
|
renderedWidth = renderedHeight * rotatedAspect;
|
||||||
|
} else {
|
||||||
|
renderedWidth = viewportWidth;
|
||||||
|
renderedHeight = renderedWidth / rotatedAspect;
|
||||||
|
}
|
||||||
|
} else if (rotatedAspect > containerAspect) {
|
||||||
|
renderedWidth = viewportWidth;
|
||||||
|
renderedHeight = renderedWidth / rotatedAspect;
|
||||||
|
} else {
|
||||||
|
renderedHeight = viewportHeight;
|
||||||
|
renderedWidth = renderedHeight * rotatedAspect;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rotatedWidth = `${Math.ceil(renderedHeight)}px`;
|
||||||
|
const rotatedHeight = `${Math.ceil(renderedWidth)}px`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
transform: transforms.join(" "),
|
transform: transforms.join(" "),
|
||||||
width: shouldRotateClockwise ? rotatedWidth : "100%",
|
width: shouldRotateClockwise ? rotatedWidth : "100%",
|
||||||
height: shouldRotateClockwise ? rotatedHeight : "100%",
|
height: shouldRotateClockwise ? rotatedHeight : "100%",
|
||||||
};
|
};
|
||||||
}, [shouldRotateClockwise, viewportHeight, viewportWidth]);
|
}, [
|
||||||
|
cameraConfig.detect.height,
|
||||||
|
cameraConfig.detect.width,
|
||||||
|
shouldFillContainer,
|
||||||
|
shouldRotateClockwise,
|
||||||
|
viewportHeight,
|
||||||
|
viewportWidth,
|
||||||
|
]);
|
||||||
// stats
|
// stats
|
||||||
|
|
||||||
const [stats, setStats] = useState<PlayerStatsType>({
|
const [stats, setStats] = useState<PlayerStatsType>({
|
||||||
@ -310,7 +348,7 @@ export default function LivePlayer({
|
|||||||
className={cn(
|
className={cn(
|
||||||
"size-full rounded-lg md:rounded-2xl",
|
"size-full rounded-lg md:rounded-2xl",
|
||||||
shouldFillContainer && "object-cover",
|
shouldFillContainer && "object-cover",
|
||||||
liveReady ? "" : "hidden",
|
liveReady ? "opacity-100" : "opacity-0",
|
||||||
)}
|
)}
|
||||||
camera={streamName}
|
camera={streamName}
|
||||||
playbackEnabled={cameraActive || liveReady}
|
playbackEnabled={cameraActive || liveReady}
|
||||||
@ -333,7 +371,7 @@ export default function LivePlayer({
|
|||||||
className={cn(
|
className={cn(
|
||||||
"size-full rounded-lg md:rounded-2xl",
|
"size-full rounded-lg md:rounded-2xl",
|
||||||
shouldFillContainer && "object-cover",
|
shouldFillContainer && "object-cover",
|
||||||
liveReady ? "" : "hidden",
|
liveReady ? "opacity-100" : "opacity-0",
|
||||||
)}
|
)}
|
||||||
camera={streamName}
|
camera={streamName}
|
||||||
playbackEnabled={cameraActive || liveReady}
|
playbackEnabled={cameraActive || liveReady}
|
||||||
@ -373,7 +411,11 @@ export default function LivePlayer({
|
|||||||
}
|
}
|
||||||
useWebGL={useWebGL}
|
useWebGL={useWebGL}
|
||||||
setStats={setStats}
|
setStats={setStats}
|
||||||
containerRef={containerRef ?? internalContainerRef}
|
containerRef={
|
||||||
|
applyDashboardTransforms
|
||||||
|
? mediaContentRef
|
||||||
|
: (containerRef ?? internalContainerRef)
|
||||||
|
}
|
||||||
onPlaying={playerIsPlaying}
|
onPlaying={playerIsPlaying}
|
||||||
fit={shouldFillContainer ? "cover" : "contain"}
|
fit={shouldFillContainer ? "cover" : "contain"}
|
||||||
/>
|
/>
|
||||||
@ -421,6 +463,7 @@ export default function LivePlayer({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
ref={mediaContentRef}
|
||||||
className="absolute left-1/2 top-1/2"
|
className="absolute left-1/2 top-1/2"
|
||||||
style={mediaTransformStyle}
|
style={mediaTransformStyle}
|
||||||
>
|
>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user