Add support for go2rtc for non-Frigate cameras
This commit is contained in:
@@ -10,7 +10,7 @@ import { MemoryRequestCache, RecordingSegmentsCache, RequestCache } from './cach
|
||||
import { CameraManagerEngine } from './engine';
|
||||
import { CameraInitializationError } from './error';
|
||||
import { Engine } from './types';
|
||||
import { getCameraEntityFromConfig } from './util';
|
||||
import { getCameraEntityFromConfig } from './utils';
|
||||
|
||||
export class CameraManagerEngineFactory {
|
||||
protected _entityRegistryManager: EntityRegistryManager;
|
||||
|
||||
@@ -62,7 +62,7 @@ import {
|
||||
RecordingSegmentsQuery,
|
||||
RecordingSegmentsQueryResultsMap,
|
||||
} from '../types';
|
||||
import { getCameraEntityFromConfig } from '../util';
|
||||
import { getCameraEntityFromConfig, getDefaultGo2RTCEndpoint } from '../utils.js';
|
||||
import frigateLogo from './assets/frigate-logo-dark.svg';
|
||||
import { FrigateViewMediaFactory } from './media';
|
||||
import { FrigateViewMediaClassifier } from './media-classifier';
|
||||
@@ -1147,26 +1147,6 @@ export class FrigateCameraManagerEngine
|
||||
};
|
||||
};
|
||||
|
||||
const getGo2RTC = (): CameraEndpoint | null => {
|
||||
const stream = cameraConfig.go2rtc?.stream ?? cameraConfig.frigate.camera_name;
|
||||
const url = cameraConfig.go2rtc?.url
|
||||
? cameraConfig.go2rtc.url.replace(/\/+$/, '')
|
||||
: null;
|
||||
const endpoint = url
|
||||
? `${url}/api/ws?src=${stream}`
|
||||
: // go2rtc is exposed by the integration under the (slightly
|
||||
// misleading) 'mse' path, even though that path can serve all go2rtc
|
||||
// modes.
|
||||
`/api/frigate/${cameraConfig.frigate.client_id}/mse/api/ws?src=${stream}`;
|
||||
|
||||
return {
|
||||
endpoint: endpoint,
|
||||
|
||||
// Only sign the endpoint if it's local to HA.
|
||||
sign: endpoint.startsWith('/'),
|
||||
};
|
||||
};
|
||||
|
||||
const getJSMPEG = (): CameraEndpoint | null => {
|
||||
return {
|
||||
endpoint:
|
||||
@@ -1189,11 +1169,20 @@ export class FrigateCameraManagerEngine
|
||||
};
|
||||
|
||||
const ui = getUIEndpoint();
|
||||
const go2rtc = getGo2RTC();
|
||||
const go2rtc = getDefaultGo2RTCEndpoint(cameraConfig, {
|
||||
url:
|
||||
cameraConfig.go2rtc?.url ??
|
||||
// go2rtc is exposed by the Frigate integration under the (slightly
|
||||
// misleading) 'mse' path, even though that path can serve all go2rtc
|
||||
// modes.
|
||||
`/api/frigate/${cameraConfig.frigate.client_id}/mse`,
|
||||
stream: cameraConfig.go2rtc?.stream ?? cameraConfig.frigate.camera_name,
|
||||
});
|
||||
const jsmpeg = getJSMPEG();
|
||||
const webrtcCard = getWebRTCCard();
|
||||
|
||||
return {
|
||||
...super.getCameraEndpoints(cameraConfig, context),
|
||||
...(ui && { ui: ui }),
|
||||
...(go2rtc && { go2rtc: go2rtc }),
|
||||
...(jsmpeg && { jsmpeg: jsmpeg }),
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
RecordingSegmentsQuery,
|
||||
RecordingSegmentsQueryResultsMap,
|
||||
} from '../types';
|
||||
import { getDefaultGo2RTCEndpoint } from '../utils.js';
|
||||
|
||||
export class GenericCameraManagerEngine implements CameraManagerEngine {
|
||||
public getEngineType(): Engine {
|
||||
@@ -165,10 +166,7 @@ export class GenericCameraManagerEngine implements CameraManagerEngine {
|
||||
getEntityTitle(hass, cameraConfig.webrtc_card?.entity) ??
|
||||
cameraConfig.id ??
|
||||
'',
|
||||
icon:
|
||||
cameraConfig?.icon ??
|
||||
getEntityIcon(hass, cameraConfig.camera_entity) ??
|
||||
'mdi:video',
|
||||
icon: cameraConfig?.icon ?? getEntityIcon(hass, cameraConfig.camera_entity),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -191,9 +189,14 @@ export class GenericCameraManagerEngine implements CameraManagerEngine {
|
||||
}
|
||||
|
||||
public getCameraEndpoints(
|
||||
_cameraConfig: CameraConfig,
|
||||
cameraConfig: CameraConfig,
|
||||
_context?: CameraEndpointsContext,
|
||||
): CameraEndpoints | null {
|
||||
return null;
|
||||
const go2rtc = getDefaultGo2RTCEndpoint(cameraConfig);
|
||||
return go2rtc
|
||||
? {
|
||||
go2rtc: go2rtc,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ import add from 'date-fns/add';
|
||||
import cloneDeep from 'lodash-es/cloneDeep';
|
||||
import merge from 'lodash-es/merge.js';
|
||||
import sum from 'lodash-es/sum';
|
||||
import { CardCameraAPI } from '../card-controller/types.js';
|
||||
import { CameraConfig, CamerasConfig } from '../config/types.js';
|
||||
import { MEDIA_CHUNK_SIZE_DEFAULT } from '../const.js';
|
||||
import { localize } from '../localize/localize.js';
|
||||
import { allPromises, arrayify, setify } from '../utils/basic.js';
|
||||
import { getCameraID } from '../utils/camera.js';
|
||||
import { CardCameraAPI } from '../card-controller/types.js';
|
||||
import { log } from '../utils/debug.js';
|
||||
import { EntityRegistryManager } from '../utils/ha/entity-registry/index.js';
|
||||
import { ViewMedia } from '../view/media.js';
|
||||
@@ -51,7 +51,7 @@ import {
|
||||
RecordingSegmentsQueryResultsMap,
|
||||
ResultsMap,
|
||||
} from './types.js';
|
||||
import { sortMedia } from './util.js';
|
||||
import { sortMedia } from './utils.js';
|
||||
|
||||
class QueryClassifier {
|
||||
public static isEventQuery(query: DataQuery | PartialDataQuery): query is EventQuery {
|
||||
|
||||
@@ -384,8 +384,7 @@ export class MotionEyeCameraManagerEngine extends BrowseMediaCameraManagerEngine
|
||||
|
||||
public getCameraEndpoints(
|
||||
cameraConfig: CameraConfig,
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
_context?: CameraEndpointsContext,
|
||||
context?: CameraEndpointsContext,
|
||||
): CameraEndpoints | null {
|
||||
const getUIEndpoint = (): CameraEndpoint | null => {
|
||||
return cameraConfig.motioneye?.url
|
||||
@@ -394,9 +393,9 @@ export class MotionEyeCameraManagerEngine extends BrowseMediaCameraManagerEngine
|
||||
}
|
||||
: null;
|
||||
};
|
||||
|
||||
const ui = getUIEndpoint();
|
||||
return {
|
||||
...super.getCameraEndpoints(cameraConfig, context),
|
||||
...(ui && { ui: ui }),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import uniqBy from 'lodash-es/uniqBy';
|
||||
import { CameraConfig } from '../config/types';
|
||||
import { ViewMedia } from '../view/media';
|
||||
import { DateRange } from './range';
|
||||
import { CameraEndpoint } from './types';
|
||||
|
||||
export const convertRangeToCacheFriendlyTimes = (
|
||||
range: DateRange,
|
||||
@@ -58,3 +59,26 @@ export const sortMedia = (mediaArray: ViewMedia[]): ViewMedia[] => {
|
||||
export const getCameraEntityFromConfig = (cameraConfig: CameraConfig): string | null => {
|
||||
return cameraConfig.camera_entity ?? cameraConfig.webrtc_card?.entity ?? null;
|
||||
};
|
||||
|
||||
export const getDefaultGo2RTCEndpoint = (
|
||||
cameraConfig: CameraConfig,
|
||||
options?: {
|
||||
url?: string;
|
||||
stream?: string;
|
||||
},
|
||||
): CameraEndpoint | null => {
|
||||
const url = options?.url ?? cameraConfig.go2rtc?.url;
|
||||
const stream = options?.stream ?? cameraConfig.go2rtc?.stream;
|
||||
|
||||
if (!url || !stream) {
|
||||
return null;
|
||||
}
|
||||
const endpoint = `${url}/api/ws?src=${stream}`;
|
||||
|
||||
return {
|
||||
endpoint: endpoint,
|
||||
|
||||
// Only sign the endpoint if it's local to HA.
|
||||
sign: endpoint.startsWith('/'),
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user