@apocaliss92/scrypted-reolink-native 0.2.16 → 0.2.18
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/.vscode/settings.json +1 -1
- package/dist/main.nodejs.js +1 -1
- package/dist/plugin.zip +0 -0
- package/package.json +1 -1
- package/src/camera.ts +50 -40
- package/src/main.ts +3 -2
- package/src/multiFocal.ts +4 -4
- package/src/nvr.ts +2 -1
package/dist/plugin.zip
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/camera.ts
CHANGED
|
@@ -5,8 +5,6 @@ import path from 'path';
|
|
|
5
5
|
import fs from 'fs';
|
|
6
6
|
import crypto from 'crypto';
|
|
7
7
|
import { spawn } from 'node:child_process';
|
|
8
|
-
import http from 'http';
|
|
9
|
-
import https from 'https';
|
|
10
8
|
import type { UrlMediaStreamOptions } from "../../scrypted/plugins/rtsp/src/rtsp";
|
|
11
9
|
import { BaseBaichuanClass, type BaichuanConnectionCallbacks, type BaichuanConnectionConfig } from "./baichuan-base";
|
|
12
10
|
import { createBaichuanApi, normalizeUid, type BaichuanTransport } from "./connect";
|
|
@@ -237,10 +235,10 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
237
235
|
defaultValue: 'default',
|
|
238
236
|
choices: ['default', 'autotrack', 'telephoto'] as NativeVideoStreamVariant[],
|
|
239
237
|
},
|
|
240
|
-
capabilities: {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
},
|
|
238
|
+
// capabilities: {
|
|
239
|
+
// json: true,
|
|
240
|
+
// hide: true,
|
|
241
|
+
// },
|
|
244
242
|
multifocalInfo: {
|
|
245
243
|
json: true,
|
|
246
244
|
hide: true,
|
|
@@ -672,6 +670,8 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
672
670
|
private takePictureInFlight: Promise<MediaObject> | undefined;
|
|
673
671
|
forceNewSnapshot: boolean = false;
|
|
674
672
|
|
|
673
|
+
public cachedCapabilities: DeviceCapabilities | undefined;
|
|
674
|
+
|
|
675
675
|
// Video stream properties
|
|
676
676
|
protected cachedVideoStreamOptions?: UrlMediaStreamOptions[];
|
|
677
677
|
protected fetchingStreamsPromise: Promise<UrlMediaStreamOptions[]> | undefined;
|
|
@@ -915,8 +915,8 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
915
915
|
await fs.promises.mkdir(cacheDir, { recursive: true });
|
|
916
916
|
}
|
|
917
917
|
|
|
918
|
-
const { clipsSource } = this.storageSettings.values;
|
|
919
|
-
const useNvr = clipsSource === "NVR" && this.nvrDevice;
|
|
918
|
+
// const { clipsSource } = this.storageSettings.values;
|
|
919
|
+
// const useNvr = clipsSource === "NVR" && this.nvrDevice;
|
|
920
920
|
|
|
921
921
|
// Both standalone and NVR now use a URL-based playback path.
|
|
922
922
|
// In NVR mode, `videoId` is expected to be a full recording path (e.g. /mnt/sda/...).
|
|
@@ -1046,8 +1046,8 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
1046
1046
|
// Ensure cache directory exists
|
|
1047
1047
|
await fs.promises.mkdir(cacheDir, { recursive: true });
|
|
1048
1048
|
|
|
1049
|
-
const { clipsSource } = this.storageSettings.values;
|
|
1050
|
-
const useNvr = clipsSource === "NVR" && this.nvrDevice;
|
|
1049
|
+
// const { clipsSource } = this.storageSettings.values;
|
|
1050
|
+
// const useNvr = clipsSource === "NVR" && this.nvrDevice;
|
|
1051
1051
|
|
|
1052
1052
|
// NVR mode: `thumbnailId` is expected to be a full recording path (e.g. /mnt/sda/...).
|
|
1053
1053
|
// Use the same ffmpeg-based thumbnail extraction flow as other sources.
|
|
@@ -1468,32 +1468,40 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
1468
1468
|
return await super.createStreamClient(streamKey);
|
|
1469
1469
|
}
|
|
1470
1470
|
|
|
1471
|
-
public getAbilities(): DeviceCapabilities {
|
|
1472
|
-
|
|
1473
|
-
const variantType = this.storageSettings.values.variantType;
|
|
1474
|
-
const ifaces = this.multiFocalDevice.getInterfaces(variantType);
|
|
1475
|
-
if (ifaces?.capabilities) return ifaces.capabilities;
|
|
1476
|
-
} else {
|
|
1477
|
-
const caps = this.storageSettings.values.capabilities;
|
|
1478
|
-
if (caps) return caps;
|
|
1479
|
-
}
|
|
1471
|
+
public async getAbilities(): Promise<DeviceCapabilities> {
|
|
1472
|
+
const logger = this.getBaichuanLogger();
|
|
1480
1473
|
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1474
|
+
try {
|
|
1475
|
+
if (this.multiFocalDevice) {
|
|
1476
|
+
const variantType = this.storageSettings.values.variantType;
|
|
1477
|
+
const ifaces = await this.multiFocalDevice.getInterfaces(variantType);
|
|
1478
|
+
if (ifaces?.capabilities) return ifaces.capabilities;
|
|
1479
|
+
} else {
|
|
1480
|
+
if (this.cachedCapabilities) return this.cachedCapabilities;
|
|
1481
|
+
|
|
1482
|
+
const client = await this.ensureClient();
|
|
1483
|
+
const { capabilities } = await client.getDeviceCapabilities(this.storageSettings.values.rtspChannel ?? 0);
|
|
1484
|
+
this.cachedCapabilities = capabilities;
|
|
1485
|
+
return capabilities;
|
|
1486
|
+
}
|
|
1487
|
+
} catch (e) {
|
|
1488
|
+
logger.error('Failed to get abilities', e);
|
|
1489
|
+
return {
|
|
1490
|
+
channel: this.storageSettings.values.rtspChannel ?? 0,
|
|
1491
|
+
ptzMode: 'none',
|
|
1492
|
+
hasPan: false,
|
|
1493
|
+
hasTilt: false,
|
|
1494
|
+
hasZoom: false,
|
|
1495
|
+
hasPresets: false,
|
|
1496
|
+
hasPtz: false,
|
|
1497
|
+
hasBattery: !!this.isBattery,
|
|
1498
|
+
hasIntercom: false,
|
|
1499
|
+
hasSiren: false,
|
|
1500
|
+
hasFloodlight: false,
|
|
1501
|
+
hasPir: false,
|
|
1502
|
+
isDoorbell: false,
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1497
1505
|
}
|
|
1498
1506
|
|
|
1499
1507
|
getBaichuanDebugOptions(): any | undefined {
|
|
@@ -1620,8 +1628,8 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
1620
1628
|
);
|
|
1621
1629
|
}
|
|
1622
1630
|
|
|
1623
|
-
updatePtzCaps() {
|
|
1624
|
-
const { hasPan, hasTilt, hasZoom } = this.getAbilities();
|
|
1631
|
+
async updatePtzCaps() {
|
|
1632
|
+
const { hasPan, hasTilt, hasZoom } = await this.getAbilities();
|
|
1625
1633
|
this.ptzCapabilities = {
|
|
1626
1634
|
...this.ptzCapabilities,
|
|
1627
1635
|
pan: hasPan,
|
|
@@ -1994,7 +2002,9 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
1994
2002
|
}
|
|
1995
2003
|
|
|
1996
2004
|
async reportDevices(): Promise<void> {
|
|
1997
|
-
const abilities = this.getAbilities();
|
|
2005
|
+
const abilities = await this.getAbilities();
|
|
2006
|
+
const logger = this.getBaichuanLogger();
|
|
2007
|
+
logger.debug(`Reporting devices: ${JSON.stringify(abilities)}`);
|
|
1998
2008
|
|
|
1999
2009
|
const { hasSiren, hasFloodlight, hasPir } = abilities;
|
|
2000
2010
|
|
|
@@ -2269,7 +2279,7 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
2269
2279
|
const api = await this.ensureClient();
|
|
2270
2280
|
|
|
2271
2281
|
const channel = this.storageSettings.values.rtspChannel;
|
|
2272
|
-
const { hasSiren, hasFloodlight, hasPir } = this.getAbilities();
|
|
2282
|
+
const { hasSiren, hasFloodlight, hasPir } = await this.getAbilities();
|
|
2273
2283
|
|
|
2274
2284
|
try {
|
|
2275
2285
|
// Align siren state
|
|
@@ -2691,7 +2701,7 @@ export class ReolinkCamera extends BaseBaichuanClass implements VideoCamera, Cam
|
|
|
2691
2701
|
logger.error('Failed to initialize StreamManager', e?.message || String(e));
|
|
2692
2702
|
}
|
|
2693
2703
|
|
|
2694
|
-
const { hasIntercom, hasPtz } = this.getAbilities();
|
|
2704
|
+
const { hasIntercom, hasPtz } = await this.getAbilities();
|
|
2695
2705
|
|
|
2696
2706
|
if (hasIntercom) {
|
|
2697
2707
|
this.intercom = new ReolinkBaichuanIntercom(this);
|
package/src/main.ts
CHANGED
|
@@ -119,7 +119,7 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
119
119
|
device.storageSettings.values.username = username;
|
|
120
120
|
device.storageSettings.values.password = password;
|
|
121
121
|
device.storageSettings.values.uid = uid;
|
|
122
|
-
device.
|
|
122
|
+
device.cachedCapabilities = capabilities;
|
|
123
123
|
|
|
124
124
|
return nativeId;
|
|
125
125
|
}
|
|
@@ -190,10 +190,11 @@ class ReolinkNativePlugin extends ScryptedDeviceBase implements DeviceProvider,
|
|
|
190
190
|
device.storageSettings.values.password = password;
|
|
191
191
|
device.storageSettings.values.rtspChannel = rtspChannel;
|
|
192
192
|
device.storageSettings.values.ipAddress = ipAddress;
|
|
193
|
-
device.storageSettings.values.capabilities = capabilities;
|
|
194
193
|
device.storageSettings.values.uid = uid;
|
|
195
194
|
device.storageSettings.values.discoveryMethod = detection.udpDiscoveryMethod;
|
|
196
195
|
|
|
196
|
+
device.cachedCapabilities = capabilities;
|
|
197
|
+
|
|
197
198
|
return nativeId;
|
|
198
199
|
}
|
|
199
200
|
catch (e) {
|
package/src/multiFocal.ts
CHANGED
|
@@ -25,9 +25,10 @@ export class ReolinkNativeMultiFocalDevice extends ReolinkCamera implements Sett
|
|
|
25
25
|
return this.name || 'Multi-Focal Device';
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
getInterfaces(lensType?: NativeVideoStreamVariant) {
|
|
28
|
+
async getInterfaces(lensType?: NativeVideoStreamVariant) {
|
|
29
29
|
const logger = this.getBaichuanLogger();
|
|
30
|
-
const {
|
|
30
|
+
const { multifocalInfo } = this.storageSettings.values;
|
|
31
|
+
const caps = await this.getAbilities();
|
|
31
32
|
|
|
32
33
|
let capabilities: DeviceCapabilities = { ...caps };
|
|
33
34
|
|
|
@@ -77,7 +78,6 @@ export class ReolinkNativeMultiFocalDevice extends ReolinkCamera implements Sett
|
|
|
77
78
|
logger.debug({ multifocalInfo, capabilities });
|
|
78
79
|
|
|
79
80
|
this.storageSettings.values.multifocalInfo = multifocalInfo;
|
|
80
|
-
this.storageSettings.values.capabilities = capabilities;
|
|
81
81
|
|
|
82
82
|
for (const channelInfo of multifocalInfo?.channels ?? []) {
|
|
83
83
|
const { channel, lensType, variantType } = channelInfo;
|
|
@@ -86,7 +86,7 @@ export class ReolinkNativeMultiFocalDevice extends ReolinkCamera implements Sett
|
|
|
86
86
|
const nativeId = `${this.nativeId}-${lensType}${this.isBattery ? batteryCameraSuffix : cameraSuffix}`;
|
|
87
87
|
|
|
88
88
|
this.channelToNativeIdMap.set(channel, nativeId);
|
|
89
|
-
const { interfaces, capabilities: deviceCapabilities } = this.getInterfaces();
|
|
89
|
+
const { interfaces, capabilities: deviceCapabilities } = await this.getInterfaces();
|
|
90
90
|
|
|
91
91
|
const device: Device = {
|
|
92
92
|
providerNativeId: this.nativeId,
|
package/src/nvr.ts
CHANGED
|
@@ -501,9 +501,10 @@ export class ReolinkNativeNvrDevice extends BaseBaichuanClass implements Setting
|
|
|
501
501
|
device.storageSettings.values.password = password;
|
|
502
502
|
device.storageSettings.values.rtspChannel = entry.rtspChannel;
|
|
503
503
|
device.storageSettings.values.ipAddress = ipAddress;
|
|
504
|
-
device.storageSettings.values.capabilities = capabilities;
|
|
505
504
|
device.storageSettings.values.uid = uid;
|
|
506
505
|
|
|
506
|
+
device.cachedCapabilities = capabilities;
|
|
507
|
+
|
|
507
508
|
this.discoveredDevices.delete(adopt.nativeId);
|
|
508
509
|
return device?.id;
|
|
509
510
|
}
|