mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-03 06:50:58 +00:00
Compare commits
2 Commits
8e98dff671
...
73f0ca663b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73f0ca663b | ||
|
|
441d57c76b |
@ -136,6 +136,7 @@ class CameraMaintainer(threading.Thread):
|
|||||||
self.ptz_metrics[name],
|
self.ptz_metrics[name],
|
||||||
self.region_grids[name],
|
self.region_grids[name],
|
||||||
self.stop_event,
|
self.stop_event,
|
||||||
|
self.config.logger,
|
||||||
)
|
)
|
||||||
self.camera_processes[config.name] = camera_process
|
self.camera_processes[config.name] = camera_process
|
||||||
camera_process.start()
|
camera_process.start()
|
||||||
@ -156,7 +157,11 @@ class CameraMaintainer(threading.Thread):
|
|||||||
self.frame_manager.create(f"{config.name}_frame{i}", frame_size)
|
self.frame_manager.create(f"{config.name}_frame{i}", frame_size)
|
||||||
|
|
||||||
capture_process = CameraCapture(
|
capture_process = CameraCapture(
|
||||||
config, count, self.camera_metrics[name], self.stop_event
|
config,
|
||||||
|
count,
|
||||||
|
self.camera_metrics[name],
|
||||||
|
self.stop_event,
|
||||||
|
self.config.logger,
|
||||||
)
|
)
|
||||||
capture_process.daemon = True
|
capture_process.daemon = True
|
||||||
self.capture_processes[name] = capture_process
|
self.capture_processes[name] = capture_process
|
||||||
|
|||||||
@ -16,7 +16,7 @@ from frigate.comms.recordings_updater import (
|
|||||||
RecordingsDataSubscriber,
|
RecordingsDataSubscriber,
|
||||||
RecordingsDataTypeEnum,
|
RecordingsDataTypeEnum,
|
||||||
)
|
)
|
||||||
from frigate.config import CameraConfig, DetectConfig, ModelConfig
|
from frigate.config import CameraConfig, DetectConfig, LoggerConfig, ModelConfig
|
||||||
from frigate.config.camera.camera import CameraTypeEnum
|
from frigate.config.camera.camera import CameraTypeEnum
|
||||||
from frigate.config.camera.updater import (
|
from frigate.config.camera.updater import (
|
||||||
CameraConfigUpdateEnum,
|
CameraConfigUpdateEnum,
|
||||||
@ -539,6 +539,7 @@ class CameraCapture(FrigateProcess):
|
|||||||
shm_frame_count: int,
|
shm_frame_count: int,
|
||||||
camera_metrics: CameraMetrics,
|
camera_metrics: CameraMetrics,
|
||||||
stop_event: MpEvent,
|
stop_event: MpEvent,
|
||||||
|
log_config: LoggerConfig | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
stop_event,
|
stop_event,
|
||||||
@ -549,9 +550,10 @@ class CameraCapture(FrigateProcess):
|
|||||||
self.config = config
|
self.config = config
|
||||||
self.shm_frame_count = shm_frame_count
|
self.shm_frame_count = shm_frame_count
|
||||||
self.camera_metrics = camera_metrics
|
self.camera_metrics = camera_metrics
|
||||||
|
self.log_config = log_config
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
self.pre_run_setup()
|
self.pre_run_setup(self.log_config)
|
||||||
camera_watchdog = CameraWatchdog(
|
camera_watchdog = CameraWatchdog(
|
||||||
self.config,
|
self.config,
|
||||||
self.shm_frame_count,
|
self.shm_frame_count,
|
||||||
@ -577,6 +579,7 @@ class CameraTracker(FrigateProcess):
|
|||||||
ptz_metrics: PTZMetrics,
|
ptz_metrics: PTZMetrics,
|
||||||
region_grid: list[list[dict[str, Any]]],
|
region_grid: list[list[dict[str, Any]]],
|
||||||
stop_event: MpEvent,
|
stop_event: MpEvent,
|
||||||
|
log_config: LoggerConfig | None = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(
|
super().__init__(
|
||||||
stop_event,
|
stop_event,
|
||||||
@ -592,9 +595,10 @@ class CameraTracker(FrigateProcess):
|
|||||||
self.camera_metrics = camera_metrics
|
self.camera_metrics = camera_metrics
|
||||||
self.ptz_metrics = ptz_metrics
|
self.ptz_metrics = ptz_metrics
|
||||||
self.region_grid = region_grid
|
self.region_grid = region_grid
|
||||||
|
self.log_config = log_config
|
||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
self.pre_run_setup()
|
self.pre_run_setup(self.log_config)
|
||||||
frame_queue = self.camera_metrics.frame_queue
|
frame_queue = self.camera_metrics.frame_queue
|
||||||
frame_shape = self.config.frame_shape
|
frame_shape = self.config.frame_shape
|
||||||
|
|
||||||
|
|||||||
@ -850,6 +850,29 @@ function FrigateCameraFeatures({
|
|||||||
}
|
}
|
||||||
}, [activeToastId, t]);
|
}, [activeToastId, t]);
|
||||||
|
|
||||||
|
const endEventViaBeacon = useCallback(() => {
|
||||||
|
if (!recordingEventIdRef.current) return;
|
||||||
|
|
||||||
|
const url = `${window.location.origin}/api/events/${recordingEventIdRef.current}/end`;
|
||||||
|
const payload = JSON.stringify({
|
||||||
|
end_time: Math.ceil(Date.now() / 1000),
|
||||||
|
});
|
||||||
|
|
||||||
|
// this needs to be a synchronous XMLHttpRequest to guarantee the PUT
|
||||||
|
// reaches the server before the browser kills the page
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
try {
|
||||||
|
xhr.open("PUT", url, false);
|
||||||
|
xhr.setRequestHeader("Content-Type", "application/json");
|
||||||
|
xhr.setRequestHeader("X-CSRF-TOKEN", "1");
|
||||||
|
xhr.setRequestHeader("X-CACHE-BYPASS", "1");
|
||||||
|
xhr.withCredentials = true;
|
||||||
|
xhr.send(payload);
|
||||||
|
} catch (e) {
|
||||||
|
// Silently ignore errors during unload
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleEventButtonClick = useCallback(() => {
|
const handleEventButtonClick = useCallback(() => {
|
||||||
if (isRecording) {
|
if (isRecording) {
|
||||||
endEvent();
|
endEvent();
|
||||||
@ -887,8 +910,19 @@ function FrigateCameraFeatures({
|
|||||||
}, [camera.name, isRestreamed, preferredLiveMode, t]);
|
}, [camera.name, isRestreamed, preferredLiveMode, t]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Handle page unload/close (browser close, tab close, refresh, navigation to external site)
|
||||||
|
const handleBeforeUnload = () => {
|
||||||
|
if (recordingEventIdRef.current) {
|
||||||
|
endEventViaBeacon();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener("beforeunload", handleBeforeUnload);
|
||||||
|
|
||||||
// ensure manual event is stopped when component unmounts
|
// ensure manual event is stopped when component unmounts
|
||||||
return () => {
|
return () => {
|
||||||
|
window.removeEventListener("beforeunload", handleBeforeUnload);
|
||||||
|
|
||||||
if (recordingEventIdRef.current) {
|
if (recordingEventIdRef.current) {
|
||||||
endEvent();
|
endEvent();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user