@camstack/addon-provider-rtsp 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon.js +109 -197
- package/dist/addon.js.map +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/chunk-2B5J5HPN.mjs +294 -0
- package/dist/chunk-2B5J5HPN.mjs.map +1 -0
- package/dist/index.d.mts +13 -28
- package/dist/index.d.ts +13 -28
- package/dist/index.js +109 -197
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-4KD2JX6K.mjs +0 -382
- package/dist/chunk-4KD2JX6K.mjs.map +0 -1
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// src/rtsp-device.ts
|
|
2
|
+
import { DeviceType } from "@camstack/types";
|
|
3
|
+
var RtspDevice = class {
|
|
4
|
+
id;
|
|
5
|
+
name;
|
|
6
|
+
providerId;
|
|
7
|
+
type = DeviceType.Camera;
|
|
8
|
+
capabilities;
|
|
9
|
+
ctx;
|
|
10
|
+
stableId;
|
|
11
|
+
settings;
|
|
12
|
+
capabilityMap = /* @__PURE__ */ new Map();
|
|
13
|
+
constructor(device, settings, ctx) {
|
|
14
|
+
this.id = device.id;
|
|
15
|
+
this.stableId = device.stableId;
|
|
16
|
+
this.name = device.name;
|
|
17
|
+
this.providerId = device.integrationId;
|
|
18
|
+
this.settings = settings;
|
|
19
|
+
this.ctx = ctx;
|
|
20
|
+
this.capabilities = ["camera"];
|
|
21
|
+
this.capabilityMap.set("camera", this.createCamera());
|
|
22
|
+
}
|
|
23
|
+
getCapability(cap) {
|
|
24
|
+
return this.capabilityMap.get(cap) ?? null;
|
|
25
|
+
}
|
|
26
|
+
hasCapability(cap) {
|
|
27
|
+
return this.capabilityMap.has(cap);
|
|
28
|
+
}
|
|
29
|
+
getState() {
|
|
30
|
+
return { online: true };
|
|
31
|
+
}
|
|
32
|
+
getMetadata() {
|
|
33
|
+
return { manufacturer: "Generic RTSP" };
|
|
34
|
+
}
|
|
35
|
+
createCamera() {
|
|
36
|
+
const mainUrl = String(this.settings["main_stream_url"] ?? "");
|
|
37
|
+
const subUrl = String(this.settings["sub_stream_url"] ?? "");
|
|
38
|
+
const snapshotUrl = String(this.settings["snapshot_url"] ?? "");
|
|
39
|
+
const deviceId = this.id;
|
|
40
|
+
return {
|
|
41
|
+
kind: "camera",
|
|
42
|
+
async getSnapshot() {
|
|
43
|
+
if (snapshotUrl) {
|
|
44
|
+
const res = await fetch(snapshotUrl);
|
|
45
|
+
return Buffer.from(await res.arrayBuffer());
|
|
46
|
+
}
|
|
47
|
+
return Buffer.alloc(0);
|
|
48
|
+
},
|
|
49
|
+
async getStreamOptions() {
|
|
50
|
+
const options = [
|
|
51
|
+
{
|
|
52
|
+
id: `${deviceId}_main`,
|
|
53
|
+
label: "Main",
|
|
54
|
+
protocol: "rtsp",
|
|
55
|
+
quality: "main",
|
|
56
|
+
url: mainUrl
|
|
57
|
+
}
|
|
58
|
+
];
|
|
59
|
+
if (subUrl) {
|
|
60
|
+
options.push({
|
|
61
|
+
id: `${deviceId}_sub`,
|
|
62
|
+
label: "Sub",
|
|
63
|
+
protocol: "rtsp",
|
|
64
|
+
quality: "sub",
|
|
65
|
+
url: subUrl
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return options;
|
|
69
|
+
},
|
|
70
|
+
async getStreamUrl(option) {
|
|
71
|
+
return option.url ?? mainUrl;
|
|
72
|
+
},
|
|
73
|
+
getConnectionMode() {
|
|
74
|
+
return "always-on";
|
|
75
|
+
},
|
|
76
|
+
async setConnectionMode() {
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// src/rtsp-provider.ts
|
|
83
|
+
function sanitizeStableId(name) {
|
|
84
|
+
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "") || `rtsp-${Date.now()}`;
|
|
85
|
+
}
|
|
86
|
+
var RtspProvider = class {
|
|
87
|
+
id;
|
|
88
|
+
type = "rtsp";
|
|
89
|
+
name;
|
|
90
|
+
discoveryMode = "manual";
|
|
91
|
+
ctx;
|
|
92
|
+
integration;
|
|
93
|
+
registry;
|
|
94
|
+
devices = [];
|
|
95
|
+
constructor(integration, registry, ctx) {
|
|
96
|
+
this.id = integration.id;
|
|
97
|
+
this.name = integration.name;
|
|
98
|
+
this.integration = integration;
|
|
99
|
+
this.registry = registry;
|
|
100
|
+
this.ctx = ctx;
|
|
101
|
+
}
|
|
102
|
+
async start() {
|
|
103
|
+
const registeredDevices = this.registry.listDevices(this.integration.id);
|
|
104
|
+
for (const device of registeredDevices) {
|
|
105
|
+
if (!device.enabled) continue;
|
|
106
|
+
const settings = this.registry.getDeviceSettings(device.id);
|
|
107
|
+
this.devices.push(this.buildDevice(device, settings));
|
|
108
|
+
}
|
|
109
|
+
this.ctx.logger.info(`RTSP provider started with ${this.devices.length} cameras`);
|
|
110
|
+
}
|
|
111
|
+
async stop() {
|
|
112
|
+
this.devices.length = 0;
|
|
113
|
+
this.ctx.logger.info("RTSP provider stopped");
|
|
114
|
+
}
|
|
115
|
+
getStatus() {
|
|
116
|
+
return { connected: true, deviceCount: this.devices.length };
|
|
117
|
+
}
|
|
118
|
+
async discoverDevices() {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
getDevices() {
|
|
122
|
+
return [...this.devices];
|
|
123
|
+
}
|
|
124
|
+
getDeviceConfigSchema() {
|
|
125
|
+
return {
|
|
126
|
+
sections: [
|
|
127
|
+
{
|
|
128
|
+
id: "device-info",
|
|
129
|
+
title: "Device Configuration",
|
|
130
|
+
description: "Configure the RTSP camera connection",
|
|
131
|
+
columns: 1,
|
|
132
|
+
fields: [
|
|
133
|
+
{
|
|
134
|
+
type: "text",
|
|
135
|
+
key: "name",
|
|
136
|
+
label: "Device Name",
|
|
137
|
+
placeholder: "e.g. Front Door Camera",
|
|
138
|
+
required: true
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: "text",
|
|
142
|
+
key: "main_stream_url",
|
|
143
|
+
label: "Main Stream URL",
|
|
144
|
+
placeholder: "rtsp://192.168.1.100:554/stream1",
|
|
145
|
+
inputType: "url",
|
|
146
|
+
required: true
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: "text",
|
|
150
|
+
key: "sub_stream_url",
|
|
151
|
+
label: "Sub Stream URL",
|
|
152
|
+
placeholder: "rtsp://192.168.1.100:554/stream2",
|
|
153
|
+
inputType: "url"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: "text",
|
|
157
|
+
key: "snapshot_url",
|
|
158
|
+
label: "Snapshot URL",
|
|
159
|
+
placeholder: "http://192.168.1.100/snapshot.jpg",
|
|
160
|
+
inputType: "url"
|
|
161
|
+
}
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
]
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
async createDevice(config) {
|
|
168
|
+
const name = String(config["name"] ?? "").trim();
|
|
169
|
+
if (!name) throw new Error("Device name is required");
|
|
170
|
+
const mainStreamUrl = String(config["main_stream_url"] ?? "").trim();
|
|
171
|
+
if (!mainStreamUrl) throw new Error("Main stream URL is required");
|
|
172
|
+
const stableId = sanitizeStableId(name);
|
|
173
|
+
const existing = this.registry.getDeviceByStableId(stableId);
|
|
174
|
+
if (existing) throw new Error(`A device with name "${name}" already exists (stableId: ${stableId})`);
|
|
175
|
+
const device = this.registry.createDevice({
|
|
176
|
+
integrationId: this.integration.id,
|
|
177
|
+
stableId,
|
|
178
|
+
type: "camera",
|
|
179
|
+
name,
|
|
180
|
+
enabled: true,
|
|
181
|
+
info: {},
|
|
182
|
+
settings: {
|
|
183
|
+
main_stream_url: mainStreamUrl,
|
|
184
|
+
sub_stream_url: config["sub_stream_url"] ? String(config["sub_stream_url"]) : "",
|
|
185
|
+
snapshot_url: config["snapshot_url"] ? String(config["snapshot_url"]) : ""
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
const settings = this.registry.getDeviceSettings(device.id);
|
|
189
|
+
const rtspDevice = this.buildDevice(device, settings);
|
|
190
|
+
this.devices.push(rtspDevice);
|
|
191
|
+
this.ctx.logger.info(`Created RTSP device: ${device.id} / ${stableId} (${name})`);
|
|
192
|
+
return rtspDevice;
|
|
193
|
+
}
|
|
194
|
+
subscribeLiveEvents(_callback) {
|
|
195
|
+
return () => {
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
buildDevice(device, settings) {
|
|
199
|
+
const deviceCtx = {
|
|
200
|
+
id: `device:${device.id}`,
|
|
201
|
+
logger: this.ctx.logger.child(device.name),
|
|
202
|
+
eventBus: this.ctx.eventBus,
|
|
203
|
+
storage: this.ctx.storage,
|
|
204
|
+
config: this.ctx.config
|
|
205
|
+
};
|
|
206
|
+
return new RtspDevice(device, settings, deviceCtx);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// src/addon.ts
|
|
211
|
+
var RtspProviderAddon = class {
|
|
212
|
+
manifest = {
|
|
213
|
+
id: "provider-rtsp",
|
|
214
|
+
name: "RTSP Camera Provider",
|
|
215
|
+
version: "0.1.0",
|
|
216
|
+
description: "Direct connection to cameras via RTSP URL",
|
|
217
|
+
capabilities: ["device-provider"]
|
|
218
|
+
};
|
|
219
|
+
provider = null;
|
|
220
|
+
async initialize(context) {
|
|
221
|
+
const registry = context.integrationRegistry;
|
|
222
|
+
if (!registry) {
|
|
223
|
+
context.logger.warn("IntegrationRegistry not available \u2014 RTSP provider cannot start");
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
let integration = registry.getIntegrationByAddonId("provider-rtsp");
|
|
227
|
+
if (!integration) {
|
|
228
|
+
integration = registry.createIntegration({
|
|
229
|
+
addonId: "provider-rtsp",
|
|
230
|
+
name: "RTSP Cameras",
|
|
231
|
+
enabled: true,
|
|
232
|
+
info: { discoveryMode: "manual", icon: "assets/icon.svg", color: "#78716c" }
|
|
233
|
+
});
|
|
234
|
+
context.logger.info(`Created RTSP integration: ${integration.id}`);
|
|
235
|
+
}
|
|
236
|
+
if (!integration.enabled) {
|
|
237
|
+
context.logger.info("RTSP integration is disabled \u2014 skipping start");
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.provider = new RtspProvider(integration, registry, {
|
|
241
|
+
id: context.id,
|
|
242
|
+
logger: context.logger,
|
|
243
|
+
eventBus: context.eventBus,
|
|
244
|
+
storage: context.storage,
|
|
245
|
+
config: context.config
|
|
246
|
+
});
|
|
247
|
+
await this.provider.start();
|
|
248
|
+
context.logger.info(`RTSP provider started (integration=${integration.id}, devices=${this.provider.getDevices().length})`);
|
|
249
|
+
}
|
|
250
|
+
async shutdown() {
|
|
251
|
+
await this.provider?.stop();
|
|
252
|
+
this.provider = null;
|
|
253
|
+
}
|
|
254
|
+
getCapabilityProvider(name) {
|
|
255
|
+
if (name === "device-provider" && this.provider) {
|
|
256
|
+
return this.provider;
|
|
257
|
+
}
|
|
258
|
+
return null;
|
|
259
|
+
}
|
|
260
|
+
getConfigSchema() {
|
|
261
|
+
return {
|
|
262
|
+
sections: [
|
|
263
|
+
{
|
|
264
|
+
id: "general",
|
|
265
|
+
title: "RTSP Provider",
|
|
266
|
+
description: "Configure generic RTSP camera connections",
|
|
267
|
+
columns: 1,
|
|
268
|
+
fields: [
|
|
269
|
+
{ type: "text", key: "name", label: "Provider Name", placeholder: "RTSP Cameras" },
|
|
270
|
+
{
|
|
271
|
+
type: "info",
|
|
272
|
+
key: "info",
|
|
273
|
+
label: "Camera Configuration",
|
|
274
|
+
content: "Individual cameras are configured via the device management interface after adding this provider.",
|
|
275
|
+
variant: "info"
|
|
276
|
+
}
|
|
277
|
+
]
|
|
278
|
+
}
|
|
279
|
+
]
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
getConfig() {
|
|
283
|
+
return {};
|
|
284
|
+
}
|
|
285
|
+
async onConfigChange(_config) {
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
export {
|
|
290
|
+
RtspDevice,
|
|
291
|
+
RtspProvider,
|
|
292
|
+
RtspProviderAddon
|
|
293
|
+
};
|
|
294
|
+
//# sourceMappingURL=chunk-2B5J5HPN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/rtsp-device.ts","../src/rtsp-provider.ts","../src/addon.ts"],"sourcesContent":["import { DeviceType } from '@camstack/types'\nimport type {\n IDevice,\n DeviceState,\n DeviceMetadata,\n DeviceCapabilityName,\n IDeviceCapability,\n CamstackContext,\n ICamera,\n StreamOption,\n ConnectionMode,\n Device,\n} from '@camstack/types'\n\nexport class RtspDevice implements IDevice {\n readonly id: string\n readonly name: string\n readonly providerId: string\n readonly type: DeviceType = DeviceType.Camera\n readonly capabilities: DeviceCapabilityName[]\n readonly ctx: CamstackContext\n\n readonly stableId: string\n private readonly settings: Record<string, unknown>\n private readonly capabilityMap = new Map<DeviceCapabilityName, IDeviceCapability>()\n\n constructor(\n device: Device,\n settings: Record<string, unknown>,\n ctx: CamstackContext,\n ) {\n this.id = device.id\n this.stableId = device.stableId\n this.name = device.name\n this.providerId = device.integrationId\n this.settings = settings\n this.ctx = ctx\n\n this.capabilities = ['camera']\n this.capabilityMap.set('camera', this.createCamera())\n }\n\n getCapability<T extends IDeviceCapability>(cap: DeviceCapabilityName): T | null {\n return (this.capabilityMap.get(cap) as T) ?? null\n }\n\n hasCapability(cap: DeviceCapabilityName): boolean {\n return this.capabilityMap.has(cap)\n }\n\n getState(): DeviceState {\n return { online: true }\n }\n\n getMetadata(): DeviceMetadata {\n return { manufacturer: 'Generic RTSP' }\n }\n\n private createCamera(): ICamera {\n const mainUrl = String(this.settings['main_stream_url'] ?? '')\n const subUrl = String(this.settings['sub_stream_url'] ?? '')\n const snapshotUrl = String(this.settings['snapshot_url'] ?? '')\n const deviceId = this.id\n\n return {\n kind: 'camera',\n\n async getSnapshot() {\n if (snapshotUrl) {\n const res = await fetch(snapshotUrl)\n return Buffer.from(await res.arrayBuffer())\n }\n return Buffer.alloc(0)\n },\n\n async getStreamOptions(): Promise<StreamOption[]> {\n const options: StreamOption[] = [\n {\n id: `${deviceId}_main`,\n label: 'Main',\n protocol: 'rtsp',\n quality: 'main',\n url: mainUrl,\n },\n ]\n if (subUrl) {\n options.push({\n id: `${deviceId}_sub`,\n label: 'Sub',\n protocol: 'rtsp',\n quality: 'sub',\n url: subUrl,\n })\n }\n return options\n },\n\n async getStreamUrl(option: StreamOption) {\n return option.url ?? mainUrl\n },\n\n getConnectionMode(): ConnectionMode {\n return 'always-on'\n },\n\n async setConnectionMode() {},\n }\n }\n}\n","import { RtspDevice } from './rtsp-device.js'\nimport type {\n IDeviceProvider,\n ProviderStatus,\n DiscoveredDevice,\n LiveEvent,\n IDevice,\n CamstackContext,\n ConfigUISchema,\n Integration,\n Device,\n IIntegrationRegistry,\n} from '@camstack/types'\n\nfunction sanitizeStableId(name: string): string {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '')\n || `rtsp-${Date.now()}`\n}\n\nexport class RtspProvider implements IDeviceProvider {\n readonly id: string\n readonly type = 'rtsp'\n readonly name: string\n readonly discoveryMode: 'manual' = 'manual'\n readonly ctx: CamstackContext\n\n private readonly integration: Integration\n private readonly registry: IIntegrationRegistry\n private readonly devices: RtspDevice[] = []\n\n constructor(integration: Integration, registry: IIntegrationRegistry, ctx: CamstackContext) {\n this.id = integration.id\n this.name = integration.name\n this.integration = integration\n this.registry = registry\n this.ctx = ctx\n }\n\n async start(): Promise<void> {\n // Load devices from centralized registry\n const registeredDevices = this.registry.listDevices(this.integration.id)\n\n for (const device of registeredDevices) {\n if (!device.enabled) continue\n const settings = this.registry.getDeviceSettings(device.id)\n this.devices.push(this.buildDevice(device, settings))\n }\n\n this.ctx.logger.info(`RTSP provider started with ${this.devices.length} cameras`)\n }\n\n async stop(): Promise<void> {\n this.devices.length = 0\n this.ctx.logger.info('RTSP provider stopped')\n }\n\n getStatus(): ProviderStatus {\n return { connected: true, deviceCount: this.devices.length }\n }\n\n async discoverDevices(): Promise<DiscoveredDevice[]> {\n return []\n }\n\n getDevices(): IDevice[] {\n return [...this.devices]\n }\n\n getDeviceConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'device-info',\n title: 'Device Configuration',\n description: 'Configure the RTSP camera connection',\n columns: 1,\n fields: [\n {\n type: 'text',\n key: 'name',\n label: 'Device Name',\n placeholder: 'e.g. Front Door Camera',\n required: true,\n },\n {\n type: 'text',\n key: 'main_stream_url',\n label: 'Main Stream URL',\n placeholder: 'rtsp://192.168.1.100:554/stream1',\n inputType: 'url',\n required: true,\n },\n {\n type: 'text',\n key: 'sub_stream_url',\n label: 'Sub Stream URL',\n placeholder: 'rtsp://192.168.1.100:554/stream2',\n inputType: 'url',\n },\n {\n type: 'text',\n key: 'snapshot_url',\n label: 'Snapshot URL',\n placeholder: 'http://192.168.1.100/snapshot.jpg',\n inputType: 'url',\n },\n ],\n },\n ],\n }\n }\n\n async createDevice(config: Record<string, unknown>): Promise<IDevice> {\n const name = String(config['name'] ?? '').trim()\n if (!name) throw new Error('Device name is required')\n\n const mainStreamUrl = String(config['main_stream_url'] ?? '').trim()\n if (!mainStreamUrl) throw new Error('Main stream URL is required')\n\n const stableId = sanitizeStableId(name)\n\n // Check if stableId already exists globally\n const existing = this.registry.getDeviceByStableId(stableId)\n if (existing) throw new Error(`A device with name \"${name}\" already exists (stableId: ${stableId})`)\n\n // Create in centralized registry\n const device = this.registry.createDevice({\n integrationId: this.integration.id,\n stableId,\n type: 'camera',\n name,\n enabled: true,\n info: {},\n settings: {\n main_stream_url: mainStreamUrl,\n sub_stream_url: config['sub_stream_url'] ? String(config['sub_stream_url']) : '',\n snapshot_url: config['snapshot_url'] ? String(config['snapshot_url']) : '',\n },\n })\n\n const settings = this.registry.getDeviceSettings(device.id)\n const rtspDevice = this.buildDevice(device, settings)\n this.devices.push(rtspDevice)\n\n this.ctx.logger.info(`Created RTSP device: ${device.id} / ${stableId} (${name})`)\n return rtspDevice\n }\n\n subscribeLiveEvents(_callback: (event: LiveEvent) => void): () => void {\n return () => {}\n }\n\n private buildDevice(device: Device, settings: Record<string, unknown>): RtspDevice {\n const deviceCtx: CamstackContext = {\n id: `device:${device.id}`,\n logger: this.ctx.logger.child(device.name),\n eventBus: this.ctx.eventBus,\n storage: this.ctx.storage,\n config: this.ctx.config,\n }\n return new RtspDevice(device, settings, deviceCtx)\n }\n}\n","import type {\n ICamstackAddon,\n AddonManifest,\n AddonContext,\n CapabilityProviderMap,\n ConfigUISchema,\n IConfigurable,\n IIntegrationRegistry,\n} from '@camstack/types'\nimport { RtspProvider } from './rtsp-provider.js'\n\nexport class RtspProviderAddon implements ICamstackAddon, IConfigurable {\n readonly manifest: AddonManifest = {\n id: 'provider-rtsp',\n name: 'RTSP Camera Provider',\n version: '0.1.0',\n description: 'Direct connection to cameras via RTSP URL',\n capabilities: ['device-provider'],\n }\n\n private provider: RtspProvider | null = null\n\n async initialize(context: AddonContext): Promise<void> {\n // Get integration registry from context (injected by server)\n const registry = (context as any).integrationRegistry as IIntegrationRegistry | undefined\n if (!registry) {\n context.logger.warn('IntegrationRegistry not available — RTSP provider cannot start')\n return\n }\n\n // Find or create the integration entry\n let integration = registry.getIntegrationByAddonId('provider-rtsp')\n if (!integration) {\n integration = registry.createIntegration({\n addonId: 'provider-rtsp',\n name: 'RTSP Cameras',\n enabled: true,\n info: { discoveryMode: 'manual', icon: 'assets/icon.svg', color: '#78716c' },\n })\n context.logger.info(`Created RTSP integration: ${integration.id}`)\n }\n\n if (!integration.enabled) {\n context.logger.info('RTSP integration is disabled — skipping start')\n return\n }\n\n // Create provider with registry access\n this.provider = new RtspProvider(integration, registry, {\n id: context.id,\n logger: context.logger,\n eventBus: context.eventBus,\n storage: context.storage,\n config: context.config,\n })\n\n // Auto-start\n await this.provider.start()\n context.logger.info(`RTSP provider started (integration=${integration.id}, devices=${this.provider.getDevices().length})`)\n }\n\n async shutdown(): Promise<void> {\n await this.provider?.stop()\n this.provider = null\n }\n\n getCapabilityProvider<K extends keyof CapabilityProviderMap>(\n name: K,\n ): CapabilityProviderMap[K] | null {\n if (name === 'device-provider' && this.provider) {\n return this.provider as unknown as CapabilityProviderMap[K]\n }\n return null\n }\n\n getConfigSchema(): ConfigUISchema {\n return {\n sections: [\n {\n id: 'general',\n title: 'RTSP Provider',\n description: 'Configure generic RTSP camera connections',\n columns: 1,\n fields: [\n { type: 'text', key: 'name', label: 'Provider Name', placeholder: 'RTSP Cameras' },\n {\n type: 'info',\n key: 'info',\n label: 'Camera Configuration',\n content: 'Individual cameras are configured via the device management interface after adding this provider.',\n variant: 'info',\n },\n ],\n },\n ],\n }\n }\n\n getConfig(): Record<string, unknown> {\n return {}\n }\n\n async onConfigChange(_config: Record<string, unknown>): Promise<void> {\n // Config changes handled by integration settings\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,38 +1,21 @@
|
|
|
1
1
|
export { RtspProviderAddon } from './addon.mjs';
|
|
2
|
-
import { IDevice, DeviceType, DeviceCapabilityName, CamstackContext, IDeviceCapability, DeviceState, DeviceMetadata, IDeviceProvider, ProviderStatus, DiscoveredDevice, ConfigUISchema, LiveEvent } from '@camstack/types';
|
|
3
|
-
|
|
4
|
-
interface RtspCameraConfig {
|
|
5
|
-
readonly id: string;
|
|
6
|
-
readonly name: string;
|
|
7
|
-
readonly url: string;
|
|
8
|
-
readonly subStreamUrl?: string;
|
|
9
|
-
readonly snapshotUrl?: string;
|
|
10
|
-
readonly audioEnabled?: boolean;
|
|
11
|
-
readonly width?: number;
|
|
12
|
-
readonly height?: number;
|
|
13
|
-
}
|
|
14
|
-
interface RtspProviderConfig {
|
|
15
|
-
readonly id: string;
|
|
16
|
-
readonly name: string;
|
|
17
|
-
readonly cameras: readonly RtspCameraConfig[];
|
|
18
|
-
}
|
|
2
|
+
import { IDevice, DeviceType, DeviceCapabilityName, CamstackContext, Device, IDeviceCapability, DeviceState, DeviceMetadata, IDeviceProvider, Integration, IIntegrationRegistry, ProviderStatus, DiscoveredDevice, ConfigUISchema, LiveEvent } from '@camstack/types';
|
|
19
3
|
|
|
20
4
|
declare class RtspDevice implements IDevice {
|
|
21
|
-
private readonly config;
|
|
22
5
|
readonly id: string;
|
|
23
6
|
readonly name: string;
|
|
24
7
|
readonly providerId: string;
|
|
25
8
|
readonly type: DeviceType;
|
|
26
9
|
readonly capabilities: DeviceCapabilityName[];
|
|
27
10
|
readonly ctx: CamstackContext;
|
|
11
|
+
readonly stableId: string;
|
|
12
|
+
private readonly settings;
|
|
28
13
|
private readonly capabilityMap;
|
|
29
|
-
constructor(
|
|
14
|
+
constructor(device: Device, settings: Record<string, unknown>, ctx: CamstackContext);
|
|
30
15
|
getCapability<T extends IDeviceCapability>(cap: DeviceCapabilityName): T | null;
|
|
31
16
|
hasCapability(cap: DeviceCapabilityName): boolean;
|
|
32
17
|
getState(): DeviceState;
|
|
33
18
|
getMetadata(): DeviceMetadata;
|
|
34
|
-
/** Return the camera config for persistence */
|
|
35
|
-
getCameraConfig(): RtspCameraConfig;
|
|
36
19
|
private createCamera;
|
|
37
20
|
}
|
|
38
21
|
|
|
@@ -42,8 +25,10 @@ declare class RtspProvider implements IDeviceProvider {
|
|
|
42
25
|
readonly name: string;
|
|
43
26
|
readonly discoveryMode: 'manual';
|
|
44
27
|
readonly ctx: CamstackContext;
|
|
28
|
+
private readonly integration;
|
|
29
|
+
private readonly registry;
|
|
45
30
|
private readonly devices;
|
|
46
|
-
constructor(
|
|
31
|
+
constructor(integration: Integration, registry: IIntegrationRegistry, ctx: CamstackContext);
|
|
47
32
|
start(): Promise<void>;
|
|
48
33
|
stop(): Promise<void>;
|
|
49
34
|
getStatus(): ProviderStatus;
|
|
@@ -53,11 +38,11 @@ declare class RtspProvider implements IDeviceProvider {
|
|
|
53
38
|
createDevice(config: Record<string, unknown>): Promise<IDevice>;
|
|
54
39
|
subscribeLiveEvents(_callback: (event: LiveEvent) => void): () => void;
|
|
55
40
|
private buildDevice;
|
|
56
|
-
/**
|
|
57
|
-
* Persist all dynamically-created device configs so they survive restarts.
|
|
58
|
-
* Saves the full list of camera configs under the 'devices' key in the provider's config.
|
|
59
|
-
*/
|
|
60
|
-
private persistDeviceConfigs;
|
|
61
41
|
}
|
|
62
42
|
|
|
63
|
-
|
|
43
|
+
interface RtspProviderConfig {
|
|
44
|
+
readonly id: string;
|
|
45
|
+
readonly name: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { RtspDevice, RtspProvider, type RtspProviderConfig };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,21 @@
|
|
|
1
1
|
export { RtspProviderAddon } from './addon.js';
|
|
2
|
-
import { IDevice, DeviceType, DeviceCapabilityName, CamstackContext, IDeviceCapability, DeviceState, DeviceMetadata, IDeviceProvider, ProviderStatus, DiscoveredDevice, ConfigUISchema, LiveEvent } from '@camstack/types';
|
|
3
|
-
|
|
4
|
-
interface RtspCameraConfig {
|
|
5
|
-
readonly id: string;
|
|
6
|
-
readonly name: string;
|
|
7
|
-
readonly url: string;
|
|
8
|
-
readonly subStreamUrl?: string;
|
|
9
|
-
readonly snapshotUrl?: string;
|
|
10
|
-
readonly audioEnabled?: boolean;
|
|
11
|
-
readonly width?: number;
|
|
12
|
-
readonly height?: number;
|
|
13
|
-
}
|
|
14
|
-
interface RtspProviderConfig {
|
|
15
|
-
readonly id: string;
|
|
16
|
-
readonly name: string;
|
|
17
|
-
readonly cameras: readonly RtspCameraConfig[];
|
|
18
|
-
}
|
|
2
|
+
import { IDevice, DeviceType, DeviceCapabilityName, CamstackContext, Device, IDeviceCapability, DeviceState, DeviceMetadata, IDeviceProvider, Integration, IIntegrationRegistry, ProviderStatus, DiscoveredDevice, ConfigUISchema, LiveEvent } from '@camstack/types';
|
|
19
3
|
|
|
20
4
|
declare class RtspDevice implements IDevice {
|
|
21
|
-
private readonly config;
|
|
22
5
|
readonly id: string;
|
|
23
6
|
readonly name: string;
|
|
24
7
|
readonly providerId: string;
|
|
25
8
|
readonly type: DeviceType;
|
|
26
9
|
readonly capabilities: DeviceCapabilityName[];
|
|
27
10
|
readonly ctx: CamstackContext;
|
|
11
|
+
readonly stableId: string;
|
|
12
|
+
private readonly settings;
|
|
28
13
|
private readonly capabilityMap;
|
|
29
|
-
constructor(
|
|
14
|
+
constructor(device: Device, settings: Record<string, unknown>, ctx: CamstackContext);
|
|
30
15
|
getCapability<T extends IDeviceCapability>(cap: DeviceCapabilityName): T | null;
|
|
31
16
|
hasCapability(cap: DeviceCapabilityName): boolean;
|
|
32
17
|
getState(): DeviceState;
|
|
33
18
|
getMetadata(): DeviceMetadata;
|
|
34
|
-
/** Return the camera config for persistence */
|
|
35
|
-
getCameraConfig(): RtspCameraConfig;
|
|
36
19
|
private createCamera;
|
|
37
20
|
}
|
|
38
21
|
|
|
@@ -42,8 +25,10 @@ declare class RtspProvider implements IDeviceProvider {
|
|
|
42
25
|
readonly name: string;
|
|
43
26
|
readonly discoveryMode: 'manual';
|
|
44
27
|
readonly ctx: CamstackContext;
|
|
28
|
+
private readonly integration;
|
|
29
|
+
private readonly registry;
|
|
45
30
|
private readonly devices;
|
|
46
|
-
constructor(
|
|
31
|
+
constructor(integration: Integration, registry: IIntegrationRegistry, ctx: CamstackContext);
|
|
47
32
|
start(): Promise<void>;
|
|
48
33
|
stop(): Promise<void>;
|
|
49
34
|
getStatus(): ProviderStatus;
|
|
@@ -53,11 +38,11 @@ declare class RtspProvider implements IDeviceProvider {
|
|
|
53
38
|
createDevice(config: Record<string, unknown>): Promise<IDevice>;
|
|
54
39
|
subscribeLiveEvents(_callback: (event: LiveEvent) => void): () => void;
|
|
55
40
|
private buildDevice;
|
|
56
|
-
/**
|
|
57
|
-
* Persist all dynamically-created device configs so they survive restarts.
|
|
58
|
-
* Saves the full list of camera configs under the 'devices' key in the provider's config.
|
|
59
|
-
*/
|
|
60
|
-
private persistDeviceConfigs;
|
|
61
41
|
}
|
|
62
42
|
|
|
63
|
-
|
|
43
|
+
interface RtspProviderConfig {
|
|
44
|
+
readonly id: string;
|
|
45
|
+
readonly name: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { RtspDevice, RtspProvider, type RtspProviderConfig };
|