mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-11 05:35:25 +03:00
Always show video controls even when zooming
This commit is contained in:
parent
ea11cab734
commit
911277ecf4
@ -1,10 +1,4 @@
|
|||||||
import {
|
import { MutableRefObject, useEffect, useRef, useState } from "react";
|
||||||
MutableRefObject,
|
|
||||||
ReactNode,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from "react";
|
|
||||||
import Hls from "hls.js";
|
import Hls from "hls.js";
|
||||||
import { isAndroid, isDesktop, isMobile } from "react-device-detect";
|
import { isAndroid, isDesktop, isMobile } from "react-device-detect";
|
||||||
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
import { TransformComponent, TransformWrapper } from "react-zoom-pan-pinch";
|
||||||
@ -19,7 +13,6 @@ const unsupportedErrorCodes = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
type HlsVideoPlayerProps = {
|
type HlsVideoPlayerProps = {
|
||||||
children?: ReactNode;
|
|
||||||
videoRef: MutableRefObject<HTMLVideoElement | null>;
|
videoRef: MutableRefObject<HTMLVideoElement | null>;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
currentSource: string;
|
currentSource: string;
|
||||||
@ -30,7 +23,6 @@ type HlsVideoPlayerProps = {
|
|||||||
onPlaying?: () => void;
|
onPlaying?: () => void;
|
||||||
};
|
};
|
||||||
export default function HlsVideoPlayer({
|
export default function HlsVideoPlayer({
|
||||||
children,
|
|
||||||
videoRef,
|
videoRef,
|
||||||
visible,
|
visible,
|
||||||
currentSource,
|
currentSource,
|
||||||
@ -89,13 +81,68 @@ export default function HlsVideoPlayer({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<TransformWrapper minScale={1.0}>
|
<TransformWrapper minScale={1.0}>
|
||||||
|
<VideoControls
|
||||||
|
className="absolute bottom-5 left-1/2 -translate-x-1/2 z-50"
|
||||||
|
video={videoRef.current}
|
||||||
|
isPlaying={isPlaying}
|
||||||
|
show={controls}
|
||||||
|
controlsOpen={controlsOpen}
|
||||||
|
setControlsOpen={setControlsOpen}
|
||||||
|
playbackRate={videoRef.current?.playbackRate ?? 1}
|
||||||
|
hotKeys={hotKeys}
|
||||||
|
onPlayPause={(play) => {
|
||||||
|
if (!videoRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (play) {
|
||||||
|
videoRef.current.play();
|
||||||
|
} else {
|
||||||
|
videoRef.current.pause();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onSeek={(diff) => {
|
||||||
|
const currentTime = videoRef.current?.currentTime;
|
||||||
|
|
||||||
|
if (!videoRef.current || !currentTime) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
videoRef.current.currentTime = Math.max(0, currentTime + diff);
|
||||||
|
}}
|
||||||
|
onSetPlaybackRate={(rate) =>
|
||||||
|
videoRef.current ? (videoRef.current.playbackRate = rate) : null
|
||||||
|
}
|
||||||
|
/>
|
||||||
<TransformComponent
|
<TransformComponent
|
||||||
wrapperStyle={{
|
wrapperStyle={{
|
||||||
position: "relative",
|
|
||||||
display: visible ? undefined : "none",
|
display: visible ? undefined : "none",
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
}}
|
}}
|
||||||
|
wrapperProps={{
|
||||||
|
onMouseMove: isDesktop
|
||||||
|
? (e) => {
|
||||||
|
if (!videoRef.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rect = videoRef.current.getBoundingClientRect();
|
||||||
|
|
||||||
|
if (
|
||||||
|
e.clientX > rect.left &&
|
||||||
|
e.clientX < rect.right &&
|
||||||
|
e.clientY > rect.top &&
|
||||||
|
e.clientY < rect.bottom
|
||||||
|
) {
|
||||||
|
setControls(true);
|
||||||
|
} else {
|
||||||
|
setControls(controlsOpen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
|
onClick: isDesktop ? undefined : () => setControls(!controls),
|
||||||
|
}}
|
||||||
contentStyle={{
|
contentStyle={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: isMobile ? "100%" : undefined,
|
height: isMobile ? "100%" : undefined,
|
||||||
@ -145,61 +192,6 @@ export default function HlsVideoPlayer({
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<div
|
|
||||||
className="absolute inset-0"
|
|
||||||
onMouseOver={
|
|
||||||
isDesktop
|
|
||||||
? () => {
|
|
||||||
setControls(true);
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
onMouseOut={
|
|
||||||
isDesktop
|
|
||||||
? () => {
|
|
||||||
setControls(controlsOpen);
|
|
||||||
}
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
onClick={isDesktop ? undefined : () => setControls(!controls)}
|
|
||||||
>
|
|
||||||
<div className={`size-full relative ${visible ? "" : "hidden"}`}>
|
|
||||||
<VideoControls
|
|
||||||
className="absolute bottom-5 left-1/2 -translate-x-1/2"
|
|
||||||
video={videoRef.current}
|
|
||||||
isPlaying={isPlaying}
|
|
||||||
show={controls}
|
|
||||||
controlsOpen={controlsOpen}
|
|
||||||
setControlsOpen={setControlsOpen}
|
|
||||||
playbackRate={videoRef.current?.playbackRate ?? 1}
|
|
||||||
hotKeys={hotKeys}
|
|
||||||
onPlayPause={(play) => {
|
|
||||||
if (!videoRef.current) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (play) {
|
|
||||||
videoRef.current.play();
|
|
||||||
} else {
|
|
||||||
videoRef.current.pause();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onSeek={(diff) => {
|
|
||||||
const currentTime = videoRef.current?.currentTime;
|
|
||||||
|
|
||||||
if (!videoRef.current || !currentTime) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
videoRef.current.currentTime = Math.max(0, currentTime + diff);
|
|
||||||
}}
|
|
||||||
onSetPlaybackRate={(rate) =>
|
|
||||||
videoRef.current ? (videoRef.current.playbackRate = rate) : null
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</TransformComponent>
|
</TransformComponent>
|
||||||
</TransformWrapper>
|
</TransformWrapper>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -364,11 +364,11 @@ export function RecordingView({
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
key={mainCamera}
|
key={mainCamera}
|
||||||
className={
|
className={`relative ${
|
||||||
isDesktop
|
isDesktop
|
||||||
? `${mainCameraAspect == "tall" ? "h-[50%] md:h-[60%] lg:h-[75%] xl:h-[90%]" : mainCameraAspect == "wide" ? "w-full" : "w-[78%]"} px-4 flex justify-center`
|
? `${mainCameraAspect == "tall" ? "h-[50%] md:h-[60%] lg:h-[75%] xl:h-[90%]" : mainCameraAspect == "wide" ? "w-full" : "w-[78%]"} px-4 flex justify-center`
|
||||||
: `portrait:w-full pt-2 ${mainCameraAspect == "wide" ? "landscape:w-full aspect-wide" : "landscape:h-[94%] aspect-video"}`
|
: `portrait:w-full pt-2 ${mainCameraAspect == "wide" ? "landscape:w-full aspect-wide" : "landscape:h-[94%] aspect-video"}`
|
||||||
}
|
}`}
|
||||||
style={{
|
style={{
|
||||||
aspectRatio: isDesktop
|
aspectRatio: isDesktop
|
||||||
? mainCameraAspect == "tall"
|
? mainCameraAspect == "tall"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user