mirror of
https://github.com/blakeblackshear/frigate.git
synced 2025-01-07 00:06:57 +01:00
Live camera aspect ratio fixes (#10266)
* dynamically manage aspect ratio * full size * always use camera aspect ratio for mobile * no need for different handling for pano cams * don't set aspect ratio on fullscreen
This commit is contained in:
parent
7be2923d2d
commit
ed99be0856
@ -93,7 +93,7 @@ export default function LivePlayer({
|
||||
if (liveMode == "webrtc") {
|
||||
player = (
|
||||
<WebRtcPlayer
|
||||
className={`rounded-2xl h-full ${liveReady ? "" : "hidden"}`}
|
||||
className={`rounded-2xl size-full ${liveReady ? "" : "hidden"}`}
|
||||
camera={cameraConfig.live.stream_name}
|
||||
playbackEnabled={cameraActive}
|
||||
audioEnabled={playAudio}
|
||||
@ -104,7 +104,7 @@ export default function LivePlayer({
|
||||
if ("MediaSource" in window || "ManagedMediaSource" in window) {
|
||||
player = (
|
||||
<MSEPlayer
|
||||
className={`rounded-2xl h-full ${liveReady ? "" : "hidden"}`}
|
||||
className={`rounded-2xl size-full ${liveReady ? "" : "hidden"}`}
|
||||
camera={cameraConfig.name}
|
||||
playbackEnabled={cameraActive}
|
||||
audioEnabled={playAudio}
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { MutableRefObject, useEffect, useMemo, useState } from "react";
|
||||
|
||||
export function useResizeObserver(...refs: MutableRefObject<Element | null>[]) {
|
||||
const [dimensions, setDimensions] = useState(
|
||||
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,
|
||||
@ -21,14 +25,18 @@ export function useResizeObserver(...refs: MutableRefObject<Element | null>[]) {
|
||||
|
||||
useEffect(() => {
|
||||
refs.forEach((ref) => {
|
||||
if (ref.current) {
|
||||
if (ref instanceof Window) {
|
||||
resizeObserver.observe(document.body);
|
||||
} else if (ref.current) {
|
||||
resizeObserver.observe(ref.current);
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
refs.forEach((ref) => {
|
||||
if (ref.current) {
|
||||
if (ref instanceof Window) {
|
||||
resizeObserver.unobserve(document.body);
|
||||
} else if (ref.current) {
|
||||
resizeObserver.unobserve(ref.current);
|
||||
}
|
||||
});
|
||||
|
@ -15,6 +15,7 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||
import useKeyboardListener from "@/hooks/use-keyboard-listener";
|
||||
import { CameraConfig } from "@/types/frigateConfig";
|
||||
import { CameraPtzInfo } from "@/types/ptz";
|
||||
@ -61,6 +62,8 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) {
|
||||
const navigate = useNavigate();
|
||||
const { isPortrait } = useMobileOrientation();
|
||||
const mainRef = useRef<HTMLDivElement | null>(null);
|
||||
const [{ width: windowWidth, height: windowHeight }] =
|
||||
useResizeObserver(window);
|
||||
|
||||
// camera features
|
||||
|
||||
@ -105,7 +108,7 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) {
|
||||
return "absolute left-2 right-2 top-[50%] -translate-y-[50%]";
|
||||
} else {
|
||||
if (aspect > 16 / 9) {
|
||||
return "absolute left-12 top-[50%] -translate-y-[50%]";
|
||||
return "absolute left-0 top-[50%] -translate-y-[50%]";
|
||||
} else {
|
||||
return "absolute top-2 bottom-2 left-[50%] -translate-x-[50%]";
|
||||
}
|
||||
@ -114,17 +117,33 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) {
|
||||
|
||||
if (fullscreen) {
|
||||
if (aspect > 16 / 9) {
|
||||
return "absolute inset-x-0 top-[50%] -translate-y-[50%]";
|
||||
return "absolute inset-x-2 top-[50%] -translate-y-[50%]";
|
||||
} else {
|
||||
return "absolute inset-y-0 left-[50%] -translate-x-[50%]";
|
||||
return "absolute inset-y-2 left-[50%] -translate-x-[50%]";
|
||||
}
|
||||
} else if (aspect > 2) {
|
||||
return "absolute left-2 right-2 top-[50%] -translate-y-[50%]";
|
||||
} else {
|
||||
return "absolute top-2 bottom-2 left-[50%] -translate-x-[50%]";
|
||||
}
|
||||
}, [camera, fullscreen, isPortrait]);
|
||||
|
||||
const windowAspectRatio = useMemo(() => {
|
||||
return windowWidth / windowHeight;
|
||||
}, [windowWidth, windowHeight]);
|
||||
|
||||
const cameraAspectRatio = useMemo(() => {
|
||||
return camera.detect.width / camera.detect.height;
|
||||
}, [camera]);
|
||||
|
||||
const aspectRatio = useMemo<number>(() => {
|
||||
if (isMobile || fullscreen) {
|
||||
return cameraAspectRatio;
|
||||
} else {
|
||||
return windowAspectRatio < cameraAspectRatio
|
||||
? windowAspectRatio - 0.05
|
||||
: cameraAspectRatio - 0.03;
|
||||
}
|
||||
}, [cameraAspectRatio, windowAspectRatio, fullscreen]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={mainRef}
|
||||
@ -216,14 +235,16 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) {
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
</div>
|
||||
<div className="relative size-full">
|
||||
<div className="relative size-full p-2">
|
||||
<div
|
||||
className={growClassName}
|
||||
style={{ aspectRatio: camera.detect.width / camera.detect.height }}
|
||||
style={{
|
||||
aspectRatio: aspectRatio,
|
||||
}}
|
||||
>
|
||||
<LivePlayer
|
||||
key={camera.name}
|
||||
className={`size-full ${fullscreen ? "*:rounded-none" : ""}`}
|
||||
className={`${fullscreen ? "*:rounded-none" : ""}`}
|
||||
windowVisible
|
||||
showStillWithoutActivity={false}
|
||||
cameraConfig={camera}
|
||||
|
@ -75,7 +75,7 @@ export default function LiveDashboardView({
|
||||
}, [visibilityListener]);
|
||||
|
||||
return (
|
||||
<div className="size-full overflow-y-scroll px-2">
|
||||
<div className="size-full overflow-y-auto px-2">
|
||||
{isMobile && (
|
||||
<div className="relative h-9 flex items-center justify-between">
|
||||
<Logo className="absolute inset-y-0 inset-x-1/2 -translate-x-1/2 h-8" />
|
||||
|
Loading…
Reference in New Issue
Block a user