@apocaliss92/scrypted-reolink-native 0.2.2 → 0.2.3
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/main.nodejs.js +1 -1
- package/dist/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/camera.ts +30 -17
- package/src/multiFocal.ts +11 -2
- package/src/utils.ts +8 -4
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/camera.ts
CHANGED
|
@@ -199,6 +199,11 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
199
199
|
private readonly onSimpleEventBound = (ev: ReolinkSimpleEvent) => this.onSimpleEvent(ev);
|
|
200
200
|
|
|
201
201
|
storageSettings = new StorageSettings(this, {
|
|
202
|
+
debugLogs: {
|
|
203
|
+
title: 'Debug logs',
|
|
204
|
+
type: 'boolean',
|
|
205
|
+
immediate: true,
|
|
206
|
+
},
|
|
202
207
|
// Basic connection settings
|
|
203
208
|
ipAddress: {
|
|
204
209
|
title: 'IP Address',
|
|
@@ -262,11 +267,6 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
262
267
|
await this.credentialsChanged();
|
|
263
268
|
}
|
|
264
269
|
},
|
|
265
|
-
debugLogs: {
|
|
266
|
-
title: 'Debug logs',
|
|
267
|
-
type: 'boolean',
|
|
268
|
-
immediate: true,
|
|
269
|
-
},
|
|
270
270
|
mixinsSetup: {
|
|
271
271
|
type: 'boolean',
|
|
272
272
|
hide: true,
|
|
@@ -1319,15 +1319,22 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
1319
1319
|
}
|
|
1320
1320
|
|
|
1321
1321
|
protected getStreamClientInputs(): BaichuanConnectionConfig {
|
|
1322
|
-
const { ipAddress, username, password } = this.storageSettings.values;
|
|
1322
|
+
const { ipAddress, username, password, uid, discoveryMethod } = this.storageSettings.values;
|
|
1323
1323
|
const debugOptions = this.getBaichuanDebugOptions();
|
|
1324
1324
|
|
|
1325
|
+
const normalizedUid = this.isBattery ? normalizeUid(uid) : undefined;
|
|
1326
|
+
if (this.isBattery && !normalizedUid) {
|
|
1327
|
+
throw new Error('UID is required for battery cameras (BCUDP)');
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1325
1330
|
return {
|
|
1326
1331
|
host: ipAddress,
|
|
1327
1332
|
username,
|
|
1328
1333
|
password,
|
|
1334
|
+
uid: normalizedUid,
|
|
1329
1335
|
transport: this.transport,
|
|
1330
1336
|
debugOptions,
|
|
1337
|
+
udpDiscoveryMethod: discoveryMethod as BaichuanClientOptions["udpDiscoveryMethod"],
|
|
1331
1338
|
};
|
|
1332
1339
|
}
|
|
1333
1340
|
|
|
@@ -2348,17 +2355,24 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
2348
2355
|
const { rtspChannel, variantType } = this.storageSettings.values;
|
|
2349
2356
|
|
|
2350
2357
|
try {
|
|
2351
|
-
// Lens-scoped behavior: request streams only for the current lens/variant.
|
|
2352
|
-
// This keeps a single native_main and native_sub for the device.
|
|
2353
|
-
const lensParam: NativeVideoStreamVariant | undefined = variantType as any;
|
|
2354
2358
|
|
|
2355
2359
|
const { nativeStreams, rtmpStreams, rtspStreams } = await client.buildVideoStreamOptions({
|
|
2356
2360
|
onNvr: this.isOnNvr,
|
|
2357
2361
|
channel: rtspChannel,
|
|
2358
2362
|
compositeOnly: this.isMultiFocal,
|
|
2359
|
-
|
|
2363
|
+
lens: variantType,
|
|
2360
2364
|
});
|
|
2361
2365
|
|
|
2366
|
+
logger.debug(`Supported streams: ${JSON.stringify({
|
|
2367
|
+
nativeStreams,
|
|
2368
|
+
rtmpStreams,
|
|
2369
|
+
rtspStreams,
|
|
2370
|
+
variantType,
|
|
2371
|
+
onNvr: this.isOnNvr,
|
|
2372
|
+
channel: rtspChannel,
|
|
2373
|
+
compositeOnly: this.isMultiFocal,
|
|
2374
|
+
})}`);
|
|
2375
|
+
|
|
2362
2376
|
// const urls = client.getRtspUrl(rtspChannel);
|
|
2363
2377
|
|
|
2364
2378
|
// let supportedStreams: ReolinkSupportedStream[] = [];
|
|
@@ -2413,12 +2427,10 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
2413
2427
|
}
|
|
2414
2428
|
}
|
|
2415
2429
|
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
return streams;
|
|
2421
|
-
}
|
|
2430
|
+
logger.log('Fetched video stream options', streams.map((s) => s.name).join(', '));
|
|
2431
|
+
logger.debug(JSON.stringify({ streams }));
|
|
2432
|
+
this.cachedVideoStreamOptions = streams;
|
|
2433
|
+
return streams;
|
|
2422
2434
|
|
|
2423
2435
|
return [];
|
|
2424
2436
|
} finally {
|
|
@@ -2605,6 +2617,7 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
2605
2617
|
const { interfaces, type } = getDeviceInterfaces({
|
|
2606
2618
|
capabilities,
|
|
2607
2619
|
logger: this.console,
|
|
2620
|
+
lensType: this.storageSettings.values.variantType,
|
|
2608
2621
|
});
|
|
2609
2622
|
|
|
2610
2623
|
const device: Device = {
|
|
@@ -2696,7 +2709,7 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
2696
2709
|
this.storageSettings.settings.pipSize.hide = !this.isMultiFocal;
|
|
2697
2710
|
this.storageSettings.settings.pipMargin.hide = !this.isMultiFocal;
|
|
2698
2711
|
|
|
2699
|
-
this.storageSettings.settings.uid.hide = !this.isBattery
|
|
2712
|
+
this.storageSettings.settings.uid.hide = !this.isBattery || this.isOnNvr;
|
|
2700
2713
|
this.storageSettings.settings.discoveryMethod.hide = !this.isBattery && !this.nvrDevice;
|
|
2701
2714
|
|
|
2702
2715
|
if (this.isBattery && !this.storageSettings.values.mixinsSetup) {
|
package/src/multiFocal.ts
CHANGED
|
@@ -50,9 +50,10 @@ export class ReolinkNativeMultiFocalDevice extends ReolinkCamera implements Sett
|
|
|
50
50
|
const { interfaces } = getDeviceInterfaces({
|
|
51
51
|
capabilities,
|
|
52
52
|
logger,
|
|
53
|
+
lensType,
|
|
53
54
|
});
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
logger.debug(`Interfaces found for lens ${lensType}: ${JSON.stringify({ interfaces, capabilities, multifocalInfo })}`);
|
|
56
57
|
|
|
57
58
|
return { interfaces, capabilities };
|
|
58
59
|
}
|
|
@@ -193,15 +194,23 @@ export class ReolinkNativeMultiFocalDevice extends ReolinkCamera implements Sett
|
|
|
193
194
|
}
|
|
194
195
|
|
|
195
196
|
protected getStreamClientInputs(): BaichuanConnectionConfig {
|
|
196
|
-
const { ipAddress, username, password } = this.storageSettings.values;
|
|
197
|
+
const { ipAddress, username, password, uid, discoveryMethod } = this.storageSettings.values;
|
|
197
198
|
const debugOptions = this.getBaichuanDebugOptions();
|
|
198
199
|
|
|
200
|
+
// Multifocal battery cams use BCUDP for streaming too; UID is required.
|
|
201
|
+
const normalizedUid = this.isBattery ? uid?.trim() || undefined : undefined;
|
|
202
|
+
if (this.isBattery && !normalizedUid) {
|
|
203
|
+
throw new Error('UID is required for battery cameras (BCUDP)');
|
|
204
|
+
}
|
|
205
|
+
|
|
199
206
|
return {
|
|
200
207
|
host: ipAddress,
|
|
201
208
|
username,
|
|
202
209
|
password,
|
|
210
|
+
uid: normalizedUid,
|
|
203
211
|
transport: this.transport,
|
|
204
212
|
debugOptions,
|
|
213
|
+
udpDiscoveryMethod: discoveryMethod,
|
|
205
214
|
};
|
|
206
215
|
}
|
|
207
216
|
|
package/src/utils.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DeviceCapabilities, EnrichedRecordingFile, ParsedRecordingFileName, RecordingFile, ReolinkBaichuanApi, ReolinkDeviceInfo, VodFile, VodSearchResponse } from "@apocaliss92/reolink-baichuan-js" with { "resolution-mode": "import" };
|
|
1
|
+
import type { DeviceCapabilities, EnrichedRecordingFile, NativeVideoStreamVariant, ParsedRecordingFileName, RecordingFile, ReolinkBaichuanApi, ReolinkDeviceInfo, VodFile, VodSearchResponse } from "@apocaliss92/reolink-baichuan-js" with { "resolution-mode": "import" };
|
|
2
2
|
import sdk, { DeviceBase, HttpRequest, HttpResponse, MediaObject, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, VideoClip, VideoClips } from "@scrypted/sdk";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { Readable } from "stream";
|
|
@@ -58,9 +58,10 @@ export const pirSuffix = `-pir`;
|
|
|
58
58
|
|
|
59
59
|
export const getDeviceInterfaces = (props: {
|
|
60
60
|
capabilities: DeviceCapabilities,
|
|
61
|
-
logger: Console
|
|
61
|
+
logger: Console,
|
|
62
|
+
lensType?: NativeVideoStreamVariant
|
|
62
63
|
}) => {
|
|
63
|
-
const { capabilities, logger } = props;
|
|
64
|
+
const { capabilities, logger, lensType } = props;
|
|
64
65
|
|
|
65
66
|
const interfaces = [
|
|
66
67
|
ScryptedInterface.VideoCamera,
|
|
@@ -71,9 +72,12 @@ export const getDeviceInterfaces = (props: {
|
|
|
71
72
|
ScryptedInterface.AudioSensor,
|
|
72
73
|
ScryptedInterface.MotionSensor,
|
|
73
74
|
ScryptedInterface.VideoTextOverlays,
|
|
74
|
-
ScryptedInterface.VideoClips,
|
|
75
75
|
];
|
|
76
76
|
|
|
77
|
+
if (!lensType) {
|
|
78
|
+
interfaces.push(ScryptedInterface.VideoClips);
|
|
79
|
+
}
|
|
80
|
+
|
|
77
81
|
try {
|
|
78
82
|
const {
|
|
79
83
|
hasPtz,
|