mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-09 04:35:25 +03:00
Respect motion only when playing back motion
This commit is contained in:
parent
3a9607e59b
commit
e77836b3e3
@ -6,7 +6,7 @@ import { useEffect, useMemo, useState } from "react";
|
||||
import MSEPlayer from "./MsePlayer";
|
||||
import JSMpegPlayer from "./JSMpegPlayer";
|
||||
import { MdCircle } from "react-icons/md";
|
||||
import useCameraActivity from "@/hooks/use-camera-activity";
|
||||
import { useCameraActivity } from "@/hooks/use-camera-activity";
|
||||
import { useRecordingsState } from "@/api/ws";
|
||||
import { LivePlayerMode } from "@/types/live";
|
||||
import useCameraLiveMode from "@/hooks/use-camera-live-mode";
|
||||
|
||||
@ -4,6 +4,8 @@ import {
|
||||
useMotionActivity,
|
||||
} from "@/api/ws";
|
||||
import { CameraConfig } from "@/types/frigateConfig";
|
||||
import { MotionData, ReviewSegment } from "@/types/review";
|
||||
import { TimeRange } from "@/types/timeline";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
type useCameraActivityReturn = {
|
||||
@ -12,7 +14,7 @@ type useCameraActivityReturn = {
|
||||
activeAudio: boolean;
|
||||
};
|
||||
|
||||
export default function useCameraActivity(
|
||||
export function useCameraActivity(
|
||||
camera: CameraConfig,
|
||||
): useCameraActivityReturn {
|
||||
const [activeObjects, setActiveObjects] = useState<string[]>([]);
|
||||
@ -66,3 +68,40 @@ export default function useCameraActivity(
|
||||
: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function useCameraMotionTimestamps(
|
||||
timeRange: TimeRange,
|
||||
motionOnly: boolean,
|
||||
events: ReviewSegment[],
|
||||
motion: MotionData[],
|
||||
) {
|
||||
const timestamps = useMemo(() => {
|
||||
const seekableTimestamps = [];
|
||||
for (let i = timeRange.after; i <= timeRange.before; i += 0.5) {
|
||||
if (!motionOnly) {
|
||||
seekableTimestamps.push(i);
|
||||
} else {
|
||||
if (
|
||||
events.find((seg) => seg.start_time <= i && seg.end_time >= i) !=
|
||||
undefined
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const relevantMotion = motion.find(
|
||||
(mot) => mot.start_time <= i && mot.start_time + 15 >= i,
|
||||
);
|
||||
|
||||
if (!relevantMotion || relevantMotion.motion == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
seekableTimestamps.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return seekableTimestamps;
|
||||
}, [timeRange, motionOnly, events, motion]);
|
||||
|
||||
return timestamps;
|
||||
}
|
||||
|
||||
@ -23,11 +23,4 @@ type Timeline = {
|
||||
source: string;
|
||||
};
|
||||
|
||||
// may be used in the future, keep for now for reference
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
type HourlyTimeline = {
|
||||
start: number;
|
||||
end: number;
|
||||
count: number;
|
||||
hours: { [key: string]: Timeline[] };
|
||||
};
|
||||
export type TimeRange = { before: number; after: number };
|
||||
|
||||
@ -39,6 +39,8 @@ import PreviewPlayer, {
|
||||
import SummaryTimeline from "@/components/timeline/SummaryTimeline";
|
||||
import { RecordingStartingPoint } from "@/types/record";
|
||||
import VideoControls from "@/components/player/VideoControls";
|
||||
import { TimeRange } from "@/types/timeline";
|
||||
import { useCameraMotionTimestamps } from "@/hooks/use-camera-activity";
|
||||
|
||||
type EventViewProps = {
|
||||
reviews?: ReviewSegment[];
|
||||
@ -606,7 +608,7 @@ type MotionReviewProps = {
|
||||
significant_motion: ReviewSegment[];
|
||||
};
|
||||
relevantPreviews?: Preview[];
|
||||
timeRange: { before: number; after: number };
|
||||
timeRange: TimeRange;
|
||||
startTime?: number;
|
||||
filter?: ReviewFilter;
|
||||
motionOnly?: boolean;
|
||||
@ -718,6 +720,12 @@ function MotionReview({
|
||||
|
||||
const [playbackRate, setPlaybackRate] = useState(8);
|
||||
const [controlsOpen, setControlsOpen] = useState(false);
|
||||
const seekTimestamps = useCameraMotionTimestamps(
|
||||
timeRange,
|
||||
motionOnly,
|
||||
reviewItems?.all ?? [],
|
||||
motionData ?? [],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!playing) {
|
||||
@ -725,17 +733,22 @@ function MotionReview({
|
||||
}
|
||||
|
||||
const interval = 500 / playbackRate;
|
||||
const startTime = currentTime;
|
||||
const startIdx = seekTimestamps.findIndex((time) => time > currentTime);
|
||||
|
||||
if (!startIdx) {
|
||||
return;
|
||||
}
|
||||
|
||||
let counter = 0;
|
||||
const intervalId = setInterval(() => {
|
||||
counter += 0.5;
|
||||
counter += 1;
|
||||
|
||||
if (startTime + counter >= timeRange.before) {
|
||||
if (startIdx + counter >= seekTimestamps.length) {
|
||||
setPlaying(false);
|
||||
return;
|
||||
}
|
||||
|
||||
setCurrentTime(startTime + counter);
|
||||
setCurrentTime(seekTimestamps[startIdx + counter]);
|
||||
}, interval);
|
||||
|
||||
return () => {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user