@camstack/addon-provider-reolink 1.2.138 → 1.2.140
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-2M4UO7MB-CB-tIHMA.mjs +2 -0
- package/dist/BaichuanVideoStream-2M4UO7MB-Cqjt1oxu.js +3 -0
- package/dist/addon.js +807 -302
- package/dist/addon.mjs +657 -152
- package/dist/{chunk-KWWUCNIY-Ccq-OAGJ.mjs → chunk-ZQFQRCLQ-BNqCZtSS.mjs} +1 -1
- package/dist/{chunk-KWWUCNIY-BtO6U6BT.js → chunk-ZQFQRCLQ-CR7OOtpp.js} +1 -1
- package/package.json +2 -2
- package/dist/BaichuanVideoStream-PBJL3EB5-D-etWPiW.mjs +0 -2
- package/dist/BaichuanVideoStream-PBJL3EB5-qv_JKCPo.js +0 -3
- /package/dist/{DiagnosticsTools-TID5M22B-9NV95vRN.mjs → DiagnosticsTools-GOFDNGAY-9NV95vRN.mjs} +0 -0
- /package/dist/{DiagnosticsTools-TID5M22B-CD4rRF8a.js → DiagnosticsTools-GOFDNGAY-CD4rRF8a.js} +0 -0
package/dist/addon.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const
|
|
3
|
+
const require_chunk_ZQFQRCLQ = require("./chunk-ZQFQRCLQ-CR7OOtpp.js");
|
|
4
4
|
let node_crypto = require("node:crypto");
|
|
5
5
|
let events = require("events");
|
|
6
6
|
let fs = require("fs");
|
|
@@ -5386,7 +5386,7 @@ var ZodIssueCode = {
|
|
|
5386
5386
|
var ZodFirstPartyTypeKind;
|
|
5387
5387
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5388
5388
|
//#endregion
|
|
5389
|
-
//#region ../types/dist/sleep-
|
|
5389
|
+
//#region ../types/dist/sleep-vl6nBE8d.mjs
|
|
5390
5390
|
/**
|
|
5391
5391
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5392
5392
|
* window to float samples (D455).
|
|
@@ -31657,14 +31657,81 @@ function summarisePrivacyAudio(profiles) {
|
|
|
31657
31657
|
if (profiles.length === 0) return null;
|
|
31658
31658
|
return profiles.some((p) => p.audioEnabled);
|
|
31659
31659
|
}
|
|
31660
|
+
/**
|
|
31661
|
+
* What a preset id DOES on this camera.
|
|
31662
|
+
*
|
|
31663
|
+
* On several PTZ firmwares the preset namespace is shared: low ids are stored
|
|
31664
|
+
* positions, a reserved band triggers camera FUNCTIONS. The dispensa camera
|
|
31665
|
+
* (Hikvision) returns its own reserved band in the preset list, named by the
|
|
31666
|
+
* firmware:
|
|
31667
|
+
*
|
|
31668
|
+
* 34 Back to origin · 39 Day mode · 40 Night mode · 46 Day/Night Auto Mode
|
|
31669
|
+
* 92 Set manual limits · 93 Save manual limits · 94 Remote reboot
|
|
31670
|
+
* 95 Call OSD menu
|
|
31671
|
+
*
|
|
31672
|
+
* We used to hand all of these to the UI as ordinary presets. Saving over one
|
|
31673
|
+
* is what produced `PUT /ISAPI/PTZCtrl/channels/1/presets/34 -> HTTP 500`: the
|
|
31674
|
+
* camera refusing to let "Back to origin" be overwritten, surfaced to the
|
|
31675
|
+
* operator as a transport failure.
|
|
31676
|
+
*
|
|
31677
|
+
* A function preset stays fully usable as a DESTINATION -- `goToPreset('34')`
|
|
31678
|
+
* is the single most useful thing that camera can do. Only `savePreset` and
|
|
31679
|
+
* `deletePreset` are gated.
|
|
31680
|
+
*/
|
|
31681
|
+
var PtzPresetFunctionSchema = _enum([
|
|
31682
|
+
"home",
|
|
31683
|
+
"day-mode",
|
|
31684
|
+
"night-mode",
|
|
31685
|
+
"day-night-auto",
|
|
31686
|
+
"set-limits",
|
|
31687
|
+
"save-limits",
|
|
31688
|
+
"reboot",
|
|
31689
|
+
"osd-menu"
|
|
31690
|
+
]);
|
|
31660
31691
|
var PtzPresetSchema = object({
|
|
31661
31692
|
id: string(),
|
|
31662
|
-
name: string()
|
|
31693
|
+
name: string(),
|
|
31694
|
+
/**
|
|
31695
|
+
* The firmware function this id performs, when the provider KNOWS the id is
|
|
31696
|
+
* reserved. `null` = an ordinary stored position, OR a reserved id this
|
|
31697
|
+
* provider does not recognise -- the two are told apart by `writable`.
|
|
31698
|
+
*/
|
|
31699
|
+
fn: PtzPresetFunctionSchema.nullable(),
|
|
31700
|
+
/**
|
|
31701
|
+
* Whether `savePreset` / `deletePreset` may target this id. A provider sets
|
|
31702
|
+
* it false only for a band it KNOWS is reserved; where the firmware is not
|
|
31703
|
+
* documented it stays true and a refusal comes from the camera, named.
|
|
31704
|
+
*/
|
|
31705
|
+
writable: boolean()
|
|
31663
31706
|
});
|
|
31707
|
+
/**
|
|
31708
|
+
* Where the head is pointing -- per axis, and `null` when the driver cannot
|
|
31709
|
+
* read it.
|
|
31710
|
+
*
|
|
31711
|
+
* It used to be three REQUIRED numbers, which left a provider that cannot read
|
|
31712
|
+
* position no way to say so. All four said `0`:
|
|
31713
|
+
*
|
|
31714
|
+
* reolink `return { pan: 0, tilt: 0, zoom: 0 }` "until a position-query
|
|
31715
|
+
* path lands upstream"
|
|
31716
|
+
* hikvision stub, "firmware-dependent and frequently absent"
|
|
31717
|
+
* amcrest stub, "no generic absolute-position read for this model family"
|
|
31718
|
+
* onvif throws
|
|
31719
|
+
*
|
|
31720
|
+
* So every consumer asking where a camera points was told "perfectly centred"
|
|
31721
|
+
* by four cameras that had never looked. That is D393 -- a measurement that
|
|
31722
|
+
* FAILED is `null`, never `0`, and the type says so all the way to the
|
|
31723
|
+
* decision -- the same shape as the unreadable `statfs` folded into "0 bytes of
|
|
31724
|
+
* headroom", which evacuated a healthy disk.
|
|
31725
|
+
*
|
|
31726
|
+
* D393 also says to check for a narrower structural TWIN of the result type.
|
|
31727
|
+
* There is one: `PtzStatusSchema` extends this, so the lie had already
|
|
31728
|
+
* propagated into `getStatus`, which is the surface `getPosition`'s own comment
|
|
31729
|
+
* tells callers to migrate to.
|
|
31730
|
+
*/
|
|
31664
31731
|
var PtzPositionSchema = object({
|
|
31665
|
-
pan: number(),
|
|
31666
|
-
tilt: number(),
|
|
31667
|
-
zoom: number()
|
|
31732
|
+
pan: number().nullable(),
|
|
31733
|
+
tilt: number().nullable(),
|
|
31734
|
+
zoom: number().nullable()
|
|
31668
31735
|
});
|
|
31669
31736
|
var PtzMoveCommandSchema = object({
|
|
31670
31737
|
pan: number().optional(),
|
|
@@ -31686,7 +31753,72 @@ var PtzOptionsSchema = object({
|
|
|
31686
31753
|
maxPresets: number().optional(),
|
|
31687
31754
|
/** Whether the camera exposes a controllable autofocus toggle
|
|
31688
31755
|
* (boolean `hasX` per the getOptions availability convention). */
|
|
31689
|
-
hasAutofocus: boolean()
|
|
31756
|
+
hasAutofocus: boolean(),
|
|
31757
|
+
/**
|
|
31758
|
+
* How many distinct speeds this camera's NATIVE scale offers.
|
|
31759
|
+
*
|
|
31760
|
+
* The cap's `speed` is normalized 0..1 and each provider maps it down --
|
|
31761
|
+
* Baichuan 1..63, Dahua 1..8, ISAPI's percentage -100..100. The normalized
|
|
31762
|
+
* value hides how coarse that really is: asking an amcrest for `0.37` is
|
|
31763
|
+
* meaningless, because it has eight steps and three of them round to the
|
|
31764
|
+
* same one. A loop that tunes its own gain has to know the granularity of
|
|
31765
|
+
* the knob it is turning.
|
|
31766
|
+
*
|
|
31767
|
+
* `null` = the driver does not know, or the scale is continuous (ONVIF takes
|
|
31768
|
+
* a float). Never a made-up number.
|
|
31769
|
+
*/
|
|
31770
|
+
speedSteps: number().int().positive().nullable(),
|
|
31771
|
+
/**
|
|
31772
|
+
* How long ONE `move` pulse runs on this driver, ms.
|
|
31773
|
+
*
|
|
31774
|
+
* `move` is a self-terminating burst everywhere, but every provider hardcoded
|
|
31775
|
+
* its own duration in private -- 200 reolink, 350 amcrest, 500 hikvision,
|
|
31776
|
+
* 1000 onvif -- so no caller could read it. It is the DENOMINATOR of "how far
|
|
31777
|
+
* did the head travel per pulse": without it a measured displacement has no
|
|
31778
|
+
* gain to be divided into.
|
|
31779
|
+
*
|
|
31780
|
+
* `null` = the driver cannot say.
|
|
31781
|
+
*/
|
|
31782
|
+
moveImpulseMs: number().int().positive().nullable()
|
|
31783
|
+
});
|
|
31784
|
+
/**
|
|
31785
|
+
* Which preset `goHome` goes to, and WHO decided.
|
|
31786
|
+
*
|
|
31787
|
+
* `goHome` used to be three vendor "conventions" written in three comments --
|
|
31788
|
+
* Reolink preset 0, Hikvision preset '1', Dahua preset 1 -- and on this fleet
|
|
31789
|
+
* not one of the three cameras honours its own:
|
|
31790
|
+
*
|
|
31791
|
+
* 592 Videocamera camera Daniel (reolink) preset 0 holds "stanza"
|
|
31792
|
+
* 1438 Videocamera dispensa (hikvision) preset 1 holds "Credenza"
|
|
31793
|
+
* 3836 Videocamera studio (amcrest) preset 1 holds "Preset1"
|
|
31794
|
+
*
|
|
31795
|
+
* So `goHome` meant "go wherever the operator happened to save in slot 0 or 1",
|
|
31796
|
+
* and two of the three swallowed the failure in a bare `catch`. For autotrack
|
|
31797
|
+
* this is the HOTTEST path -- it runs every time a subject is released -- so it
|
|
31798
|
+
* needs an answer that is true per camera and audible when it is missing.
|
|
31799
|
+
*
|
|
31800
|
+
* `source` is what makes it honest:
|
|
31801
|
+
* - `operator` -- picked in the UI, stored by the provider.
|
|
31802
|
+
* - `firmware` -- the camera itself named a preset `fn: 'home'` (Hikvision's
|
|
31803
|
+
* "Back to origin"), adopted as the default with nothing to configure.
|
|
31804
|
+
* - `native` -- the driver homes WITHOUT a preset at all. ONVIF does:
|
|
31805
|
+
* `goHome` is `ptzAbsoluteMove({x:0, y:0, zoom:0})`. `presetId` is null and
|
|
31806
|
+
* that is not a failure -- there is nothing to pick, and the UI must offer
|
|
31807
|
+
* no picker.
|
|
31808
|
+
* - `none` -- nothing is configured and the camera names nothing.
|
|
31809
|
+
* `goHome` REFUSES rather than moving the head somewhere arbitrary.
|
|
31810
|
+
*
|
|
31811
|
+
* `source === 'none'` is the refusal condition, NOT `presetId === null`: the
|
|
31812
|
+
* native case has no preset and homes perfectly well.
|
|
31813
|
+
*/
|
|
31814
|
+
var PtzHomePresetSchema = object({
|
|
31815
|
+
presetId: string().nullable(),
|
|
31816
|
+
source: _enum([
|
|
31817
|
+
"operator",
|
|
31818
|
+
"firmware",
|
|
31819
|
+
"native",
|
|
31820
|
+
"none"
|
|
31821
|
+
])
|
|
31690
31822
|
});
|
|
31691
31823
|
var ptzCapability = {
|
|
31692
31824
|
name: "ptz",
|
|
@@ -31727,7 +31859,66 @@ var ptzCapability = {
|
|
|
31727
31859
|
auth: "admin"
|
|
31728
31860
|
}),
|
|
31729
31861
|
getOptions: method(object({ deviceId: number() }), PtzOptionsSchema),
|
|
31862
|
+
/**
|
|
31863
|
+
* Move to the camera's configured home preset. THROWS when
|
|
31864
|
+
* `getHomePreset()` resolves to `none` -- a head that did not move must
|
|
31865
|
+
* never look like a head that went home.
|
|
31866
|
+
*/
|
|
31730
31867
|
goHome: method(object({ deviceId: number() }), _void(), { kind: "mutation" }),
|
|
31868
|
+
/** Which preset `goHome` targets, and who decided it. */
|
|
31869
|
+
getHomePreset: method(object({ deviceId: number() }), PtzHomePresetSchema),
|
|
31870
|
+
/**
|
|
31871
|
+
* Pin the home preset for this camera. `null` clears the operator's choice
|
|
31872
|
+
* and falls back to whatever the firmware names, or to `none`.
|
|
31873
|
+
*/
|
|
31874
|
+
setHomePreset: method(object({
|
|
31875
|
+
deviceId: number(),
|
|
31876
|
+
presetId: string().nullable()
|
|
31877
|
+
}), _void(), {
|
|
31878
|
+
kind: "mutation",
|
|
31879
|
+
auth: "admin"
|
|
31880
|
+
}),
|
|
31881
|
+
/**
|
|
31882
|
+
* Make WHERE THE HEAD IS POINTING RIGHT NOW this camera's home.
|
|
31883
|
+
*
|
|
31884
|
+
* `setHomePreset` takes a preset id, and a preset id is the wrong shape for
|
|
31885
|
+
* the most natural thing an operator does: aim the camera, then say "here".
|
|
31886
|
+
* It is also the only shape a camera whose home is NOT a preset can accept
|
|
31887
|
+
* -- Reolink's home is a guard point, a stored position with no id at all,
|
|
31888
|
+
* and hiding the control for that case (as the UI briefly did) left the one
|
|
31889
|
+
* vendor with a native home unable to set it.
|
|
31890
|
+
*
|
|
31891
|
+
* Each provider does it its own way:
|
|
31892
|
+
* reolink `setGrd` with `needSetPos`, pinning the guard point here
|
|
31893
|
+
* hikvision / amcrest save a preset, then pin it as home
|
|
31894
|
+
* onvif REFUSES -- its home is the PTZ origin and cannot be moved
|
|
31895
|
+
*
|
|
31896
|
+
* A provider that cannot honour it throws rather than silently doing
|
|
31897
|
+
* nothing: an operator who pressed "set home here" and saw no error would
|
|
31898
|
+
* believe it took.
|
|
31899
|
+
*/
|
|
31900
|
+
captureHomeHere: method(object({ deviceId: number() }), _void(), {
|
|
31901
|
+
kind: "mutation",
|
|
31902
|
+
auth: "admin"
|
|
31903
|
+
}),
|
|
31904
|
+
/**
|
|
31905
|
+
* How long the camera waits, idle, before returning home on its own --
|
|
31906
|
+
* `null` when it has no such behaviour.
|
|
31907
|
+
*
|
|
31908
|
+
* Reolink's guard point carries one (`timeout`, freely settable in
|
|
31909
|
+
* seconds). It is a real function of the camera that we did not expose at
|
|
31910
|
+
* all, and it belongs next to the home it governs rather than in a vendor
|
|
31911
|
+
* settings page nobody associates with Home.
|
|
31912
|
+
*/
|
|
31913
|
+
getHomeReturnSeconds: method(object({ deviceId: number() }), number().int().nullable()),
|
|
31914
|
+
/** Set the idle-return delay. Refused by a camera that has no such timer. */
|
|
31915
|
+
setHomeReturnSeconds: method(object({
|
|
31916
|
+
deviceId: number(),
|
|
31917
|
+
seconds: number().int().min(0).max(3600)
|
|
31918
|
+
}), _void(), {
|
|
31919
|
+
kind: "mutation",
|
|
31920
|
+
auth: "admin"
|
|
31921
|
+
}),
|
|
31731
31922
|
/**
|
|
31732
31923
|
* Pull the current PTZ position. Redundant with the auto-injected
|
|
31733
31924
|
* `getStatus` method (see `status` below); kept for callers that
|
|
@@ -41386,6 +41577,12 @@ Object.freeze({
|
|
|
41386
41577
|
addonId: null,
|
|
41387
41578
|
access: "create"
|
|
41388
41579
|
},
|
|
41580
|
+
"ptz.captureHomeHere": {
|
|
41581
|
+
capName: "ptz",
|
|
41582
|
+
capScope: "device",
|
|
41583
|
+
addonId: null,
|
|
41584
|
+
access: "create"
|
|
41585
|
+
},
|
|
41389
41586
|
"ptz.continuousMove": {
|
|
41390
41587
|
capName: "ptz",
|
|
41391
41588
|
capScope: "device",
|
|
@@ -41398,6 +41595,18 @@ Object.freeze({
|
|
|
41398
41595
|
addonId: null,
|
|
41399
41596
|
access: "delete"
|
|
41400
41597
|
},
|
|
41598
|
+
"ptz.getHomePreset": {
|
|
41599
|
+
capName: "ptz",
|
|
41600
|
+
capScope: "device",
|
|
41601
|
+
addonId: null,
|
|
41602
|
+
access: "view"
|
|
41603
|
+
},
|
|
41604
|
+
"ptz.getHomeReturnSeconds": {
|
|
41605
|
+
capName: "ptz",
|
|
41606
|
+
capScope: "device",
|
|
41607
|
+
addonId: null,
|
|
41608
|
+
access: "view"
|
|
41609
|
+
},
|
|
41401
41610
|
"ptz.getOptions": {
|
|
41402
41611
|
capName: "ptz",
|
|
41403
41612
|
capScope: "device",
|
|
@@ -41446,6 +41655,18 @@ Object.freeze({
|
|
|
41446
41655
|
addonId: null,
|
|
41447
41656
|
access: "create"
|
|
41448
41657
|
},
|
|
41658
|
+
"ptz.setHomePreset": {
|
|
41659
|
+
capName: "ptz",
|
|
41660
|
+
capScope: "device",
|
|
41661
|
+
addonId: null,
|
|
41662
|
+
access: "create"
|
|
41663
|
+
},
|
|
41664
|
+
"ptz.setHomeReturnSeconds": {
|
|
41665
|
+
capName: "ptz",
|
|
41666
|
+
capScope: "device",
|
|
41667
|
+
addonId: null,
|
|
41668
|
+
access: "create"
|
|
41669
|
+
},
|
|
41449
41670
|
"ptz.stop": {
|
|
41450
41671
|
capName: "ptz",
|
|
41451
41672
|
capScope: "device",
|
|
@@ -44609,6 +44830,11 @@ Object.freeze({
|
|
|
44609
44830
|
form: "single",
|
|
44610
44831
|
optional: false
|
|
44611
44832
|
}],
|
|
44833
|
+
"ptz.captureHomeHere": [{
|
|
44834
|
+
name: "deviceId",
|
|
44835
|
+
form: "single",
|
|
44836
|
+
optional: false
|
|
44837
|
+
}],
|
|
44612
44838
|
"ptz.continuousMove": [{
|
|
44613
44839
|
name: "deviceId",
|
|
44614
44840
|
form: "single",
|
|
@@ -44619,6 +44845,16 @@ Object.freeze({
|
|
|
44619
44845
|
form: "single",
|
|
44620
44846
|
optional: false
|
|
44621
44847
|
}],
|
|
44848
|
+
"ptz.getHomePreset": [{
|
|
44849
|
+
name: "deviceId",
|
|
44850
|
+
form: "single",
|
|
44851
|
+
optional: false
|
|
44852
|
+
}],
|
|
44853
|
+
"ptz.getHomeReturnSeconds": [{
|
|
44854
|
+
name: "deviceId",
|
|
44855
|
+
form: "single",
|
|
44856
|
+
optional: false
|
|
44857
|
+
}],
|
|
44622
44858
|
"ptz.getOptions": [{
|
|
44623
44859
|
name: "deviceId",
|
|
44624
44860
|
form: "single",
|
|
@@ -44659,6 +44895,16 @@ Object.freeze({
|
|
|
44659
44895
|
form: "single",
|
|
44660
44896
|
optional: false
|
|
44661
44897
|
}],
|
|
44898
|
+
"ptz.setHomePreset": [{
|
|
44899
|
+
name: "deviceId",
|
|
44900
|
+
form: "single",
|
|
44901
|
+
optional: false
|
|
44902
|
+
}],
|
|
44903
|
+
"ptz.setHomeReturnSeconds": [{
|
|
44904
|
+
name: "deviceId",
|
|
44905
|
+
form: "single",
|
|
44906
|
+
optional: false
|
|
44907
|
+
}],
|
|
44662
44908
|
"ptz.stop": [{
|
|
44663
44909
|
name: "deviceId",
|
|
44664
44910
|
form: "single",
|
|
@@ -68343,7 +68589,7 @@ var require_yazl = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) => {
|
|
|
68343
68589
|
}
|
|
68344
68590
|
}));
|
|
68345
68591
|
//#endregion
|
|
68346
|
-
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-
|
|
68592
|
+
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-KWQVN7H5.js
|
|
68347
68593
|
var import_undici = require_undici();
|
|
68348
68594
|
var import_yazl = /* @__PURE__ */ require_chunk.__toESM(require_yazl(), 1);
|
|
68349
68595
|
var FLAGS_CAM_V2 = {
|
|
@@ -69620,13 +69866,13 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69620
69866
|
sec: 59
|
|
69621
69867
|
};
|
|
69622
69868
|
}
|
|
69623
|
-
|
|
69869
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Date conversion: start=${start.toISOString()} -> ReolinkTime=${JSON.stringify(startTime)}, end=${end.toISOString()} -> ReolinkTime=${JSON.stringify(endTime)}`);
|
|
69624
69870
|
if (!bypassCache) {
|
|
69625
69871
|
this.cleanRecordingsCache();
|
|
69626
69872
|
const cacheKey = this.getNvrRecordingsCacheKey(channel, startTime, endTime, streamType, iLogicChannel, autoSearchByDay);
|
|
69627
69873
|
const cached = this.recordingsCache.get(cacheKey);
|
|
69628
69874
|
if (cached && cached.expiresAt > Date.now()) {
|
|
69629
|
-
|
|
69875
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Cache hit: returning ${cached.data.length} cached enriched recordings`);
|
|
69630
69876
|
return cached.data;
|
|
69631
69877
|
}
|
|
69632
69878
|
}
|
|
@@ -69678,7 +69924,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69678
69924
|
const firstResult = dayResponse[0];
|
|
69679
69925
|
if (firstResult && firstResult.code === 0 && firstResult.value?.SearchResult?.File) {
|
|
69680
69926
|
const files = firstResult.value.SearchResult.File;
|
|
69681
|
-
if (files.length > 0 && files[0])
|
|
69927
|
+
if (files.length > 0 && files[0]) require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Raw API response for day ${day}/${month}/${year}: ${JSON.stringify({
|
|
69682
69928
|
fileCount: files.length,
|
|
69683
69929
|
sampleFile: {
|
|
69684
69930
|
name: files[0].name,
|
|
@@ -69714,7 +69960,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69714
69960
|
} catch (e) {}
|
|
69715
69961
|
enriched2.push(this.enrichVodFile(vodFile, channel, streamUrl));
|
|
69716
69962
|
}
|
|
69717
|
-
|
|
69963
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Returning ${enriched2.length} enriched recording files from autoSearchByDay`);
|
|
69718
69964
|
if (!bypassCache) {
|
|
69719
69965
|
const cacheKey = this.getNvrRecordingsCacheKey(channel, startTime, endTime, streamType, iLogicChannel, autoSearchByDay);
|
|
69720
69966
|
this.recordingsCache.set(cacheKey, {
|
|
@@ -69742,7 +69988,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69742
69988
|
const response = await this.call("Search", param, 0);
|
|
69743
69989
|
allResults.push(...response);
|
|
69744
69990
|
} else {
|
|
69745
|
-
|
|
69991
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Range spans ${dayRanges.length} days, splitting into separate day queries`);
|
|
69746
69992
|
for (const range of dayRanges) {
|
|
69747
69993
|
const param = { Search: {
|
|
69748
69994
|
channel,
|
|
@@ -69752,7 +69998,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69752
69998
|
EndTime: range.end
|
|
69753
69999
|
} };
|
|
69754
70000
|
if (iLogicChannel > 0) param.Search.iLogicChannel = iLogicChannel;
|
|
69755
|
-
|
|
70001
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Querying day: ${range.start.year}-${range.start.mon}-${range.start.day} (${range.start.hour}:${range.start.min}:${range.start.sec} to ${range.end.hour}:${range.end.min}:${range.end.sec})`);
|
|
69756
70002
|
const response = await this.call("Search", param, 0);
|
|
69757
70003
|
allResults.push(...response);
|
|
69758
70004
|
}
|
|
@@ -69762,7 +70008,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69762
70008
|
const firstResult = result[0];
|
|
69763
70009
|
if (firstResult && firstResult.code === 0 && firstResult.value?.SearchResult?.File) {
|
|
69764
70010
|
const files = firstResult.value.SearchResult.File;
|
|
69765
|
-
if (files.length > 0 && files[0])
|
|
70011
|
+
if (files.length > 0 && files[0]) require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Raw API response (normal search): ${JSON.stringify({
|
|
69766
70012
|
fileCount: files.length,
|
|
69767
70013
|
sampleFile: {
|
|
69768
70014
|
name: files[0].name,
|
|
@@ -69779,12 +70025,12 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69779
70025
|
const searchResult = res.value?.SearchResult;
|
|
69780
70026
|
if (searchResult?.File) allFiles.push(...searchResult.File);
|
|
69781
70027
|
}
|
|
69782
|
-
|
|
70028
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Collected ${allFiles.length} raw VodFiles from API search results`);
|
|
69783
70029
|
if (allFiles.length > 0) {
|
|
69784
70030
|
const sampleSize = Math.min(3, allFiles.length);
|
|
69785
70031
|
for (let i = 0; i < sampleSize; i++) {
|
|
69786
70032
|
const file = allFiles[i];
|
|
69787
|
-
if (file)
|
|
70033
|
+
if (file) require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Sample file ${i + 1}/${allFiles.length}: ${JSON.stringify({
|
|
69788
70034
|
name: file.name,
|
|
69789
70035
|
type: file.type,
|
|
69790
70036
|
size: file.size,
|
|
@@ -69807,7 +70053,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69807
70053
|
} catch (e) {}
|
|
69808
70054
|
enriched.push(this.enrichVodFile(vodFile, channel, streamUrl));
|
|
69809
70055
|
}
|
|
69810
|
-
|
|
70056
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Returning ${enriched.length} enriched recording files`);
|
|
69811
70057
|
if (!bypassCache) {
|
|
69812
70058
|
const cacheKey = this.getNvrRecordingsCacheKey(channel, startTime, endTime, streamType, iLogicChannel, autoSearchByDay);
|
|
69813
70059
|
this.recordingsCache.set(cacheKey, {
|
|
@@ -69844,7 +70090,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69844
70090
|
prepare: true,
|
|
69845
70091
|
seek: seekSeconds
|
|
69846
70092
|
});
|
|
69847
|
-
|
|
70093
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclipThumbnailJpeg", `Extracting thumbnail from VOD URL (FLV): ${vodUrl.substring(0, 100)}... (seek=${seekSeconds}s)`);
|
|
69848
70094
|
const { spawn: spawn2 } = await import("child_process");
|
|
69849
70095
|
return new Promise((resolve, reject) => {
|
|
69850
70096
|
const chunks = [];
|
|
@@ -69892,7 +70138,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69892
70138
|
reject(/* @__PURE__ */ new Error(`ffmpeg produced too small output: ${jpeg.length} bytes`));
|
|
69893
70139
|
return;
|
|
69894
70140
|
}
|
|
69895
|
-
|
|
70141
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclipThumbnailJpeg", `Successfully extracted thumbnail: ${jpeg.length} bytes`);
|
|
69896
70142
|
resolve(jpeg);
|
|
69897
70143
|
} else reject(/* @__PURE__ */ new Error(`ffmpeg exited with code ${code}: ${stderr.slice(-500)}`));
|
|
69898
70144
|
});
|
|
@@ -69941,10 +70187,10 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69941
70187
|
}
|
|
69942
70188
|
} }
|
|
69943
70189
|
}];
|
|
69944
|
-
|
|
70190
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "prepareNvrVodDownload", `Request body: ${JSON.stringify(body)}`);
|
|
69945
70191
|
try {
|
|
69946
70192
|
const response = await this.callMany(body);
|
|
69947
|
-
|
|
70193
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "prepareNvrVodDownload", `Response: ${JSON.stringify(response)}`);
|
|
69948
70194
|
const first = response[0];
|
|
69949
70195
|
if (!first || first.code !== 0 || !first.value?.fileList) {
|
|
69950
70196
|
const rspCode = first?.error?.rspCode;
|
|
@@ -69965,7 +70211,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69965
70211
|
if (!filename) throw new Error(`NvrDownload: no files found in response`);
|
|
69966
70212
|
return filename;
|
|
69967
70213
|
} catch (error) {
|
|
69968
|
-
|
|
70214
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "prepareNvrVodDownload", `Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
69969
70215
|
throw error;
|
|
69970
70216
|
}
|
|
69971
70217
|
}
|
|
@@ -70161,7 +70407,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70161
70407
|
* Convert a VodFile to RecordingFile with parsed metadata.
|
|
70162
70408
|
*/
|
|
70163
70409
|
enrichVodFile(vodFile, channel, streamUrl) {
|
|
70164
|
-
|
|
70410
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `RAW VodFile from API: ${JSON.stringify({
|
|
70165
70411
|
name: vodFile.name,
|
|
70166
70412
|
type: vodFile.type,
|
|
70167
70413
|
size: vodFile.size,
|
|
@@ -70214,7 +70460,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70214
70460
|
hashBits0to15: hashRevBin.slice(0, 16)
|
|
70215
70461
|
};
|
|
70216
70462
|
}
|
|
70217
|
-
|
|
70463
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Parsed filename: ${JSON.stringify({
|
|
70218
70464
|
fileName: vodFile.name,
|
|
70219
70465
|
filenameParts,
|
|
70220
70466
|
hexValueFromFilename,
|
|
@@ -70241,13 +70487,13 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70241
70487
|
const hexFlags = parsed?.flags;
|
|
70242
70488
|
if (parsed?.devType === "hub" && parsed?.version === 4) {
|
|
70243
70489
|
if (hexValueFromFilename && hexValueFromFilename !== "unknown") {
|
|
70244
|
-
|
|
70245
|
-
|
|
70490
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `WARNING: Hub v4 hex value "${hexValueFromFilename}" appears to be constant across files. Detection flags are likely NOT encoded in filename for this version. Detection information may need to be retrieved via a separate API call or may not be available.`);
|
|
70491
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `NOTE: For Hub v4, the API response only provides 'type' field which is "${vodFile.type}". No detection-specific fields are available in the Search API response.`);
|
|
70246
70492
|
}
|
|
70247
70493
|
}
|
|
70248
|
-
|
|
70494
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Hex flags from filename: ${JSON.stringify(hexFlags)}`);
|
|
70249
70495
|
const typeFlags = this.parseRecordTypeFlags(vodFile.type);
|
|
70250
|
-
|
|
70496
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Type flags from recordType "${vodFile.type}": ${JSON.stringify(typeFlags)}`);
|
|
70251
70497
|
const hasPerson = (hexFlags?.aiPerson ?? false) || typeFlags.hasPerson;
|
|
70252
70498
|
const hasVehicle = (hexFlags?.aiVehicle ?? false) || typeFlags.hasVehicle;
|
|
70253
70499
|
const hasAnimal = (hexFlags?.aiAnimal ?? false) || typeFlags.hasAnimal;
|
|
@@ -70258,7 +70504,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70258
70504
|
const hasPackage = (hexFlags?.package ?? false) || typeFlags.hasPackage;
|
|
70259
70505
|
const hasRf = (hexFlags?.rf ?? false) || typeFlags.hasRf;
|
|
70260
70506
|
const hasOther = (hexFlags?.aiOther ?? false) || typeFlags.hasOther;
|
|
70261
|
-
|
|
70507
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Final merged flags: ${JSON.stringify({
|
|
70262
70508
|
hasPerson,
|
|
70263
70509
|
hasVehicle,
|
|
70264
70510
|
hasAnimal,
|
|
@@ -70664,8 +70910,8 @@ function nowIsoCompact() {
|
|
|
70664
70910
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
70665
70911
|
}
|
|
70666
70912
|
function nalTypesSummary(videoType, accessUnitAnnexB) {
|
|
70667
|
-
if (videoType === "H264") return
|
|
70668
|
-
return
|
|
70913
|
+
if (videoType === "H264") return require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads(accessUnitAnnexB).map((n) => (n[0] ?? 0) & 31);
|
|
70914
|
+
return require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads2(accessUnitAnnexB).map((nal) => require_chunk_ZQFQRCLQ.getH265NalType(nal)).filter((t) => typeof t === "number");
|
|
70669
70915
|
}
|
|
70670
70916
|
function normalizeProfiles(p) {
|
|
70671
70917
|
const out = [];
|
|
@@ -71105,7 +71351,7 @@ async function sampleStreams(opts) {
|
|
|
71105
71351
|
});
|
|
71106
71352
|
};
|
|
71107
71353
|
api.client.on("frame", onFrame);
|
|
71108
|
-
const videoStream = new
|
|
71354
|
+
const videoStream = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
71109
71355
|
client: api.client,
|
|
71110
71356
|
api,
|
|
71111
71357
|
channel,
|
|
@@ -72155,7 +72401,7 @@ async function runMultifocalDiagnosticsConsecutively(params) {
|
|
|
72155
72401
|
let audioFrames = 0;
|
|
72156
72402
|
let lastSnapshotAtMs = 0;
|
|
72157
72403
|
const client = params.api.client;
|
|
72158
|
-
const videoStream = new
|
|
72404
|
+
const videoStream = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
72159
72405
|
client,
|
|
72160
72406
|
channel: chNative,
|
|
72161
72407
|
profile,
|
|
@@ -72239,7 +72485,7 @@ async function runMultifocalDiagnosticsConsecutively(params) {
|
|
|
72239
72485
|
const baseStreamName = profile === "main" ? "mainStream" : profile === "sub" ? "subStream" : "externStream";
|
|
72240
72486
|
const headerStreamTypeCandidates = profile === "sub" ? [1, 3] : profile === "main" ? [0, 2] : [0];
|
|
72241
72487
|
const channelIdTagCandidates = uniq([chNative, chNative + 1].filter((n) => Number.isFinite(n) && n >= 0));
|
|
72242
|
-
const messageClassCandidates = params.probeFull ? [
|
|
72488
|
+
const messageClassCandidates = params.probeFull ? [require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24, 0] : [require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24];
|
|
72243
72489
|
const extensionXmlCandidates = params.probeFull ? ["", buildChannelExtensionXml(chNative)] : [buildChannelExtensionXml(chNative)];
|
|
72244
72490
|
const attempts = [];
|
|
72245
72491
|
for (const messageClass of messageClassCandidates) for (const streamTypeHeader of headerStreamTypeCandidates) for (const extensionXml of extensionXmlCandidates) {
|
|
@@ -74760,14 +75006,14 @@ var require_lz4 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) => {
|
|
|
74760
75006
|
};
|
|
74761
75007
|
}));
|
|
74762
75008
|
//#endregion
|
|
74763
|
-
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-
|
|
75009
|
+
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-CE77DTET.js
|
|
74764
75010
|
var import_fxp = require_fxp();
|
|
74765
75011
|
var import_lz4 = /* @__PURE__ */ require_chunk.__toESM(require_lz4(), 1);
|
|
74766
75012
|
function encodeHeader(h) {
|
|
74767
|
-
const hasOffset =
|
|
75013
|
+
const hasOffset = require_chunk_ZQFQRCLQ.bcHeaderHasPayloadOffset(h.messageClass);
|
|
74768
75014
|
const headerLen = hasOffset ? 24 : 20;
|
|
74769
75015
|
const buf = Buffer.alloc(headerLen);
|
|
74770
|
-
const magic = h.magic ??
|
|
75016
|
+
const magic = h.magic ?? require_chunk_ZQFQRCLQ.BC_MAGIC;
|
|
74771
75017
|
if (magic.length !== 4) throw new Error("magic must be 4 bytes");
|
|
74772
75018
|
magic.copy(buf, 0);
|
|
74773
75019
|
buf.writeUInt32LE(h.cmdId >>> 0, 4);
|
|
@@ -74783,7 +75029,7 @@ function encodeHeader(h) {
|
|
|
74783
75029
|
function decodeHeader(buf) {
|
|
74784
75030
|
if (buf.length < 20) throw new Error("not enough data for Baichuan header");
|
|
74785
75031
|
const magic = buf.subarray(0, 4);
|
|
74786
|
-
if (!magic.equals(
|
|
75032
|
+
if (!magic.equals(require_chunk_ZQFQRCLQ.BC_MAGIC) && !magic.equals(require_chunk_ZQFQRCLQ.BC_MAGIC_REV)) throw new Error(`invalid Baichuan magic: ${magic.toString("hex")}`);
|
|
74787
75033
|
const cmdId = buf.readUInt32LE(4);
|
|
74788
75034
|
const bodyLen = buf.readUInt32LE(8);
|
|
74789
75035
|
const channelId = buf.readUInt8(12);
|
|
@@ -74791,7 +75037,7 @@ function decodeHeader(buf) {
|
|
|
74791
75037
|
const msgNum = buf.readUInt16LE(14);
|
|
74792
75038
|
const responseCode = buf.readUInt16LE(16);
|
|
74793
75039
|
const messageClass = buf.readUInt16LE(18);
|
|
74794
|
-
const headerLen =
|
|
75040
|
+
const headerLen = require_chunk_ZQFQRCLQ.bcHeaderHasPayloadOffset(messageClass) ? 24 : 20;
|
|
74795
75041
|
if (buf.length < headerLen) throw new Error("not enough data for Baichuan header (needs 24 bytes)");
|
|
74796
75042
|
const messageKey = buf.readUInt32LE(12);
|
|
74797
75043
|
const header = {
|
|
@@ -74861,9 +75107,9 @@ var BaichuanFrameParser = class {
|
|
|
74861
75107
|
this.needed = 4;
|
|
74862
75108
|
break;
|
|
74863
75109
|
}
|
|
74864
|
-
if (!this.buffer.subarray(0, 4).equals(
|
|
74865
|
-
const idx = this.buffer.indexOf(
|
|
74866
|
-
const idxRev = this.buffer.indexOf(
|
|
75110
|
+
if (!this.buffer.subarray(0, 4).equals(require_chunk_ZQFQRCLQ.BC_MAGIC) && !this.buffer.subarray(0, 4).equals(require_chunk_ZQFQRCLQ.BC_MAGIC_REV)) {
|
|
75111
|
+
const idx = this.buffer.indexOf(require_chunk_ZQFQRCLQ.BC_MAGIC);
|
|
75112
|
+
const idxRev = this.buffer.indexOf(require_chunk_ZQFQRCLQ.BC_MAGIC_REV);
|
|
74867
75113
|
const next = idx === -1 ? idxRev : idxRev === -1 ? idx : Math.min(idx, idxRev);
|
|
74868
75114
|
if (next === -1) {
|
|
74869
75115
|
this.buffer = this.buffer.subarray(Math.max(0, this.buffer.length - 3));
|
|
@@ -75079,8 +75325,8 @@ function buildC2mQ(params) {
|
|
|
75079
75325
|
const os$5 = params.os ?? "MAC";
|
|
75080
75326
|
return buildP2pXml(`<C2M_Q><uid>${xmlEscape(params.uid)}</uid><p>${xmlEscape(os$5)}</p></C2M_Q>`);
|
|
75081
75327
|
}
|
|
75082
|
-
function parseIpPortBlock(
|
|
75083
|
-
const m = new RegExp(`<${
|
|
75328
|
+
function parseIpPortBlock(tag2, body) {
|
|
75329
|
+
const m = new RegExp(`<${tag2}>([\\s\\S]*?)</${tag2}>`, "i").exec(body);
|
|
75084
75330
|
if (!m) return void 0;
|
|
75085
75331
|
const block = m[1] ?? "";
|
|
75086
75332
|
const ip = /<ip>([^<]+)<\/ip>/i.exec(block)?.[1];
|
|
@@ -75125,8 +75371,8 @@ function parseR2cCr(xml) {
|
|
|
75125
75371
|
if (!Number.isFinite(rsp)) return void 0;
|
|
75126
75372
|
const sidStr = /<sid>(-?\d+)<\/sid>/i.exec(body)?.[1];
|
|
75127
75373
|
const sid = sidStr != null ? Number(sidStr) : void 0;
|
|
75128
|
-
const parseCustom = (
|
|
75129
|
-
const mm = new RegExp(`<${
|
|
75374
|
+
const parseCustom = (tag2) => {
|
|
75375
|
+
const mm = new RegExp(`<${tag2}>([\\s\\S]*?)</${tag2}>`, "i").exec(body);
|
|
75130
75376
|
if (!mm) return void 0;
|
|
75131
75377
|
const block = mm[1] ?? "";
|
|
75132
75378
|
const ip = /<ip>([^<]+)<\/ip>/i.exec(block)?.[1];
|
|
@@ -76686,12 +76932,12 @@ function asLogger(logger) {
|
|
|
76686
76932
|
error: resolveMethod(base, "error"),
|
|
76687
76933
|
debug: resolveMethod(base, "debug")
|
|
76688
76934
|
};
|
|
76689
|
-
out.child = (
|
|
76935
|
+
out.child = (tag2) => createTaggedLogger(out, tag2);
|
|
76690
76936
|
return out;
|
|
76691
76937
|
}
|
|
76692
|
-
function createTaggedLogger(base,
|
|
76938
|
+
function createTaggedLogger(base, tag2) {
|
|
76693
76939
|
const b = base.log ? base : asLogger(base);
|
|
76694
|
-
const prefix = `[${
|
|
76940
|
+
const prefix = `[${tag2}] `;
|
|
76695
76941
|
const wrap = (fn) => {
|
|
76696
76942
|
return (message, ...optionalParams) => {
|
|
76697
76943
|
if (typeof message === "string") fn(`${prefix}${message}`, ...optionalParams);
|
|
@@ -76718,7 +76964,7 @@ function createDebugGateLogger(base, enabled = false) {
|
|
|
76718
76964
|
error: b.error,
|
|
76719
76965
|
debug: enabled ? b.debug : noop
|
|
76720
76966
|
};
|
|
76721
|
-
out.child = (
|
|
76967
|
+
out.child = (tag2) => createDebugGateLogger(createTaggedLogger(out, tag2), enabled);
|
|
76722
76968
|
return out;
|
|
76723
76969
|
}
|
|
76724
76970
|
function isTalkCmd(cmdId) {
|
|
@@ -76878,7 +77124,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
76878
77124
|
constructor(options) {
|
|
76879
77125
|
super();
|
|
76880
77126
|
this.opts = options;
|
|
76881
|
-
this.debugCfg =
|
|
77127
|
+
this.debugCfg = require_chunk_ZQFQRCLQ.normalizeDebugOptions(options.debugOptions);
|
|
76882
77128
|
this.logger = createDebugGateLogger(options.logger, this.debugCfg.general || this.debugCfg.traceNativeStream || this.debugCfg.traceRecordings || this.debugCfg.traceTalk || this.debugCfg.traceEvents || this.debugCfg.debugRtsp);
|
|
76883
77129
|
this.on("error", (err) => {
|
|
76884
77130
|
this.logFixed("error", {
|
|
@@ -77360,7 +77606,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77360
77606
|
streamType: 0,
|
|
77361
77607
|
msgNum,
|
|
77362
77608
|
responseCode: 0,
|
|
77363
|
-
messageClass:
|
|
77609
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
77364
77610
|
payloadOffset: 0
|
|
77365
77611
|
});
|
|
77366
77612
|
this.logDebug("udp_keepalive_ping_tx", {
|
|
@@ -77392,7 +77638,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77392
77638
|
cmdId: 93,
|
|
77393
77639
|
channel: this.opts.channel ?? 0,
|
|
77394
77640
|
channelIdOverride: 0,
|
|
77395
|
-
messageClass:
|
|
77641
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
77396
77642
|
streamType: 0,
|
|
77397
77643
|
extensionXml: "",
|
|
77398
77644
|
internal: true
|
|
@@ -77731,7 +77977,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77731
77977
|
cmdId: 2,
|
|
77732
77978
|
payloadXml: logoutXml,
|
|
77733
77979
|
extensionXml: "",
|
|
77734
|
-
messageClass:
|
|
77980
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
77735
77981
|
channelIdOverride: effectiveHostChannelId,
|
|
77736
77982
|
timeoutMs: 5e3
|
|
77737
77983
|
})).header.responseCode;
|
|
@@ -77844,12 +78090,12 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77844
78090
|
};
|
|
77845
78091
|
s.frames++;
|
|
77846
78092
|
if (now - s.lastLogMs >= 1e3) {
|
|
77847
|
-
|
|
78093
|
+
require_chunk_ZQFQRCLQ.debugLog(this.debugCfg, this.logger, "BaichuanRx", `rx cmdId=3 frames=${s.frames} lastMsgNum=${frame.header.msgNum} lastResponseCode=${frame.header.responseCode} lastChannelId=${frame.header.channelId} lastStreamType=${frame.header.streamType} lastBodyLen=${frame.body.length} lastPayloadLen=${frame.payload.length}`);
|
|
77848
78094
|
s.lastLogMs = now;
|
|
77849
78095
|
s.frames = 0;
|
|
77850
78096
|
}
|
|
77851
78097
|
this.rxCmdTraceStats.set(3, s);
|
|
77852
|
-
} else
|
|
78098
|
+
} else require_chunk_ZQFQRCLQ.debugLog(this.debugCfg, this.logger, "BaichuanRx", `rx cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} streamType=${frame.header.streamType} bodyLen=${frame.body.length} payloadLen=${frame.payload.length} payloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
77853
78099
|
if (this.transport === "udp" && frame.header.cmdId === 234) {
|
|
77854
78100
|
try {
|
|
77855
78101
|
const header = encodeHeader({
|
|
@@ -77886,7 +78132,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77886
78132
|
}
|
|
77887
78133
|
return;
|
|
77888
78134
|
}
|
|
77889
|
-
if (this.debugCfg.traceTalk && isTalkCmd(frame.header.cmdId))
|
|
78135
|
+
if (this.debugCfg.traceTalk && isTalkCmd(frame.header.cmdId)) require_chunk_ZQFQRCLQ.talkTraceLog(this.debugCfg, this.logger, "BaichuanTalk", `rx cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} bodyLen=${frame.body.length} payloadLen=${frame.payload.length} payloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
77890
78136
|
this.emit("frame", frame);
|
|
77891
78137
|
const key = `${frame.header.cmdId}:${frame.header.msgNum}`;
|
|
77892
78138
|
const pending = this.pending.get(key);
|
|
@@ -77907,7 +78153,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77907
78153
|
};
|
|
77908
78154
|
s.frames++;
|
|
77909
78155
|
if (now2 - s.lastLogMs >= 500) {
|
|
77910
|
-
|
|
78156
|
+
require_chunk_ZQFQRCLQ.traceLog(this.debugCfg, this.logger, "BaichuanTrace", `rx stream frames cmdId=3 msgNum=${frame.header.msgNum} frames=${s.frames} lastChannelId=${frame.header.channelId} lastBodyLen=${frame.body.length} lastPayloadLen=${frame.payload.length} lastPayloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
77911
78157
|
s.lastLogMs = now2;
|
|
77912
78158
|
s.frames = 0;
|
|
77913
78159
|
}
|
|
@@ -77938,7 +78184,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77938
78184
|
const eventLogTag = sid ? `BaichuanEvent sid=${sid}` : "BaichuanEvent";
|
|
77939
78185
|
const events$1 = this.parseEvents(frame);
|
|
77940
78186
|
for (const event of events$1) {
|
|
77941
|
-
|
|
78187
|
+
require_chunk_ZQFQRCLQ.eventTraceLog(this.debugCfg, this.logger, eventLogTag, `dispatch cmdId=33 msgNum=${frame.header.msgNum} channelId=${frame.header.channelId} type=${event.type} eventChannel=${event.channel}` + (event.type === "ai" ? ` aiType=${event.ai?.type ?? "unknown"} detected=${event.ai?.detected ?? ""}` : "") + (event.type === "motion" ? ` source=${event.motion?.source ?? ""}` : ""));
|
|
77942
78188
|
this.emit("event", event);
|
|
77943
78189
|
}
|
|
77944
78190
|
} catch (error) {
|
|
@@ -77997,7 +78243,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77997
78243
|
if (!xml || !xml.startsWith("<?xml")) return [];
|
|
77998
78244
|
if (this.debugCfg.traceEvents) {
|
|
77999
78245
|
const snippet = xml.length > 500 ? `${xml.slice(0, 500)}...` : xml;
|
|
78000
|
-
|
|
78246
|
+
require_chunk_ZQFQRCLQ.eventTraceLog(this.debugCfg, this.logger, eventRawLogTag, `rx cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} xml=${JSON.stringify(snippet)}`);
|
|
78001
78247
|
}
|
|
78002
78248
|
const fallbackChannelId = frame.header.channelId;
|
|
78003
78249
|
const fallbackChannel = fallbackChannelId === 250 ? 0 : Math.max(0, fallbackChannelId - 1);
|
|
@@ -78015,7 +78261,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78015
78261
|
const timeStampRaw2 = (getXmlText(alarmXml, "timeStamp") ?? getXmlText(alarmXml, "timestamp") ?? "").trim();
|
|
78016
78262
|
const timeStampNum2 = timeStampRaw2.length ? Number(timeStampRaw2) : void 0;
|
|
78017
78263
|
const alarmTimeStamp2 = Number.isFinite(timeStampNum2) ? timeStampNum2 : void 0;
|
|
78018
|
-
if (this.debugCfg.traceEvents)
|
|
78264
|
+
if (this.debugCfg.traceEvents) require_chunk_ZQFQRCLQ.eventTraceLog(this.debugCfg, this.logger, eventRawLogTag, `AlarmEvent channel=${channel} status=${JSON.stringify(status2)} aiType=${JSON.stringify(aiTypeRaw2)}`);
|
|
78019
78265
|
const statusTokens2 = status2.toLowerCase().split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
78020
78266
|
const visitorActive2 = statusTokens2.includes("visitor");
|
|
78021
78267
|
const dayNightActive2 = statusTokens2.includes("dn") || statusTokens2.includes("daynight");
|
|
@@ -78289,15 +78535,15 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78289
78535
|
const extBuf = Buffer.from(extXml, "utf8");
|
|
78290
78536
|
const payloadBuf = Buffer.from(payloadXml, "utf8");
|
|
78291
78537
|
if (enc.kind === "none") return Buffer.concat([extBuf, payloadBuf]);
|
|
78292
|
-
if (enc.kind === "bc") return Buffer.concat([
|
|
78293
|
-
if (enc.kind === "aes" || enc.kind === "full_aes") return Buffer.concat([
|
|
78538
|
+
if (enc.kind === "bc") return Buffer.concat([require_chunk_ZQFQRCLQ.bcEncrypt(extBuf, channelId), require_chunk_ZQFQRCLQ.bcEncrypt(payloadBuf, channelId)]);
|
|
78539
|
+
if (enc.kind === "aes" || enc.kind === "full_aes") return Buffer.concat([require_chunk_ZQFQRCLQ.aesEncrypt(extBuf, enc.key), require_chunk_ZQFQRCLQ.aesEncrypt(payloadBuf, enc.key)]);
|
|
78294
78540
|
return Buffer.concat([extBuf, payloadBuf]);
|
|
78295
78541
|
}
|
|
78296
78542
|
encodeBodyBinary(extXml, payload, channelId, enc) {
|
|
78297
78543
|
const extBuf = Buffer.from(extXml, "utf8");
|
|
78298
78544
|
if (enc.kind === "none") return Buffer.concat([extBuf, payload]);
|
|
78299
|
-
if (enc.kind === "bc") return Buffer.concat([
|
|
78300
|
-
if (enc.kind === "aes" || enc.kind === "full_aes") return Buffer.concat([
|
|
78545
|
+
if (enc.kind === "bc") return Buffer.concat([require_chunk_ZQFQRCLQ.bcEncrypt(extBuf, channelId), payload]);
|
|
78546
|
+
if (enc.kind === "aes" || enc.kind === "full_aes") return Buffer.concat([require_chunk_ZQFQRCLQ.aesEncrypt(extBuf, enc.key), payload]);
|
|
78301
78547
|
return Buffer.concat([extBuf, payload]);
|
|
78302
78548
|
}
|
|
78303
78549
|
/**
|
|
@@ -78342,7 +78588,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78342
78588
|
bodyLen,
|
|
78343
78589
|
binaryPayload: true
|
|
78344
78590
|
});
|
|
78345
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78591
|
+
if (this.debugCfg.traceTalk && isTalkCmd(cmdId)) require_chunk_ZQFQRCLQ.talkTraceLog(this.debugCfg, this.logger, "BaichuanTalk", `tx cmdId=${cmdId} msgNum=${msgNum} channelId=${channelId} streamType=${params.streamType ?? 0} class=0x${messageClass.toString(16)} bodyLen=${bodyLen} payloadOffset=${payloadOffset} binaryPayloadLen=${params.payload.length}`);
|
|
78346
78592
|
this.recordTx({
|
|
78347
78593
|
cmdId,
|
|
78348
78594
|
responseCode: 0,
|
|
@@ -78359,8 +78605,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78359
78605
|
let dec;
|
|
78360
78606
|
try {
|
|
78361
78607
|
if (enc.kind === "none") dec = buf;
|
|
78362
|
-
else if (enc.kind === "bc") dec =
|
|
78363
|
-
else dec =
|
|
78608
|
+
else if (enc.kind === "bc") dec = require_chunk_ZQFQRCLQ.bcDecrypt(buf, channelId);
|
|
78609
|
+
else dec = require_chunk_ZQFQRCLQ.aesDecrypt(buf, enc.key);
|
|
78364
78610
|
} catch {
|
|
78365
78611
|
return;
|
|
78366
78612
|
}
|
|
@@ -78426,8 +78672,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78426
78672
|
messageClass,
|
|
78427
78673
|
bodyLen
|
|
78428
78674
|
});
|
|
78429
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78430
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78675
|
+
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4)) require_chunk_ZQFQRCLQ.traceLog(this.debugCfg, this.logger, "BaichuanTrace", `tx cmdId=${cmdId} msgNum=${msgNum} channelId=${channelId} streamType=${params.streamType ?? 0} class=0x${messageClass.toString(16)} bodyLen=${bodyLen} payloadOffset=${payloadOffset}`);
|
|
78676
|
+
if (this.debugCfg.traceTalk && isTalkCmd(cmdId)) require_chunk_ZQFQRCLQ.talkTraceLog(this.debugCfg, this.logger, "BaichuanTalk", `tx cmdId=${cmdId} msgNum=${msgNum} channelId=${channelId} streamType=${params.streamType ?? 0} class=0x${messageClass.toString(16)} bodyLen=${bodyLen} payloadOffset=${payloadOffset}`);
|
|
78431
78677
|
this.recordTx({
|
|
78432
78678
|
cmdId,
|
|
78433
78679
|
responseCode: 0,
|
|
@@ -78442,8 +78688,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78442
78688
|
responseCode: frame.header.responseCode,
|
|
78443
78689
|
msgNum: frame.header.msgNum
|
|
78444
78690
|
});
|
|
78445
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78446
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78691
|
+
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4)) require_chunk_ZQFQRCLQ.traceLog(this.debugCfg, this.logger, "BaichuanTrace", `rx cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} bodyLen=${frame.body.length} payloadLen=${frame.payload.length} payloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
78692
|
+
if (this.debugCfg.traceTalk && isTalkCmd(cmdId)) require_chunk_ZQFQRCLQ.talkTraceLog(this.debugCfg, this.logger, "BaichuanTalk", `rx cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} bodyLen=${frame.body.length} payloadLen=${frame.payload.length} payloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
78447
78693
|
if (frame.header.responseCode === 400) {
|
|
78448
78694
|
if (frame.body.length === 0) throw new Error("Baichuan authentication failed (responseCode 400, empty body) - check username/password");
|
|
78449
78695
|
}
|
|
@@ -78513,9 +78759,9 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78513
78759
|
messageClass,
|
|
78514
78760
|
bodyLen
|
|
78515
78761
|
});
|
|
78516
|
-
if (_BaichuanClient.recordingCmdIds.has(cmdId))
|
|
78517
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78518
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78762
|
+
if (_BaichuanClient.recordingCmdIds.has(cmdId)) require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugCfg, this.logger, "BaichuanRecordings", `tx recording cmdId=${cmdId} msgNum=${msgNum} channelId=${channelId} streamType=${params.streamType ?? 0} bodyLen=${bodyLen}`);
|
|
78763
|
+
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4)) require_chunk_ZQFQRCLQ.traceLog(this.debugCfg, this.logger, "BaichuanTrace", `tx cmdId=${cmdId} msgNum=${msgNum} channelId=${channelId} streamType=${params.streamType ?? 0} class=0x${messageClass.toString(16)} bodyLen=${bodyLen} payloadOffset=${payloadOffset}`);
|
|
78764
|
+
if (this.debugCfg.traceTalk && isTalkCmd(cmdId)) require_chunk_ZQFQRCLQ.talkTraceLog(this.debugCfg, this.logger, "BaichuanTalk", `tx cmdId=${cmdId} msgNum=${msgNum} channelId=${channelId} streamType=${params.streamType ?? 0} class=0x${messageClass.toString(16)} bodyLen=${bodyLen} payloadOffset=${payloadOffset}`);
|
|
78519
78765
|
this.recordTx({
|
|
78520
78766
|
cmdId,
|
|
78521
78767
|
responseCode: 0,
|
|
@@ -78530,9 +78776,9 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78530
78776
|
responseCode: frame.header.responseCode,
|
|
78531
78777
|
msgNum: frame.header.msgNum
|
|
78532
78778
|
});
|
|
78533
|
-
if (_BaichuanClient.recordingCmdIds.has(frame.header.cmdId))
|
|
78534
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78535
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78779
|
+
if (_BaichuanClient.recordingCmdIds.has(frame.header.cmdId)) require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugCfg, this.logger, "BaichuanRecordings", `rx recording cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} bodyLen=${frame.body.length} payloadLen=${frame.payload.length} payloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
78780
|
+
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4)) require_chunk_ZQFQRCLQ.traceLog(this.debugCfg, this.logger, "BaichuanTrace", `rx cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} bodyLen=${frame.body.length} payloadLen=${frame.payload.length} payloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
78781
|
+
if (this.debugCfg.traceTalk && isTalkCmd(cmdId)) require_chunk_ZQFQRCLQ.talkTraceLog(this.debugCfg, this.logger, "BaichuanTalk", `rx cmdId=${frame.header.cmdId} msgNum=${frame.header.msgNum} responseCode=${frame.header.responseCode} channelId=${frame.header.channelId} bodyLen=${frame.body.length} payloadLen=${frame.payload.length} payloadOffset=${frame.header.payloadOffset ?? 0}`);
|
|
78536
78782
|
if (!internal) this.kickIdleDisconnectTimer();
|
|
78537
78783
|
return frame;
|
|
78538
78784
|
}
|
|
@@ -79354,8 +79600,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79354
79600
|
const tryAs = (enc) => {
|
|
79355
79601
|
try {
|
|
79356
79602
|
if (enc.kind === "none") return buf;
|
|
79357
|
-
if (enc.kind === "bc") return
|
|
79358
|
-
if (enc.kind === "aes" || enc.kind === "full_aes") return
|
|
79603
|
+
if (enc.kind === "bc") return require_chunk_ZQFQRCLQ.bcDecrypt(buf, channelId);
|
|
79604
|
+
if (enc.kind === "aes" || enc.kind === "full_aes") return require_chunk_ZQFQRCLQ.aesDecrypt(buf, enc.key);
|
|
79359
79605
|
return null;
|
|
79360
79606
|
} catch {
|
|
79361
79607
|
return null;
|
|
@@ -79385,7 +79631,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79385
79631
|
streamType: 0,
|
|
79386
79632
|
msgNum,
|
|
79387
79633
|
responseCode: encByte,
|
|
79388
|
-
messageClass:
|
|
79634
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_LEGACY
|
|
79389
79635
|
});
|
|
79390
79636
|
const pendingKey = `${cmdId}:${msgNum}`;
|
|
79391
79637
|
const framePromise = new Promise((resolve, reject) => {
|
|
@@ -79417,15 +79663,15 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79417
79663
|
else if (encType === 1) this.enc = { kind: "bc" };
|
|
79418
79664
|
else if (encType === 2) this.enc = {
|
|
79419
79665
|
kind: "aes",
|
|
79420
|
-
key:
|
|
79666
|
+
key: require_chunk_ZQFQRCLQ.deriveAesKey(nonce, this.opts.password)
|
|
79421
79667
|
};
|
|
79422
79668
|
else if (encType === 18) this.enc = {
|
|
79423
79669
|
kind: "full_aes",
|
|
79424
|
-
key:
|
|
79670
|
+
key: require_chunk_ZQFQRCLQ.deriveAesKey(nonce, this.opts.password)
|
|
79425
79671
|
};
|
|
79426
79672
|
else throw new Error(`Baichuan login: unknown encType=0x${encType.toString(16)}`);
|
|
79427
|
-
const userHash =
|
|
79428
|
-
const passHash =
|
|
79673
|
+
const userHash = require_chunk_ZQFQRCLQ.md5StrModern(`${this.opts.username}${nonce}`);
|
|
79674
|
+
const passHash = require_chunk_ZQFQRCLQ.md5StrModern(`${this.opts.password}${nonce}`);
|
|
79429
79675
|
const loginXml = buildLoginXml(userHash, passHash);
|
|
79430
79676
|
this.logDebug("login_hash", {
|
|
79431
79677
|
username: this.opts.username,
|
|
@@ -79440,7 +79686,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79440
79686
|
cmdId: 1,
|
|
79441
79687
|
payloadXml: loginXml,
|
|
79442
79688
|
extensionXml: "",
|
|
79443
|
-
messageClass:
|
|
79689
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
79444
79690
|
channelIdOverride: effectiveHostChannelId,
|
|
79445
79691
|
encryption: loginEnc,
|
|
79446
79692
|
timeoutMs: 1e4
|
|
@@ -79500,7 +79746,7 @@ async function* createNativeStream(api, channel, profile, options) {
|
|
|
79500
79746
|
client = api.client;
|
|
79501
79747
|
}
|
|
79502
79748
|
}
|
|
79503
|
-
const videoStream = new
|
|
79749
|
+
const videoStream = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
79504
79750
|
client,
|
|
79505
79751
|
api,
|
|
79506
79752
|
channel,
|
|
@@ -80018,7 +80264,7 @@ var H264Flow = class extends BaseFlow {
|
|
|
80018
80264
|
super(transport, "H264");
|
|
80019
80265
|
}
|
|
80020
80266
|
extractParameterSets(accessUnitAnnexB) {
|
|
80021
|
-
const nals =
|
|
80267
|
+
const nals = require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads(accessUnitAnnexB);
|
|
80022
80268
|
for (const nal of nals) {
|
|
80023
80269
|
if (nal.length < 1) continue;
|
|
80024
80270
|
const nalType = (nal[0] ?? 0) & 31;
|
|
@@ -80063,9 +80309,9 @@ var H265Flow = class extends BaseFlow {
|
|
|
80063
80309
|
super(transport, "H265");
|
|
80064
80310
|
}
|
|
80065
80311
|
extractParameterSets(accessUnitAnnexB) {
|
|
80066
|
-
const vps =
|
|
80067
|
-
const sps =
|
|
80068
|
-
const pps =
|
|
80312
|
+
const vps = require_chunk_ZQFQRCLQ.extractVpsFromAnnexB(accessUnitAnnexB);
|
|
80313
|
+
const sps = require_chunk_ZQFQRCLQ.extractSpsFromAnnexB(accessUnitAnnexB);
|
|
80314
|
+
const pps = require_chunk_ZQFQRCLQ.extractPpsFromAnnexB(accessUnitAnnexB);
|
|
80069
80315
|
if (vps && !this.vps) this.vps = vps;
|
|
80070
80316
|
if (sps && !this.sps) this.sps = sps;
|
|
80071
80317
|
if (pps && !this.pps) this.pps = pps;
|
|
@@ -80449,8 +80695,8 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
80449
80695
|
/** Returns true if the raw (packed/Annex B) frame is an IDR (H.264) or IRAP (H.265). */
|
|
80450
80696
|
isRawFrameKeyframe(frame) {
|
|
80451
80697
|
try {
|
|
80452
|
-
if (frame.videoType === "H264") return _BaichuanRtspServer.splitAnnexBNals(
|
|
80453
|
-
if (frame.videoType === "H265") return
|
|
80698
|
+
if (frame.videoType === "H264") return _BaichuanRtspServer.splitAnnexBNals(require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data)).some((n) => n.length >= 1 && (n[0] & 31) === 5);
|
|
80699
|
+
if (frame.videoType === "H265") return require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads2(require_chunk_ZQFQRCLQ.convertToAnnexB2(frame.data)).some((n) => n.length >= 2 && require_chunk_ZQFQRCLQ.isH265Irap(n[0] >> 1 & 63));
|
|
80454
80700
|
} catch {}
|
|
80455
80701
|
return false;
|
|
80456
80702
|
}
|
|
@@ -81350,13 +81596,13 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81350
81596
|
if (resources?.rtpAudioTimestamp !== void 0) resources.rtpAudioTimestamp = resources.rtpAudioTimestamp + 1024 >>> 0;
|
|
81351
81597
|
};
|
|
81352
81598
|
const isH265IrapAccessUnit = (annexB) => {
|
|
81353
|
-
const nals =
|
|
81599
|
+
const nals = require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads2(annexB);
|
|
81354
81600
|
for (const nal of nals) {
|
|
81355
81601
|
if (nal.length < 2) continue;
|
|
81356
81602
|
const b0 = nal[0];
|
|
81357
81603
|
if (b0 === void 0) continue;
|
|
81358
81604
|
if ((b0 & 128) !== 0) continue;
|
|
81359
|
-
if (
|
|
81605
|
+
if (require_chunk_ZQFQRCLQ.isH265Irap(b0 >> 1 & 63)) return true;
|
|
81360
81606
|
}
|
|
81361
81607
|
return false;
|
|
81362
81608
|
};
|
|
@@ -81512,7 +81758,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81512
81758
|
continue;
|
|
81513
81759
|
}
|
|
81514
81760
|
if (frame.videoType === "H264" || frame.videoType === "H265") {
|
|
81515
|
-
const normalizedVideoData = frame.videoType === "H264" ?
|
|
81761
|
+
const normalizedVideoData = frame.videoType === "H264" ? require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data) : require_chunk_ZQFQRCLQ.convertToAnnexB2(frame.data);
|
|
81516
81762
|
if (frameCount === 0) this.setFlowVideoType(frame.videoType, "first video frame");
|
|
81517
81763
|
if (!this.flow.getFmtp().hasParamSets) {
|
|
81518
81764
|
this.flow.extractParameterSets(normalizedVideoData);
|
|
@@ -81528,7 +81774,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81528
81774
|
}
|
|
81529
81775
|
if (useDirectRtp) {
|
|
81530
81776
|
const videoType = frame.videoType ?? this.flow.videoType;
|
|
81531
|
-
const normalizedVideoData = videoType === "H264" ?
|
|
81777
|
+
const normalizedVideoData = videoType === "H264" ? require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data) : require_chunk_ZQFQRCLQ.convertToAnnexB2(frame.data);
|
|
81532
81778
|
if (!resources?.seenFirstVideoKeyframe) if (videoType === "H265") {
|
|
81533
81779
|
const { hasParamSets } = this.flow.getFmtp();
|
|
81534
81780
|
if (!hasParamSets) {
|
|
@@ -81604,7 +81850,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81604
81850
|
const headHex = frame.data.subarray(0, 16).toString("hex");
|
|
81605
81851
|
this.rtspDebugLog(`First video frame written to ffmpeg stdin for client ${clientId} (len=${frame.data.length}, head=${headHex})`);
|
|
81606
81852
|
}
|
|
81607
|
-
if (!stdin.write(frame.videoType === "H264" ?
|
|
81853
|
+
if (!stdin.write(frame.videoType === "H264" ? require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data) : frame.data)) await new Promise((resolve) => {
|
|
81608
81854
|
if (stdin) stdin.once("drain", () => resolve());
|
|
81609
81855
|
else resolve();
|
|
81610
81856
|
});
|
|
@@ -81716,7 +81962,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81716
81962
|
ensureContinuousStream(dedicatedClient) {
|
|
81717
81963
|
if (this.continuousStream) return this.continuousStream;
|
|
81718
81964
|
const createLiveStream = async () => {
|
|
81719
|
-
return new
|
|
81965
|
+
return new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
81720
81966
|
client: dedicatedClient ?? this.api.client,
|
|
81721
81967
|
api: this.api,
|
|
81722
81968
|
channel: this.channel,
|
|
@@ -82412,29 +82658,29 @@ function parseSupportXml(xml) {
|
|
|
82412
82658
|
if (!match) return void 0;
|
|
82413
82659
|
const supportXml = match[1] ?? "";
|
|
82414
82660
|
const ptzMode = supportXml.match(/<ptzMode>([^<]*)<\/ptzMode>/i)?.[1];
|
|
82415
|
-
const topLevelInt = (
|
|
82416
|
-
return toNumberOrUndefined(supportXml.match(new RegExp(`<${
|
|
82661
|
+
const topLevelInt = (tag2) => {
|
|
82662
|
+
return toNumberOrUndefined(supportXml.match(new RegExp(`<${tag2}>([^<]*)<\\/${tag2}>`, "i"))?.[1]);
|
|
82417
82663
|
};
|
|
82418
|
-
const topLevelString = (
|
|
82419
|
-
return supportXml.match(new RegExp(`<${
|
|
82664
|
+
const topLevelString = (tag2) => {
|
|
82665
|
+
return supportXml.match(new RegExp(`<${tag2}>([^<]*)<\\/${tag2}>`, "i"))?.[1];
|
|
82420
82666
|
};
|
|
82421
82667
|
const items = [];
|
|
82422
82668
|
for (const itemMatch of supportXml.matchAll(/<item[^>]*>([\s\S]*?)<\/item>/gi)) {
|
|
82423
82669
|
const itemXml = itemMatch[1] ?? "";
|
|
82424
82670
|
const item = { chnID: toNumberOrUndefined(itemXml.match(/<chnID>([^<]*)<\/chnID>/i)?.[1]) ?? 0 };
|
|
82425
82671
|
for (const tagMatch of itemXml.matchAll(/<([A-Za-z0-9_]+)>([^<]*)<\/\1>/g)) {
|
|
82426
|
-
const
|
|
82672
|
+
const tag2 = tagMatch[1];
|
|
82427
82673
|
const value = tagMatch[2];
|
|
82428
|
-
if (!
|
|
82429
|
-
if (
|
|
82430
|
-
item[
|
|
82674
|
+
if (!tag2) continue;
|
|
82675
|
+
if (tag2 === "chnID") continue;
|
|
82676
|
+
item[tag2] = toNumberOrUndefined(value) ?? value;
|
|
82431
82677
|
}
|
|
82432
82678
|
items.push(item);
|
|
82433
82679
|
}
|
|
82434
82680
|
const support = { items };
|
|
82435
82681
|
if (ptzMode !== void 0) support.ptzMode = ptzMode;
|
|
82436
|
-
const assignInt = (key,
|
|
82437
|
-
const v = topLevelInt(
|
|
82682
|
+
const assignInt = (key, tag2) => {
|
|
82683
|
+
const v = topLevelInt(tag2);
|
|
82438
82684
|
if (v !== void 0) support[key] = v;
|
|
82439
82685
|
};
|
|
82440
82686
|
assignInt("IOInputPortNum", "IOInputPortNum");
|
|
@@ -82661,15 +82907,15 @@ function extractCanvasFromShelterXml(xml) {
|
|
|
82661
82907
|
const yMatch = xml.match(/<topLeftY>(\d+)<\/topLeftY>/g) ?? [];
|
|
82662
82908
|
let canvasX = 0;
|
|
82663
82909
|
let canvasY = 0;
|
|
82664
|
-
for (const
|
|
82665
|
-
const v = Number(
|
|
82910
|
+
for (const tag2 of xMatch) {
|
|
82911
|
+
const v = Number(tag2.replace(/<\/?topLeftX>/g, "")) | 0;
|
|
82666
82912
|
if (v > 0) {
|
|
82667
82913
|
canvasX = v & 65535;
|
|
82668
82914
|
break;
|
|
82669
82915
|
}
|
|
82670
82916
|
}
|
|
82671
|
-
for (const
|
|
82672
|
-
const v = Number(
|
|
82917
|
+
for (const tag2 of yMatch) {
|
|
82918
|
+
const v = Number(tag2.replace(/<\/?topLeftY>/g, "")) | 0;
|
|
82673
82919
|
if (v > 0) {
|
|
82674
82920
|
canvasY = v & 65535;
|
|
82675
82921
|
break;
|
|
@@ -82682,9 +82928,9 @@ function extractCanvasFromShelterXml(xml) {
|
|
|
82682
82928
|
}
|
|
82683
82929
|
function parseRectTags(block) {
|
|
82684
82930
|
const out = {};
|
|
82685
|
-
const grab = (
|
|
82686
|
-
const m = block.match(new RegExp(`<${
|
|
82687
|
-
if (m && m[1] !== void 0) out[
|
|
82931
|
+
const grab = (tag2) => {
|
|
82932
|
+
const m = block.match(new RegExp(`<${tag2}>([^<]*)<\\/${tag2}>`));
|
|
82933
|
+
if (m && m[1] !== void 0) out[tag2] = m[1];
|
|
82688
82934
|
};
|
|
82689
82935
|
grab("id");
|
|
82690
82936
|
grab("name");
|
|
@@ -82929,9 +83175,9 @@ var buildDetectionClasses = (parsed, recordType) => {
|
|
|
82929
83175
|
};
|
|
82930
83176
|
var getXmlTexts = (xml, tags) => {
|
|
82931
83177
|
const out = {};
|
|
82932
|
-
for (const
|
|
82933
|
-
const v = getXmlText(xml,
|
|
82934
|
-
if (v !== void 0) out[
|
|
83178
|
+
for (const tag2 of tags) {
|
|
83179
|
+
const v = getXmlText(xml, tag2);
|
|
83180
|
+
if (v !== void 0) out[tag2] = v;
|
|
82935
83181
|
}
|
|
82936
83182
|
return out;
|
|
82937
83183
|
};
|
|
@@ -83193,11 +83439,11 @@ function patchBlock(xml, block, fields) {
|
|
|
83193
83439
|
const end = xml.indexOf(`</${block}>`, start);
|
|
83194
83440
|
if (end < 0) return xml;
|
|
83195
83441
|
let body = xml.slice(start, end);
|
|
83196
|
-
for (const [
|
|
83442
|
+
for (const [tag2, value] of Object.entries(fields)) {
|
|
83197
83443
|
if (value === void 0) continue;
|
|
83198
83444
|
const escaped = escapeXmlText(typeof value === "boolean" ? value ? "1" : "0" : String(value));
|
|
83199
|
-
if (body.includes(`<${
|
|
83200
|
-
else body += `<${
|
|
83445
|
+
if (body.includes(`<${tag2}>`)) body = body.replace(new RegExp(`<${tag2}>[^<]*<\\/${tag2}>`), `<${tag2}>${escaped}</${tag2}>`);
|
|
83446
|
+
else body += `<${tag2}>${escaped}</${tag2}>`;
|
|
83201
83447
|
}
|
|
83202
83448
|
return xml.slice(0, start) + body + xml.slice(end);
|
|
83203
83449
|
}
|
|
@@ -83265,6 +83511,66 @@ var OSD_CORNER_LABELS = {
|
|
|
83265
83511
|
"bottom-left": "Bottom left",
|
|
83266
83512
|
"bottom-right": "Bottom right"
|
|
83267
83513
|
};
|
|
83514
|
+
function wireFloat(value) {
|
|
83515
|
+
return value.toExponential(6).replace(/e([+-])(\d)$/, "e$10$2");
|
|
83516
|
+
}
|
|
83517
|
+
function buildPtzGuardExtensionXml(channelId, direction) {
|
|
83518
|
+
return `<?xml version="1.0" encoding="UTF-8" ?>
|
|
83519
|
+
<Extension version="1.1">
|
|
83520
|
+
<channelId>${channelId}</channelId>${direction === "read" ? `
|
|
83521
|
+
<chnType>0</chnType>` : ""}
|
|
83522
|
+
</Extension>
|
|
83523
|
+
`;
|
|
83524
|
+
}
|
|
83525
|
+
function guardBody(channelId, command, fields) {
|
|
83526
|
+
return [
|
|
83527
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",
|
|
83528
|
+
"<body>",
|
|
83529
|
+
"<PtzGuard version=\"1.1\">",
|
|
83530
|
+
`<channelId>${channelId}</channelId>`,
|
|
83531
|
+
...fields,
|
|
83532
|
+
`<command>${command}</command>`,
|
|
83533
|
+
"<imageName></imageName>",
|
|
83534
|
+
`<xpos>${wireFloat(0)}</xpos>`,
|
|
83535
|
+
`<ypos>${wireFloat(0)}</ypos>`,
|
|
83536
|
+
`<height>${wireFloat(0)}</height>`,
|
|
83537
|
+
`<width>${wireFloat(0)}</width>`,
|
|
83538
|
+
"<mode>global</mode>",
|
|
83539
|
+
"</PtzGuard>",
|
|
83540
|
+
"</body>",
|
|
83541
|
+
""
|
|
83542
|
+
].join("\n");
|
|
83543
|
+
}
|
|
83544
|
+
function buildPtzGuardGoXml(channelId) {
|
|
83545
|
+
return guardBody(channelId, "toGrd", ["<benable>0</benable>", "<timeout>68</timeout>"]);
|
|
83546
|
+
}
|
|
83547
|
+
function buildPtzGuardSetXml(input) {
|
|
83548
|
+
return guardBody(input.channelId, "setGrd", [
|
|
83549
|
+
`<benable>${input.enabled ? 1 : 0}</benable>`,
|
|
83550
|
+
`<timeout>${Math.round(input.timeoutSeconds)}</timeout>`,
|
|
83551
|
+
...input.setPosition ? ["<needSetPos>1</needSetPos>"] : []
|
|
83552
|
+
]);
|
|
83553
|
+
}
|
|
83554
|
+
function tag(xml, name) {
|
|
83555
|
+
const m = new RegExp(`<${name}>([\\s\\S]*?)</${name}>`).exec(xml);
|
|
83556
|
+
return m === null ? null : (m[1] ?? "").trim();
|
|
83557
|
+
}
|
|
83558
|
+
function parsePtzGuardXml(xml) {
|
|
83559
|
+
if (!xml.includes("<PtzGuard")) return null;
|
|
83560
|
+
const enabled = tag(xml, "benable");
|
|
83561
|
+
const valid = tag(xml, "bvalid");
|
|
83562
|
+
const timeout = tag(xml, "timeout");
|
|
83563
|
+
if (enabled === null || valid === null || timeout === null) return null;
|
|
83564
|
+
const timeoutSeconds = Number.parseInt(timeout, 10);
|
|
83565
|
+
if (!Number.isFinite(timeoutSeconds)) return null;
|
|
83566
|
+
return {
|
|
83567
|
+
enabled: enabled === "1",
|
|
83568
|
+
valid: valid === "1",
|
|
83569
|
+
timeoutSeconds,
|
|
83570
|
+
mode: tag(xml, "mode") ?? "global",
|
|
83571
|
+
imageName: tag(xml, "imageName") ?? ""
|
|
83572
|
+
};
|
|
83573
|
+
}
|
|
83268
83574
|
var emitter = new events.EventEmitter();
|
|
83269
83575
|
var lastEventByCamera = /* @__PURE__ */ new Map();
|
|
83270
83576
|
var MAX_GLOBAL_EVENTS = 300;
|
|
@@ -84477,8 +84783,8 @@ var buildFileInfoListStopXml = (params) => {
|
|
|
84477
84783
|
</body>`;
|
|
84478
84784
|
};
|
|
84479
84785
|
var sleepMs = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
84480
|
-
var xmlDateTimePayload = (
|
|
84481
|
-
return `<${
|
|
84786
|
+
var xmlDateTimePayload = (tag2, d) => {
|
|
84787
|
+
return `<${tag2}><year>${d.getFullYear()}</year><month>${d.getMonth() + 1}</month><day>${d.getDate()}</day><hour>${d.getHours()}</hour><minute>${d.getMinutes()}</minute><second>${d.getSeconds()}</second></${tag2}>`;
|
|
84482
84788
|
};
|
|
84483
84789
|
var buildFileInfoListOpenXml = (params) => {
|
|
84484
84790
|
return `<?xml version="1.0" encoding="UTF-8" ?>
|
|
@@ -84666,10 +84972,10 @@ var isPlausibleStream = (s) => {
|
|
|
84666
84972
|
return s.width > 0 && s.height > 0 && (s.frameRate > 0 || s.bitRate > 0);
|
|
84667
84973
|
};
|
|
84668
84974
|
var logDebugStreamBlock = (params) => {
|
|
84669
|
-
const { logger, traceNativeStream, channel, tag, blockXml } = params;
|
|
84975
|
+
const { logger, traceNativeStream, channel, tag: tag2, blockXml } = params;
|
|
84670
84976
|
if (!traceNativeStream) return;
|
|
84671
84977
|
if (!blockXml) {
|
|
84672
|
-
(logger.warn ?? logger.log).call(logger, `[ReolinkBaichuanApi] getStreamMetadata(traceNativeStream): channel=${channel} tag=<${
|
|
84978
|
+
(logger.warn ?? logger.log).call(logger, `[ReolinkBaichuanApi] getStreamMetadata(traceNativeStream): channel=${channel} tag=<${tag2}> missing`);
|
|
84673
84979
|
return;
|
|
84674
84980
|
}
|
|
84675
84981
|
const raw = blockXml;
|
|
@@ -84696,7 +85002,7 @@ var logDebugStreamBlock = (params) => {
|
|
|
84696
85002
|
const previewMax = 1400;
|
|
84697
85003
|
const xmlPreview = raw.length <= previewMax ? raw : raw.slice(0, previewMax) + `
|
|
84698
85004
|
...truncated (+${raw.length - previewMax} chars)`;
|
|
84699
|
-
(logger.warn ?? logger.log).call(logger, `[ReolinkBaichuanApi] getStreamMetadata(traceNativeStream): channel=${channel} tag=<${
|
|
85005
|
+
(logger.warn ?? logger.log).call(logger, `[ReolinkBaichuanApi] getStreamMetadata(traceNativeStream): channel=${channel} tag=<${tag2}> enabled=${isEnabled} plausible=${plausible} width=${width} height=${height} frame=${frameRate} bitRate=${bitRate} audio=${audio} videoEncType=${videoEncTypeText ?? "?"} rawFields=${JSON.stringify({
|
|
84700
85006
|
widthText,
|
|
84701
85007
|
heightText,
|
|
84702
85008
|
frameText,
|
|
@@ -84789,20 +85095,20 @@ var parseChannelStreamMetadataFromGetEncXml = (params) => {
|
|
|
84789
85095
|
audioEnabled = audioEnabled && s.audio === 1;
|
|
84790
85096
|
}
|
|
84791
85097
|
}
|
|
84792
|
-
for (const
|
|
85098
|
+
for (const tag2 of [
|
|
84793
85099
|
"extStream",
|
|
84794
85100
|
"thirdStream",
|
|
84795
85101
|
"externStream",
|
|
84796
85102
|
"extraStream"
|
|
84797
85103
|
]) {
|
|
84798
|
-
const extMatch = xml.match(new RegExp(`<${
|
|
85104
|
+
const extMatch = xml.match(new RegExp(`<${tag2}[^>]*>([\\s\\S]*?)<\\/${tag2}>`));
|
|
84799
85105
|
if (!extMatch) continue;
|
|
84800
85106
|
const extXml = extMatch[1] ?? "";
|
|
84801
85107
|
logDebugStreamBlock({
|
|
84802
85108
|
logger,
|
|
84803
85109
|
traceNativeStream,
|
|
84804
85110
|
channel,
|
|
84805
|
-
tag,
|
|
85111
|
+
tag: tag2,
|
|
84806
85112
|
blockXml: extXml
|
|
84807
85113
|
});
|
|
84808
85114
|
const s = buildStream({
|
|
@@ -84893,7 +85199,7 @@ var sendTalkConfigWithReset = async (params) => {
|
|
|
84893
85199
|
channel: params.channel,
|
|
84894
85200
|
...params.channelIdOverride != null ? { channelIdOverride: params.channelIdOverride } : {},
|
|
84895
85201
|
payloadXml: params.payloadXml,
|
|
84896
|
-
messageClass:
|
|
85202
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
84897
85203
|
})).header.responseCode;
|
|
84898
85204
|
};
|
|
84899
85205
|
const code = await trySend();
|
|
@@ -84903,7 +85209,7 @@ var sendTalkConfigWithReset = async (params) => {
|
|
|
84903
85209
|
channel: params.channel,
|
|
84904
85210
|
...params.channelIdOverride != null ? { channelIdOverride: params.channelIdOverride } : {},
|
|
84905
85211
|
payloadXml: "",
|
|
84906
|
-
messageClass:
|
|
85212
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
84907
85213
|
});
|
|
84908
85214
|
const retryCode = await trySend();
|
|
84909
85215
|
if (retryCode !== 200) throw new Error(`TalkConfig rejected after reset (responseCode ${retryCode})`);
|
|
@@ -84970,7 +85276,7 @@ var createBufferedTalkSession = (params) => {
|
|
|
84970
85276
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
84971
85277
|
extensionXml: buildBinaryExtensionXml(channel),
|
|
84972
85278
|
payload: Buffer.concat(parts),
|
|
84973
|
-
messageClass:
|
|
85279
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
84974
85280
|
});
|
|
84975
85281
|
const playLengthMs = samplesSent / info.audioConfig.sampleRate * 1e3;
|
|
84976
85282
|
const now = Date.now();
|
|
@@ -85016,7 +85322,7 @@ var createBufferedTalkSession = (params) => {
|
|
|
85016
85322
|
channel,
|
|
85017
85323
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
85018
85324
|
payloadXml: "",
|
|
85019
|
-
messageClass:
|
|
85325
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
85020
85326
|
});
|
|
85021
85327
|
if (frame.header.responseCode !== 200) throw new Error(`TalkReset rejected (responseCode ${frame.header.responseCode})`);
|
|
85022
85328
|
if (params.closeSocketOnStop) try {
|
|
@@ -86395,7 +86701,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86395
86701
|
* @param logger - Optional logger for debug output
|
|
86396
86702
|
* @returns The socket and a release function
|
|
86397
86703
|
*/
|
|
86398
|
-
async acquirePooledSocket(
|
|
86704
|
+
async acquirePooledSocket(tag2, logger) {
|
|
86399
86705
|
const log = logger ?? this.logger;
|
|
86400
86706
|
const now = Date.now();
|
|
86401
86707
|
const cooldownEntry = this.socketPoolCooldowns.get(this.host);
|
|
@@ -86406,12 +86712,12 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86406
86712
|
} else if (now < cooldownEntry.cooldownUntil) {
|
|
86407
86713
|
const remainingMs = cooldownEntry.cooldownUntil - now;
|
|
86408
86714
|
const reason = this.lastD2cDiscAtMs > 0 && now - this.lastD2cDiscAtMs < 12e4 ? "D2C_DISC (camera sleeping)" : "repeated login failures";
|
|
86409
|
-
const error = /* @__PURE__ */ new Error(`[SocketPool] Host ${this.host} is in cooldown for ${Math.ceil(remainingMs / 1e3)}s due to ${reason}. tag=${
|
|
86715
|
+
const error = /* @__PURE__ */ new Error(`[SocketPool] Host ${this.host} is in cooldown for ${Math.ceil(remainingMs / 1e3)}s due to ${reason}. tag=${tag2}`);
|
|
86410
86716
|
log?.debug?.(error.message);
|
|
86411
86717
|
throw error;
|
|
86412
86718
|
}
|
|
86413
86719
|
}
|
|
86414
|
-
const existing = this.socketPool.get(
|
|
86720
|
+
const existing = this.socketPool.get(tag2);
|
|
86415
86721
|
if (existing) {
|
|
86416
86722
|
if (existing.idleCloseTimer) {
|
|
86417
86723
|
clearTimeout(existing.idleCloseTimer);
|
|
@@ -86421,35 +86727,35 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86421
86727
|
const client2 = await existing.pendingPromise;
|
|
86422
86728
|
existing.refCount++;
|
|
86423
86729
|
existing.lastUsedAt = Date.now();
|
|
86424
|
-
log?.debug?.(`[SocketPool] Waited for pending socket creation for tag=${
|
|
86730
|
+
log?.debug?.(`[SocketPool] Waited for pending socket creation for tag=${tag2} (refCount=${existing.refCount})`);
|
|
86425
86731
|
return {
|
|
86426
86732
|
client: client2,
|
|
86427
|
-
release: () => this.releasePooledSocket(
|
|
86733
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86428
86734
|
};
|
|
86429
86735
|
}
|
|
86430
86736
|
if (existing.refCount === 0) {
|
|
86431
86737
|
existing.refCount = 1;
|
|
86432
86738
|
existing.lastUsedAt = Date.now();
|
|
86433
|
-
log?.debug?.(`[SocketPool] Reusing idle socket for tag=${
|
|
86739
|
+
log?.debug?.(`[SocketPool] Reusing idle socket for tag=${tag2}`);
|
|
86434
86740
|
try {
|
|
86435
86741
|
if (!existing.client.loggedIn) await existing.client.login();
|
|
86436
86742
|
} catch {}
|
|
86437
86743
|
if (existing.client.loggedIn) return {
|
|
86438
86744
|
client: existing.client,
|
|
86439
|
-
release: () => this.releasePooledSocket(
|
|
86745
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86440
86746
|
};
|
|
86441
|
-
} else if (
|
|
86747
|
+
} else if (tag2.startsWith("replay:")) log?.debug?.(`[SocketPool] Preempting active replay socket for tag=${tag2}`);
|
|
86442
86748
|
else {
|
|
86443
86749
|
existing.refCount++;
|
|
86444
86750
|
existing.lastUsedAt = Date.now();
|
|
86445
|
-
log?.debug?.(`[SocketPool] Reusing active socket for tag=${
|
|
86751
|
+
log?.debug?.(`[SocketPool] Reusing active socket for tag=${tag2} (refCount=${existing.refCount})`);
|
|
86446
86752
|
return {
|
|
86447
86753
|
client: existing.client,
|
|
86448
|
-
release: () => this.releasePooledSocket(
|
|
86754
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86449
86755
|
};
|
|
86450
86756
|
}
|
|
86451
|
-
log?.debug?.(`[SocketPool] Closing existing socket for tag=${
|
|
86452
|
-
this.socketPool.delete(
|
|
86757
|
+
log?.debug?.(`[SocketPool] Closing existing socket for tag=${tag2} (recreating)`);
|
|
86758
|
+
this.socketPool.delete(tag2);
|
|
86453
86759
|
if (existing.generalPermitRelease) {
|
|
86454
86760
|
try {
|
|
86455
86761
|
existing.generalPermitRelease();
|
|
@@ -86462,10 +86768,10 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86462
86768
|
skipLogout: true
|
|
86463
86769
|
});
|
|
86464
86770
|
} catch (e) {
|
|
86465
|
-
log?.warn?.(`[SocketPool] Error closing old socket for tag=${
|
|
86771
|
+
log?.warn?.(`[SocketPool] Error closing old socket for tag=${tag2}: ${e}`);
|
|
86466
86772
|
}
|
|
86467
86773
|
}
|
|
86468
|
-
log?.log?.(`[SocketPool] Creating new socket for tag=${
|
|
86774
|
+
log?.log?.(`[SocketPool] Creating new socket for tag=${tag2}`);
|
|
86469
86775
|
const entry = {
|
|
86470
86776
|
client: void 0,
|
|
86471
86777
|
refCount: 0,
|
|
@@ -86482,7 +86788,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86482
86788
|
} : this.clientOptions);
|
|
86483
86789
|
this.attachD2cDiscListener(newClient);
|
|
86484
86790
|
newClient.on("error", (err) => {
|
|
86485
|
-
log?.debug?.(`[SocketPool] tag=${
|
|
86791
|
+
log?.debug?.(`[SocketPool] tag=${tag2} client error: ${err?.message ?? err}`);
|
|
86486
86792
|
});
|
|
86487
86793
|
await newClient.login();
|
|
86488
86794
|
const existingCooldown = this.socketPoolCooldowns.get(this.host);
|
|
@@ -86494,10 +86800,10 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86494
86800
|
entry.refCount = 1;
|
|
86495
86801
|
entry.lastUsedAt = Date.now();
|
|
86496
86802
|
delete entry.pendingPromise;
|
|
86497
|
-
log?.log?.(`[SocketPool] Socket connected for tag=${
|
|
86498
|
-
if (
|
|
86803
|
+
log?.log?.(`[SocketPool] Socket connected for tag=${tag2}`);
|
|
86804
|
+
if (tag2 !== "general") try {
|
|
86499
86805
|
const generalEntry = this.socketPool.get("general");
|
|
86500
|
-
if (generalEntry?.client) entry.generalPermitRelease = generalEntry.client.acquirePermit(0, `streaming-peer:${
|
|
86806
|
+
if (generalEntry?.client) entry.generalPermitRelease = generalEntry.client.acquirePermit(0, `streaming-peer:${tag2}`);
|
|
86501
86807
|
} catch {}
|
|
86502
86808
|
if (this.sessionGuardEnabled) this.maybeRebootOnTooManySessions();
|
|
86503
86809
|
return newClient;
|
|
@@ -86508,21 +86814,21 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86508
86814
|
if (failureCount >= _ReolinkBaichuanApi.SOCKET_POOL_FAILURE_THRESHOLD) {
|
|
86509
86815
|
const backoffMs = Math.min(_ReolinkBaichuanApi.SOCKET_POOL_BASE_COOLDOWN_MS * Math.pow(2, failureCount - _ReolinkBaichuanApi.SOCKET_POOL_FAILURE_THRESHOLD), _ReolinkBaichuanApi.SOCKET_POOL_MAX_COOLDOWN_MS);
|
|
86510
86816
|
cooldownUntil = now2 + backoffMs;
|
|
86511
|
-
log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}). Entering cooldown for ${Math.ceil(backoffMs / 1e3)}s. tag=${
|
|
86512
|
-
} else log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}/${_ReolinkBaichuanApi.SOCKET_POOL_FAILURE_THRESHOLD} before cooldown). tag=${
|
|
86817
|
+
log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}). Entering cooldown for ${Math.ceil(backoffMs / 1e3)}s. tag=${tag2}`);
|
|
86818
|
+
} else log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}/${_ReolinkBaichuanApi.SOCKET_POOL_FAILURE_THRESHOLD} before cooldown). tag=${tag2}`);
|
|
86513
86819
|
this.socketPoolCooldowns.set(this.host, {
|
|
86514
86820
|
failureCount,
|
|
86515
86821
|
lastFailureAt: now2,
|
|
86516
86822
|
cooldownUntil
|
|
86517
86823
|
});
|
|
86518
|
-
this.socketPool.delete(
|
|
86824
|
+
this.socketPool.delete(tag2);
|
|
86519
86825
|
throw loginError;
|
|
86520
86826
|
}
|
|
86521
86827
|
})();
|
|
86522
|
-
this.socketPool.set(
|
|
86828
|
+
this.socketPool.set(tag2, entry);
|
|
86523
86829
|
return {
|
|
86524
86830
|
client: await entry.pendingPromise,
|
|
86525
|
-
release: () => this.releasePooledSocket(
|
|
86831
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86526
86832
|
};
|
|
86527
86833
|
}
|
|
86528
86834
|
/**
|
|
@@ -86530,31 +86836,31 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86530
86836
|
* For shared sockets (general, streaming), just decrements refCount.
|
|
86531
86837
|
* For replay sockets, schedules idle close.
|
|
86532
86838
|
*/
|
|
86533
|
-
async releasePooledSocket(
|
|
86839
|
+
async releasePooledSocket(tag2, logger) {
|
|
86534
86840
|
const log = logger ?? this.logger;
|
|
86535
|
-
const entry = this.socketPool.get(
|
|
86841
|
+
const entry = this.socketPool.get(tag2);
|
|
86536
86842
|
if (!entry) return;
|
|
86537
86843
|
entry.refCount = Math.max(0, entry.refCount - 1);
|
|
86538
86844
|
entry.lastUsedAt = Date.now();
|
|
86539
|
-
log?.debug?.(`[SocketPool] Released socket for tag=${
|
|
86845
|
+
log?.debug?.(`[SocketPool] Released socket for tag=${tag2} (refCount=${entry.refCount})`);
|
|
86540
86846
|
if (entry.refCount > 0) return;
|
|
86541
|
-
const isReplayTag =
|
|
86542
|
-
const isStreamingTag =
|
|
86543
|
-
if (
|
|
86847
|
+
const isReplayTag = tag2.startsWith("replay:");
|
|
86848
|
+
const isStreamingTag = tag2.startsWith("streaming:");
|
|
86849
|
+
if (tag2 === "general") return;
|
|
86544
86850
|
if (isStreamingTag) {
|
|
86545
86851
|
if (entry.idleCloseTimer) return;
|
|
86546
86852
|
entry.idleCloseTimer = setTimeout(async () => {
|
|
86547
|
-
const current = this.socketPool.get(
|
|
86853
|
+
const current = this.socketPool.get(tag2);
|
|
86548
86854
|
if (!current) return;
|
|
86549
86855
|
if (current.refCount > 0) return;
|
|
86550
|
-
this.socketPool.delete(
|
|
86856
|
+
this.socketPool.delete(tag2);
|
|
86551
86857
|
if (current.generalPermitRelease) {
|
|
86552
86858
|
try {
|
|
86553
86859
|
current.generalPermitRelease();
|
|
86554
86860
|
} catch {}
|
|
86555
86861
|
current.generalPermitRelease = void 0;
|
|
86556
86862
|
}
|
|
86557
|
-
log?.log?.(`[SocketPool] Closing idle streaming socket for tag=${
|
|
86863
|
+
log?.log?.(`[SocketPool] Closing idle streaming socket for tag=${tag2}`);
|
|
86558
86864
|
try {
|
|
86559
86865
|
await current.client.close({
|
|
86560
86866
|
reason: "streaming idle close",
|
|
@@ -86567,11 +86873,11 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86567
86873
|
if (isReplayTag) {
|
|
86568
86874
|
if (entry.idleCloseTimer) return;
|
|
86569
86875
|
entry.idleCloseTimer = setTimeout(async () => {
|
|
86570
|
-
const current = this.socketPool.get(
|
|
86876
|
+
const current = this.socketPool.get(tag2);
|
|
86571
86877
|
if (!current) return;
|
|
86572
86878
|
if (current.refCount > 0) return;
|
|
86573
|
-
this.socketPool.delete(
|
|
86574
|
-
log?.debug?.(`[SocketPool] Closing idle replay socket for tag=${
|
|
86879
|
+
this.socketPool.delete(tag2);
|
|
86880
|
+
log?.debug?.(`[SocketPool] Closing idle replay socket for tag=${tag2} (keepalive expired)`);
|
|
86575
86881
|
try {
|
|
86576
86882
|
await current.client.close({
|
|
86577
86883
|
reason: "replay idle keepalive expired",
|
|
@@ -86581,24 +86887,24 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86581
86887
|
}, _ReolinkBaichuanApi.SOCKET_POOL_KEEPALIVE_MS);
|
|
86582
86888
|
return;
|
|
86583
86889
|
}
|
|
86584
|
-
this.socketPool.delete(
|
|
86890
|
+
this.socketPool.delete(tag2);
|
|
86585
86891
|
try {
|
|
86586
86892
|
await entry.client.close({
|
|
86587
86893
|
reason: "socket pool release",
|
|
86588
86894
|
skipLogout: true
|
|
86589
86895
|
});
|
|
86590
|
-
log?.log?.(`[SocketPool] Closed socket for tag=${
|
|
86896
|
+
log?.log?.(`[SocketPool] Closed socket for tag=${tag2}`);
|
|
86591
86897
|
} catch (e) {
|
|
86592
|
-
log?.warn?.(`[SocketPool] Error closing socket for tag=${
|
|
86898
|
+
log?.warn?.(`[SocketPool] Error closing socket for tag=${tag2}: ${e}`);
|
|
86593
86899
|
}
|
|
86594
86900
|
}
|
|
86595
86901
|
/**
|
|
86596
86902
|
* Force-close a socket by tag.
|
|
86597
86903
|
* Used to preempt existing connections before acquiring a new one.
|
|
86598
86904
|
*/
|
|
86599
|
-
async forceClosePooledSocket(
|
|
86905
|
+
async forceClosePooledSocket(tag2, logger) {
|
|
86600
86906
|
const log = logger ?? this.logger;
|
|
86601
|
-
const entry = this.socketPool.get(
|
|
86907
|
+
const entry = this.socketPool.get(tag2);
|
|
86602
86908
|
if (!entry) return false;
|
|
86603
86909
|
if (entry.idleCloseTimer) {
|
|
86604
86910
|
clearTimeout(entry.idleCloseTimer);
|
|
@@ -86610,16 +86916,16 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86610
86916
|
} catch {}
|
|
86611
86917
|
entry.generalPermitRelease = void 0;
|
|
86612
86918
|
}
|
|
86613
|
-
log?.debug?.(`[SocketPool] Force-closing socket for tag=${
|
|
86614
|
-
this.socketPool.delete(
|
|
86919
|
+
log?.debug?.(`[SocketPool] Force-closing socket for tag=${tag2}`);
|
|
86920
|
+
this.socketPool.delete(tag2);
|
|
86615
86921
|
try {
|
|
86616
86922
|
await entry.client.close({
|
|
86617
86923
|
reason: "force closed",
|
|
86618
86924
|
skipLogout: true
|
|
86619
86925
|
});
|
|
86620
|
-
log?.log?.(`[SocketPool] Force-closed socket for tag=${
|
|
86926
|
+
log?.log?.(`[SocketPool] Force-closed socket for tag=${tag2}`);
|
|
86621
86927
|
} catch (e) {
|
|
86622
|
-
log?.warn?.(`[SocketPool] Error during force-close for tag=${
|
|
86928
|
+
log?.warn?.(`[SocketPool] Error during force-close for tag=${tag2}: ${e}`);
|
|
86623
86929
|
}
|
|
86624
86930
|
return true;
|
|
86625
86931
|
}
|
|
@@ -86629,7 +86935,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86629
86935
|
async cleanupSocketPool() {
|
|
86630
86936
|
const entries = Array.from(this.socketPool.entries());
|
|
86631
86937
|
this.socketPool.clear();
|
|
86632
|
-
await Promise.allSettled(entries.map(async ([
|
|
86938
|
+
await Promise.allSettled(entries.map(async ([tag2, entry]) => {
|
|
86633
86939
|
try {
|
|
86634
86940
|
if (entry.idleCloseTimer) clearTimeout(entry.idleCloseTimer);
|
|
86635
86941
|
if (entry.generalPermitRelease) {
|
|
@@ -86638,7 +86944,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86638
86944
|
} catch {}
|
|
86639
86945
|
entry.generalPermitRelease = void 0;
|
|
86640
86946
|
}
|
|
86641
|
-
this.logger?.debug?.(`[SocketPool] Cleanup: closing tag=${
|
|
86947
|
+
this.logger?.debug?.(`[SocketPool] Cleanup: closing tag=${tag2}`);
|
|
86642
86948
|
await entry.client.close({
|
|
86643
86949
|
reason: "API cleanup",
|
|
86644
86950
|
skipLogout: true
|
|
@@ -86671,17 +86977,17 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86671
86977
|
* ```
|
|
86672
86978
|
*/
|
|
86673
86979
|
async createDedicatedSession(sessionKey, logger) {
|
|
86674
|
-
const
|
|
86675
|
-
(logger ?? this.logger)?.debug?.(`[SocketPool] createDedicatedSession sessionKey=${sessionKey} \u2192 tag=${
|
|
86676
|
-
return await this.acquirePooledSocket(
|
|
86980
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
86981
|
+
(logger ?? this.logger)?.debug?.(`[SocketPool] createDedicatedSession sessionKey=${sessionKey} \u2192 tag=${tag2}`);
|
|
86982
|
+
return await this.acquirePooledSocket(tag2, logger);
|
|
86677
86983
|
}
|
|
86678
86984
|
/**
|
|
86679
86985
|
* @deprecated Use forceClosePooledSocket via createDedicatedSession instead.
|
|
86680
86986
|
* Force-close a dedicated client if it exists.
|
|
86681
86987
|
*/
|
|
86682
86988
|
async forceCloseDedicatedClient(sessionKey, logger) {
|
|
86683
|
-
const
|
|
86684
|
-
return await this.forceClosePooledSocket(
|
|
86989
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
86990
|
+
return await this.forceClosePooledSocket(tag2, logger);
|
|
86685
86991
|
}
|
|
86686
86992
|
/**
|
|
86687
86993
|
* @deprecated Cleanup handled by cleanupSocketPool now.
|
|
@@ -86696,8 +87002,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86696
87002
|
const debugCfg = this.client.getDebugConfig?.();
|
|
86697
87003
|
if (debugCfg) {
|
|
86698
87004
|
const sid = this.client.getSocketSessionId?.();
|
|
86699
|
-
const
|
|
86700
|
-
|
|
87005
|
+
const tag2 = sid ? `ReolinkSimpleEvent sid=${sid}` : "ReolinkSimpleEvent";
|
|
87006
|
+
require_chunk_ZQFQRCLQ.eventTraceLog(debugCfg, this.logger, tag2, `dispatch type=${evt.type} channel=${evt.channel} timestamp=${evt.timestamp}`);
|
|
86701
87007
|
}
|
|
86702
87008
|
for (const cb of this.simpleEventListeners) try {
|
|
86703
87009
|
Promise.resolve(cb(evt)).catch((e) => {
|
|
@@ -86708,7 +87014,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86708
87014
|
}
|
|
86709
87015
|
}
|
|
86710
87016
|
constructor(opts) {
|
|
86711
|
-
const dbg =
|
|
87017
|
+
const dbg = require_chunk_ZQFQRCLQ.normalizeDebugOptions(opts.debugOptions);
|
|
86712
87018
|
this.logger = createDebugGateLogger(opts.logger, dbg.general || dbg.traceNativeStream || dbg.traceRecordings || dbg.traceTalk || dbg.traceEvents || dbg.debugRtsp);
|
|
86713
87019
|
this.clientOptions = {
|
|
86714
87020
|
host: opts.host,
|
|
@@ -87295,7 +87601,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87295
87601
|
return;
|
|
87296
87602
|
}
|
|
87297
87603
|
entry.startInFlight = (async () => {
|
|
87298
|
-
const { BaichuanVideoStream: BaichuanVideoStream2 } = await Promise.resolve().then(() => require("./BaichuanVideoStream-
|
|
87604
|
+
const { BaichuanVideoStream: BaichuanVideoStream2 } = await Promise.resolve().then(() => require("./BaichuanVideoStream-2M4UO7MB-Cqjt1oxu.js"));
|
|
87299
87605
|
const sessionKey = `live:object-detections:ch${entry.channel}:${entry.profile}`;
|
|
87300
87606
|
const dedicated = await this.createDedicatedSession(sessionKey);
|
|
87301
87607
|
const stream$12 = new BaichuanVideoStream2({
|
|
@@ -87772,7 +88078,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87772
88078
|
channel: ch,
|
|
87773
88079
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
87774
88080
|
payloadXml: "",
|
|
87775
|
-
messageClass:
|
|
88081
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
87776
88082
|
});
|
|
87777
88083
|
if (frame.header.responseCode !== 200) throw new Error(`TalkReset rejected (responseCode ${frame.header.responseCode})`);
|
|
87778
88084
|
}
|
|
@@ -87791,7 +88097,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87791
88097
|
channel: ch,
|
|
87792
88098
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
87793
88099
|
payloadXml,
|
|
87794
|
-
messageClass:
|
|
88100
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
87795
88101
|
})).header.responseCode;
|
|
87796
88102
|
};
|
|
87797
88103
|
const code = await trySend();
|
|
@@ -87862,8 +88168,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87862
88168
|
const idleTimeoutMs = options?.idleTimeoutMs ?? 3e4;
|
|
87863
88169
|
const sessionKey = `talk:${options?.deviceId ?? "unknown"}:ch${channel}:${Date.now()}`;
|
|
87864
88170
|
logger?.info?.(`[DedicatedTalk] Creating session: ${sessionKey} (idleTimeout=${idleTimeoutMs}ms)`);
|
|
87865
|
-
const
|
|
87866
|
-
const { client: dedicatedClient, release } = await this.acquirePooledSocket(
|
|
88171
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
88172
|
+
const { client: dedicatedClient, release } = await this.acquirePooledSocket(tag2, logger);
|
|
87867
88173
|
const summary = this.getSocketPoolSummary();
|
|
87868
88174
|
logger?.info?.(`[DedicatedTalk] Session created [sessions: ${summary.count} active${summary.count > 0 ? ` (${summary.tags.join(", ")})` : ""}]`);
|
|
87869
88175
|
try {
|
|
@@ -87943,7 +88249,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87943
88249
|
cmdId: 10,
|
|
87944
88250
|
channel,
|
|
87945
88251
|
payloadXml: "",
|
|
87946
|
-
messageClass:
|
|
88252
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
87947
88253
|
});
|
|
87948
88254
|
return parseTalkAbilityXml(frame.body.length === 0 ? "" : client.tryDecryptXml(frame.body, frame.header.channelId, client.enc));
|
|
87949
88255
|
}
|
|
@@ -87976,8 +88282,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87976
88282
|
}
|
|
87977
88283
|
/** SetNetPort via Baichuan: cmd_id 36 (enable/disable rtsp/rtmp/onvif/http/https) */
|
|
87978
88284
|
async setPortEnabled(params) {
|
|
87979
|
-
const
|
|
87980
|
-
const xml = `<?xml version="1.0" encoding="UTF-8" ?><body><${
|
|
88285
|
+
const tag2 = `${params.port[0].toUpperCase()}${params.port.slice(1)}Port`;
|
|
88286
|
+
const xml = `<?xml version="1.0" encoding="UTF-8" ?><body><${tag2} version="1.1"><enable>${params.enable ? 1 : 0}</enable></${tag2}></body>`;
|
|
87981
88287
|
await this.sendXml({
|
|
87982
88288
|
cmdId: 36,
|
|
87983
88289
|
payloadXml: xml
|
|
@@ -88008,13 +88314,13 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
88008
88314
|
*/
|
|
88009
88315
|
async setPortConfig(patch) {
|
|
88010
88316
|
const blocks = [];
|
|
88011
|
-
const append = (
|
|
88317
|
+
const append = (tag2, portField, cfg) => {
|
|
88012
88318
|
if (!cfg) return;
|
|
88013
88319
|
if (cfg.port === void 0 && cfg.enable === void 0) return;
|
|
88014
88320
|
const inner = [];
|
|
88015
88321
|
if (cfg.port !== void 0) inner.push(`<${portField}>${cfg.port}</${portField}>`);
|
|
88016
88322
|
if (cfg.enable !== void 0) inner.push(`<enable>${cfg.enable ? 1 : 0}</enable>`);
|
|
88017
|
-
blocks.push(`<${
|
|
88323
|
+
blocks.push(`<${tag2} version="1.1">${inner.join("")}</${tag2}>`);
|
|
88018
88324
|
};
|
|
88019
88325
|
append("ServerPort", "serverPort", patch.server);
|
|
88020
88326
|
append("HttpPort", "httpPort", patch.http);
|
|
@@ -88528,8 +88834,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
88528
88834
|
];
|
|
88529
88835
|
const current = await this.getEncXml(ch);
|
|
88530
88836
|
let updated = null;
|
|
88531
|
-
for (const
|
|
88532
|
-
const sectionRe = new RegExp(`(<${
|
|
88837
|
+
for (const tag2 of candidateTags) {
|
|
88838
|
+
const sectionRe = new RegExp(`(<${tag2}[^>]*>[\\s\\S]*?<videoEncType>)(\\d+)(</videoEncType>)`);
|
|
88533
88839
|
if (!sectionRe.test(current)) continue;
|
|
88534
88840
|
const next = current.replace(sectionRe, `$1${desired}$3`);
|
|
88535
88841
|
if (next !== current) {
|
|
@@ -89015,8 +89321,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89015
89321
|
const start = params.start;
|
|
89016
89322
|
const endOfStartDay = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 23, 59, 59, 999);
|
|
89017
89323
|
const end = params.end.getTime() > endOfStartDay.getTime() ? endOfStartDay : params.end;
|
|
89018
|
-
|
|
89019
|
-
|
|
89324
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclips", `Query: start=${start.toISOString()}, end=${end.toISOString()} (forced same day)`);
|
|
89325
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclips", `Using UID for channel ${channel}: ${uid}`);
|
|
89020
89326
|
const streamType = params.streamType ?? "subStream";
|
|
89021
89327
|
const recordType = params.recordType ?? "manual, sched, io, md, people, face, vehicle, dog_cat, visitor, other, package";
|
|
89022
89328
|
const maxIterations = params.maxIterations ?? 50;
|
|
@@ -89036,7 +89342,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89036
89342
|
...params.timeoutMs != null ? { timeoutMs: params.timeoutMs } : {}
|
|
89037
89343
|
});
|
|
89038
89344
|
const unique = dedupeRecordingFiles(files);
|
|
89039
|
-
|
|
89345
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclips", `FileInfoList complete: ${unique.length} unique files (from ${files.length} total)`);
|
|
89040
89346
|
return unique;
|
|
89041
89347
|
});
|
|
89042
89348
|
}
|
|
@@ -89059,9 +89365,9 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89059
89365
|
const streamType = params.streamType;
|
|
89060
89366
|
const logger = params.logger ?? this.logger;
|
|
89061
89367
|
const sessionKey = params.deviceId ? `replay:${params.deviceId}:ch${channel}` : `replay:standalone:ch${channel}:${Date.now()}`;
|
|
89062
|
-
const
|
|
89063
|
-
logger?.debug?.(`[startRecordingReplayStreamStandalone] sessionKey=${sessionKey} -> tag=${
|
|
89064
|
-
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(
|
|
89368
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
89369
|
+
logger?.debug?.(`[startRecordingReplayStreamStandalone] sessionKey=${sessionKey} -> tag=${tag2}`);
|
|
89370
|
+
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(tag2, logger);
|
|
89065
89371
|
const uid = await this.ensureUidForRecordings(channel, void 0);
|
|
89066
89372
|
const payloadXml = buildFileInfoListReplayByNameXml({
|
|
89067
89373
|
channel,
|
|
@@ -89072,7 +89378,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89072
89378
|
});
|
|
89073
89379
|
const msgNum = 0;
|
|
89074
89380
|
dedicatedClient.subscribeVideoStream(5, msgNum);
|
|
89075
|
-
const stream$14 = new
|
|
89381
|
+
const stream$14 = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
89076
89382
|
client: dedicatedClient,
|
|
89077
89383
|
channel,
|
|
89078
89384
|
profile: streamType === "subStream" ? "sub" : "main",
|
|
@@ -89091,7 +89397,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89091
89397
|
channel,
|
|
89092
89398
|
channelIdOverride: sessionCounter,
|
|
89093
89399
|
payloadXml,
|
|
89094
|
-
messageClass:
|
|
89400
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89095
89401
|
msgNumOverride: 0,
|
|
89096
89402
|
timeoutMs: params.timeoutMs,
|
|
89097
89403
|
internal: true
|
|
@@ -89123,7 +89429,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89123
89429
|
cmdId: 7,
|
|
89124
89430
|
channel,
|
|
89125
89431
|
payloadXml: stopXml,
|
|
89126
|
-
messageClass:
|
|
89432
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89127
89433
|
timeoutMs: 2e3,
|
|
89128
89434
|
internal: true
|
|
89129
89435
|
});
|
|
@@ -89164,8 +89470,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89164
89470
|
const streamType = params.streamType;
|
|
89165
89471
|
const logger = params.logger ?? this.logger;
|
|
89166
89472
|
const sessionKey = params.deviceId ? `replay:${params.deviceId}:ch${channel}` : `replay:nvr:ch${channel}:${Date.now()}`;
|
|
89167
|
-
const
|
|
89168
|
-
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(
|
|
89473
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
89474
|
+
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(tag2, logger);
|
|
89169
89475
|
let uid;
|
|
89170
89476
|
try {
|
|
89171
89477
|
uid = await this.ensureUidForRecordings(channel, void 0);
|
|
@@ -89180,7 +89486,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89180
89486
|
});
|
|
89181
89487
|
const msgNum = 0;
|
|
89182
89488
|
dedicatedClient.subscribeVideoStream(5, msgNum);
|
|
89183
|
-
const stream$15 = new
|
|
89489
|
+
const stream$15 = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
89184
89490
|
client: dedicatedClient,
|
|
89185
89491
|
channel,
|
|
89186
89492
|
profile: streamType === "subStream" ? "sub" : "main",
|
|
@@ -89200,7 +89506,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89200
89506
|
channelIdOverride,
|
|
89201
89507
|
payloadXml,
|
|
89202
89508
|
extensionXml: "",
|
|
89203
|
-
messageClass:
|
|
89509
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89204
89510
|
msgNumOverride: msgNum,
|
|
89205
89511
|
timeoutMs: params.timeoutMs,
|
|
89206
89512
|
internal: true
|
|
@@ -89232,7 +89538,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89232
89538
|
cmdId: 7,
|
|
89233
89539
|
channel,
|
|
89234
89540
|
payloadXml: stopXml,
|
|
89235
|
-
messageClass:
|
|
89541
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89236
89542
|
timeoutMs: 2e3,
|
|
89237
89543
|
internal: true
|
|
89238
89544
|
});
|
|
@@ -89319,30 +89625,30 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89319
89625
|
async ensureUidForRecordings(channel, explicitUid) {
|
|
89320
89626
|
const dbg = this.client.getDebugConfig?.();
|
|
89321
89627
|
const logger = this.logger;
|
|
89322
|
-
|
|
89628
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Checking UID: explicitUid=${explicitUid}, this.uid=${this.uid}`);
|
|
89323
89629
|
const trimmedExplicit = explicitUid?.trim();
|
|
89324
89630
|
if (trimmedExplicit) {
|
|
89325
|
-
|
|
89631
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using explicit UID: ${trimmedExplicit}`);
|
|
89326
89632
|
return trimmedExplicit;
|
|
89327
89633
|
}
|
|
89328
89634
|
const perChannel = await this.discoverUidForRecordingsForChannel(channel);
|
|
89329
89635
|
if (perChannel) {
|
|
89330
|
-
|
|
89636
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using per-channel UID: ${perChannel}`);
|
|
89331
89637
|
return perChannel;
|
|
89332
89638
|
}
|
|
89333
89639
|
const configured = this.uid?.trim();
|
|
89334
89640
|
if (configured) {
|
|
89335
|
-
|
|
89641
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using configured UID: ${configured}`);
|
|
89336
89642
|
return configured;
|
|
89337
89643
|
}
|
|
89338
89644
|
if (this.nativeOnly) {
|
|
89339
|
-
|
|
89645
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Native-only: no UID available (channel=${channel})`);
|
|
89340
89646
|
throw new Error("UID is required to access recordings in native-only mode. Provide a UID explicitly, configure the client with a UID, or wait for cmd_id=145 push cache to populate per-channel UIDs.");
|
|
89341
89647
|
}
|
|
89342
|
-
|
|
89648
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `No UID available, attempting device auto-discovery (ch=${channel})`);
|
|
89343
89649
|
const discovered = await this.discoverDeviceUidForRecordings(channel);
|
|
89344
89650
|
if (discovered) return discovered;
|
|
89345
|
-
|
|
89651
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Auto-discovery failed - no UID found`);
|
|
89346
89652
|
throw new Error("UID is required to access recordings. Provide a UID explicitly or configure the client with a UID.");
|
|
89347
89653
|
}
|
|
89348
89654
|
cacheChannelUid(channel, uid) {
|
|
@@ -89365,35 +89671,35 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89365
89671
|
const logger = this.logger;
|
|
89366
89672
|
const fromPush = this.getUidFromPushCacheForChannel(channel);
|
|
89367
89673
|
if (fromPush) {
|
|
89368
|
-
|
|
89674
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using per-channel UID from push cache: ${fromPush}`);
|
|
89369
89675
|
return fromPush;
|
|
89370
89676
|
}
|
|
89371
89677
|
if (this.nativeOnly) {
|
|
89372
|
-
|
|
89678
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Native-only: skipping per-channel UID discovery via HTTP/CGI (channel=${channel})`);
|
|
89373
89679
|
return;
|
|
89374
89680
|
}
|
|
89375
89681
|
try {
|
|
89376
|
-
|
|
89682
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Attempting per-channel UID discovery via HTTP CGI GetChannelstatus (channel=${channel})`);
|
|
89377
89683
|
const uidCandidate = await discoverPerChannelUidViaCgiChannelstatus({
|
|
89378
89684
|
channel,
|
|
89379
89685
|
login: () => this.cgiApi.login(),
|
|
89380
89686
|
getChannelstatus: () => this.cgiApi.GetChannelstatus()
|
|
89381
89687
|
});
|
|
89382
|
-
|
|
89688
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `[HTTP CGI] GetChannelstatus channel=${channel} uid=${uidCandidate || "(missing)"}`);
|
|
89383
89689
|
if (uidCandidate) {
|
|
89384
89690
|
this.cacheChannelUid(channel, uidCandidate);
|
|
89385
|
-
|
|
89691
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using per-channel UID from GetChannelstatus: ${uidCandidate}`);
|
|
89386
89692
|
return uidCandidate;
|
|
89387
89693
|
}
|
|
89388
89694
|
} catch (e) {
|
|
89389
|
-
|
|
89695
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `[HTTP CGI] GetChannelstatus failed: ${formatErrorForLog(e)}`);
|
|
89390
89696
|
}
|
|
89391
89697
|
}
|
|
89392
89698
|
async discoverDeviceUidForRecordings(channel) {
|
|
89393
89699
|
if (this.nativeOnly) return void 0;
|
|
89394
89700
|
const dbg = this.client.getDebugConfig?.();
|
|
89395
89701
|
const logger = this.logger;
|
|
89396
|
-
const trace = (message) =>
|
|
89702
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", message);
|
|
89397
89703
|
const discoveredUid = await discoverDeviceUidForRecordings({
|
|
89398
89704
|
channel,
|
|
89399
89705
|
getInfo: () => this.getInfo(),
|
|
@@ -89468,7 +89774,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89468
89774
|
await this.client.login();
|
|
89469
89775
|
const dbg = this.client.getDebugConfig?.();
|
|
89470
89776
|
const logger = this.logger;
|
|
89471
|
-
const trace = (message) =>
|
|
89777
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclipThumbnail", message);
|
|
89472
89778
|
const channel = this.normalizeChannel(params.channel);
|
|
89473
89779
|
const snapStreamType = (params.snapType ?? "sub") === "main" ? "mainStream" : "subStream";
|
|
89474
89780
|
const timeoutMs = params.timeoutMs ?? 3e4;
|
|
@@ -89519,7 +89825,7 @@ ${xml}`);
|
|
|
89519
89825
|
cmdId: 298,
|
|
89520
89826
|
...isNvr && headerChannelIdOverride != null ? { channelIdOverride: headerChannelIdOverride } : {},
|
|
89521
89827
|
msgNumOverride: 0,
|
|
89522
|
-
messageClass:
|
|
89828
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89523
89829
|
streamType: 0,
|
|
89524
89830
|
payloadXml: xml,
|
|
89525
89831
|
timeoutMs
|
|
@@ -89996,7 +90302,7 @@ ${stderr}`));
|
|
|
89996
90302
|
await this.client.login();
|
|
89997
90303
|
const dbg = this.client.getDebugConfig?.();
|
|
89998
90304
|
const logger = this.logger;
|
|
89999
|
-
const trace = (message) =>
|
|
90305
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "fileInfoListDownload", message);
|
|
90000
90306
|
const channel = this.normalizeChannel(params.channel);
|
|
90001
90307
|
const uid = await this.ensureUidForRecordings(channel, params.uid);
|
|
90002
90308
|
const headerChannelIdOverride = this.resolveHeaderChannelIdForLogicalChannel(channel);
|
|
@@ -90042,7 +90348,7 @@ ${stderr}`));
|
|
|
90042
90348
|
cmdId: 13,
|
|
90043
90349
|
channel,
|
|
90044
90350
|
...typeof chId === "number" ? { channelIdOverride: chId } : {},
|
|
90045
|
-
messageClass:
|
|
90351
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_FILE_DOWNLOAD,
|
|
90046
90352
|
extensionXml: buildBinaryExtensionXml(channel),
|
|
90047
90353
|
payloadXml,
|
|
90048
90354
|
streamType: st,
|
|
@@ -90071,7 +90377,7 @@ ${stderr}`));
|
|
|
90071
90377
|
await this.client.login();
|
|
90072
90378
|
const dbg = this.client.getDebugConfig?.();
|
|
90073
90379
|
const logger = this.logger;
|
|
90074
|
-
const trace = (message) =>
|
|
90380
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "fileInfoListPagedDownload", message);
|
|
90075
90381
|
const channel = this.normalizeChannel(params.channel);
|
|
90076
90382
|
const uid = await this.ensureUidForRecordings(channel, params.uid);
|
|
90077
90383
|
trace(`Starting paged download: channel=${channel}, uid=${uid}, fileName=${params.fileName}`);
|
|
@@ -90108,7 +90414,7 @@ ${stderr}`));
|
|
|
90108
90414
|
await this.client.login();
|
|
90109
90415
|
const dbg = this.client.getDebugConfig?.();
|
|
90110
90416
|
const logger = this.logger;
|
|
90111
|
-
const trace = (message) =>
|
|
90417
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "fileInfoListReplayBinaryDownload", message);
|
|
90112
90418
|
const channel = this.normalizeChannel(params.channel);
|
|
90113
90419
|
const headerChannelIdOverride = this.resolveHeaderChannelIdForLogicalChannel(channel);
|
|
90114
90420
|
const ident = params.fileName;
|
|
@@ -90137,7 +90443,7 @@ ${stderr}`));
|
|
|
90137
90443
|
channel,
|
|
90138
90444
|
...isNvr ? { channelIdOverride: headerChannelIdOverride ?? 82 } : {},
|
|
90139
90445
|
msgNumOverride: 0,
|
|
90140
|
-
messageClass:
|
|
90446
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
90141
90447
|
payloadXml,
|
|
90142
90448
|
streamType: 0,
|
|
90143
90449
|
timeoutMs
|
|
@@ -90221,7 +90527,7 @@ ${stderr}`));
|
|
|
90221
90527
|
async downloadRecordingDemuxed(params) {
|
|
90222
90528
|
const raw = await this.downloadRecording(params);
|
|
90223
90529
|
const frames = [];
|
|
90224
|
-
const decoder = new
|
|
90530
|
+
const decoder = new require_chunk_ZQFQRCLQ.BcMediaAnnexBDecoder({
|
|
90225
90531
|
strict: false,
|
|
90226
90532
|
logger: this.logger,
|
|
90227
90533
|
onVideoAccessUnit: ({ annexB }) => {
|
|
@@ -90268,7 +90574,7 @@ ${stderr}`));
|
|
|
90268
90574
|
const videoFrames = [];
|
|
90269
90575
|
const audioFrames = [];
|
|
90270
90576
|
let audioCodec = null;
|
|
90271
|
-
const decoder = new
|
|
90577
|
+
const decoder = new require_chunk_ZQFQRCLQ.BcMediaAnnexBDecoder({
|
|
90272
90578
|
strict: false,
|
|
90273
90579
|
logger: this.logger,
|
|
90274
90580
|
onVideoAccessUnit: ({ annexB, microseconds }) => {
|
|
@@ -90682,7 +90988,7 @@ ${stderr}`));
|
|
|
90682
90988
|
params: {
|
|
90683
90989
|
cmdId: 31,
|
|
90684
90990
|
channelIdOverride: channel,
|
|
90685
|
-
messageClass:
|
|
90991
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
90686
90992
|
}
|
|
90687
90993
|
},
|
|
90688
90994
|
{
|
|
@@ -90690,7 +90996,7 @@ ${stderr}`));
|
|
|
90690
90996
|
params: {
|
|
90691
90997
|
cmdId: 31,
|
|
90692
90998
|
channelIdOverride: 251,
|
|
90693
|
-
messageClass:
|
|
90999
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
90694
91000
|
}
|
|
90695
91001
|
},
|
|
90696
91002
|
{
|
|
@@ -90698,7 +91004,7 @@ ${stderr}`));
|
|
|
90698
91004
|
params: {
|
|
90699
91005
|
cmdId: 31,
|
|
90700
91006
|
channelIdOverride: 250,
|
|
90701
|
-
messageClass:
|
|
91007
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
90702
91008
|
}
|
|
90703
91009
|
},
|
|
90704
91010
|
{
|
|
@@ -90706,7 +91012,7 @@ ${stderr}`));
|
|
|
90706
91012
|
params: {
|
|
90707
91013
|
cmdId: 31,
|
|
90708
91014
|
channelIdOverride: 250,
|
|
90709
|
-
messageClass:
|
|
91015
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
90710
91016
|
extensionXml: `<?xml version="1.0" encoding="UTF-8" ?><Extension version="1.1"><channelId>251</channelId></Extension>`
|
|
90711
91017
|
}
|
|
90712
91018
|
}
|
|
@@ -90749,7 +91055,7 @@ ${stderr}`));
|
|
|
90749
91055
|
const frame = await this.client.sendFrame({
|
|
90750
91056
|
cmdId: 31,
|
|
90751
91057
|
channelIdOverride: Number(channel),
|
|
90752
|
-
messageClass:
|
|
91058
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
90753
91059
|
timeoutMs
|
|
90754
91060
|
});
|
|
90755
91061
|
lastCode = frame.header.responseCode;
|
|
@@ -91030,7 +91336,7 @@ ${stderr}`));
|
|
|
91030
91336
|
msgNumOverride: msgNum,
|
|
91031
91337
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91032
91338
|
payloadXml,
|
|
91033
|
-
messageClass:
|
|
91339
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91034
91340
|
streamType: config.streamType,
|
|
91035
91341
|
timeoutMs: 2e4
|
|
91036
91342
|
};
|
|
@@ -91162,7 +91468,7 @@ ${stderr}`));
|
|
|
91162
91468
|
channelIdOverride: channelId,
|
|
91163
91469
|
extensionXml: a.extensionXml,
|
|
91164
91470
|
payloadXml: a.payloadXml,
|
|
91165
|
-
messageClass:
|
|
91471
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91166
91472
|
streamType: a.streamType,
|
|
91167
91473
|
...msgNum !== void 0 ? { msgNumOverride: msgNum } : {},
|
|
91168
91474
|
timeoutMs: 2e3
|
|
@@ -91192,7 +91498,7 @@ ${stderr}`));
|
|
|
91192
91498
|
channel: ch,
|
|
91193
91499
|
channelIdOverride: channelId,
|
|
91194
91500
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91195
|
-
messageClass:
|
|
91501
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91196
91502
|
streamType: 0
|
|
91197
91503
|
});
|
|
91198
91504
|
} catch (e) {
|
|
@@ -91234,7 +91540,7 @@ ${stderr}`));
|
|
|
91234
91540
|
channel: ch,
|
|
91235
91541
|
channelIdOverride: channelId,
|
|
91236
91542
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91237
|
-
messageClass:
|
|
91543
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91238
91544
|
streamType: 0
|
|
91239
91545
|
});
|
|
91240
91546
|
} catch (e) {
|
|
@@ -91256,7 +91562,7 @@ ${stderr}`));
|
|
|
91256
91562
|
channelIdOverride: channelId,
|
|
91257
91563
|
extensionXml,
|
|
91258
91564
|
payloadXml,
|
|
91259
|
-
messageClass:
|
|
91565
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91260
91566
|
streamType: 0
|
|
91261
91567
|
});
|
|
91262
91568
|
if (frame.header.responseCode !== 200) {
|
|
@@ -91288,7 +91594,7 @@ ${stderr}`));
|
|
|
91288
91594
|
channelIdOverride: channelId,
|
|
91289
91595
|
extensionXml,
|
|
91290
91596
|
payloadXml,
|
|
91291
|
-
messageClass:
|
|
91597
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91292
91598
|
streamType: 0
|
|
91293
91599
|
});
|
|
91294
91600
|
if (frame.header.responseCode !== 200) throw new Error(`PTZ preset move rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91309,7 +91615,7 @@ ${stderr}`));
|
|
|
91309
91615
|
channelIdOverride: channelId,
|
|
91310
91616
|
extensionXml,
|
|
91311
91617
|
payloadXml,
|
|
91312
|
-
messageClass:
|
|
91618
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91313
91619
|
streamType: 0
|
|
91314
91620
|
});
|
|
91315
91621
|
if (frame.header.responseCode !== 200) throw new Error(`PTZ preset save rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91326,7 +91632,7 @@ ${stderr}`));
|
|
|
91326
91632
|
channelIdOverride: channelId,
|
|
91327
91633
|
extensionXml,
|
|
91328
91634
|
payloadXml,
|
|
91329
|
-
messageClass:
|
|
91635
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91330
91636
|
streamType: 0
|
|
91331
91637
|
});
|
|
91332
91638
|
if (frame.header.responseCode !== 200) throw new Error(`PTZ goto preset rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91353,7 +91659,7 @@ ${stderr}`));
|
|
|
91353
91659
|
channelIdOverride: channelId,
|
|
91354
91660
|
extensionXml,
|
|
91355
91661
|
payloadXml,
|
|
91356
|
-
messageClass:
|
|
91662
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91357
91663
|
streamType: 0
|
|
91358
91664
|
})).header.responseCode };
|
|
91359
91665
|
},
|
|
@@ -91392,6 +91698,73 @@ ${stderr}`));
|
|
|
91392
91698
|
return result;
|
|
91393
91699
|
}
|
|
91394
91700
|
/**
|
|
91701
|
+
* Read the PTZ guard point ("monitoring point" in the app).
|
|
91702
|
+
*
|
|
91703
|
+
* cmd_id: 332
|
|
91704
|
+
*
|
|
91705
|
+
* Returns `null` when the camera has no readable guard configuration — never
|
|
91706
|
+
* a fabricated "none", because that answer is what a consumer uses to decide
|
|
91707
|
+
* whether to move the head.
|
|
91708
|
+
*/
|
|
91709
|
+
async getPtzGuard(channel) {
|
|
91710
|
+
const ch = this.normalizeChannel(channel);
|
|
91711
|
+
return parsePtzGuardXml(await this.sendXml({
|
|
91712
|
+
cmdId: 332,
|
|
91713
|
+
channel: ch,
|
|
91714
|
+
channelIdOverride: ch,
|
|
91715
|
+
extensionXml: buildPtzGuardExtensionXml(ch, "read"),
|
|
91716
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91717
|
+
streamType: 0
|
|
91718
|
+
}));
|
|
91719
|
+
}
|
|
91720
|
+
/**
|
|
91721
|
+
* Configure the PTZ guard point.
|
|
91722
|
+
*
|
|
91723
|
+
* cmd_id: 331 with `<command>setGrd</command>`
|
|
91724
|
+
*
|
|
91725
|
+
* `setPosition` pins the guard point to the head's CURRENT position. Leave it
|
|
91726
|
+
* false when only changing the timeout or the enable flag: re-sending it
|
|
91727
|
+
* would silently move a point the operator had already placed.
|
|
91728
|
+
*/
|
|
91729
|
+
async setPtzGuard(options, channel) {
|
|
91730
|
+
const ch = this.normalizeChannel(channel);
|
|
91731
|
+
await this.sendXml({
|
|
91732
|
+
cmdId: 331,
|
|
91733
|
+
channel: ch,
|
|
91734
|
+
channelIdOverride: ch,
|
|
91735
|
+
extensionXml: buildPtzGuardExtensionXml(ch, "write"),
|
|
91736
|
+
payloadXml: buildPtzGuardSetXml({
|
|
91737
|
+
channelId: ch,
|
|
91738
|
+
enabled: options.enabled,
|
|
91739
|
+
timeoutSeconds: options.timeoutSeconds,
|
|
91740
|
+
setPosition: options.setPosition === true
|
|
91741
|
+
}),
|
|
91742
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91743
|
+
streamType: 0
|
|
91744
|
+
});
|
|
91745
|
+
}
|
|
91746
|
+
/**
|
|
91747
|
+
* Send the head to the guard point NOW.
|
|
91748
|
+
*
|
|
91749
|
+
* cmd_id: 331 with `<command>toGrd</command>`
|
|
91750
|
+
*
|
|
91751
|
+
* This is the closest thing Baichuan has to a "go home": the guard point is
|
|
91752
|
+
* an operator-placed position, unlike preset slot 0 which merely happens to
|
|
91753
|
+
* be first.
|
|
91754
|
+
*/
|
|
91755
|
+
async goToPtzGuard(channel) {
|
|
91756
|
+
const ch = this.normalizeChannel(channel);
|
|
91757
|
+
await this.sendXml({
|
|
91758
|
+
cmdId: 331,
|
|
91759
|
+
channel: ch,
|
|
91760
|
+
channelIdOverride: ch,
|
|
91761
|
+
extensionXml: buildPtzGuardExtensionXml(ch, "write"),
|
|
91762
|
+
payloadXml: buildPtzGuardGoXml(ch),
|
|
91763
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91764
|
+
streamType: 0
|
|
91765
|
+
});
|
|
91766
|
+
}
|
|
91767
|
+
/**
|
|
91395
91768
|
* Read zoom/focus min/max/current positions.
|
|
91396
91769
|
* cmd_id: 294 (MSG_ID_GET_ZOOM_FOCUS)
|
|
91397
91770
|
*/
|
|
@@ -91403,7 +91776,7 @@ ${stderr}`));
|
|
|
91403
91776
|
channel: ch,
|
|
91404
91777
|
channelIdOverride: channelId,
|
|
91405
91778
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91406
|
-
messageClass:
|
|
91779
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91407
91780
|
streamType: 0
|
|
91408
91781
|
});
|
|
91409
91782
|
const parseTriplet = (sectionTag) => {
|
|
@@ -91441,7 +91814,7 @@ ${stderr}`));
|
|
|
91441
91814
|
channelIdOverride: channelId,
|
|
91442
91815
|
extensionXml,
|
|
91443
91816
|
payloadXml,
|
|
91444
|
-
messageClass:
|
|
91817
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91445
91818
|
streamType: 0
|
|
91446
91819
|
});
|
|
91447
91820
|
if (frame.header.responseCode !== 200) throw new Error(`Zoom rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91484,10 +91857,10 @@ ${stderr}`));
|
|
|
91484
91857
|
notifyD2cDisc() {
|
|
91485
91858
|
const now = Date.now();
|
|
91486
91859
|
this.lastD2cDiscAtMs = now;
|
|
91487
|
-
const streamingTags = Array.from(this.socketPool.keys()).filter((
|
|
91860
|
+
const streamingTags = Array.from(this.socketPool.keys()).filter((tag2) => tag2.startsWith("streaming:"));
|
|
91488
91861
|
if (streamingTags.length > 0) {
|
|
91489
91862
|
this.logger?.log?.(`[D2C_DISC] Force-closing ${streamingTags.length} streaming socket(s): ${streamingTags.join(", ")}`);
|
|
91490
|
-
for (const
|
|
91863
|
+
for (const tag2 of streamingTags) this.forceClosePooledSocket(tag2, this.logger).catch(() => {});
|
|
91491
91864
|
}
|
|
91492
91865
|
const immediateCooldownUntil = now + _ReolinkBaichuanApi.D2C_DISC_IMMEDIATE_COOLDOWN_MS;
|
|
91493
91866
|
const existing = this.socketPoolCooldowns.get(this.host);
|
|
@@ -91520,15 +91893,15 @@ ${stderr}`));
|
|
|
91520
91893
|
* Returns undefined if the client is not in the pool (e.g. it's the general socket used directly).
|
|
91521
91894
|
*/
|
|
91522
91895
|
findSocketTagForClient(client) {
|
|
91523
|
-
for (const [
|
|
91896
|
+
for (const [tag2, entry] of this.socketPool) if (entry.client === client) return tag2;
|
|
91524
91897
|
}
|
|
91525
91898
|
/**
|
|
91526
91899
|
* Reset the consecutive stream-start timeout counter for a streaming socket.
|
|
91527
91900
|
* Called on successful stream start.
|
|
91528
91901
|
*/
|
|
91529
91902
|
resetStreamTimeoutCounter(client) {
|
|
91530
|
-
const
|
|
91531
|
-
if (
|
|
91903
|
+
const tag2 = this.findSocketTagForClient(client);
|
|
91904
|
+
if (tag2) this.consecutiveStreamTimeouts.delete(tag2);
|
|
91532
91905
|
}
|
|
91533
91906
|
/**
|
|
91534
91907
|
* Track a stream-start timeout on a streaming socket.
|
|
@@ -91536,14 +91909,14 @@ ${stderr}`));
|
|
|
91536
91909
|
* socket so the next attempt creates a fresh connection.
|
|
91537
91910
|
*/
|
|
91538
91911
|
trackStreamTimeout(client) {
|
|
91539
|
-
const
|
|
91540
|
-
if (!
|
|
91541
|
-
const count = (this.consecutiveStreamTimeouts.get(
|
|
91542
|
-
this.consecutiveStreamTimeouts.set(
|
|
91912
|
+
const tag2 = this.findSocketTagForClient(client);
|
|
91913
|
+
if (!tag2 || !tag2.startsWith("streaming:")) return;
|
|
91914
|
+
const count = (this.consecutiveStreamTimeouts.get(tag2) ?? 0) + 1;
|
|
91915
|
+
this.consecutiveStreamTimeouts.set(tag2, count);
|
|
91543
91916
|
if (count >= _ReolinkBaichuanApi.MAX_CONSECUTIVE_STREAM_TIMEOUTS) {
|
|
91544
|
-
this.logger?.warn?.(`[SocketPool] ${count} consecutive stream timeouts on tag=${
|
|
91545
|
-
this.consecutiveStreamTimeouts.delete(
|
|
91546
|
-
this.forceClosePooledSocket(
|
|
91917
|
+
this.logger?.warn?.(`[SocketPool] ${count} consecutive stream timeouts on tag=${tag2}, force-closing socket`);
|
|
91918
|
+
this.consecutiveStreamTimeouts.delete(tag2);
|
|
91919
|
+
this.forceClosePooledSocket(tag2, this.logger).catch(() => {});
|
|
91547
91920
|
}
|
|
91548
91921
|
}
|
|
91549
91922
|
/**
|
|
@@ -92410,8 +92783,20 @@ ${xml}`);
|
|
|
92410
92783
|
const support = supportResult.status === "fulfilled" ? supportResult.value : void 0;
|
|
92411
92784
|
const abilities = abilitiesResult.status === "fulfilled" ? abilitiesResult.value : void 0;
|
|
92412
92785
|
const supportItem = getSupportItemForChannel(support, ch);
|
|
92786
|
+
let model;
|
|
92787
|
+
try {
|
|
92788
|
+
const info = await this.getInfo(void 0, { timeoutMs: 5e3 });
|
|
92789
|
+
model = typeof info?.type === "string" ? info.type : void 0;
|
|
92790
|
+
} catch (e) {
|
|
92791
|
+
this.logger.debug("[ReolinkBaichuanApi] getDeviceCapabilities: getInfo(type) failed", {
|
|
92792
|
+
host: this.host,
|
|
92793
|
+
channel: ch,
|
|
92794
|
+
err: e instanceof Error ? e.message : String(e)
|
|
92795
|
+
});
|
|
92796
|
+
}
|
|
92413
92797
|
const capabilities = computeDeviceCapabilities({
|
|
92414
92798
|
channel: ch,
|
|
92799
|
+
...model != null && { model },
|
|
92415
92800
|
...support != null && { support },
|
|
92416
92801
|
...abilities != null && { abilities }
|
|
92417
92802
|
});
|
|
@@ -93180,7 +93565,7 @@ ${xml}`);
|
|
|
93180
93565
|
* @returns Test results for all stream types and profiles
|
|
93181
93566
|
*/
|
|
93182
93567
|
async testChannelStreams(channel, logger) {
|
|
93183
|
-
const { testChannelStreams } = await Promise.resolve().then(() => require("./DiagnosticsTools-
|
|
93568
|
+
const { testChannelStreams } = await Promise.resolve().then(() => require("./DiagnosticsTools-GOFDNGAY-CD4rRF8a.js"));
|
|
93184
93569
|
return await testChannelStreams({
|
|
93185
93570
|
api: this,
|
|
93186
93571
|
channel: this.normalizeChannel(channel),
|
|
@@ -93196,7 +93581,7 @@ ${xml}`);
|
|
|
93196
93581
|
* @returns Complete diagnostics for all channels and streams
|
|
93197
93582
|
*/
|
|
93198
93583
|
async collectMultifocalDiagnostics(logger) {
|
|
93199
|
-
const { collectMultifocalDiagnostics } = await Promise.resolve().then(() => require("./DiagnosticsTools-
|
|
93584
|
+
const { collectMultifocalDiagnostics } = await Promise.resolve().then(() => require("./DiagnosticsTools-GOFDNGAY-CD4rRF8a.js"));
|
|
93200
93585
|
return await collectMultifocalDiagnostics({
|
|
93201
93586
|
api: this,
|
|
93202
93587
|
logger
|
|
@@ -95230,7 +95615,7 @@ ${scheduleItems}
|
|
|
95230
95615
|
if (raw.length === 0) throw new Error("Downloaded recording is empty");
|
|
95231
95616
|
const videoFrames = [];
|
|
95232
95617
|
let videoType = null;
|
|
95233
|
-
const decoder = new
|
|
95618
|
+
const decoder = new require_chunk_ZQFQRCLQ.BcMediaAnnexBDecoder({
|
|
95234
95619
|
strict: false,
|
|
95235
95620
|
logger: this.logger,
|
|
95236
95621
|
onVideoAccessUnit: ({ annexB: annexB2, microseconds }) => {
|
|
@@ -95578,7 +95963,7 @@ ${scheduleItems}
|
|
|
95578
95963
|
return {
|
|
95579
95964
|
getPlaylist: () => {
|
|
95580
95965
|
try {
|
|
95581
|
-
const { readFileSync } =
|
|
95966
|
+
const { readFileSync } = require_chunk_ZQFQRCLQ.__require("fs");
|
|
95582
95967
|
return readFileSync(playlistPath, "utf8");
|
|
95583
95968
|
} catch {
|
|
95584
95969
|
return "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:4\n";
|
|
@@ -95587,7 +95972,7 @@ ${scheduleItems}
|
|
|
95587
95972
|
getSegment: (name) => {
|
|
95588
95973
|
if (segments.has(name)) return segments.get(name);
|
|
95589
95974
|
try {
|
|
95590
|
-
const { readFileSync } =
|
|
95975
|
+
const { readFileSync } = require_chunk_ZQFQRCLQ.__require("fs");
|
|
95591
95976
|
const data = readFileSync(path$3.join(tempDir, name));
|
|
95592
95977
|
segments.set(name, data);
|
|
95593
95978
|
return data;
|
|
@@ -95597,7 +95982,7 @@ ${scheduleItems}
|
|
|
95597
95982
|
},
|
|
95598
95983
|
listSegments: () => {
|
|
95599
95984
|
try {
|
|
95600
|
-
const { readdirSync } =
|
|
95985
|
+
const { readdirSync } = require_chunk_ZQFQRCLQ.__require("fs");
|
|
95601
95986
|
return readdirSync(tempDir).filter((f) => f.endsWith(".ts"));
|
|
95602
95987
|
} catch {
|
|
95603
95988
|
return [];
|
|
@@ -97182,41 +97567,41 @@ async function autoDetectDeviceType(inputs) {
|
|
|
97182
97567
|
variant: "cmd80 class=0x6414",
|
|
97183
97568
|
op: () => api.getInfo(void 0, {
|
|
97184
97569
|
timeoutMs: 2500,
|
|
97185
|
-
messageClass:
|
|
97570
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
97186
97571
|
})
|
|
97187
97572
|
},
|
|
97188
97573
|
{
|
|
97189
97574
|
variant: "cmd80 class=0x6614",
|
|
97190
97575
|
op: () => api.getInfo(void 0, {
|
|
97191
97576
|
timeoutMs: 3e3,
|
|
97192
|
-
messageClass:
|
|
97577
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_20
|
|
97193
97578
|
})
|
|
97194
97579
|
},
|
|
97195
97580
|
{
|
|
97196
97581
|
variant: "cmd318(ch0) class=0x6414",
|
|
97197
97582
|
op: () => api.getInfo(0, {
|
|
97198
97583
|
timeoutMs: 3e3,
|
|
97199
|
-
messageClass:
|
|
97584
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
97200
97585
|
})
|
|
97201
97586
|
},
|
|
97202
97587
|
{
|
|
97203
97588
|
variant: "cmd318(ch0) class=0x6614",
|
|
97204
97589
|
op: () => api.getInfo(0, {
|
|
97205
97590
|
timeoutMs: 3500,
|
|
97206
|
-
messageClass:
|
|
97591
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_20
|
|
97207
97592
|
})
|
|
97208
97593
|
}
|
|
97209
97594
|
]), runProbeVariants("getSupportInfo", [{
|
|
97210
97595
|
variant: "cmd199 class=0x6414",
|
|
97211
97596
|
op: () => api.getSupportInfo({
|
|
97212
97597
|
timeoutMs: 2500,
|
|
97213
|
-
messageClass:
|
|
97598
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
97214
97599
|
})
|
|
97215
97600
|
}, {
|
|
97216
97601
|
variant: "cmd199 class=0x6614",
|
|
97217
97602
|
op: () => api.getSupportInfo({
|
|
97218
97603
|
timeoutMs: 3500,
|
|
97219
|
-
messageClass:
|
|
97604
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_20
|
|
97220
97605
|
})
|
|
97221
97606
|
}])]);
|
|
97222
97607
|
const deviceInfo = infoProbe?.value;
|
|
@@ -143745,7 +144130,7 @@ async function createRfc4571TcpServerInternal(options) {
|
|
|
143745
144130
|
streamClient = dedicatedSession.client;
|
|
143746
144131
|
logSessionsSummary(`dedicated session created: ${sessionKey}`);
|
|
143747
144132
|
} else streamClient = baseApi.client;
|
|
143748
|
-
const createLiveStream = async () => new
|
|
144133
|
+
const createLiveStream = async () => new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
143749
144134
|
client: streamClient,
|
|
143750
144135
|
api: baseApi,
|
|
143751
144136
|
channel: ch,
|
|
@@ -148323,6 +148708,17 @@ var ReolinkStreamProfileOptionsSchema = object({
|
|
|
148323
148708
|
}).optional()
|
|
148324
148709
|
});
|
|
148325
148710
|
var reolinkCameraSchema = object({
|
|
148711
|
+
/**
|
|
148712
|
+
* Which preset `ptz.goHome` targets on THIS camera.
|
|
148713
|
+
*
|
|
148714
|
+
* Empty = nothing configured, and `goHome` then REFUSES. It used to go to a
|
|
148715
|
+
* hardcoded slot on a vendor "convention" this fleet contradicts: reolink
|
|
148716
|
+
* went to preset 0, which on device 592 holds "stanza"; amcrest went to
|
|
148717
|
+
* preset 1, which on device 3836 holds "Preset1". Both swallowed the failure
|
|
148718
|
+
* in a bare catch, so a head that never moved was indistinguishable from a
|
|
148719
|
+
* head that went home.
|
|
148720
|
+
*/
|
|
148721
|
+
homePresetId: string().default("").describe("Preset id ptz.goHome targets (empty = goHome refuses)"),
|
|
148326
148722
|
host: string().describe("Camera IP or hostname"),
|
|
148327
148723
|
port: number().default(9e3).describe("Baichuan port (default 9000)"),
|
|
148328
148724
|
username: string().default("admin").describe("Username"),
|
|
@@ -149613,6 +150009,20 @@ function coerceNumber(value) {
|
|
|
149613
150009
|
return null;
|
|
149614
150010
|
}
|
|
149615
150011
|
/**
|
|
150012
|
+
* Baichuan's native PTZ speed scale is 1..63; `runPtz` maps the cap's
|
|
150013
|
+
* normalized 0..1 onto it. Named because the autotrack loop has to know the
|
|
150014
|
+
* GRANULARITY of the knob it turns -- a normalized 0.37 means something very
|
|
150015
|
+
* different on 63 steps than on amcrest's 8.
|
|
150016
|
+
*/
|
|
150017
|
+
var BAICHUAN_SPEED_STEPS = 63;
|
|
150018
|
+
/**
|
|
150019
|
+
* How long one `ptz.move` pulse runs, ms -- the `autoStopMs` handed to
|
|
150020
|
+
* Baichuan. It is the DENOMINATOR of "how far did the head travel per pulse",
|
|
150021
|
+
* so it is exported through `getOptions` rather than left a literal no caller
|
|
150022
|
+
* could read.
|
|
150023
|
+
*/
|
|
150024
|
+
var PTZ_MOVE_IMPULSE_MS = 200;
|
|
150025
|
+
/**
|
|
149616
150026
|
* Per-device transient diagnostics blob populated from the lib's
|
|
149617
150027
|
* `getOnlineUserSessionsForUi` + `getSocketPoolSummary` +
|
|
149618
150028
|
* `getSocketPoolCooldownStatus` calls. NOT persisted — recomputed on
|
|
@@ -149954,6 +150364,48 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
149954
150364
|
* during `adoptDevice`). Standalone cameras default to 0 so the
|
|
149955
150365
|
* pre-Hub behavior is preserved verbatim.
|
|
149956
150366
|
*/
|
|
150367
|
+
/**
|
|
150368
|
+
* Which preset `goHome` targets, and who decided it.
|
|
150369
|
+
*
|
|
150370
|
+
* Baichuan names no home of its own, so the operator's pick is the only
|
|
150371
|
+
* answer there can be. With none, `none` -- and `goHome` refuses rather than
|
|
150372
|
+
* moving the head to whatever happens to sit in slot 0.
|
|
150373
|
+
*/
|
|
150374
|
+
async resolveHomePreset() {
|
|
150375
|
+
const chosen = this.config.get("homePresetId") ?? "";
|
|
150376
|
+
if (chosen !== "") return {
|
|
150377
|
+
presetId: chosen,
|
|
150378
|
+
source: "operator"
|
|
150379
|
+
};
|
|
150380
|
+
if ((await this.readGuardStatus())?.valid === true) return {
|
|
150381
|
+
presetId: null,
|
|
150382
|
+
source: "native"
|
|
150383
|
+
};
|
|
150384
|
+
return {
|
|
150385
|
+
presetId: null,
|
|
150386
|
+
source: "none"
|
|
150387
|
+
};
|
|
150388
|
+
}
|
|
150389
|
+
/**
|
|
150390
|
+
* The camera's guard-point configuration, or `null` when it cannot be read.
|
|
150391
|
+
*
|
|
150392
|
+
* Never a fabricated "no guard configured": that answer decides whether
|
|
150393
|
+
* `goHome` moves the head, and an unreadable camera is not evidence that no
|
|
150394
|
+
* guard point exists (D393).
|
|
150395
|
+
*/
|
|
150396
|
+
async readGuardStatus() {
|
|
150397
|
+
try {
|
|
150398
|
+
const api = await this.ensureApi();
|
|
150399
|
+
const channel = this.getChannel();
|
|
150400
|
+
return await api.getPtzGuard(channel);
|
|
150401
|
+
} catch (err) {
|
|
150402
|
+
this.ctx.logger.warn("reolink guard point unreadable — goHome will fall back", {
|
|
150403
|
+
tags: { deviceId: this.id },
|
|
150404
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
150405
|
+
});
|
|
150406
|
+
return null;
|
|
150407
|
+
}
|
|
150408
|
+
}
|
|
149957
150409
|
getChannel() {
|
|
149958
150410
|
const ch = this.config.get("channel");
|
|
149959
150411
|
if (typeof ch === "number" && ch >= 0) return ch;
|
|
@@ -153331,7 +153783,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
153331
153783
|
const channel = this.getChannel();
|
|
153332
153784
|
return (await api.getPtzPresets(channel)).map((p) => ({
|
|
153333
153785
|
id: String(p.id),
|
|
153334
|
-
name: p.name
|
|
153786
|
+
name: p.name,
|
|
153787
|
+
fn: null,
|
|
153788
|
+
writable: true
|
|
153335
153789
|
}));
|
|
153336
153790
|
} catch {
|
|
153337
153791
|
return [];
|
|
@@ -153367,7 +153821,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
153367
153821
|
hasTilt: false,
|
|
153368
153822
|
hasZoom: false,
|
|
153369
153823
|
supportsPresets: false,
|
|
153370
|
-
hasAutofocus: false
|
|
153824
|
+
hasAutofocus: false,
|
|
153825
|
+
speedSteps: BAICHUAN_SPEED_STEPS,
|
|
153826
|
+
moveImpulseMs: PTZ_MOVE_IMPULSE_MS
|
|
153371
153827
|
};
|
|
153372
153828
|
const hasAutofocus = this.config.get("deviceCache")?.autoFocusSnapshot?.supported === true;
|
|
153373
153829
|
return this.resolveCapOptions({
|
|
@@ -153380,7 +153836,9 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
153380
153836
|
hasTilt: capabilities.hasTilt,
|
|
153381
153837
|
hasZoom: capabilities.hasZoom,
|
|
153382
153838
|
supportsPresets: capabilities.hasPresets,
|
|
153383
|
-
hasAutofocus
|
|
153839
|
+
hasAutofocus,
|
|
153840
|
+
speedSteps: BAICHUAN_SPEED_STEPS,
|
|
153841
|
+
moveImpulseMs: PTZ_MOVE_IMPULSE_MS
|
|
153384
153842
|
};
|
|
153385
153843
|
},
|
|
153386
153844
|
fallback: () => {
|
|
@@ -153390,42 +153848,89 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
153390
153848
|
hasTilt: hasPtz,
|
|
153391
153849
|
hasZoom: hasPtz,
|
|
153392
153850
|
supportsPresets: hasPtz,
|
|
153393
|
-
hasAutofocus
|
|
153851
|
+
hasAutofocus,
|
|
153852
|
+
speedSteps: BAICHUAN_SPEED_STEPS,
|
|
153853
|
+
moveImpulseMs: PTZ_MOVE_IMPULSE_MS
|
|
153394
153854
|
};
|
|
153395
153855
|
}
|
|
153396
153856
|
});
|
|
153397
153857
|
},
|
|
153398
153858
|
goHome: async ({ deviceId }) => {
|
|
153399
153859
|
if (deviceId !== this.id) return;
|
|
153400
|
-
|
|
153401
|
-
|
|
153402
|
-
|
|
153403
|
-
|
|
153404
|
-
}
|
|
153860
|
+
const home = await this.resolveHomePreset();
|
|
153861
|
+
if (home.source === "native") {
|
|
153862
|
+
await (await this.ensureApi()).goToPtzGuard(this.getChannel());
|
|
153863
|
+
return;
|
|
153864
|
+
}
|
|
153865
|
+
if (home.source === "none" || home.presetId === null) throw new Error("No home preset configured for this camera, and it has no guard point set — set one in the PTZ settings, or place a guard point on the camera");
|
|
153866
|
+
const id = Number(home.presetId);
|
|
153867
|
+
if (!Number.isFinite(id)) throw new Error(`Configured home preset is not a Baichuan id: ${home.presetId}`);
|
|
153868
|
+
const api = await this.ensureApi();
|
|
153869
|
+
const channel = this.getChannel();
|
|
153870
|
+
await api.moveToPtzPreset(channel, id);
|
|
153871
|
+
},
|
|
153872
|
+
getHomePreset: async ({ deviceId }) => {
|
|
153873
|
+
if (deviceId !== this.id) return {
|
|
153874
|
+
presetId: null,
|
|
153875
|
+
source: "none"
|
|
153876
|
+
};
|
|
153877
|
+
return this.resolveHomePreset();
|
|
153878
|
+
},
|
|
153879
|
+
captureHomeHere: async ({ deviceId }) => {
|
|
153880
|
+
if (deviceId !== this.id) return;
|
|
153881
|
+
const current = await this.readGuardStatus();
|
|
153882
|
+
const api = await this.ensureApi();
|
|
153883
|
+
const channel = this.getChannel();
|
|
153884
|
+
await api.setPtzGuard({
|
|
153885
|
+
enabled: current?.enabled ?? false,
|
|
153886
|
+
timeoutSeconds: current?.timeoutSeconds ?? 60,
|
|
153887
|
+
setPosition: true
|
|
153888
|
+
}, channel);
|
|
153889
|
+
this.ctx.logger.info("reolink: guard point pinned to the current position", { tags: { deviceId: this.id } });
|
|
153890
|
+
},
|
|
153891
|
+
getHomeReturnSeconds: async ({ deviceId }) => {
|
|
153892
|
+
if (deviceId !== this.id) return null;
|
|
153893
|
+
const guard = await this.readGuardStatus();
|
|
153894
|
+
return guard === null ? null : guard.timeoutSeconds;
|
|
153895
|
+
},
|
|
153896
|
+
setHomeReturnSeconds: async ({ deviceId, seconds }) => {
|
|
153897
|
+
if (deviceId !== this.id) return;
|
|
153898
|
+
const current = await this.readGuardStatus();
|
|
153899
|
+
const api = await this.ensureApi();
|
|
153900
|
+
const channel = this.getChannel();
|
|
153901
|
+
await api.setPtzGuard({
|
|
153902
|
+
enabled: current?.enabled ?? true,
|
|
153903
|
+
timeoutSeconds: seconds,
|
|
153904
|
+
setPosition: false
|
|
153905
|
+
}, channel);
|
|
153906
|
+
},
|
|
153907
|
+
setHomePreset: async ({ deviceId, presetId }) => {
|
|
153908
|
+
if (deviceId !== this.id) return;
|
|
153909
|
+
await this.config.setAll({ homePresetId: presetId ?? "" });
|
|
153405
153910
|
},
|
|
153406
153911
|
getPosition: async ({ deviceId }) => {
|
|
153407
153912
|
if (deviceId !== this.id) return {
|
|
153408
|
-
pan:
|
|
153409
|
-
tilt:
|
|
153410
|
-
zoom:
|
|
153913
|
+
pan: null,
|
|
153914
|
+
tilt: null,
|
|
153915
|
+
zoom: null
|
|
153411
153916
|
};
|
|
153412
153917
|
return {
|
|
153413
|
-
pan:
|
|
153414
|
-
tilt:
|
|
153415
|
-
zoom:
|
|
153918
|
+
pan: null,
|
|
153919
|
+
tilt: null,
|
|
153920
|
+
zoom: null
|
|
153416
153921
|
};
|
|
153417
153922
|
},
|
|
153418
153923
|
getStatus: async ({ deviceId }) => {
|
|
153419
153924
|
if (deviceId !== this.id) return {
|
|
153420
|
-
pan:
|
|
153421
|
-
tilt:
|
|
153422
|
-
zoom:
|
|
153925
|
+
pan: null,
|
|
153926
|
+
tilt: null,
|
|
153927
|
+
zoom: null,
|
|
153423
153928
|
autofocus: false
|
|
153424
153929
|
};
|
|
153425
153930
|
return {
|
|
153426
|
-
pan:
|
|
153427
|
-
tilt:
|
|
153428
|
-
zoom:
|
|
153931
|
+
pan: null,
|
|
153932
|
+
tilt: null,
|
|
153933
|
+
zoom: null,
|
|
153429
153934
|
autofocus: (this.config.get("deviceCache")?.autoFocusSnapshot)?.enabled === true
|
|
153430
153935
|
};
|
|
153431
153936
|
},
|
|
@@ -153476,13 +153981,13 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
153476
153981
|
if (tilt !== void 0 && Math.abs(tilt) > .01) cmds.push(tilt > 0 ? "Up" : "Down");
|
|
153477
153982
|
if (zoom !== void 0 && Math.abs(zoom) > .01) await this.runZoom(api, channel, zoom);
|
|
153478
153983
|
if (cmds.length === 0) return;
|
|
153479
|
-
const baichuanSpeed = speed === void 0 ?
|
|
153984
|
+
const baichuanSpeed = speed === void 0 ? Math.round(BAICHUAN_SPEED_STEPS / 2) : Math.max(1, Math.min(BAICHUAN_SPEED_STEPS, Math.round(speed * BAICHUAN_SPEED_STEPS)));
|
|
153480
153985
|
for (const command of cmds) try {
|
|
153481
153986
|
await api.ptz(channel, {
|
|
153482
153987
|
action: "start",
|
|
153483
153988
|
command,
|
|
153484
153989
|
speed: baichuanSpeed,
|
|
153485
|
-
...continuous ? {} : { autoStopMs:
|
|
153990
|
+
...continuous ? {} : { autoStopMs: PTZ_MOVE_IMPULSE_MS }
|
|
153486
153991
|
});
|
|
153487
153992
|
} catch (err) {
|
|
153488
153993
|
this.ctx.logger.warn("Baichuan ptz command failed", {
|