mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-12 18:17:36 +03:00
pause on lifecycle item click and point click
This commit is contained in:
parent
9599450cff
commit
4f3507b08e
@ -19,7 +19,7 @@ type ObjectTrackOverlayProps = {
|
|||||||
videoWidth: number;
|
videoWidth: number;
|
||||||
videoHeight: number;
|
videoHeight: number;
|
||||||
className?: string;
|
className?: string;
|
||||||
onSeekToTime?: (timestamp: number) => void;
|
onSeekToTime?: (timestamp: number, play?: boolean) => void;
|
||||||
objectTimeline?: ObjectLifecycleSequence[];
|
objectTimeline?: ObjectLifecycleSequence[];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -227,7 +227,7 @@ export default function ObjectTrackOverlay({
|
|||||||
|
|
||||||
const handlePointClick = useCallback(
|
const handlePointClick = useCallback(
|
||||||
(timestamp: number) => {
|
(timestamp: number) => {
|
||||||
onSeekToTime?.(timestamp);
|
onSeekToTime?.(timestamp, false);
|
||||||
},
|
},
|
||||||
[onSeekToTime],
|
[onSeekToTime],
|
||||||
);
|
);
|
||||||
|
|||||||
@ -49,7 +49,7 @@ type HlsVideoPlayerProps = {
|
|||||||
onPlayerLoaded?: () => void;
|
onPlayerLoaded?: () => void;
|
||||||
onTimeUpdate?: (time: number) => void;
|
onTimeUpdate?: (time: number) => void;
|
||||||
onPlaying?: () => void;
|
onPlaying?: () => void;
|
||||||
onSeekToTime?: (timestamp: number) => void;
|
onSeekToTime?: (timestamp: number, play?: boolean) => 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;
|
||||||
@ -328,9 +328,10 @@ export default function HlsVideoPlayer({
|
|||||||
videoWidth={videoDimensions.width}
|
videoWidth={videoDimensions.width}
|
||||||
videoHeight={videoDimensions.height}
|
videoHeight={videoDimensions.height}
|
||||||
className="absolute inset-0 z-10"
|
className="absolute inset-0 z-10"
|
||||||
onSeekToTime={(timestamp) => {
|
onSeekToTime={(timestamp, play) => {
|
||||||
if (onSeekToTime) {
|
if (onSeekToTime) {
|
||||||
onSeekToTime(timestamp);
|
console.log("object track overlay seek", timestamp, play);
|
||||||
|
onSeekToTime(timestamp, play);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
objectTimeline={selectedObjectTimeline}
|
objectTimeline={selectedObjectTimeline}
|
||||||
|
|||||||
@ -111,6 +111,7 @@ export class DynamicVideoController {
|
|||||||
if (play) {
|
if (play) {
|
||||||
this.waitAndPlay();
|
this.waitAndPlay();
|
||||||
} else {
|
} else {
|
||||||
|
console.log("called pause", Date.now());
|
||||||
this.playerController.pause();
|
this.playerController.pause();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -32,7 +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;
|
onSeekToTime?: (timestamp: number, play?: boolean) => 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>;
|
||||||
@ -267,7 +267,12 @@ export default function DynamicVideoPlayer({
|
|||||||
onTimeUpdate={onTimeUpdate}
|
onTimeUpdate={onTimeUpdate}
|
||||||
onPlayerLoaded={onPlayerLoaded}
|
onPlayerLoaded={onPlayerLoaded}
|
||||||
onClipEnded={onValidateClipEnd}
|
onClipEnded={onValidateClipEnd}
|
||||||
onSeekToTime={onSeekToTime}
|
onSeekToTime={(timestamp, play) => {
|
||||||
|
if (onSeekToTime) {
|
||||||
|
console.log("hls player seek", timestamp, play);
|
||||||
|
onSeekToTime(timestamp, play);
|
||||||
|
}
|
||||||
|
}}
|
||||||
onPlaying={() => {
|
onPlaying={() => {
|
||||||
if (isScrubbing) {
|
if (isScrubbing) {
|
||||||
playerRef.current?.pause();
|
playerRef.current?.pause();
|
||||||
|
|||||||
@ -28,7 +28,8 @@ import { cn } from "@/lib/utils";
|
|||||||
type DetailStreamProps = {
|
type DetailStreamProps = {
|
||||||
reviewItems?: ReviewSegment[];
|
reviewItems?: ReviewSegment[];
|
||||||
currentTime: number;
|
currentTime: number;
|
||||||
onSeek: (timestamp: number) => void;
|
// `play` follows DynamicVideoController convention; pass `false` to pause
|
||||||
|
onSeek: (timestamp: number, play?: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function DetailStream({
|
export default function DetailStream({
|
||||||
@ -398,7 +399,7 @@ function EventCollapsible({
|
|||||||
event.id != selectedObjectId &&
|
event.id != selectedObjectId &&
|
||||||
(effectiveTime ?? 0) >= (event.start_time ?? 0) &&
|
(effectiveTime ?? 0) >= (event.start_time ?? 0) &&
|
||||||
(effectiveTime ?? 0) <= (event.end_time ?? event.start_time ?? 0) &&
|
(effectiveTime ?? 0) <= (event.end_time ?? event.start_time ?? 0) &&
|
||||||
"bg-secondary-highlight/80 outline-[1px] -outline-offset-[0.8px] outline-primary/40",
|
"bg-secondary outline-[1px] -outline-offset-[0.8px] outline-primary/40",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
@ -464,11 +465,12 @@ function EventCollapsible({
|
|||||||
|
|
||||||
type LifecycleItemProps = {
|
type LifecycleItemProps = {
|
||||||
event: ObjectLifecycleSequence;
|
event: ObjectLifecycleSequence;
|
||||||
onSeek: (timestamp: number) => void;
|
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
|
onSeek?: (timestamp: number, play?: boolean) => void;
|
||||||
|
play?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
function LifecycleItem({ event, isActive }: LifecycleItemProps) {
|
function LifecycleItem({ event, isActive, onSeek }: LifecycleItemProps) {
|
||||||
const { t } = useTranslation("views/events");
|
const { t } = useTranslation("views/events");
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
|
||||||
@ -490,9 +492,13 @@ function LifecycleItem({ event, isActive }: LifecycleItemProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
role="button"
|
||||||
|
onClick={() => onSeek?.(event.timestamp ?? 0, false)}
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex items-center gap-2 text-sm text-primary-variant",
|
"flex cursor-pointer items-center gap-2 text-sm text-primary-variant",
|
||||||
isActive ? "text-white" : "duration-500",
|
isActive
|
||||||
|
? "font-semibold text-primary dark:font-normal"
|
||||||
|
: "duration-500",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex size-4 items-center justify-center">
|
<div className="flex size-4 items-center justify-center">
|
||||||
@ -542,14 +548,12 @@ function ObjectTimeline({
|
|||||||
const isActive =
|
const isActive =
|
||||||
Math.abs((effectiveTime ?? 0) - (event.timestamp ?? 0)) <= 0.5;
|
Math.abs((effectiveTime ?? 0) - (event.timestamp ?? 0)) <= 0.5;
|
||||||
return (
|
return (
|
||||||
<div
|
<LifecycleItem
|
||||||
key={`${event.timestamp}-${event.source_id ?? idx}`}
|
key={`${event.timestamp}-${event.source_id ?? idx}`}
|
||||||
onClick={() => {
|
event={event}
|
||||||
onSeek(event.timestamp);
|
onSeek={onSeek}
|
||||||
}}
|
isActive={isActive}
|
||||||
>
|
/>
|
||||||
<LifecycleItem event={event} onSeek={onSeek} isActive={isActive} />
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -283,15 +283,15 @@ export function RecordingView({
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
const manuallySetCurrentTime = useCallback(
|
const manuallySetCurrentTime = useCallback(
|
||||||
(time: number) => {
|
(time: number, play: boolean = false) => {
|
||||||
if (!currentTimeRange) {
|
if (!currentTimeRange) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
console.log("manually set time", time, play);
|
||||||
setCurrentTime(time);
|
setCurrentTime(time);
|
||||||
|
|
||||||
if (currentTimeRange.after <= time && currentTimeRange.before >= time) {
|
if (currentTimeRange.after <= time && currentTimeRange.before >= time) {
|
||||||
mainControllerRef.current?.seekToTimestamp(time, true);
|
mainControllerRef.current?.seekToTimestamp(time, !play);
|
||||||
} else {
|
} else {
|
||||||
updateSelectedSegment(time, true);
|
updateSelectedSegment(time, true);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user