From 0b8859c76c82ced8fe62b9d96ebace18ee752644 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Mon, 11 Mar 2024 13:56:32 -0600 Subject: [PATCH] Support preview player that shows current hour images --- .../player/PreviewThumbnailPlayer.tsx | 3 +- .../components/player/PreviewVideoPlayer.tsx | 230 ------------------ web/src/utils/timelineUtil.tsx | 2 +- 3 files changed, 3 insertions(+), 232 deletions(-) delete mode 100644 web/src/components/player/PreviewVideoPlayer.tsx diff --git a/web/src/components/player/PreviewThumbnailPlayer.tsx b/web/src/components/player/PreviewThumbnailPlayer.tsx index 4cf7f29b5..12e869877 100644 --- a/web/src/components/player/PreviewThumbnailPlayer.tsx +++ b/web/src/components/player/PreviewThumbnailPlayer.tsx @@ -527,6 +527,7 @@ function InProgressPreview({ `preview/${review.camera}/start/${Math.floor(review.start_time) - PREVIEW_PADDING}/end/${ Math.ceil(review.end_time) + PREVIEW_PADDING }/frames`, + { revalidateOnFocus: false }, ); const [manualFrame, setManualFrame] = useState(false); const [hoverTimeout, setHoverTimeout] = useState(); @@ -642,7 +643,7 @@ function InProgressPreview({
void; - onClick?: () => void; -}; -export default function PreviewVideoPlayer({ - className, - camera, - timeRange, - cameraPreviews, - startTime, - onControllerReady, - onClick, -}: PreviewVideoPlayerProps) { - const { data: config } = useSWR("config"); - - // controlling playback - - const previewRef = useRef(null); - const controller = useMemo(() => { - if (!config || !previewRef.current) { - return undefined; - } - - return new PreviewVideoController(camera, previewRef); - // we only care when preview is ready - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [camera, config, previewRef.current]); - - useEffect(() => { - if (!controller) { - return; - } - - if (controller) { - onControllerReady(controller); - } - // we only want to fire once when players are ready - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [controller]); - - // initial state - - const initialPreview = useMemo(() => { - return cameraPreviews.find( - (preview) => - preview.camera == camera && - Math.round(preview.start) >= timeRange.start && - Math.floor(preview.end) <= timeRange.end, - ); - - // we only want to calculate this once - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const [currentPreview, setCurrentPreview] = useState(initialPreview); - - const onPreviewSeeked = useCallback(() => { - if (!controller) { - return; - } - - controller.finishedSeeking(); - }, [controller]); - - useEffect(() => { - if (!controller) { - return; - } - - const preview = cameraPreviews.find( - (preview) => - preview.camera == camera && - Math.round(preview.start) >= timeRange.start && - Math.floor(preview.end) <= timeRange.end, - ); - setCurrentPreview(preview); - - controller.newPlayback({ - preview, - timeRange, - }); - - // we only want this to change when recordings update - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [controller, timeRange]); - - useEffect(() => { - if (!currentPreview || !previewRef.current) { - return; - } - - previewRef.current.load(); - }, [currentPreview, previewRef]); - - return ( -
- - {cameraPreviews && !currentPreview && ( -
- No Preview Found -
- )} -
- ); -} - -export class PreviewVideoController { - // main state - public camera = ""; - private previewRef: MutableRefObject; - private timeRange: { start: number; end: number } | undefined = undefined; - - // preview - private preview: Preview | undefined = undefined; - private timeToSeek: number | undefined = undefined; - private seeking = false; - - constructor( - camera: string, - previewRef: MutableRefObject, - ) { - this.camera = camera; - this.previewRef = previewRef; - } - - newPlayback(newPlayback: PreviewPlayback) { - this.preview = newPlayback.preview; - this.seeking = false; - - this.timeRange = newPlayback.timeRange; - } - - scrubToTimestamp(time: number): boolean { - if (!this.preview || !this.timeRange) { - return false; - } - - if (time < this.preview.start || time > this.preview.end) { - return false; - } - - if (this.seeking) { - this.timeToSeek = time; - } else { - if (this.previewRef.current) { - this.previewRef.current.currentTime = Math.max( - 0, - time - this.preview.start, - ); - this.seeking = true; - } - } - - return true; - } - - setNewPreviewStartTime(time: number) { - this.timeToSeek = time; - } - - finishedSeeking() { - if (!this.previewRef.current || !this.preview) { - return; - } - - if ( - this.timeToSeek && - this.timeToSeek != this.previewRef.current?.currentTime - ) { - this.previewRef.current.currentTime = - this.timeToSeek - this.preview.start; - } else { - this.seeking = false; - } - } - - previewReady() { - this.seeking = false; - this.previewRef.current?.pause(); - - if (this.timeToSeek) { - this.finishedSeeking(); - } - } -} diff --git a/web/src/utils/timelineUtil.tsx b/web/src/utils/timelineUtil.tsx index 291a3fb52..0e0b1d104 100644 --- a/web/src/utils/timelineUtil.tsx +++ b/web/src/utils/timelineUtil.tsx @@ -163,7 +163,7 @@ export function getChunkedTimeRange( while (end < endTimestamp) { startDay.setHours(startDay.getHours() + 1); - if (startDay > endOfThisHour || startDay.getTime() / 1000 > endTimestamp) { + if (startDay > endOfThisHour) { break; }