Streamline live view (#9772)

* Break out live page

* Improving layouts and add chip component

* Improve default camera player sizing

* Improve live updating

* Cleanup and fit figma

* Use fixed height

* Masonry layout

* Fix stuff

* Don't force heights

* Adjust scaling

* Cleanup

* remove sidebar (#9731)

* remove sidebar

* keep sidebar on mobile for now and add icons

* Fix revalidation

* Cleanup

* Cleanup width

* Add chips for activity on cameras

* Remove dashboard from header

* Use Inter font (#9735)

* Show still image when no activity is occurring

* remove unused search params

* add playing check for webrtc

* Don't use grid at all for single column

* Fix height on mobile

* a few style updates to better match figma (#9745)

* Remove active objects when they become stationary

* Move to sidebar only and make settings separate component

* Fix layout

* Animate visibility of chips

* Sidebar is full screen

* Fix tall aspect ratio cameras

* Fix complicated aspect logic

* remove

* Adjust thumbnail aspect and add text

* margin on single column layout

* Smaller event thumb text

* Simplify basic image view

* Only show the red dot when camera is recording

* Improve typing for camera toggles

* animate chips with react-transition-group (#9763)

* don't flash when going to still image

* revalidate

* tooltips and active tracking outline (#9766)

* tooltips

* fix tooltip provider and add active tracking outline

* remove unused icon

* remove figma comment

* Get live mode working for jsmpeg

* add small gradient below timeago on event thumbnails (#9767)

* Create live mode hook and make sure jsmpeg can be used

* Enforce env var

* Use print

* Remove unstable

* Add tooltips to thumbnails

* Put back vite

* Format

* Update web/src/components/player/JSMpegPlayer.tsx

---------

Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
Co-authored-by: Blake Blackshear <blake@frigate.video>
This commit is contained in:
Nicolas Mowen
2024-02-10 05:30:53 -07:00
committed by GitHub
parent f6a4c2a7b3
commit 64988c9be0
33 changed files with 1111 additions and 972 deletions

View File

@@ -0,0 +1,68 @@
import {
useAudioActivity,
useFrigateEvents,
useMotionActivity,
} from "@/api/ws";
import { CameraConfig } from "@/types/frigateConfig";
import { useEffect, useMemo, useState } from "react";
type useCameraActivityReturn = {
activeTracking: boolean;
activeMotion: boolean;
activeAudio: boolean;
};
export default function useCameraActivity(
camera: CameraConfig
): useCameraActivityReturn {
const [activeObjects, setActiveObjects] = useState<string[]>([]);
const hasActiveObjects = useMemo(
() => activeObjects.length > 0,
[activeObjects]
);
const { payload: detectingMotion } = useMotionActivity(camera.name);
const { payload: event } = useFrigateEvents();
const { payload: audioRms } = useAudioActivity(camera.name);
useEffect(() => {
if (!event) {
return;
}
if (event.after.camera != camera.name) {
return;
}
const eventIndex = activeObjects.indexOf(event.after.id);
if (event.type == "end") {
if (eventIndex != -1) {
const newActiveObjects = [...activeObjects];
newActiveObjects.splice(eventIndex, 1);
setActiveObjects(newActiveObjects);
}
} else {
if (eventIndex == -1) {
// add unknown event to list if not stationary
if (!event.after.stationary) {
const newActiveObjects = [...activeObjects, event.after.id];
setActiveObjects(newActiveObjects);
}
} else {
// remove known event from list if it has become stationary
if (event.after.stationary) {
activeObjects.splice(eventIndex, 1);
}
}
}
}, [event, activeObjects]);
return {
activeTracking: hasActiveObjects,
activeMotion: detectingMotion == "ON",
activeAudio: camera.audio.enabled_in_config
? audioRms >= camera.audio.min_volume
: false,
};
}

View File

@@ -0,0 +1,49 @@
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
import { useMemo } from "react";
import useSWR from "swr";
import { usePersistence } from "./use-persistence";
import { LivePlayerMode } from "@/types/live";
export default function useCameraLiveMode(
cameraConfig: CameraConfig,
preferredMode?: string
): LivePlayerMode {
const { data: config } = useSWR<FrigateConfig>("config");
const restreamEnabled = useMemo(() => {
if (!config) {
return false;
}
return (
cameraConfig &&
Object.keys(config.go2rtc.streams || {}).includes(
cameraConfig.live.stream_name
)
);
}, [config, cameraConfig]);
const defaultLiveMode = useMemo(() => {
if (config && cameraConfig) {
if (restreamEnabled) {
return cameraConfig.ui.live_mode || config?.ui.live_mode;
}
return "jsmpeg";
}
return undefined;
}, [cameraConfig, restreamEnabled]);
const [viewSource] = usePersistence(
`${cameraConfig.name}-source`,
defaultLiveMode
);
if (
restreamEnabled &&
(preferredMode == "mse" || preferredMode == "webrtc")
) {
return preferredMode;
} else {
return viewSource;
}
}