Add out-of-the-box Frigate PTZ support.
This commit is contained in:
+82
-38
@@ -1,7 +1,8 @@
|
||||
import { CameraConfig } from '../config/types';
|
||||
import { ViewMedia } from '../view/media';
|
||||
import { Camera } from './camera';
|
||||
import { CameraManagerEngine } from './engine';
|
||||
import { CameraConfigs, Engine } from './types';
|
||||
import { Engine } from './types';
|
||||
|
||||
type CameraManagerEngineCameraIDMap = Map<CameraManagerEngine, Set<string>>;
|
||||
|
||||
@@ -10,74 +11,82 @@ export interface CameraManagerReadOnlyConfigStore {
|
||||
getCameraConfigForMedia(media: ViewMedia): CameraConfig | null;
|
||||
|
||||
hasCameraID(cameraID: string): boolean;
|
||||
hasVisibleCameraID(cameraID: string): boolean;
|
||||
|
||||
getCamera(cameraID: string): Camera | null;
|
||||
getCameraCount(): number;
|
||||
getVisibleCameraCount(): number;
|
||||
|
||||
getCameras(): CameraConfigs;
|
||||
getVisibleCameras(): CameraConfigs;
|
||||
getCameraConfigs(cameraIDs?: Iterable<string>): IterableIterator<CameraConfig>;
|
||||
getCameraConfigEntries(
|
||||
cameraIDs?: Iterable<string>,
|
||||
): IterableIterator<[string, CameraConfig]>;
|
||||
|
||||
getCameraIDs(): Set<string>;
|
||||
getVisibleCameraIDs(): Set<string>;
|
||||
|
||||
getAllDependentCameras(cameraID: string): Set<string>;
|
||||
}
|
||||
|
||||
export class CameraManagerStore implements CameraManagerReadOnlyConfigStore {
|
||||
protected _allConfigs: Map<string, CameraConfig> = new Map();
|
||||
protected _visibleConfigs: Map<string, CameraConfig> = new Map();
|
||||
protected _enginesByCamera: Map<string, CameraManagerEngine> = new Map();
|
||||
protected _cameras: Map<string, Camera> = new Map();
|
||||
protected _enginesByType: Map<Engine, CameraManagerEngine> = new Map();
|
||||
|
||||
public addCamera(
|
||||
cameraID: string,
|
||||
cameraConfig: CameraConfig,
|
||||
engine: CameraManagerEngine,
|
||||
): void {
|
||||
if (!cameraConfig.hide) {
|
||||
this._visibleConfigs.set(cameraID, cameraConfig);
|
||||
}
|
||||
this._allConfigs.set(cameraID, cameraConfig);
|
||||
this._enginesByCamera.set(cameraID, engine);
|
||||
this._enginesByType.set(engine.getEngineType(), engine);
|
||||
public addCamera(camera: Camera): void {
|
||||
this._cameras.set(camera.getID(), camera);
|
||||
this._enginesByType.set(camera.getEngine().getEngineType(), camera.getEngine());
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this._allConfigs.clear();
|
||||
this._visibleConfigs.clear();
|
||||
this._enginesByCamera.clear();
|
||||
this._cameras.clear();
|
||||
this._enginesByType.clear();
|
||||
}
|
||||
|
||||
public getCamera(cameraID: string): Camera | null {
|
||||
return this._cameras.get(cameraID) ?? null;
|
||||
}
|
||||
public getCameraConfig(cameraID: string): CameraConfig | null {
|
||||
return this._allConfigs.get(cameraID) ?? null;
|
||||
return this._cameras.get(cameraID)?.getConfig() ?? null;
|
||||
}
|
||||
|
||||
public hasCameraID(cameraID: string): boolean {
|
||||
return this._allConfigs.has(cameraID);
|
||||
}
|
||||
public hasVisibleCameraID(cameraID: string): boolean {
|
||||
return this._visibleConfigs.has(cameraID);
|
||||
return this._cameras.has(cameraID);
|
||||
}
|
||||
|
||||
public getCameraCount(): number {
|
||||
return this._allConfigs.size;
|
||||
return this._cameras.size;
|
||||
}
|
||||
public getVisibleCameraCount(): number {
|
||||
return this._visibleConfigs.size;
|
||||
return this.getVisibleCameraIDs().size;
|
||||
}
|
||||
|
||||
public getCameras(): CameraConfigs {
|
||||
return this._allConfigs;
|
||||
public getCameras(): Map<string, Camera> {
|
||||
return this._cameras;
|
||||
}
|
||||
public getVisibleCameras(): CameraConfigs {
|
||||
return this._visibleConfigs;
|
||||
|
||||
public *getCameraConfigs(
|
||||
cameraIDs?: Iterable<string>,
|
||||
): IterableIterator<CameraConfig> {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
for (const [_cameraID, config] of this.getCameraConfigEntries(cameraIDs)) {
|
||||
yield config;
|
||||
}
|
||||
}
|
||||
public *getCameraConfigEntries(
|
||||
cameraIDs?: Iterable<string>,
|
||||
): IterableIterator<[string, CameraConfig]> {
|
||||
for (const cameraID of cameraIDs ?? this._cameras.keys()) {
|
||||
const config = this.getCameraConfig(cameraID);
|
||||
|
||||
if (config) {
|
||||
yield [cameraID, config];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getCameraIDs(): Set<string> {
|
||||
return new Set(this._allConfigs.keys());
|
||||
return new Set(this._cameras.keys());
|
||||
}
|
||||
public getVisibleCameraIDs(): Set<string> {
|
||||
return new Set(this._visibleConfigs.keys());
|
||||
return this._getMatchingCameraIDs((camera) => !camera.getConfig().hide);
|
||||
}
|
||||
|
||||
public getCameraConfigForMedia(media: ViewMedia): CameraConfig | null {
|
||||
@@ -89,7 +98,7 @@ export class CameraManagerStore implements CameraManagerReadOnlyConfigStore {
|
||||
}
|
||||
|
||||
public getEngineForCameraID(cameraID: string): CameraManagerEngine | null {
|
||||
return this._enginesByCamera.get(cameraID) ?? null;
|
||||
return this._cameras.get(cameraID)?.getEngine() ?? null;
|
||||
}
|
||||
|
||||
public getEnginesForCameraIDs(
|
||||
@@ -114,7 +123,42 @@ export class CameraManagerStore implements CameraManagerReadOnlyConfigStore {
|
||||
return this.getEngineForCameraID(media.getCameraID());
|
||||
}
|
||||
|
||||
public getAllEngines(): CameraManagerEngine[] {
|
||||
return [...this._enginesByType.values()];
|
||||
/**
|
||||
* Get all cameras that depend on a given camera.
|
||||
* @param cameraManager The camera manager.
|
||||
* @param cameraID ID of the target camera.
|
||||
* @returns A set of dependent cameraIDs or null (since JS sets guarantee order,
|
||||
* the first item in the set is guaranteed to be the cameraID itself).
|
||||
*/
|
||||
public getAllDependentCameras(cameraID: string): Set<string> {
|
||||
const cameraIDs: Set<string> = new Set();
|
||||
const getDependentCameras = (cameraID: string): void => {
|
||||
const cameraConfig = this.getCameraConfig(cameraID);
|
||||
if (cameraConfig) {
|
||||
cameraIDs.add(cameraID);
|
||||
const dependentCameras: Set<string> = new Set();
|
||||
cameraConfig.dependencies.cameras.forEach((item) => dependentCameras.add(item));
|
||||
if (cameraConfig.dependencies.all_cameras) {
|
||||
this.getCameraIDs().forEach((cameraID) => dependentCameras.add(cameraID));
|
||||
}
|
||||
for (const eventCameraID of dependentCameras) {
|
||||
if (!cameraIDs.has(eventCameraID)) {
|
||||
getDependentCameras(eventCameraID);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
getDependentCameras(cameraID);
|
||||
return cameraIDs;
|
||||
}
|
||||
|
||||
protected _getMatchingCameraIDs(func: (camera: Camera) => boolean): Set<string> {
|
||||
const output = new Set<string>();
|
||||
for (const [cameraID, camera] of this._cameras.entries()) {
|
||||
if (func(camera)) {
|
||||
output.add(cameraID);
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user