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:
Nicolas Mowen 2024-03-15 07:03:14 -06:00 committed by GitHub
parent c66f552280
commit f5a26c5962
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 77 additions and 50 deletions

14
web/package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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}

View File

@ -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>