forked from Github/frigate
Motion review changes (#10667)
* Add outlines in motion only mode * fix playground
This commit is contained in:
@@ -4,7 +4,9 @@ import {
|
||||
useMotionActivity,
|
||||
} from "@/api/ws";
|
||||
import { CameraConfig } from "@/types/frigateConfig";
|
||||
import { MotionData, ReviewSegment } from "@/types/review";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useTimelineUtils } from "./use-timeline-utils";
|
||||
|
||||
type useCameraActivityReturn = {
|
||||
activeTracking: boolean;
|
||||
@@ -66,3 +68,124 @@ export function useCameraActivity(
|
||||
: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function useCameraMotionNextTimestamp(
|
||||
timeRangeSegmentEnd: number,
|
||||
segmentDuration: number,
|
||||
motionOnly: boolean,
|
||||
reviewItems: ReviewSegment[],
|
||||
motionData: MotionData[],
|
||||
currentTime: number,
|
||||
) {
|
||||
const { alignStartDateToTimeline } = useTimelineUtils({
|
||||
segmentDuration,
|
||||
});
|
||||
|
||||
const noMotionRanges = useMemo(() => {
|
||||
if (!motionData || !reviewItems) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!motionOnly) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const ranges = [];
|
||||
let currentSegmentStart = null;
|
||||
let currentSegmentEnd = null;
|
||||
|
||||
// align motion start to timeline start
|
||||
const offset =
|
||||
(motionData[0].start_time -
|
||||
alignStartDateToTimeline(timeRangeSegmentEnd)) %
|
||||
segmentDuration;
|
||||
|
||||
const startIndex =
|
||||
offset > 0 ? Math.floor(offset / (segmentDuration / 15)) : 0;
|
||||
|
||||
for (
|
||||
let i = startIndex;
|
||||
i < motionData.length;
|
||||
i = i + segmentDuration / 15
|
||||
) {
|
||||
const motionStart = motionData[i].start_time;
|
||||
const motionEnd = motionStart + segmentDuration;
|
||||
|
||||
const segmentMotion = motionData
|
||||
.slice(i, i + segmentDuration / 15)
|
||||
.some(({ motion }) => motion !== undefined && motion > 0);
|
||||
const overlappingReviewItems = reviewItems.some(
|
||||
(item) =>
|
||||
(item.start_time >= motionStart && item.start_time < motionEnd) ||
|
||||
(item.end_time > motionStart && item.end_time <= motionEnd) ||
|
||||
(item.start_time <= motionStart && item.end_time >= motionEnd),
|
||||
);
|
||||
|
||||
if (!segmentMotion || overlappingReviewItems) {
|
||||
if (currentSegmentStart === null) {
|
||||
currentSegmentStart = motionStart;
|
||||
}
|
||||
currentSegmentEnd = motionEnd;
|
||||
} else {
|
||||
if (currentSegmentStart !== null) {
|
||||
ranges.push([currentSegmentStart, currentSegmentEnd]);
|
||||
currentSegmentStart = null;
|
||||
currentSegmentEnd = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentSegmentStart !== null) {
|
||||
ranges.push([currentSegmentStart, currentSegmentEnd]);
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}, [
|
||||
motionData,
|
||||
reviewItems,
|
||||
motionOnly,
|
||||
alignStartDateToTimeline,
|
||||
segmentDuration,
|
||||
timeRangeSegmentEnd,
|
||||
]);
|
||||
|
||||
const nextTimestamp = useMemo(() => {
|
||||
if (!noMotionRanges) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!motionOnly) {
|
||||
return currentTime + 0.5;
|
||||
}
|
||||
|
||||
let currentRange = 0;
|
||||
let nextTimestamp = currentTime + 0.5;
|
||||
|
||||
while (currentRange < noMotionRanges.length) {
|
||||
const [start, end] = noMotionRanges[currentRange];
|
||||
|
||||
if (start && end) {
|
||||
// If the current time is before the start of the current range
|
||||
if (currentTime < start) {
|
||||
// The next timestamp is either the start of the current range or currentTime + 0.5, whichever is smaller
|
||||
nextTimestamp = Math.min(start, nextTimestamp);
|
||||
break;
|
||||
}
|
||||
// If the current time is within the current range
|
||||
else if (currentTime >= start && currentTime < end) {
|
||||
// The next timestamp is the end of the current range
|
||||
nextTimestamp = end;
|
||||
currentRange++;
|
||||
}
|
||||
// If the current time is past the end of the current range
|
||||
else {
|
||||
currentRange++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nextTimestamp;
|
||||
}, [currentTime, noMotionRanges, motionOnly]);
|
||||
|
||||
return nextTimestamp;
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ function useDraggableElement({
|
||||
const elementEarliest = draggableElementEarliestTime
|
||||
? timestampToPixels(draggableElementEarliestTime)
|
||||
: segmentHeight * (timelineDuration / segmentDuration) -
|
||||
segmentHeight * 3;
|
||||
segmentHeight * 3.5;
|
||||
|
||||
// top of timeline - default 2 segments added for draggableElement visibility
|
||||
const elementLatest = draggableElementLatestTime
|
||||
|
||||
Reference in New Issue
Block a user