mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Add ability to zoom in to live and recordings views (#10475)
* Make live view zoomable * Add zooming to full recordings
This commit is contained in:
parent
c66f552280
commit
f5a26c5962
14
web/package-lock.json
generated
14
web/package-lock.json
generated
@ -52,6 +52,7 @@
|
|||||||
"react-tracked": "^1.7.11",
|
"react-tracked": "^1.7.11",
|
||||||
"react-transition-group": "^4.4.5",
|
"react-transition-group": "^4.4.5",
|
||||||
"react-use-websocket": "^4.7.0",
|
"react-use-websocket": "^4.7.0",
|
||||||
|
"react-zoom-pan-pinch": "^3.4.3",
|
||||||
"recoil": "^0.7.7",
|
"recoil": "^0.7.7",
|
||||||
"scroll-into-view-if-needed": "^3.1.0",
|
"scroll-into-view-if-needed": "^3.1.0",
|
||||||
"sonner": "^1.4.0",
|
"sonner": "^1.4.0",
|
||||||
@ -6694,6 +6695,19 @@
|
|||||||
"react-dom": ">= 18.0.0"
|
"react-dom": ">= 18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-zoom-pan-pinch": {
|
||||||
|
"version": "3.4.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.4.3.tgz",
|
||||||
|
"integrity": "sha512-x5MFlfAx2D6NTpZu8OISqc2nYn4p+YEaM1p21w7S/VE1wbVzK8vRzTo9Bj1ydufa649MuP7JBRM3vvj1RftFZw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8",
|
||||||
|
"npm": ">=5"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "*",
|
||||||
|
"react-dom": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/read-cache": {
|
"node_modules/read-cache": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||||
|
@ -57,6 +57,7 @@
|
|||||||
"react-tracked": "^1.7.11",
|
"react-tracked": "^1.7.11",
|
||||||
"react-transition-group": "^4.4.5",
|
"react-transition-group": "^4.4.5",
|
||||||
"react-use-websocket": "^4.7.0",
|
"react-use-websocket": "^4.7.0",
|
||||||
|
"react-zoom-pan-pinch": "^3.4.3",
|
||||||
"recoil": "^0.7.7",
|
"recoil": "^0.7.7",
|
||||||
"scroll-into-view-if-needed": "^3.1.0",
|
"scroll-into-view-if-needed": "^3.1.0",
|
||||||
"sonner": "^1.4.0",
|
"sonner": "^1.4.0",
|
||||||
|
@ -27,6 +27,7 @@ import {
|
|||||||
} from "react-icons/md";
|
} from "react-icons/md";
|
||||||
import useKeyboardListener from "@/hooks/use-keyboard-listener";
|
import useKeyboardListener from "@/hooks/use-keyboard-listener";
|
||||||
import { Slider } from "../ui/slider-volume";
|
import { Slider } from "../ui/slider-volume";
|
||||||
|
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
||||||
|
|
||||||
const HLS_MIME_TYPE = "application/vnd.apple.mpegurl" as const;
|
const HLS_MIME_TYPE = "application/vnd.apple.mpegurl" as const;
|
||||||
const unsupportedErrorCodes = [
|
const unsupportedErrorCodes = [
|
||||||
@ -169,6 +170,8 @@ export default function HlsVideoPlayer({
|
|||||||
}
|
}
|
||||||
onClick={isDesktop ? undefined : () => setControls(!controls)}
|
onClick={isDesktop ? undefined : () => setControls(!controls)}
|
||||||
>
|
>
|
||||||
|
<TransformWrapper minScale={1.0}>
|
||||||
|
<TransformComponent>
|
||||||
<video
|
<video
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
className="size-full rounded-2xl"
|
className="size-full rounded-2xl"
|
||||||
@ -182,7 +185,9 @@ export default function HlsVideoPlayer({
|
|||||||
|
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
setControls(true);
|
setControls(true);
|
||||||
setMobileCtrlTimeout(setTimeout(() => setControls(false), 4000));
|
setMobileCtrlTimeout(
|
||||||
|
setTimeout(() => setControls(false), 4000),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
onPlaying={onPlaying}
|
onPlaying={onPlaying}
|
||||||
@ -211,6 +216,8 @@ export default function HlsVideoPlayer({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</TransformComponent>
|
||||||
|
</TransformWrapper>
|
||||||
<VideoControls
|
<VideoControls
|
||||||
video={videoRef.current}
|
video={videoRef.current}
|
||||||
isPlaying={isPlaying}
|
isPlaying={isPlaying}
|
||||||
|
@ -55,6 +55,7 @@ import {
|
|||||||
MdZoomOut,
|
MdZoomOut,
|
||||||
} from "react-icons/md";
|
} from "react-icons/md";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import { TransformWrapper, TransformComponent } from "react-zoom-pan-pinch";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
|
|
||||||
type LiveCameraViewProps = {
|
type LiveCameraViewProps = {
|
||||||
@ -263,9 +264,11 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) {
|
|||||||
aspectRatio: aspectRatio,
|
aspectRatio: aspectRatio,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<TransformWrapper minScale={1.0}>
|
||||||
|
<TransformComponent>
|
||||||
<LivePlayer
|
<LivePlayer
|
||||||
key={camera.name}
|
key={camera.name}
|
||||||
className={`${fullscreen ? "*:rounded-none" : ""}`}
|
className={`m-1 ${fullscreen ? "*:rounded-none" : ""}`}
|
||||||
windowVisible
|
windowVisible
|
||||||
showStillWithoutActivity={false}
|
showStillWithoutActivity={false}
|
||||||
cameraConfig={camera}
|
cameraConfig={camera}
|
||||||
@ -273,6 +276,8 @@ export default function LiveCameraView({ camera }: LiveCameraViewProps) {
|
|||||||
micEnabled={mic}
|
micEnabled={mic}
|
||||||
preferredLiveMode={preferredLiveMode}
|
preferredLiveMode={preferredLiveMode}
|
||||||
/>
|
/>
|
||||||
|
</TransformComponent>
|
||||||
|
</TransformWrapper>
|
||||||
</div>
|
</div>
|
||||||
{camera.onvif.host != "" && <PtzControlPanel camera={camera.name} />}
|
{camera.onvif.host != "" && <PtzControlPanel camera={camera.name} />}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user