mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-13 02:27:38 +03:00
use overlay in video player
This commit is contained in:
parent
6cb1c41147
commit
5dc4b779f4
@ -19,6 +19,8 @@ import { usePersistence } from "@/hooks/use-persistence";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { ASPECT_VERTICAL_LAYOUT, RecordingPlayerError } from "@/types/record";
|
import { ASPECT_VERTICAL_LAYOUT, RecordingPlayerError } from "@/types/record";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
import ObjectTrackOverlay from "@/components/overlay/ObjectTrackOverlay";
|
||||||
|
import { useActivityStream } from "@/contexts/ActivityStreamContext";
|
||||||
|
|
||||||
// Android native hls does not seek correctly
|
// Android native hls does not seek correctly
|
||||||
const USE_NATIVE_HLS = !isAndroid;
|
const USE_NATIVE_HLS = !isAndroid;
|
||||||
@ -47,6 +49,7 @@ type HlsVideoPlayerProps = {
|
|||||||
onPlayerLoaded?: () => void;
|
onPlayerLoaded?: () => void;
|
||||||
onTimeUpdate?: (time: number) => void;
|
onTimeUpdate?: (time: number) => void;
|
||||||
onPlaying?: () => void;
|
onPlaying?: () => void;
|
||||||
|
onSeekToTime?: (timestamp: number) => void;
|
||||||
setFullResolution?: React.Dispatch<React.SetStateAction<VideoResolutionType>>;
|
setFullResolution?: React.Dispatch<React.SetStateAction<VideoResolutionType>>;
|
||||||
onUploadFrame?: (playTime: number) => Promise<AxiosResponse> | undefined;
|
onUploadFrame?: (playTime: number) => Promise<AxiosResponse> | undefined;
|
||||||
toggleFullscreen?: () => void;
|
toggleFullscreen?: () => void;
|
||||||
@ -66,6 +69,7 @@ export default function HlsVideoPlayer({
|
|||||||
onPlayerLoaded,
|
onPlayerLoaded,
|
||||||
onTimeUpdate,
|
onTimeUpdate,
|
||||||
onPlaying,
|
onPlaying,
|
||||||
|
onSeekToTime,
|
||||||
setFullResolution,
|
setFullResolution,
|
||||||
onUploadFrame,
|
onUploadFrame,
|
||||||
toggleFullscreen,
|
toggleFullscreen,
|
||||||
@ -73,6 +77,8 @@ export default function HlsVideoPlayer({
|
|||||||
}: HlsVideoPlayerProps) {
|
}: HlsVideoPlayerProps) {
|
||||||
const { t } = useTranslation("components/player");
|
const { t } = useTranslation("components/player");
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
const { selectedObjectId, currentTime, camera, isActivityMode } =
|
||||||
|
useActivityStream();
|
||||||
|
|
||||||
// playback
|
// playback
|
||||||
|
|
||||||
@ -84,17 +90,19 @@ export default function HlsVideoPlayer({
|
|||||||
const handleLoadedMetadata = useCallback(() => {
|
const handleLoadedMetadata = useCallback(() => {
|
||||||
setLoadedMetadata(true);
|
setLoadedMetadata(true);
|
||||||
if (videoRef.current) {
|
if (videoRef.current) {
|
||||||
|
const width = videoRef.current.videoWidth;
|
||||||
|
const height = videoRef.current.videoHeight;
|
||||||
|
|
||||||
if (setFullResolution) {
|
if (setFullResolution) {
|
||||||
setFullResolution({
|
setFullResolution({
|
||||||
width: videoRef.current.videoWidth,
|
width,
|
||||||
height: videoRef.current.videoHeight,
|
height,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setTallCamera(
|
setVideoDimensions({ width, height });
|
||||||
videoRef.current.videoWidth / videoRef.current.videoHeight <
|
|
||||||
ASPECT_VERTICAL_LAYOUT,
|
setTallCamera(width / height < ASPECT_VERTICAL_LAYOUT);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}, [videoRef, setFullResolution]);
|
}, [videoRef, setFullResolution]);
|
||||||
|
|
||||||
@ -174,6 +182,10 @@ export default function HlsVideoPlayer({
|
|||||||
const [controls, setControls] = useState(isMobile);
|
const [controls, setControls] = useState(isMobile);
|
||||||
const [controlsOpen, setControlsOpen] = useState(false);
|
const [controlsOpen, setControlsOpen] = useState(false);
|
||||||
const [zoomScale, setZoomScale] = useState(1.0);
|
const [zoomScale, setZoomScale] = useState(1.0);
|
||||||
|
const [videoDimensions, setVideoDimensions] = useState<{
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}>({ width: 0, height: 0 });
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isDesktop) {
|
if (!isDesktop) {
|
||||||
@ -296,6 +308,28 @@ export default function HlsVideoPlayer({
|
|||||||
height: isMobile ? "100%" : undefined,
|
height: isMobile ? "100%" : undefined,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
{isActivityMode &&
|
||||||
|
selectedObjectId &&
|
||||||
|
camera &&
|
||||||
|
currentTime &&
|
||||||
|
videoDimensions.width > 0 &&
|
||||||
|
videoDimensions.height > 0 && (
|
||||||
|
<div className="absolute z-50 size-full">
|
||||||
|
<ObjectTrackOverlay
|
||||||
|
camera={camera}
|
||||||
|
selectedObjectId={selectedObjectId}
|
||||||
|
currentTime={currentTime}
|
||||||
|
videoWidth={videoDimensions.width}
|
||||||
|
videoHeight={videoDimensions.height}
|
||||||
|
className="absolute inset-0 z-10"
|
||||||
|
onSeekToTime={(timestamp) => {
|
||||||
|
if (onSeekToTime) {
|
||||||
|
onSeekToTime(timestamp);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<video
|
<video
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
className={`size-full rounded-lg bg-black md:rounded-2xl ${loadedMetadata ? "" : "invisible"} cursor-pointer`}
|
className={`size-full rounded-lg bg-black md:rounded-2xl ${loadedMetadata ? "" : "invisible"} cursor-pointer`}
|
||||||
|
|||||||
@ -32,6 +32,7 @@ type DynamicVideoPlayerProps = {
|
|||||||
onControllerReady: (controller: DynamicVideoController) => void;
|
onControllerReady: (controller: DynamicVideoController) => void;
|
||||||
onTimestampUpdate?: (timestamp: number) => void;
|
onTimestampUpdate?: (timestamp: number) => void;
|
||||||
onClipEnded?: () => void;
|
onClipEnded?: () => void;
|
||||||
|
onSeekToTime?: (timestamp: number) => void;
|
||||||
setFullResolution: React.Dispatch<React.SetStateAction<VideoResolutionType>>;
|
setFullResolution: React.Dispatch<React.SetStateAction<VideoResolutionType>>;
|
||||||
toggleFullscreen: () => void;
|
toggleFullscreen: () => void;
|
||||||
containerRef?: React.MutableRefObject<HTMLDivElement | null>;
|
containerRef?: React.MutableRefObject<HTMLDivElement | null>;
|
||||||
@ -49,6 +50,7 @@ export default function DynamicVideoPlayer({
|
|||||||
onControllerReady,
|
onControllerReady,
|
||||||
onTimestampUpdate,
|
onTimestampUpdate,
|
||||||
onClipEnded,
|
onClipEnded,
|
||||||
|
onSeekToTime,
|
||||||
setFullResolution,
|
setFullResolution,
|
||||||
toggleFullscreen,
|
toggleFullscreen,
|
||||||
containerRef,
|
containerRef,
|
||||||
@ -265,6 +267,7 @@ export default function DynamicVideoPlayer({
|
|||||||
onTimeUpdate={onTimeUpdate}
|
onTimeUpdate={onTimeUpdate}
|
||||||
onPlayerLoaded={onPlayerLoaded}
|
onPlayerLoaded={onPlayerLoaded}
|
||||||
onClipEnded={onValidateClipEnd}
|
onClipEnded={onValidateClipEnd}
|
||||||
|
onSeekToTime={onSeekToTime}
|
||||||
onPlaying={() => {
|
onPlaying={() => {
|
||||||
if (isScrubbing) {
|
if (isScrubbing) {
|
||||||
playerRef.current?.pause();
|
playerRef.current?.pause();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user