@apocaliss92/nodelink-js 0.4.22 → 0.4.24
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/BaichuanVideoStream-NTIGPHYJ.js +7 -0
- package/dist/{DiagnosticsTools-HO3VI6D5.js → DiagnosticsTools-ILDDJZL7.js} +3 -3
- package/dist/{chunk-S2UTGNFN.js → chunk-AHY4L7JI.js} +2 -2
- package/dist/{chunk-C57QV7IL.js → chunk-GVWJGQPT.js} +5 -1
- package/dist/chunk-GVWJGQPT.js.map +1 -0
- package/dist/{chunk-EZ7WNPLB.js → chunk-JYHK2ZSH.js} +522 -19
- package/dist/chunk-JYHK2ZSH.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +507 -14
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +3 -3
- package/dist/index.cjs +535 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +327 -1
- package/dist/index.d.ts +343 -0
- package/dist/index.js +31 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/BaichuanVideoStream-HGPU2MZ3.js +0 -7
- package/dist/chunk-C57QV7IL.js.map +0 -1
- package/dist/chunk-EZ7WNPLB.js.map +0 -1
- /package/dist/{BaichuanVideoStream-HGPU2MZ3.js.map → BaichuanVideoStream-NTIGPHYJ.js.map} +0 -0
- /package/dist/{DiagnosticsTools-HO3VI6D5.js.map → DiagnosticsTools-ILDDJZL7.js.map} +0 -0
- /package/dist/{chunk-S2UTGNFN.js.map → chunk-AHY4L7JI.js.map} +0 -0
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
runAllDiagnosticsConsecutively,
|
|
31
31
|
runMultifocalDiagnosticsConsecutively,
|
|
32
32
|
xmlEscape
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-AHY4L7JI.js";
|
|
34
34
|
import {
|
|
35
35
|
BC_CLASS_FILE_DOWNLOAD,
|
|
36
36
|
BC_CLASS_LEGACY,
|
|
@@ -94,10 +94,12 @@ import {
|
|
|
94
94
|
BC_CMD_ID_GET_REC_ENC_CFG,
|
|
95
95
|
BC_CMD_ID_GET_SIREN_STATUS,
|
|
96
96
|
BC_CMD_ID_GET_SLEEP_STATE,
|
|
97
|
+
BC_CMD_ID_GET_SNAPSHOT,
|
|
97
98
|
BC_CMD_ID_GET_STREAM_INFO_LIST,
|
|
98
99
|
BC_CMD_ID_GET_SUPPORT,
|
|
99
100
|
BC_CMD_ID_GET_SYSTEM_GENERAL,
|
|
100
101
|
BC_CMD_ID_GET_TIMELAPSE_CFG,
|
|
102
|
+
BC_CMD_ID_GET_UID,
|
|
101
103
|
BC_CMD_ID_GET_VERSION_INFO,
|
|
102
104
|
BC_CMD_ID_GET_VIDEO_INPUT,
|
|
103
105
|
BC_CMD_ID_GET_WHITE_LED,
|
|
@@ -176,7 +178,7 @@ import {
|
|
|
176
178
|
splitAnnexBToNalPayloads2,
|
|
177
179
|
talkTraceLog,
|
|
178
180
|
traceLog
|
|
179
|
-
} from "./chunk-
|
|
181
|
+
} from "./chunk-GVWJGQPT.js";
|
|
180
182
|
|
|
181
183
|
// src/protocol/framing.ts
|
|
182
184
|
function encodeHeader(h) {
|
|
@@ -8319,6 +8321,353 @@ function decideSleepInferenceTransition(input) {
|
|
|
8319
8321
|
};
|
|
8320
8322
|
}
|
|
8321
8323
|
|
|
8324
|
+
// src/reolink/baichuan/utils/privacyMask.ts
|
|
8325
|
+
var DEFAULT_SHELTER_CANVAS = {
|
|
8326
|
+
width: 540,
|
|
8327
|
+
height: 304
|
|
8328
|
+
};
|
|
8329
|
+
function decodeShelterCoord(value) {
|
|
8330
|
+
const v = (value | 0) >>> 0;
|
|
8331
|
+
return { pixel: v >>> 16, canvas: v & 65535 };
|
|
8332
|
+
}
|
|
8333
|
+
function encodeShelterCoord(pixel, canvas) {
|
|
8334
|
+
const p = Math.min(65535, Math.max(0, Math.floor(pixel)));
|
|
8335
|
+
const c = Math.min(65535, Math.max(0, Math.floor(canvas)));
|
|
8336
|
+
return p * 65536 + c;
|
|
8337
|
+
}
|
|
8338
|
+
function clamp01(value) {
|
|
8339
|
+
if (!Number.isFinite(value)) return 0;
|
|
8340
|
+
if (value < 0) return 0;
|
|
8341
|
+
if (value > 1) return 1;
|
|
8342
|
+
return value;
|
|
8343
|
+
}
|
|
8344
|
+
function decodeRect(raw, canvas, idKey) {
|
|
8345
|
+
const xRaw = Number(raw["topLeftX"] ?? 0) | 0;
|
|
8346
|
+
const yRaw = Number(raw["topLeftY"] ?? 0) | 0;
|
|
8347
|
+
const wRaw = Number(raw["width"] ?? 0) | 0;
|
|
8348
|
+
const hRaw = Number(raw["height"] ?? 0) | 0;
|
|
8349
|
+
const xPixel = decodeShelterCoord(xRaw).pixel;
|
|
8350
|
+
const yPixel = decodeShelterCoord(yRaw).pixel;
|
|
8351
|
+
const wPixel = decodeShelterCoord(wRaw).pixel;
|
|
8352
|
+
const hPixel = decodeShelterCoord(hRaw).pixel;
|
|
8353
|
+
return {
|
|
8354
|
+
id: Number(raw[idKey] ?? 0) | 0,
|
|
8355
|
+
enable: Number(raw["enable"] ?? 0) === 1,
|
|
8356
|
+
layer: Number(raw["layer"] ?? 0) | 0,
|
|
8357
|
+
color: Number(raw["color"] ?? 0) | 0,
|
|
8358
|
+
x: canvas.width > 0 ? xPixel / canvas.width : 0,
|
|
8359
|
+
y: canvas.height > 0 ? yPixel / canvas.height : 0,
|
|
8360
|
+
width: canvas.width > 0 ? wPixel / canvas.width : 0,
|
|
8361
|
+
height: canvas.height > 0 ? hPixel / canvas.height : 0
|
|
8362
|
+
};
|
|
8363
|
+
}
|
|
8364
|
+
function extractCanvasFromShelterXml(xml) {
|
|
8365
|
+
const xMatch = xml.match(/<topLeftX>(\d+)<\/topLeftX>/g) ?? [];
|
|
8366
|
+
const yMatch = xml.match(/<topLeftY>(\d+)<\/topLeftY>/g) ?? [];
|
|
8367
|
+
let canvasX = 0;
|
|
8368
|
+
let canvasY = 0;
|
|
8369
|
+
for (const tag of xMatch) {
|
|
8370
|
+
const v = Number(tag.replace(/<\/?topLeftX>/g, "")) | 0;
|
|
8371
|
+
if (v > 0) {
|
|
8372
|
+
canvasX = v & 65535;
|
|
8373
|
+
break;
|
|
8374
|
+
}
|
|
8375
|
+
}
|
|
8376
|
+
for (const tag of yMatch) {
|
|
8377
|
+
const v = Number(tag.replace(/<\/?topLeftY>/g, "")) | 0;
|
|
8378
|
+
if (v > 0) {
|
|
8379
|
+
canvasY = v & 65535;
|
|
8380
|
+
break;
|
|
8381
|
+
}
|
|
8382
|
+
}
|
|
8383
|
+
return {
|
|
8384
|
+
width: canvasX > 0 ? canvasX : DEFAULT_SHELTER_CANVAS.width,
|
|
8385
|
+
height: canvasY > 0 ? canvasY : DEFAULT_SHELTER_CANVAS.height
|
|
8386
|
+
};
|
|
8387
|
+
}
|
|
8388
|
+
function parseRectTags(block) {
|
|
8389
|
+
const out = {};
|
|
8390
|
+
const grab = (tag) => {
|
|
8391
|
+
const m = block.match(new RegExp(`<${tag}>([^<]*)<\\/${tag}>`));
|
|
8392
|
+
if (m && m[1] !== void 0) out[tag] = m[1];
|
|
8393
|
+
};
|
|
8394
|
+
grab("id");
|
|
8395
|
+
grab("name");
|
|
8396
|
+
grab("enable");
|
|
8397
|
+
grab("layer");
|
|
8398
|
+
grab("color");
|
|
8399
|
+
grab("topLeftX");
|
|
8400
|
+
grab("topLeftY");
|
|
8401
|
+
grab("width");
|
|
8402
|
+
grab("height");
|
|
8403
|
+
grab("pPos");
|
|
8404
|
+
grab("tPos");
|
|
8405
|
+
grab("zPos");
|
|
8406
|
+
return out;
|
|
8407
|
+
}
|
|
8408
|
+
function decodePrivacyMaskZones(xml) {
|
|
8409
|
+
const canvas = extractCanvasFromShelterXml(xml);
|
|
8410
|
+
const enable = Number(getXmlText(xml, "enable") ?? "0") === 1;
|
|
8411
|
+
const trackEnable = Number(getXmlText(xml, "trackEnable") ?? "0") === 1;
|
|
8412
|
+
const maxTrackShelterNum = Number(getXmlText(xml, "maxTrackShelterNum") ?? "0") | 0;
|
|
8413
|
+
const rawMaxNum = getXmlText(xml, "maxNum");
|
|
8414
|
+
const maxNum = rawMaxNum !== void 0 ? Number(rawMaxNum) | 0 : maxTrackShelterNum > 0 ? maxTrackShelterNum : 4;
|
|
8415
|
+
const shelterList = [];
|
|
8416
|
+
const shelterListBlock = xml.match(
|
|
8417
|
+
/<shelterList>([\s\S]*?)<\/shelterList>/
|
|
8418
|
+
)?.[1];
|
|
8419
|
+
if (shelterListBlock) {
|
|
8420
|
+
const blocks = shelterListBlock.matchAll(
|
|
8421
|
+
/<Shelter>([\s\S]*?)<\/Shelter>/g
|
|
8422
|
+
);
|
|
8423
|
+
for (const m of blocks) {
|
|
8424
|
+
const tags = parseRectTags(m[1] ?? "");
|
|
8425
|
+
const decoded = decodeRect(tags, canvas, "id");
|
|
8426
|
+
shelterList.push(decoded);
|
|
8427
|
+
}
|
|
8428
|
+
}
|
|
8429
|
+
const trackShelterList = [];
|
|
8430
|
+
const trackBlock = xml.match(
|
|
8431
|
+
/<trackShelterList>([\s\S]*?)<\/trackShelterList>/
|
|
8432
|
+
)?.[1];
|
|
8433
|
+
if (trackBlock) {
|
|
8434
|
+
const blocks = trackBlock.matchAll(
|
|
8435
|
+
/<trackShelter>([\s\S]*?)<\/trackShelter>/g
|
|
8436
|
+
);
|
|
8437
|
+
for (const m of blocks) {
|
|
8438
|
+
const tags = parseRectTags(m[1] ?? "");
|
|
8439
|
+
const base = decodeRect(
|
|
8440
|
+
tags,
|
|
8441
|
+
canvas,
|
|
8442
|
+
"name"
|
|
8443
|
+
);
|
|
8444
|
+
trackShelterList.push({
|
|
8445
|
+
...base,
|
|
8446
|
+
pPos: Number(tags.pPos ?? -1) | 0,
|
|
8447
|
+
tPos: Number(tags.tPos ?? -1) | 0,
|
|
8448
|
+
zPos: Number(tags.zPos ?? -1) | 0
|
|
8449
|
+
});
|
|
8450
|
+
}
|
|
8451
|
+
}
|
|
8452
|
+
return {
|
|
8453
|
+
enable,
|
|
8454
|
+
maxNum,
|
|
8455
|
+
shelterList,
|
|
8456
|
+
trackEnable,
|
|
8457
|
+
maxTrackShelterNum,
|
|
8458
|
+
trackShelterList,
|
|
8459
|
+
canvas
|
|
8460
|
+
};
|
|
8461
|
+
}
|
|
8462
|
+
function denormalizeRect(rect, canvas) {
|
|
8463
|
+
const xPx = Math.min(canvas.width, Math.round(clamp01(rect.x) * canvas.width));
|
|
8464
|
+
const yPx = Math.min(canvas.height, Math.round(clamp01(rect.y) * canvas.height));
|
|
8465
|
+
const wPx = Math.min(
|
|
8466
|
+
canvas.width - xPx,
|
|
8467
|
+
Math.round(clamp01(rect.width) * canvas.width)
|
|
8468
|
+
);
|
|
8469
|
+
const hPx = Math.min(
|
|
8470
|
+
canvas.height - yPx,
|
|
8471
|
+
Math.round(clamp01(rect.height) * canvas.height)
|
|
8472
|
+
);
|
|
8473
|
+
return {
|
|
8474
|
+
topLeftX: encodeShelterCoord(xPx, canvas.width),
|
|
8475
|
+
topLeftY: encodeShelterCoord(yPx, canvas.height),
|
|
8476
|
+
width: encodeShelterCoord(wPx, canvas.width),
|
|
8477
|
+
height: encodeShelterCoord(hPx, canvas.height)
|
|
8478
|
+
};
|
|
8479
|
+
}
|
|
8480
|
+
function encodeShelterListXml(rects, canvas, maxNum) {
|
|
8481
|
+
if (maxNum <= 0) return "<shelterList />";
|
|
8482
|
+
const sorted = [...rects].sort((a, b) => a.id - b.id).slice(0, maxNum);
|
|
8483
|
+
const byId = new Map(sorted.map((r) => [r.id, r]));
|
|
8484
|
+
const parts = [];
|
|
8485
|
+
parts.push("<shelterList>");
|
|
8486
|
+
for (let id = 0; id < maxNum; id++) {
|
|
8487
|
+
const r = byId.get(id);
|
|
8488
|
+
if (r && r.enable) {
|
|
8489
|
+
const { topLeftX, topLeftY, width, height } = denormalizeRect(r, canvas);
|
|
8490
|
+
parts.push(
|
|
8491
|
+
`<Shelter><id>${id}</id><enable>1</enable><layer>${r.layer | 0}</layer><color>${r.color | 0}</color><topLeftX>${topLeftX}</topLeftX><topLeftY>${topLeftY}</topLeftY><width>${width}</width><height>${height}</height></Shelter>`
|
|
8492
|
+
);
|
|
8493
|
+
} else if (r) {
|
|
8494
|
+
const { topLeftX, topLeftY, width, height } = denormalizeRect(r, canvas);
|
|
8495
|
+
parts.push(
|
|
8496
|
+
`<Shelter><id>${id}</id><enable>0</enable><layer>${r.layer | 0}</layer><color>${r.color | 0}</color><topLeftX>${topLeftX}</topLeftX><topLeftY>${topLeftY}</topLeftY><width>${width}</width><height>${height}</height></Shelter>`
|
|
8497
|
+
);
|
|
8498
|
+
} else {
|
|
8499
|
+
parts.push(
|
|
8500
|
+
`<Shelter><id>${id}</id><enable>0</enable><layer>0</layer><color>0</color><topLeftX>0</topLeftX><topLeftY>0</topLeftY><width>0</width><height>0</height></Shelter>`
|
|
8501
|
+
);
|
|
8502
|
+
}
|
|
8503
|
+
}
|
|
8504
|
+
parts.push("</shelterList>");
|
|
8505
|
+
return parts.join("");
|
|
8506
|
+
}
|
|
8507
|
+
function encodeTrackShelterListXml(rects, canvas, maxNum) {
|
|
8508
|
+
if (maxNum <= 0) return "<trackShelterList />";
|
|
8509
|
+
const sorted = [...rects].sort((a, b) => a.id - b.id).slice(0, maxNum);
|
|
8510
|
+
const byId = new Map(sorted.map((r) => [r.id, r]));
|
|
8511
|
+
const parts = [];
|
|
8512
|
+
parts.push("<trackShelterList>");
|
|
8513
|
+
for (let id = 0; id < maxNum; id++) {
|
|
8514
|
+
const r = byId.get(id);
|
|
8515
|
+
if (r) {
|
|
8516
|
+
const { topLeftX, topLeftY, width, height } = denormalizeRect(r, canvas);
|
|
8517
|
+
parts.push(
|
|
8518
|
+
`<trackShelter><name>${id}</name><enable>${r.enable ? 1 : 0}</enable><layer>${r.layer | 0}</layer><color>${r.color | 0}</color><topLeftX>${topLeftX}</topLeftX><topLeftY>${topLeftY}</topLeftY><width>${width}</width><height>${height}</height><pPos>${r.pPos | 0}</pPos><tPos>${r.tPos | 0}</tPos><zPos>${r.zPos | 0}</zPos></trackShelter>`
|
|
8519
|
+
);
|
|
8520
|
+
} else {
|
|
8521
|
+
parts.push(
|
|
8522
|
+
`<trackShelter><name>${id}</name><enable>0</enable><layer>0</layer><color>0</color><topLeftX>0</topLeftX><topLeftY>0</topLeftY><width>0</width><height>0</height><pPos>-1</pPos><tPos>-1</tPos><zPos>-1</zPos></trackShelter>`
|
|
8523
|
+
);
|
|
8524
|
+
}
|
|
8525
|
+
}
|
|
8526
|
+
parts.push("</trackShelterList>");
|
|
8527
|
+
return parts.join("");
|
|
8528
|
+
}
|
|
8529
|
+
function patchShelterXml(shelterXml, patch, canvas, maxNum, maxTrackShelterNum) {
|
|
8530
|
+
let out = shelterXml;
|
|
8531
|
+
if (patch.enable !== void 0) {
|
|
8532
|
+
out = out.replace(
|
|
8533
|
+
/<enable>[^<]*<\/enable>/,
|
|
8534
|
+
`<enable>${patch.enable ? 1 : 0}</enable>`
|
|
8535
|
+
);
|
|
8536
|
+
}
|
|
8537
|
+
if (patch.shelterList !== void 0) {
|
|
8538
|
+
const fragment = encodeShelterListXml(patch.shelterList, canvas, maxNum);
|
|
8539
|
+
out = out.replace(/<shelterList[\s\S]*?(?:\/>|<\/shelterList>)/, fragment);
|
|
8540
|
+
}
|
|
8541
|
+
if (patch.trackEnable !== void 0) {
|
|
8542
|
+
out = out.replace(
|
|
8543
|
+
/<trackEnable>[^<]*<\/trackEnable>/,
|
|
8544
|
+
`<trackEnable>${patch.trackEnable ? 1 : 0}</trackEnable>`
|
|
8545
|
+
);
|
|
8546
|
+
}
|
|
8547
|
+
if (patch.trackShelterList !== void 0) {
|
|
8548
|
+
const fragment = encodeTrackShelterListXml(
|
|
8549
|
+
patch.trackShelterList,
|
|
8550
|
+
canvas,
|
|
8551
|
+
maxTrackShelterNum
|
|
8552
|
+
);
|
|
8553
|
+
out = out.replace(
|
|
8554
|
+
/<trackShelterList[\s\S]*?(?:\/>|<\/trackShelterList>)/,
|
|
8555
|
+
fragment
|
|
8556
|
+
);
|
|
8557
|
+
}
|
|
8558
|
+
return out;
|
|
8559
|
+
}
|
|
8560
|
+
|
|
8561
|
+
// src/reolink/baichuan/utils/aiDetectCfg.ts
|
|
8562
|
+
function decodeAiDetectCfg(xml) {
|
|
8563
|
+
const type = getXmlText(xml, "type");
|
|
8564
|
+
if (type == null) throw new Error("AiDetectCfg: missing <type>");
|
|
8565
|
+
return {
|
|
8566
|
+
chn: Number(getXmlText(xml, "chn") ?? "0") | 0,
|
|
8567
|
+
type,
|
|
8568
|
+
sensitivity: Number(getXmlText(xml, "sensitivity") ?? "0") | 0,
|
|
8569
|
+
stayTime: Number(getXmlText(xml, "stayTime") ?? "0") | 0,
|
|
8570
|
+
minTargetWidth: Number(getXmlText(xml, "minTargetWidth") ?? "0"),
|
|
8571
|
+
minTargetHeight: Number(getXmlText(xml, "minTargetHeight") ?? "0"),
|
|
8572
|
+
maxTargetWidth: Number(getXmlText(xml, "maxTargetWidth") ?? "0"),
|
|
8573
|
+
maxTargetHeight: Number(getXmlText(xml, "maxTargetHeight") ?? "0"),
|
|
8574
|
+
width: Number(getXmlText(xml, "width") ?? "0") | 0,
|
|
8575
|
+
height: Number(getXmlText(xml, "height") ?? "0") | 0,
|
|
8576
|
+
area: getXmlText(xml, "area") ?? ""
|
|
8577
|
+
};
|
|
8578
|
+
}
|
|
8579
|
+
function clamp012(value) {
|
|
8580
|
+
if (!Number.isFinite(value)) return 0;
|
|
8581
|
+
if (value < 0) return 0;
|
|
8582
|
+
if (value > 1) return 1;
|
|
8583
|
+
return value;
|
|
8584
|
+
}
|
|
8585
|
+
function fmtFraction(value) {
|
|
8586
|
+
const v = clamp012(value);
|
|
8587
|
+
const e = v.toExponential(6);
|
|
8588
|
+
return e.replace(/e([+-])(\d)$/, "e$10$2");
|
|
8589
|
+
}
|
|
8590
|
+
function patchAiDetectCfgXml(currentXml, patch) {
|
|
8591
|
+
let out = currentXml;
|
|
8592
|
+
if (patch.sensitivity !== void 0) {
|
|
8593
|
+
out = out.replace(
|
|
8594
|
+
/<sensitivity>[^<]*<\/sensitivity>/,
|
|
8595
|
+
`<sensitivity>${patch.sensitivity | 0}</sensitivity>`
|
|
8596
|
+
);
|
|
8597
|
+
}
|
|
8598
|
+
if (patch.stayTime !== void 0) {
|
|
8599
|
+
out = out.replace(
|
|
8600
|
+
/<stayTime>[^<]*<\/stayTime>/,
|
|
8601
|
+
`<stayTime>${patch.stayTime | 0}</stayTime>`
|
|
8602
|
+
);
|
|
8603
|
+
}
|
|
8604
|
+
if (patch.minTargetWidth !== void 0) {
|
|
8605
|
+
out = out.replace(
|
|
8606
|
+
/<minTargetWidth>[^<]*<\/minTargetWidth>/,
|
|
8607
|
+
`<minTargetWidth>${fmtFraction(patch.minTargetWidth)}</minTargetWidth>`
|
|
8608
|
+
);
|
|
8609
|
+
}
|
|
8610
|
+
if (patch.minTargetHeight !== void 0) {
|
|
8611
|
+
out = out.replace(
|
|
8612
|
+
/<minTargetHeight>[^<]*<\/minTargetHeight>/,
|
|
8613
|
+
`<minTargetHeight>${fmtFraction(patch.minTargetHeight)}</minTargetHeight>`
|
|
8614
|
+
);
|
|
8615
|
+
}
|
|
8616
|
+
if (patch.maxTargetWidth !== void 0) {
|
|
8617
|
+
out = out.replace(
|
|
8618
|
+
/<maxTargetWidth>[^<]*<\/maxTargetWidth>/,
|
|
8619
|
+
`<maxTargetWidth>${fmtFraction(patch.maxTargetWidth)}</maxTargetWidth>`
|
|
8620
|
+
);
|
|
8621
|
+
}
|
|
8622
|
+
if (patch.maxTargetHeight !== void 0) {
|
|
8623
|
+
out = out.replace(
|
|
8624
|
+
/<maxTargetHeight>[^<]*<\/maxTargetHeight>/,
|
|
8625
|
+
`<maxTargetHeight>${fmtFraction(patch.maxTargetHeight)}</maxTargetHeight>`
|
|
8626
|
+
);
|
|
8627
|
+
}
|
|
8628
|
+
if (patch.area !== void 0) {
|
|
8629
|
+
out = out.replace(
|
|
8630
|
+
/<area>[^<]*<\/area>/,
|
|
8631
|
+
`<area>${patch.area}</area>`
|
|
8632
|
+
);
|
|
8633
|
+
}
|
|
8634
|
+
return out;
|
|
8635
|
+
}
|
|
8636
|
+
|
|
8637
|
+
// src/reolink/baichuan/utils/motionSensitivity.ts
|
|
8638
|
+
function clampInt(value, min, max) {
|
|
8639
|
+
if (!Number.isFinite(value)) return min;
|
|
8640
|
+
return Math.min(max, Math.max(min, Math.floor(value)));
|
|
8641
|
+
}
|
|
8642
|
+
function clampSensitivity(value) {
|
|
8643
|
+
return clampInt(value, 0, 50);
|
|
8644
|
+
}
|
|
8645
|
+
function clampHour(value) {
|
|
8646
|
+
return clampInt(value, 0, 23);
|
|
8647
|
+
}
|
|
8648
|
+
function clampMinute(value) {
|
|
8649
|
+
return clampInt(value, 0, 59);
|
|
8650
|
+
}
|
|
8651
|
+
function encodeMotionSensitivityListXml(bands) {
|
|
8652
|
+
if (bands.length === 0) return "<sensitivityInfoList />";
|
|
8653
|
+
const sorted = [...bands].sort((a, b) => a.id - b.id);
|
|
8654
|
+
const parts = ["<sensitivityInfoList>"];
|
|
8655
|
+
for (const b of sorted) {
|
|
8656
|
+
parts.push(
|
|
8657
|
+
`<sensitivityInfo><id>${b.id | 0}</id><sensitivity>${clampSensitivity(b.sensitivity)}</sensitivity><beginHour>${clampHour(b.beginHour)}</beginHour><beginMinute>${clampMinute(b.beginMinute)}</beginMinute><endHour>${clampHour(b.endHour)}</endHour><endMinute>${clampMinute(b.endMinute)}</endMinute></sensitivityInfo>`
|
|
8658
|
+
);
|
|
8659
|
+
}
|
|
8660
|
+
parts.push("</sensitivityInfoList>");
|
|
8661
|
+
return parts.join("");
|
|
8662
|
+
}
|
|
8663
|
+
function patchMotionSensitivityListXml(currentXml, bands) {
|
|
8664
|
+
const fragment = encodeMotionSensitivityListXml(bands);
|
|
8665
|
+
return currentXml.replace(
|
|
8666
|
+
/<sensitivityInfoList[\s\S]*?(?:\/>|<\/sensitivityInfoList>)/,
|
|
8667
|
+
fragment
|
|
8668
|
+
);
|
|
8669
|
+
}
|
|
8670
|
+
|
|
8322
8671
|
// src/reolink/baichuan/ReolinkBaichuanApi.ts
|
|
8323
8672
|
import { spawn as spawn2 } from "child_process";
|
|
8324
8673
|
import { mkdir } from "fs/promises";
|
|
@@ -8819,15 +9168,14 @@ var getAiStateViaGetAiAlarm = async (params) => {
|
|
|
8819
9168
|
0
|
|
8820
9169
|
);
|
|
8821
9170
|
};
|
|
9171
|
+
const isSupportedResponse = (xml) => {
|
|
9172
|
+
return /<AiDetectCfg[\s>]/i.test(xml) && getXmlText(xml, "type") != null;
|
|
9173
|
+
};
|
|
8822
9174
|
for (const type of candidateTypes) {
|
|
8823
9175
|
try {
|
|
8824
9176
|
const xml = await tryOnce(type, ch);
|
|
8825
|
-
if (xml) {
|
|
8826
|
-
return {
|
|
8827
|
-
channel: ch,
|
|
8828
|
-
alarm_state: Number(getXmlText(xml, "alarm_state") ?? "0"),
|
|
8829
|
-
support: Number(getXmlText(xml, "support") ?? "0")
|
|
8830
|
-
};
|
|
9177
|
+
if (xml && isSupportedResponse(xml)) {
|
|
9178
|
+
return { channel: ch, alarm_state: 0, support: 1 };
|
|
8831
9179
|
}
|
|
8832
9180
|
} catch (e) {
|
|
8833
9181
|
if (looksLikeConnectionDrop(e)) throw e;
|
|
@@ -8837,12 +9185,8 @@ var getAiStateViaGetAiAlarm = async (params) => {
|
|
|
8837
9185
|
for (const type of candidateTypes) {
|
|
8838
9186
|
try {
|
|
8839
9187
|
const xml = await tryOnce(type, void 0);
|
|
8840
|
-
if (xml) {
|
|
8841
|
-
return {
|
|
8842
|
-
channel: ch,
|
|
8843
|
-
alarm_state: Number(getXmlText(xml, "alarm_state") ?? "0"),
|
|
8844
|
-
support: Number(getXmlText(xml, "support") ?? "0")
|
|
8845
|
-
};
|
|
9188
|
+
if (xml && isSupportedResponse(xml)) {
|
|
9189
|
+
return { channel: ch, alarm_state: 0, support: 1 };
|
|
8846
9190
|
}
|
|
8847
9191
|
} catch (e) {
|
|
8848
9192
|
if (looksLikeConnectionDrop(e)) throw e;
|
|
@@ -12924,7 +13268,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
12924
13268
|
return;
|
|
12925
13269
|
}
|
|
12926
13270
|
entry.startInFlight = (async () => {
|
|
12927
|
-
const { BaichuanVideoStream: BaichuanVideoStream2 } = await import("./BaichuanVideoStream-
|
|
13271
|
+
const { BaichuanVideoStream: BaichuanVideoStream2 } = await import("./BaichuanVideoStream-NTIGPHYJ.js");
|
|
12928
13272
|
const sessionKey = `live:object-detections:ch${entry.channel}:${entry.profile}`;
|
|
12929
13273
|
const dedicated = await this.createDedicatedSession(sessionKey);
|
|
12930
13274
|
const stream = new BaichuanVideoStream2({
|
|
@@ -14625,7 +14969,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
14625
14969
|
* Note: Snapshot uses a special message ID system for binary responses
|
|
14626
14970
|
*/
|
|
14627
14971
|
async getSnapshot(channel, options) {
|
|
14628
|
-
const cmdId =
|
|
14972
|
+
const cmdId = BC_CMD_ID_GET_SNAPSHOT;
|
|
14629
14973
|
if (channel === void 0) {
|
|
14630
14974
|
const composite = options?.compositeOptions;
|
|
14631
14975
|
const widerChannel = composite?.widerChannel ?? 0;
|
|
@@ -18228,6 +18572,12 @@ ${stderr}`)
|
|
|
18228
18572
|
`<valueTable>${opts.valueTable}</valueTable>`
|
|
18229
18573
|
);
|
|
18230
18574
|
}
|
|
18575
|
+
if (opts.sensitivitySchedule !== void 0) {
|
|
18576
|
+
modifiedXml = patchMotionSensitivityListXml(
|
|
18577
|
+
modifiedXml,
|
|
18578
|
+
opts.sensitivitySchedule
|
|
18579
|
+
);
|
|
18580
|
+
}
|
|
18231
18581
|
await this.sendXml({
|
|
18232
18582
|
cmdId: BC_CMD_ID_SET_MOTION_ALARM,
|
|
18233
18583
|
channel: ch,
|
|
@@ -18275,6 +18625,72 @@ ${stderr}`)
|
|
|
18275
18625
|
payloadXml: modifiedXml
|
|
18276
18626
|
});
|
|
18277
18627
|
}
|
|
18628
|
+
/**
|
|
18629
|
+
* SetAiDetectionFull (cmd_id=343 — same as `setAiDetection`).
|
|
18630
|
+
*
|
|
18631
|
+
* Pcap-confirmed (May 2026, E1 Zoom): the Reolink app sends the full
|
|
18632
|
+
* `<AiDetectCfg>` block via cmd_id=343 for ALL fields — area mask,
|
|
18633
|
+
* min/maxTarget* thresholds, sensitivity, stayTime — in one round-trip.
|
|
18634
|
+
* There's no separate "full setter" command (we previously suspected
|
|
18635
|
+
* cmd_id=345 but that's used for something else not yet identified).
|
|
18636
|
+
*
|
|
18637
|
+
* Wire format note: min/maxTarget* fractions are serialized in
|
|
18638
|
+
* scientific notation with 6 decimal places (e.g. "5.000000e-01" for
|
|
18639
|
+
* 0.5). The helper {@link patchAiDetectCfgXml} handles the formatting.
|
|
18640
|
+
*
|
|
18641
|
+
* @param channel 0-based channel
|
|
18642
|
+
* @param aiType one of "people" / "vehicle" / "dog_cat" / "face" / "package"
|
|
18643
|
+
* @param patch partial edit; any omitted field is preserved as-is
|
|
18644
|
+
*/
|
|
18645
|
+
async setAiDetectionFull(channel, aiType, patch) {
|
|
18646
|
+
const ch = this.normalizeChannel(channel);
|
|
18647
|
+
const resolvedAiType = await this.resolveAiTypeForSetAiDetection(
|
|
18648
|
+
ch,
|
|
18649
|
+
aiType
|
|
18650
|
+
);
|
|
18651
|
+
const getXml = `<?xml version="1.0" encoding="UTF-8" ?>
|
|
18652
|
+
<body>
|
|
18653
|
+
<AiDetectCfg version="1.1">
|
|
18654
|
+
<chn>${ch}</chn>
|
|
18655
|
+
<type>${xmlEscape(resolvedAiType)}</type>
|
|
18656
|
+
</AiDetectCfg>
|
|
18657
|
+
</body>`;
|
|
18658
|
+
const currentXml = await this.sendXml({
|
|
18659
|
+
cmdId: BC_CMD_ID_GET_AI_ALARM,
|
|
18660
|
+
channel: ch,
|
|
18661
|
+
payloadXml: getXml
|
|
18662
|
+
});
|
|
18663
|
+
const patchedXml = patchAiDetectCfgXml(currentXml, patch);
|
|
18664
|
+
await this.sendXml({
|
|
18665
|
+
cmdId: BC_CMD_ID_SET_AI_ALARM,
|
|
18666
|
+
channel: ch,
|
|
18667
|
+
payloadXml: patchedXml
|
|
18668
|
+
});
|
|
18669
|
+
}
|
|
18670
|
+
/**
|
|
18671
|
+
* GetAiDetectionFull (cmd_id=342). Typed version of `getAiAlarmRaw`
|
|
18672
|
+
* returning the full {@link AiDetectCfgZone} for a single AI type.
|
|
18673
|
+
*/
|
|
18674
|
+
async getAiDetectionFull(channel, aiType) {
|
|
18675
|
+
const ch = this.normalizeChannel(channel);
|
|
18676
|
+
const resolvedAiType = await this.resolveAiTypeForSetAiDetection(
|
|
18677
|
+
ch,
|
|
18678
|
+
aiType
|
|
18679
|
+
);
|
|
18680
|
+
const getXml = `<?xml version="1.0" encoding="UTF-8" ?>
|
|
18681
|
+
<body>
|
|
18682
|
+
<AiDetectCfg version="1.1">
|
|
18683
|
+
<chn>${ch}</chn>
|
|
18684
|
+
<type>${xmlEscape(resolvedAiType)}</type>
|
|
18685
|
+
</AiDetectCfg>
|
|
18686
|
+
</body>`;
|
|
18687
|
+
const xml = await this.sendXml({
|
|
18688
|
+
cmdId: BC_CMD_ID_GET_AI_ALARM,
|
|
18689
|
+
channel: ch,
|
|
18690
|
+
payloadXml: getXml
|
|
18691
|
+
});
|
|
18692
|
+
return decodeAiDetectCfg(xml);
|
|
18693
|
+
}
|
|
18278
18694
|
// --------------------
|
|
18279
18695
|
// Siren/Audio Alarm APIs
|
|
18280
18696
|
// --------------------
|
|
@@ -19517,7 +19933,7 @@ ${xml}`
|
|
|
19517
19933
|
* @returns Test results for all stream types and profiles
|
|
19518
19934
|
*/
|
|
19519
19935
|
async testChannelStreams(channel, logger) {
|
|
19520
|
-
const { testChannelStreams } = await import("./DiagnosticsTools-
|
|
19936
|
+
const { testChannelStreams } = await import("./DiagnosticsTools-ILDDJZL7.js");
|
|
19521
19937
|
return await testChannelStreams({
|
|
19522
19938
|
api: this,
|
|
19523
19939
|
channel: this.normalizeChannel(channel),
|
|
@@ -19533,7 +19949,7 @@ ${xml}`
|
|
|
19533
19949
|
* @returns Complete diagnostics for all channels and streams
|
|
19534
19950
|
*/
|
|
19535
19951
|
async collectMultifocalDiagnostics(logger) {
|
|
19536
|
-
const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-
|
|
19952
|
+
const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-ILDDJZL7.js");
|
|
19537
19953
|
return await collectMultifocalDiagnostics({
|
|
19538
19954
|
api: this,
|
|
19539
19955
|
logger
|
|
@@ -19855,6 +20271,69 @@ ${xml}`
|
|
|
19855
20271
|
...timeoutOpts
|
|
19856
20272
|
});
|
|
19857
20273
|
}
|
|
20274
|
+
/**
|
|
20275
|
+
* GetMaskZones (cmdId=52) returning a typed structure with normalized
|
|
20276
|
+
* 0..1 rectangles instead of the raw camera fixed-point integers.
|
|
20277
|
+
*
|
|
20278
|
+
* The camera-side coord system is `(pixel << 16) | canvas_dim` where
|
|
20279
|
+
* `canvas_dim` is the firmware-specific mask canvas (E1 Zoom = 540×304).
|
|
20280
|
+
* The returned `canvas` block remembers those dims so callers can
|
|
20281
|
+
* round-trip without re-fetching.
|
|
20282
|
+
*
|
|
20283
|
+
* @see decodePrivacyMaskZones — pure helper exported for UI consumers.
|
|
20284
|
+
*/
|
|
20285
|
+
async getMaskZones(channel, options) {
|
|
20286
|
+
const xml = await this.sendPcapDerivedSettingsGetXml({
|
|
20287
|
+
cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
|
|
20288
|
+
...channel != null ? { channel } : {},
|
|
20289
|
+
...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
|
|
20290
|
+
});
|
|
20291
|
+
return decodePrivacyMaskZones(xml);
|
|
20292
|
+
}
|
|
20293
|
+
/**
|
|
20294
|
+
* SetMaskZones (cmdId=53, read-modify-write of cmdId=52).
|
|
20295
|
+
*
|
|
20296
|
+
* Edits the rectangular shelter list and/or PTZ-tracking shelter list
|
|
20297
|
+
* in one call. Coordinates are normalized 0..1 of the camera mask
|
|
20298
|
+
* canvas — the lib re-fetches the current Shelter block, extracts the
|
|
20299
|
+
* canvas dims from the wire (low-16 of any non-zero coord), and
|
|
20300
|
+
* denormalizes back to the camera's pixel × canvas encoding.
|
|
20301
|
+
*
|
|
20302
|
+
* Pass `enable`/`trackEnable` to toggle the master enable flags without
|
|
20303
|
+
* touching the rectangle data. Pass `shelterList`/`trackShelterList` to
|
|
20304
|
+
* replace the corresponding list — missing slots are padded with
|
|
20305
|
+
* disabled zero-rects matching the camera's idle pattern.
|
|
20306
|
+
*
|
|
20307
|
+
* @param channel 0-based channel
|
|
20308
|
+
* @param patch partial edit; any omitted field is preserved as-is
|
|
20309
|
+
* @param options.canvas override the auto-detected mask canvas (only
|
|
20310
|
+
* needed when the GET response has no non-zero coords to extract from)
|
|
20311
|
+
* @param options.timeoutMs custom request timeout
|
|
20312
|
+
*/
|
|
20313
|
+
async setMaskZones(channel, patch, options) {
|
|
20314
|
+
const ch = this.normalizeChannel(channel);
|
|
20315
|
+
const timeoutOpts = options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {};
|
|
20316
|
+
const currentXml = await this.sendXml({
|
|
20317
|
+
cmdId: BC_CMD_ID_GET_PRIVACY_MASK,
|
|
20318
|
+
channel: ch,
|
|
20319
|
+
...timeoutOpts
|
|
20320
|
+
});
|
|
20321
|
+
const current = decodePrivacyMaskZones(currentXml);
|
|
20322
|
+
const canvas = options?.canvas ?? current.canvas;
|
|
20323
|
+
const patchedXml = patchShelterXml(
|
|
20324
|
+
currentXml,
|
|
20325
|
+
patch,
|
|
20326
|
+
canvas,
|
|
20327
|
+
current.maxNum,
|
|
20328
|
+
current.maxTrackShelterNum
|
|
20329
|
+
);
|
|
20330
|
+
await this.sendXml({
|
|
20331
|
+
cmdId: BC_CMD_ID_SET_PRIVACY_MASK,
|
|
20332
|
+
channel: ch,
|
|
20333
|
+
payloadXml: ensureXmlHeader(patchedXml),
|
|
20334
|
+
...timeoutOpts
|
|
20335
|
+
});
|
|
20336
|
+
}
|
|
19858
20337
|
/**
|
|
19859
20338
|
* GetAudioNoise via Baichuan (cmdId=439). Reads `enable` + `level`
|
|
19860
20339
|
* from the aiDenoise block. Mirrors reolink_aio's `GetAudioNoise`.
|
|
@@ -20541,6 +21020,18 @@ ${xml}`
|
|
|
20541
21020
|
});
|
|
20542
21021
|
return parseVersionInfo(xml);
|
|
20543
21022
|
}
|
|
21023
|
+
/**
|
|
21024
|
+
* GetUid (cmd_id=114). Returns the device UID / serial visible in the
|
|
21025
|
+
* Reolink app. Response shape: `<Uid><uid>9527000XXXXX</uid></Uid>`.
|
|
21026
|
+
* Device-global — no channel parameter.
|
|
21027
|
+
*/
|
|
21028
|
+
async getUid(options) {
|
|
21029
|
+
const xml = await this.sendXml({
|
|
21030
|
+
cmdId: BC_CMD_ID_GET_UID,
|
|
21031
|
+
...options?.timeoutMs != null ? { timeoutMs: options.timeoutMs } : {}
|
|
21032
|
+
});
|
|
21033
|
+
return (getXmlText(xml, "uid") ?? "").trim();
|
|
21034
|
+
}
|
|
20544
21035
|
async getLedState(channel, options) {
|
|
20545
21036
|
const rawXml = await this.sendPcapDerivedSettingsGetXml({
|
|
20546
21037
|
cmdId: BC_CMD_ID_GET_LED_STATE,
|
|
@@ -23985,6 +24476,18 @@ export {
|
|
|
23985
24476
|
computeDeviceCapabilities,
|
|
23986
24477
|
xmlIndicatesFloodlight,
|
|
23987
24478
|
decideSleepInferenceTransition,
|
|
24479
|
+
DEFAULT_SHELTER_CANVAS,
|
|
24480
|
+
decodeShelterCoord,
|
|
24481
|
+
encodeShelterCoord,
|
|
24482
|
+
extractCanvasFromShelterXml,
|
|
24483
|
+
decodePrivacyMaskZones,
|
|
24484
|
+
encodeShelterListXml,
|
|
24485
|
+
encodeTrackShelterListXml,
|
|
24486
|
+
patchShelterXml,
|
|
24487
|
+
decodeAiDetectCfg,
|
|
24488
|
+
patchAiDetectCfgXml,
|
|
24489
|
+
encodeMotionSensitivityListXml,
|
|
24490
|
+
patchMotionSensitivityListXml,
|
|
23988
24491
|
DUAL_LENS_DUAL_MOTION_MODELS,
|
|
23989
24492
|
DUAL_LENS_SINGLE_MOTION_MODELS,
|
|
23990
24493
|
DUAL_LENS_MODELS,
|
|
@@ -24006,4 +24509,4 @@ export {
|
|
|
24006
24509
|
isTcpFailureThatShouldFallbackToUdp,
|
|
24007
24510
|
autoDetectDeviceType
|
|
24008
24511
|
};
|
|
24009
|
-
//# sourceMappingURL=chunk-
|
|
24512
|
+
//# sourceMappingURL=chunk-JYHK2ZSH.js.map
|