@camstack/addon-provider-reolink 1.2.139 → 1.2.141
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 +582 -279
- package/dist/addon.mjs +432 -129
- 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-Dk-BdnBf.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).
|
|
@@ -31820,6 +31820,26 @@ var PtzHomePresetSchema = object({
|
|
|
31820
31820
|
"none"
|
|
31821
31821
|
])
|
|
31822
31822
|
});
|
|
31823
|
+
/**
|
|
31824
|
+
* The camera's own idle-return behaviour: whether it goes home by itself, and
|
|
31825
|
+
* after how long.
|
|
31826
|
+
*
|
|
31827
|
+
* ONE shape, not two scalars, because on the camera they are ONE fact —
|
|
31828
|
+
* Reolink's guard point carries `benable` and `timeout` in the same element,
|
|
31829
|
+
* written by the same command. Reading them apart means two round-trips that
|
|
31830
|
+
* can disagree.
|
|
31831
|
+
*
|
|
31832
|
+
* `enabled` and `seconds` are INDEPENDENT: a camera can hold a 68 s delay with
|
|
31833
|
+
* the behaviour switched off, which is exactly what the vendor app leaves when
|
|
31834
|
+
* you turn the guard point off without clearing it. The first version of this
|
|
31835
|
+
* cap reported only the delay, so that state was invisible — a camera could be
|
|
31836
|
+
* configured to return after 68 seconds with no way to say whether it should
|
|
31837
|
+
* return at all.
|
|
31838
|
+
*/
|
|
31839
|
+
var PtzHomeReturnSchema = object({
|
|
31840
|
+
enabled: boolean(),
|
|
31841
|
+
seconds: number().int()
|
|
31842
|
+
});
|
|
31823
31843
|
var ptzCapability = {
|
|
31824
31844
|
name: "ptz",
|
|
31825
31845
|
scope: "device",
|
|
@@ -31879,6 +31899,54 @@ var ptzCapability = {
|
|
|
31879
31899
|
auth: "admin"
|
|
31880
31900
|
}),
|
|
31881
31901
|
/**
|
|
31902
|
+
* Make WHERE THE HEAD IS POINTING RIGHT NOW this camera's home.
|
|
31903
|
+
*
|
|
31904
|
+
* `setHomePreset` takes a preset id, and a preset id is the wrong shape for
|
|
31905
|
+
* the most natural thing an operator does: aim the camera, then say "here".
|
|
31906
|
+
* It is also the only shape a camera whose home is NOT a preset can accept
|
|
31907
|
+
* -- Reolink's home is a guard point, a stored position with no id at all,
|
|
31908
|
+
* and hiding the control for that case (as the UI briefly did) left the one
|
|
31909
|
+
* vendor with a native home unable to set it.
|
|
31910
|
+
*
|
|
31911
|
+
* Each provider does it its own way:
|
|
31912
|
+
* reolink `setGrd` with `needSetPos`, pinning the guard point here
|
|
31913
|
+
* hikvision / amcrest save a preset, then pin it as home
|
|
31914
|
+
* onvif REFUSES -- its home is the PTZ origin and cannot be moved
|
|
31915
|
+
*
|
|
31916
|
+
* A provider that cannot honour it throws rather than silently doing
|
|
31917
|
+
* nothing: an operator who pressed "set home here" and saw no error would
|
|
31918
|
+
* believe it took.
|
|
31919
|
+
*/
|
|
31920
|
+
captureHomeHere: method(object({ deviceId: number() }), _void(), {
|
|
31921
|
+
kind: "mutation",
|
|
31922
|
+
auth: "admin"
|
|
31923
|
+
}),
|
|
31924
|
+
/**
|
|
31925
|
+
* Whether the camera returns home on its own when left idle, and after how
|
|
31926
|
+
* long. `null` when it has no such behaviour at all.
|
|
31927
|
+
*
|
|
31928
|
+
* Reolink's guard point carries one (`timeout`, freely settable in
|
|
31929
|
+
* seconds). It is a real function of the camera that we did not expose at
|
|
31930
|
+
* all, and it belongs next to the home it governs rather than in a vendor
|
|
31931
|
+
* settings page nobody associates with Home.
|
|
31932
|
+
*/
|
|
31933
|
+
getHomeReturn: method(object({ deviceId: number() }), PtzHomeReturnSchema.nullable()),
|
|
31934
|
+
/**
|
|
31935
|
+
* Set both together. Refused by a camera with no idle-return behaviour.
|
|
31936
|
+
*
|
|
31937
|
+
* They travel together for the same reason they are read together: the
|
|
31938
|
+
* underlying write carries both, so setting one alone means reading the
|
|
31939
|
+
* other back first and racing whoever else is writing.
|
|
31940
|
+
*/
|
|
31941
|
+
setHomeReturn: method(object({
|
|
31942
|
+
deviceId: number(),
|
|
31943
|
+
enabled: boolean(),
|
|
31944
|
+
seconds: number().int().min(0).max(3600)
|
|
31945
|
+
}), _void(), {
|
|
31946
|
+
kind: "mutation",
|
|
31947
|
+
auth: "admin"
|
|
31948
|
+
}),
|
|
31949
|
+
/**
|
|
31882
31950
|
* Pull the current PTZ position. Redundant with the auto-injected
|
|
31883
31951
|
* `getStatus` method (see `status` below); kept for callers that
|
|
31884
31952
|
* haven't migrated. Will be folded into `getStatus` in a future
|
|
@@ -41536,6 +41604,12 @@ Object.freeze({
|
|
|
41536
41604
|
addonId: null,
|
|
41537
41605
|
access: "create"
|
|
41538
41606
|
},
|
|
41607
|
+
"ptz.captureHomeHere": {
|
|
41608
|
+
capName: "ptz",
|
|
41609
|
+
capScope: "device",
|
|
41610
|
+
addonId: null,
|
|
41611
|
+
access: "create"
|
|
41612
|
+
},
|
|
41539
41613
|
"ptz.continuousMove": {
|
|
41540
41614
|
capName: "ptz",
|
|
41541
41615
|
capScope: "device",
|
|
@@ -41554,6 +41628,12 @@ Object.freeze({
|
|
|
41554
41628
|
addonId: null,
|
|
41555
41629
|
access: "view"
|
|
41556
41630
|
},
|
|
41631
|
+
"ptz.getHomeReturn": {
|
|
41632
|
+
capName: "ptz",
|
|
41633
|
+
capScope: "device",
|
|
41634
|
+
addonId: null,
|
|
41635
|
+
access: "view"
|
|
41636
|
+
},
|
|
41557
41637
|
"ptz.getOptions": {
|
|
41558
41638
|
capName: "ptz",
|
|
41559
41639
|
capScope: "device",
|
|
@@ -41608,6 +41688,12 @@ Object.freeze({
|
|
|
41608
41688
|
addonId: null,
|
|
41609
41689
|
access: "create"
|
|
41610
41690
|
},
|
|
41691
|
+
"ptz.setHomeReturn": {
|
|
41692
|
+
capName: "ptz",
|
|
41693
|
+
capScope: "device",
|
|
41694
|
+
addonId: null,
|
|
41695
|
+
access: "create"
|
|
41696
|
+
},
|
|
41611
41697
|
"ptz.stop": {
|
|
41612
41698
|
capName: "ptz",
|
|
41613
41699
|
capScope: "device",
|
|
@@ -44771,6 +44857,11 @@ Object.freeze({
|
|
|
44771
44857
|
form: "single",
|
|
44772
44858
|
optional: false
|
|
44773
44859
|
}],
|
|
44860
|
+
"ptz.captureHomeHere": [{
|
|
44861
|
+
name: "deviceId",
|
|
44862
|
+
form: "single",
|
|
44863
|
+
optional: false
|
|
44864
|
+
}],
|
|
44774
44865
|
"ptz.continuousMove": [{
|
|
44775
44866
|
name: "deviceId",
|
|
44776
44867
|
form: "single",
|
|
@@ -44786,6 +44877,11 @@ Object.freeze({
|
|
|
44786
44877
|
form: "single",
|
|
44787
44878
|
optional: false
|
|
44788
44879
|
}],
|
|
44880
|
+
"ptz.getHomeReturn": [{
|
|
44881
|
+
name: "deviceId",
|
|
44882
|
+
form: "single",
|
|
44883
|
+
optional: false
|
|
44884
|
+
}],
|
|
44789
44885
|
"ptz.getOptions": [{
|
|
44790
44886
|
name: "deviceId",
|
|
44791
44887
|
form: "single",
|
|
@@ -44831,6 +44927,11 @@ Object.freeze({
|
|
|
44831
44927
|
form: "single",
|
|
44832
44928
|
optional: false
|
|
44833
44929
|
}],
|
|
44930
|
+
"ptz.setHomeReturn": [{
|
|
44931
|
+
name: "deviceId",
|
|
44932
|
+
form: "single",
|
|
44933
|
+
optional: false
|
|
44934
|
+
}],
|
|
44834
44935
|
"ptz.stop": [{
|
|
44835
44936
|
name: "deviceId",
|
|
44836
44937
|
form: "single",
|
|
@@ -68515,7 +68616,7 @@ var require_yazl = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) => {
|
|
|
68515
68616
|
}
|
|
68516
68617
|
}));
|
|
68517
68618
|
//#endregion
|
|
68518
|
-
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-
|
|
68619
|
+
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-KWQVN7H5.js
|
|
68519
68620
|
var import_undici = require_undici();
|
|
68520
68621
|
var import_yazl = /* @__PURE__ */ require_chunk.__toESM(require_yazl(), 1);
|
|
68521
68622
|
var FLAGS_CAM_V2 = {
|
|
@@ -69792,13 +69893,13 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69792
69893
|
sec: 59
|
|
69793
69894
|
};
|
|
69794
69895
|
}
|
|
69795
|
-
|
|
69896
|
+
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)}`);
|
|
69796
69897
|
if (!bypassCache) {
|
|
69797
69898
|
this.cleanRecordingsCache();
|
|
69798
69899
|
const cacheKey = this.getNvrRecordingsCacheKey(channel, startTime, endTime, streamType, iLogicChannel, autoSearchByDay);
|
|
69799
69900
|
const cached = this.recordingsCache.get(cacheKey);
|
|
69800
69901
|
if (cached && cached.expiresAt > Date.now()) {
|
|
69801
|
-
|
|
69902
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Cache hit: returning ${cached.data.length} cached enriched recordings`);
|
|
69802
69903
|
return cached.data;
|
|
69803
69904
|
}
|
|
69804
69905
|
}
|
|
@@ -69850,7 +69951,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69850
69951
|
const firstResult = dayResponse[0];
|
|
69851
69952
|
if (firstResult && firstResult.code === 0 && firstResult.value?.SearchResult?.File) {
|
|
69852
69953
|
const files = firstResult.value.SearchResult.File;
|
|
69853
|
-
if (files.length > 0 && files[0])
|
|
69954
|
+
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({
|
|
69854
69955
|
fileCount: files.length,
|
|
69855
69956
|
sampleFile: {
|
|
69856
69957
|
name: files[0].name,
|
|
@@ -69886,7 +69987,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69886
69987
|
} catch (e) {}
|
|
69887
69988
|
enriched2.push(this.enrichVodFile(vodFile, channel, streamUrl));
|
|
69888
69989
|
}
|
|
69889
|
-
|
|
69990
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Returning ${enriched2.length} enriched recording files from autoSearchByDay`);
|
|
69890
69991
|
if (!bypassCache) {
|
|
69891
69992
|
const cacheKey = this.getNvrRecordingsCacheKey(channel, startTime, endTime, streamType, iLogicChannel, autoSearchByDay);
|
|
69892
69993
|
this.recordingsCache.set(cacheKey, {
|
|
@@ -69914,7 +70015,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69914
70015
|
const response = await this.call("Search", param, 0);
|
|
69915
70016
|
allResults.push(...response);
|
|
69916
70017
|
} else {
|
|
69917
|
-
|
|
70018
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Range spans ${dayRanges.length} days, splitting into separate day queries`);
|
|
69918
70019
|
for (const range of dayRanges) {
|
|
69919
70020
|
const param = { Search: {
|
|
69920
70021
|
channel,
|
|
@@ -69924,7 +70025,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69924
70025
|
EndTime: range.end
|
|
69925
70026
|
} };
|
|
69926
70027
|
if (iLogicChannel > 0) param.Search.iLogicChannel = iLogicChannel;
|
|
69927
|
-
|
|
70028
|
+
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})`);
|
|
69928
70029
|
const response = await this.call("Search", param, 0);
|
|
69929
70030
|
allResults.push(...response);
|
|
69930
70031
|
}
|
|
@@ -69934,7 +70035,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69934
70035
|
const firstResult = result[0];
|
|
69935
70036
|
if (firstResult && firstResult.code === 0 && firstResult.value?.SearchResult?.File) {
|
|
69936
70037
|
const files = firstResult.value.SearchResult.File;
|
|
69937
|
-
if (files.length > 0 && files[0])
|
|
70038
|
+
if (files.length > 0 && files[0]) require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Raw API response (normal search): ${JSON.stringify({
|
|
69938
70039
|
fileCount: files.length,
|
|
69939
70040
|
sampleFile: {
|
|
69940
70041
|
name: files[0].name,
|
|
@@ -69951,12 +70052,12 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69951
70052
|
const searchResult = res.value?.SearchResult;
|
|
69952
70053
|
if (searchResult?.File) allFiles.push(...searchResult.File);
|
|
69953
70054
|
}
|
|
69954
|
-
|
|
70055
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Collected ${allFiles.length} raw VodFiles from API search results`);
|
|
69955
70056
|
if (allFiles.length > 0) {
|
|
69956
70057
|
const sampleSize = Math.min(3, allFiles.length);
|
|
69957
70058
|
for (let i = 0; i < sampleSize; i++) {
|
|
69958
70059
|
const file = allFiles[i];
|
|
69959
|
-
if (file)
|
|
70060
|
+
if (file) require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Sample file ${i + 1}/${allFiles.length}: ${JSON.stringify({
|
|
69960
70061
|
name: file.name,
|
|
69961
70062
|
type: file.type,
|
|
69962
70063
|
size: file.size,
|
|
@@ -69979,7 +70080,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
69979
70080
|
} catch (e) {}
|
|
69980
70081
|
enriched.push(this.enrichVodFile(vodFile, channel, streamUrl));
|
|
69981
70082
|
}
|
|
69982
|
-
|
|
70083
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclips", `Returning ${enriched.length} enriched recording files`);
|
|
69983
70084
|
if (!bypassCache) {
|
|
69984
70085
|
const cacheKey = this.getNvrRecordingsCacheKey(channel, startTime, endTime, streamType, iLogicChannel, autoSearchByDay);
|
|
69985
70086
|
this.recordingsCache.set(cacheKey, {
|
|
@@ -70016,7 +70117,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70016
70117
|
prepare: true,
|
|
70017
70118
|
seek: seekSeconds
|
|
70018
70119
|
});
|
|
70019
|
-
|
|
70120
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclipThumbnailJpeg", `Extracting thumbnail from VOD URL (FLV): ${vodUrl.substring(0, 100)}... (seek=${seekSeconds}s)`);
|
|
70020
70121
|
const { spawn: spawn2 } = await import("child_process");
|
|
70021
70122
|
return new Promise((resolve, reject) => {
|
|
70022
70123
|
const chunks = [];
|
|
@@ -70064,7 +70165,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70064
70165
|
reject(/* @__PURE__ */ new Error(`ffmpeg produced too small output: ${jpeg.length} bytes`));
|
|
70065
70166
|
return;
|
|
70066
70167
|
}
|
|
70067
|
-
|
|
70168
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "getVideoclipThumbnailJpeg", `Successfully extracted thumbnail: ${jpeg.length} bytes`);
|
|
70068
70169
|
resolve(jpeg);
|
|
70069
70170
|
} else reject(/* @__PURE__ */ new Error(`ffmpeg exited with code ${code}: ${stderr.slice(-500)}`));
|
|
70070
70171
|
});
|
|
@@ -70113,10 +70214,10 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70113
70214
|
}
|
|
70114
70215
|
} }
|
|
70115
70216
|
}];
|
|
70116
|
-
|
|
70217
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "prepareNvrVodDownload", `Request body: ${JSON.stringify(body)}`);
|
|
70117
70218
|
try {
|
|
70118
70219
|
const response = await this.callMany(body);
|
|
70119
|
-
|
|
70220
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "prepareNvrVodDownload", `Response: ${JSON.stringify(response)}`);
|
|
70120
70221
|
const first = response[0];
|
|
70121
70222
|
if (!first || first.code !== 0 || !first.value?.fileList) {
|
|
70122
70223
|
const rspCode = first?.error?.rspCode;
|
|
@@ -70137,7 +70238,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70137
70238
|
if (!filename) throw new Error(`NvrDownload: no files found in response`);
|
|
70138
70239
|
return filename;
|
|
70139
70240
|
} catch (error) {
|
|
70140
|
-
|
|
70241
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "prepareNvrVodDownload", `Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
70141
70242
|
throw error;
|
|
70142
70243
|
}
|
|
70143
70244
|
}
|
|
@@ -70333,7 +70434,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70333
70434
|
* Convert a VodFile to RecordingFile with parsed metadata.
|
|
70334
70435
|
*/
|
|
70335
70436
|
enrichVodFile(vodFile, channel, streamUrl) {
|
|
70336
|
-
|
|
70437
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `RAW VodFile from API: ${JSON.stringify({
|
|
70337
70438
|
name: vodFile.name,
|
|
70338
70439
|
type: vodFile.type,
|
|
70339
70440
|
size: vodFile.size,
|
|
@@ -70386,7 +70487,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70386
70487
|
hashBits0to15: hashRevBin.slice(0, 16)
|
|
70387
70488
|
};
|
|
70388
70489
|
}
|
|
70389
|
-
|
|
70490
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Parsed filename: ${JSON.stringify({
|
|
70390
70491
|
fileName: vodFile.name,
|
|
70391
70492
|
filenameParts,
|
|
70392
70493
|
hexValueFromFilename,
|
|
@@ -70413,13 +70514,13 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70413
70514
|
const hexFlags = parsed?.flags;
|
|
70414
70515
|
if (parsed?.devType === "hub" && parsed?.version === 4) {
|
|
70415
70516
|
if (hexValueFromFilename && hexValueFromFilename !== "unknown") {
|
|
70416
|
-
|
|
70417
|
-
|
|
70517
|
+
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.`);
|
|
70518
|
+
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.`);
|
|
70418
70519
|
}
|
|
70419
70520
|
}
|
|
70420
|
-
|
|
70521
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Hex flags from filename: ${JSON.stringify(hexFlags)}`);
|
|
70421
70522
|
const typeFlags = this.parseRecordTypeFlags(vodFile.type);
|
|
70422
|
-
|
|
70523
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Type flags from recordType "${vodFile.type}": ${JSON.stringify(typeFlags)}`);
|
|
70423
70524
|
const hasPerson = (hexFlags?.aiPerson ?? false) || typeFlags.hasPerson;
|
|
70424
70525
|
const hasVehicle = (hexFlags?.aiVehicle ?? false) || typeFlags.hasVehicle;
|
|
70425
70526
|
const hasAnimal = (hexFlags?.aiAnimal ?? false) || typeFlags.hasAnimal;
|
|
@@ -70430,7 +70531,7 @@ var ReolinkCgiApi = class _ReolinkCgiApi {
|
|
|
70430
70531
|
const hasPackage = (hexFlags?.package ?? false) || typeFlags.hasPackage;
|
|
70431
70532
|
const hasRf = (hexFlags?.rf ?? false) || typeFlags.hasRf;
|
|
70432
70533
|
const hasOther = (hexFlags?.aiOther ?? false) || typeFlags.hasOther;
|
|
70433
|
-
|
|
70534
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(this.debugConfig, this.logger, "enrichVodFile", `Final merged flags: ${JSON.stringify({
|
|
70434
70535
|
hasPerson,
|
|
70435
70536
|
hasVehicle,
|
|
70436
70537
|
hasAnimal,
|
|
@@ -70836,8 +70937,8 @@ function nowIsoCompact() {
|
|
|
70836
70937
|
return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
70837
70938
|
}
|
|
70838
70939
|
function nalTypesSummary(videoType, accessUnitAnnexB) {
|
|
70839
|
-
if (videoType === "H264") return
|
|
70840
|
-
return
|
|
70940
|
+
if (videoType === "H264") return require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads(accessUnitAnnexB).map((n) => (n[0] ?? 0) & 31);
|
|
70941
|
+
return require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads2(accessUnitAnnexB).map((nal) => require_chunk_ZQFQRCLQ.getH265NalType(nal)).filter((t) => typeof t === "number");
|
|
70841
70942
|
}
|
|
70842
70943
|
function normalizeProfiles(p) {
|
|
70843
70944
|
const out = [];
|
|
@@ -71277,7 +71378,7 @@ async function sampleStreams(opts) {
|
|
|
71277
71378
|
});
|
|
71278
71379
|
};
|
|
71279
71380
|
api.client.on("frame", onFrame);
|
|
71280
|
-
const videoStream = new
|
|
71381
|
+
const videoStream = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
71281
71382
|
client: api.client,
|
|
71282
71383
|
api,
|
|
71283
71384
|
channel,
|
|
@@ -72327,7 +72428,7 @@ async function runMultifocalDiagnosticsConsecutively(params) {
|
|
|
72327
72428
|
let audioFrames = 0;
|
|
72328
72429
|
let lastSnapshotAtMs = 0;
|
|
72329
72430
|
const client = params.api.client;
|
|
72330
|
-
const videoStream = new
|
|
72431
|
+
const videoStream = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
72331
72432
|
client,
|
|
72332
72433
|
channel: chNative,
|
|
72333
72434
|
profile,
|
|
@@ -72411,7 +72512,7 @@ async function runMultifocalDiagnosticsConsecutively(params) {
|
|
|
72411
72512
|
const baseStreamName = profile === "main" ? "mainStream" : profile === "sub" ? "subStream" : "externStream";
|
|
72412
72513
|
const headerStreamTypeCandidates = profile === "sub" ? [1, 3] : profile === "main" ? [0, 2] : [0];
|
|
72413
72514
|
const channelIdTagCandidates = uniq([chNative, chNative + 1].filter((n) => Number.isFinite(n) && n >= 0));
|
|
72414
|
-
const messageClassCandidates = params.probeFull ? [
|
|
72515
|
+
const messageClassCandidates = params.probeFull ? [require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24, 0] : [require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24];
|
|
72415
72516
|
const extensionXmlCandidates = params.probeFull ? ["", buildChannelExtensionXml(chNative)] : [buildChannelExtensionXml(chNative)];
|
|
72416
72517
|
const attempts = [];
|
|
72417
72518
|
for (const messageClass of messageClassCandidates) for (const streamTypeHeader of headerStreamTypeCandidates) for (const extensionXml of extensionXmlCandidates) {
|
|
@@ -74932,14 +75033,14 @@ var require_lz4 = /* @__PURE__ */ require_chunk.__commonJSMin(((exports) => {
|
|
|
74932
75033
|
};
|
|
74933
75034
|
}));
|
|
74934
75035
|
//#endregion
|
|
74935
|
-
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-
|
|
75036
|
+
//#region node_modules/@apocaliss92/nodelink-js/dist/chunk-CE77DTET.js
|
|
74936
75037
|
var import_fxp = require_fxp();
|
|
74937
75038
|
var import_lz4 = /* @__PURE__ */ require_chunk.__toESM(require_lz4(), 1);
|
|
74938
75039
|
function encodeHeader(h) {
|
|
74939
|
-
const hasOffset =
|
|
75040
|
+
const hasOffset = require_chunk_ZQFQRCLQ.bcHeaderHasPayloadOffset(h.messageClass);
|
|
74940
75041
|
const headerLen = hasOffset ? 24 : 20;
|
|
74941
75042
|
const buf = Buffer.alloc(headerLen);
|
|
74942
|
-
const magic = h.magic ??
|
|
75043
|
+
const magic = h.magic ?? require_chunk_ZQFQRCLQ.BC_MAGIC;
|
|
74943
75044
|
if (magic.length !== 4) throw new Error("magic must be 4 bytes");
|
|
74944
75045
|
magic.copy(buf, 0);
|
|
74945
75046
|
buf.writeUInt32LE(h.cmdId >>> 0, 4);
|
|
@@ -74955,7 +75056,7 @@ function encodeHeader(h) {
|
|
|
74955
75056
|
function decodeHeader(buf) {
|
|
74956
75057
|
if (buf.length < 20) throw new Error("not enough data for Baichuan header");
|
|
74957
75058
|
const magic = buf.subarray(0, 4);
|
|
74958
|
-
if (!magic.equals(
|
|
75059
|
+
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")}`);
|
|
74959
75060
|
const cmdId = buf.readUInt32LE(4);
|
|
74960
75061
|
const bodyLen = buf.readUInt32LE(8);
|
|
74961
75062
|
const channelId = buf.readUInt8(12);
|
|
@@ -74963,7 +75064,7 @@ function decodeHeader(buf) {
|
|
|
74963
75064
|
const msgNum = buf.readUInt16LE(14);
|
|
74964
75065
|
const responseCode = buf.readUInt16LE(16);
|
|
74965
75066
|
const messageClass = buf.readUInt16LE(18);
|
|
74966
|
-
const headerLen =
|
|
75067
|
+
const headerLen = require_chunk_ZQFQRCLQ.bcHeaderHasPayloadOffset(messageClass) ? 24 : 20;
|
|
74967
75068
|
if (buf.length < headerLen) throw new Error("not enough data for Baichuan header (needs 24 bytes)");
|
|
74968
75069
|
const messageKey = buf.readUInt32LE(12);
|
|
74969
75070
|
const header = {
|
|
@@ -75033,9 +75134,9 @@ var BaichuanFrameParser = class {
|
|
|
75033
75134
|
this.needed = 4;
|
|
75034
75135
|
break;
|
|
75035
75136
|
}
|
|
75036
|
-
if (!this.buffer.subarray(0, 4).equals(
|
|
75037
|
-
const idx = this.buffer.indexOf(
|
|
75038
|
-
const idxRev = this.buffer.indexOf(
|
|
75137
|
+
if (!this.buffer.subarray(0, 4).equals(require_chunk_ZQFQRCLQ.BC_MAGIC) && !this.buffer.subarray(0, 4).equals(require_chunk_ZQFQRCLQ.BC_MAGIC_REV)) {
|
|
75138
|
+
const idx = this.buffer.indexOf(require_chunk_ZQFQRCLQ.BC_MAGIC);
|
|
75139
|
+
const idxRev = this.buffer.indexOf(require_chunk_ZQFQRCLQ.BC_MAGIC_REV);
|
|
75039
75140
|
const next = idx === -1 ? idxRev : idxRev === -1 ? idx : Math.min(idx, idxRev);
|
|
75040
75141
|
if (next === -1) {
|
|
75041
75142
|
this.buffer = this.buffer.subarray(Math.max(0, this.buffer.length - 3));
|
|
@@ -75251,8 +75352,8 @@ function buildC2mQ(params) {
|
|
|
75251
75352
|
const os$5 = params.os ?? "MAC";
|
|
75252
75353
|
return buildP2pXml(`<C2M_Q><uid>${xmlEscape(params.uid)}</uid><p>${xmlEscape(os$5)}</p></C2M_Q>`);
|
|
75253
75354
|
}
|
|
75254
|
-
function parseIpPortBlock(
|
|
75255
|
-
const m = new RegExp(`<${
|
|
75355
|
+
function parseIpPortBlock(tag2, body) {
|
|
75356
|
+
const m = new RegExp(`<${tag2}>([\\s\\S]*?)</${tag2}>`, "i").exec(body);
|
|
75256
75357
|
if (!m) return void 0;
|
|
75257
75358
|
const block = m[1] ?? "";
|
|
75258
75359
|
const ip = /<ip>([^<]+)<\/ip>/i.exec(block)?.[1];
|
|
@@ -75297,8 +75398,8 @@ function parseR2cCr(xml) {
|
|
|
75297
75398
|
if (!Number.isFinite(rsp)) return void 0;
|
|
75298
75399
|
const sidStr = /<sid>(-?\d+)<\/sid>/i.exec(body)?.[1];
|
|
75299
75400
|
const sid = sidStr != null ? Number(sidStr) : void 0;
|
|
75300
|
-
const parseCustom = (
|
|
75301
|
-
const mm = new RegExp(`<${
|
|
75401
|
+
const parseCustom = (tag2) => {
|
|
75402
|
+
const mm = new RegExp(`<${tag2}>([\\s\\S]*?)</${tag2}>`, "i").exec(body);
|
|
75302
75403
|
if (!mm) return void 0;
|
|
75303
75404
|
const block = mm[1] ?? "";
|
|
75304
75405
|
const ip = /<ip>([^<]+)<\/ip>/i.exec(block)?.[1];
|
|
@@ -76858,12 +76959,12 @@ function asLogger(logger) {
|
|
|
76858
76959
|
error: resolveMethod(base, "error"),
|
|
76859
76960
|
debug: resolveMethod(base, "debug")
|
|
76860
76961
|
};
|
|
76861
|
-
out.child = (
|
|
76962
|
+
out.child = (tag2) => createTaggedLogger(out, tag2);
|
|
76862
76963
|
return out;
|
|
76863
76964
|
}
|
|
76864
|
-
function createTaggedLogger(base,
|
|
76965
|
+
function createTaggedLogger(base, tag2) {
|
|
76865
76966
|
const b = base.log ? base : asLogger(base);
|
|
76866
|
-
const prefix = `[${
|
|
76967
|
+
const prefix = `[${tag2}] `;
|
|
76867
76968
|
const wrap = (fn) => {
|
|
76868
76969
|
return (message, ...optionalParams) => {
|
|
76869
76970
|
if (typeof message === "string") fn(`${prefix}${message}`, ...optionalParams);
|
|
@@ -76890,7 +76991,7 @@ function createDebugGateLogger(base, enabled = false) {
|
|
|
76890
76991
|
error: b.error,
|
|
76891
76992
|
debug: enabled ? b.debug : noop
|
|
76892
76993
|
};
|
|
76893
|
-
out.child = (
|
|
76994
|
+
out.child = (tag2) => createDebugGateLogger(createTaggedLogger(out, tag2), enabled);
|
|
76894
76995
|
return out;
|
|
76895
76996
|
}
|
|
76896
76997
|
function isTalkCmd(cmdId) {
|
|
@@ -77050,7 +77151,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77050
77151
|
constructor(options) {
|
|
77051
77152
|
super();
|
|
77052
77153
|
this.opts = options;
|
|
77053
|
-
this.debugCfg =
|
|
77154
|
+
this.debugCfg = require_chunk_ZQFQRCLQ.normalizeDebugOptions(options.debugOptions);
|
|
77054
77155
|
this.logger = createDebugGateLogger(options.logger, this.debugCfg.general || this.debugCfg.traceNativeStream || this.debugCfg.traceRecordings || this.debugCfg.traceTalk || this.debugCfg.traceEvents || this.debugCfg.debugRtsp);
|
|
77055
77156
|
this.on("error", (err) => {
|
|
77056
77157
|
this.logFixed("error", {
|
|
@@ -77532,7 +77633,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77532
77633
|
streamType: 0,
|
|
77533
77634
|
msgNum,
|
|
77534
77635
|
responseCode: 0,
|
|
77535
|
-
messageClass:
|
|
77636
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
77536
77637
|
payloadOffset: 0
|
|
77537
77638
|
});
|
|
77538
77639
|
this.logDebug("udp_keepalive_ping_tx", {
|
|
@@ -77564,7 +77665,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77564
77665
|
cmdId: 93,
|
|
77565
77666
|
channel: this.opts.channel ?? 0,
|
|
77566
77667
|
channelIdOverride: 0,
|
|
77567
|
-
messageClass:
|
|
77668
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
77568
77669
|
streamType: 0,
|
|
77569
77670
|
extensionXml: "",
|
|
77570
77671
|
internal: true
|
|
@@ -77903,7 +78004,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
77903
78004
|
cmdId: 2,
|
|
77904
78005
|
payloadXml: logoutXml,
|
|
77905
78006
|
extensionXml: "",
|
|
77906
|
-
messageClass:
|
|
78007
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
77907
78008
|
channelIdOverride: effectiveHostChannelId,
|
|
77908
78009
|
timeoutMs: 5e3
|
|
77909
78010
|
})).header.responseCode;
|
|
@@ -78016,12 +78117,12 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78016
78117
|
};
|
|
78017
78118
|
s.frames++;
|
|
78018
78119
|
if (now - s.lastLogMs >= 1e3) {
|
|
78019
|
-
|
|
78120
|
+
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}`);
|
|
78020
78121
|
s.lastLogMs = now;
|
|
78021
78122
|
s.frames = 0;
|
|
78022
78123
|
}
|
|
78023
78124
|
this.rxCmdTraceStats.set(3, s);
|
|
78024
|
-
} else
|
|
78125
|
+
} 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}`);
|
|
78025
78126
|
if (this.transport === "udp" && frame.header.cmdId === 234) {
|
|
78026
78127
|
try {
|
|
78027
78128
|
const header = encodeHeader({
|
|
@@ -78058,7 +78159,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78058
78159
|
}
|
|
78059
78160
|
return;
|
|
78060
78161
|
}
|
|
78061
|
-
if (this.debugCfg.traceTalk && isTalkCmd(frame.header.cmdId))
|
|
78162
|
+
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}`);
|
|
78062
78163
|
this.emit("frame", frame);
|
|
78063
78164
|
const key = `${frame.header.cmdId}:${frame.header.msgNum}`;
|
|
78064
78165
|
const pending = this.pending.get(key);
|
|
@@ -78079,7 +78180,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78079
78180
|
};
|
|
78080
78181
|
s.frames++;
|
|
78081
78182
|
if (now2 - s.lastLogMs >= 500) {
|
|
78082
|
-
|
|
78183
|
+
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}`);
|
|
78083
78184
|
s.lastLogMs = now2;
|
|
78084
78185
|
s.frames = 0;
|
|
78085
78186
|
}
|
|
@@ -78110,7 +78211,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78110
78211
|
const eventLogTag = sid ? `BaichuanEvent sid=${sid}` : "BaichuanEvent";
|
|
78111
78212
|
const events$1 = this.parseEvents(frame);
|
|
78112
78213
|
for (const event of events$1) {
|
|
78113
|
-
|
|
78214
|
+
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 ?? ""}` : ""));
|
|
78114
78215
|
this.emit("event", event);
|
|
78115
78216
|
}
|
|
78116
78217
|
} catch (error) {
|
|
@@ -78169,7 +78270,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78169
78270
|
if (!xml || !xml.startsWith("<?xml")) return [];
|
|
78170
78271
|
if (this.debugCfg.traceEvents) {
|
|
78171
78272
|
const snippet = xml.length > 500 ? `${xml.slice(0, 500)}...` : xml;
|
|
78172
|
-
|
|
78273
|
+
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)}`);
|
|
78173
78274
|
}
|
|
78174
78275
|
const fallbackChannelId = frame.header.channelId;
|
|
78175
78276
|
const fallbackChannel = fallbackChannelId === 250 ? 0 : Math.max(0, fallbackChannelId - 1);
|
|
@@ -78187,7 +78288,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78187
78288
|
const timeStampRaw2 = (getXmlText(alarmXml, "timeStamp") ?? getXmlText(alarmXml, "timestamp") ?? "").trim();
|
|
78188
78289
|
const timeStampNum2 = timeStampRaw2.length ? Number(timeStampRaw2) : void 0;
|
|
78189
78290
|
const alarmTimeStamp2 = Number.isFinite(timeStampNum2) ? timeStampNum2 : void 0;
|
|
78190
|
-
if (this.debugCfg.traceEvents)
|
|
78291
|
+
if (this.debugCfg.traceEvents) require_chunk_ZQFQRCLQ.eventTraceLog(this.debugCfg, this.logger, eventRawLogTag, `AlarmEvent channel=${channel} status=${JSON.stringify(status2)} aiType=${JSON.stringify(aiTypeRaw2)}`);
|
|
78191
78292
|
const statusTokens2 = status2.toLowerCase().split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
78192
78293
|
const visitorActive2 = statusTokens2.includes("visitor");
|
|
78193
78294
|
const dayNightActive2 = statusTokens2.includes("dn") || statusTokens2.includes("daynight");
|
|
@@ -78461,15 +78562,15 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78461
78562
|
const extBuf = Buffer.from(extXml, "utf8");
|
|
78462
78563
|
const payloadBuf = Buffer.from(payloadXml, "utf8");
|
|
78463
78564
|
if (enc.kind === "none") return Buffer.concat([extBuf, payloadBuf]);
|
|
78464
|
-
if (enc.kind === "bc") return Buffer.concat([
|
|
78465
|
-
if (enc.kind === "aes" || enc.kind === "full_aes") return Buffer.concat([
|
|
78565
|
+
if (enc.kind === "bc") return Buffer.concat([require_chunk_ZQFQRCLQ.bcEncrypt(extBuf, channelId), require_chunk_ZQFQRCLQ.bcEncrypt(payloadBuf, channelId)]);
|
|
78566
|
+
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)]);
|
|
78466
78567
|
return Buffer.concat([extBuf, payloadBuf]);
|
|
78467
78568
|
}
|
|
78468
78569
|
encodeBodyBinary(extXml, payload, channelId, enc) {
|
|
78469
78570
|
const extBuf = Buffer.from(extXml, "utf8");
|
|
78470
78571
|
if (enc.kind === "none") return Buffer.concat([extBuf, payload]);
|
|
78471
|
-
if (enc.kind === "bc") return Buffer.concat([
|
|
78472
|
-
if (enc.kind === "aes" || enc.kind === "full_aes") return Buffer.concat([
|
|
78572
|
+
if (enc.kind === "bc") return Buffer.concat([require_chunk_ZQFQRCLQ.bcEncrypt(extBuf, channelId), payload]);
|
|
78573
|
+
if (enc.kind === "aes" || enc.kind === "full_aes") return Buffer.concat([require_chunk_ZQFQRCLQ.aesEncrypt(extBuf, enc.key), payload]);
|
|
78473
78574
|
return Buffer.concat([extBuf, payload]);
|
|
78474
78575
|
}
|
|
78475
78576
|
/**
|
|
@@ -78514,7 +78615,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78514
78615
|
bodyLen,
|
|
78515
78616
|
binaryPayload: true
|
|
78516
78617
|
});
|
|
78517
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78618
|
+
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}`);
|
|
78518
78619
|
this.recordTx({
|
|
78519
78620
|
cmdId,
|
|
78520
78621
|
responseCode: 0,
|
|
@@ -78531,8 +78632,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78531
78632
|
let dec;
|
|
78532
78633
|
try {
|
|
78533
78634
|
if (enc.kind === "none") dec = buf;
|
|
78534
|
-
else if (enc.kind === "bc") dec =
|
|
78535
|
-
else dec =
|
|
78635
|
+
else if (enc.kind === "bc") dec = require_chunk_ZQFQRCLQ.bcDecrypt(buf, channelId);
|
|
78636
|
+
else dec = require_chunk_ZQFQRCLQ.aesDecrypt(buf, enc.key);
|
|
78536
78637
|
} catch {
|
|
78537
78638
|
return;
|
|
78538
78639
|
}
|
|
@@ -78598,8 +78699,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78598
78699
|
messageClass,
|
|
78599
78700
|
bodyLen
|
|
78600
78701
|
});
|
|
78601
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78602
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78702
|
+
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}`);
|
|
78703
|
+
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}`);
|
|
78603
78704
|
this.recordTx({
|
|
78604
78705
|
cmdId,
|
|
78605
78706
|
responseCode: 0,
|
|
@@ -78614,8 +78715,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78614
78715
|
responseCode: frame.header.responseCode,
|
|
78615
78716
|
msgNum: frame.header.msgNum
|
|
78616
78717
|
});
|
|
78617
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78618
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78718
|
+
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}`);
|
|
78719
|
+
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}`);
|
|
78619
78720
|
if (frame.header.responseCode === 400) {
|
|
78620
78721
|
if (frame.body.length === 0) throw new Error("Baichuan authentication failed (responseCode 400, empty body) - check username/password");
|
|
78621
78722
|
}
|
|
@@ -78685,9 +78786,9 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78685
78786
|
messageClass,
|
|
78686
78787
|
bodyLen
|
|
78687
78788
|
});
|
|
78688
|
-
if (_BaichuanClient.recordingCmdIds.has(cmdId))
|
|
78689
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78690
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78789
|
+
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}`);
|
|
78790
|
+
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}`);
|
|
78791
|
+
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}`);
|
|
78691
78792
|
this.recordTx({
|
|
78692
78793
|
cmdId,
|
|
78693
78794
|
responseCode: 0,
|
|
@@ -78702,9 +78803,9 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
78702
78803
|
responseCode: frame.header.responseCode,
|
|
78703
78804
|
msgNum: frame.header.msgNum
|
|
78704
78805
|
});
|
|
78705
|
-
if (_BaichuanClient.recordingCmdIds.has(frame.header.cmdId))
|
|
78706
|
-
if (this.debugCfg.traceNativeStream && (cmdId === 3 || cmdId === 4))
|
|
78707
|
-
if (this.debugCfg.traceTalk && isTalkCmd(cmdId))
|
|
78806
|
+
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}`);
|
|
78807
|
+
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}`);
|
|
78808
|
+
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}`);
|
|
78708
78809
|
if (!internal) this.kickIdleDisconnectTimer();
|
|
78709
78810
|
return frame;
|
|
78710
78811
|
}
|
|
@@ -79526,8 +79627,8 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79526
79627
|
const tryAs = (enc) => {
|
|
79527
79628
|
try {
|
|
79528
79629
|
if (enc.kind === "none") return buf;
|
|
79529
|
-
if (enc.kind === "bc") return
|
|
79530
|
-
if (enc.kind === "aes" || enc.kind === "full_aes") return
|
|
79630
|
+
if (enc.kind === "bc") return require_chunk_ZQFQRCLQ.bcDecrypt(buf, channelId);
|
|
79631
|
+
if (enc.kind === "aes" || enc.kind === "full_aes") return require_chunk_ZQFQRCLQ.aesDecrypt(buf, enc.key);
|
|
79531
79632
|
return null;
|
|
79532
79633
|
} catch {
|
|
79533
79634
|
return null;
|
|
@@ -79557,7 +79658,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79557
79658
|
streamType: 0,
|
|
79558
79659
|
msgNum,
|
|
79559
79660
|
responseCode: encByte,
|
|
79560
|
-
messageClass:
|
|
79661
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_LEGACY
|
|
79561
79662
|
});
|
|
79562
79663
|
const pendingKey = `${cmdId}:${msgNum}`;
|
|
79563
79664
|
const framePromise = new Promise((resolve, reject) => {
|
|
@@ -79589,15 +79690,15 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79589
79690
|
else if (encType === 1) this.enc = { kind: "bc" };
|
|
79590
79691
|
else if (encType === 2) this.enc = {
|
|
79591
79692
|
kind: "aes",
|
|
79592
|
-
key:
|
|
79693
|
+
key: require_chunk_ZQFQRCLQ.deriveAesKey(nonce, this.opts.password)
|
|
79593
79694
|
};
|
|
79594
79695
|
else if (encType === 18) this.enc = {
|
|
79595
79696
|
kind: "full_aes",
|
|
79596
|
-
key:
|
|
79697
|
+
key: require_chunk_ZQFQRCLQ.deriveAesKey(nonce, this.opts.password)
|
|
79597
79698
|
};
|
|
79598
79699
|
else throw new Error(`Baichuan login: unknown encType=0x${encType.toString(16)}`);
|
|
79599
|
-
const userHash =
|
|
79600
|
-
const passHash =
|
|
79700
|
+
const userHash = require_chunk_ZQFQRCLQ.md5StrModern(`${this.opts.username}${nonce}`);
|
|
79701
|
+
const passHash = require_chunk_ZQFQRCLQ.md5StrModern(`${this.opts.password}${nonce}`);
|
|
79601
79702
|
const loginXml = buildLoginXml(userHash, passHash);
|
|
79602
79703
|
this.logDebug("login_hash", {
|
|
79603
79704
|
username: this.opts.username,
|
|
@@ -79612,7 +79713,7 @@ var BaichuanClient = class _BaichuanClient extends events.EventEmitter {
|
|
|
79612
79713
|
cmdId: 1,
|
|
79613
79714
|
payloadXml: loginXml,
|
|
79614
79715
|
extensionXml: "",
|
|
79615
|
-
messageClass:
|
|
79716
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
79616
79717
|
channelIdOverride: effectiveHostChannelId,
|
|
79617
79718
|
encryption: loginEnc,
|
|
79618
79719
|
timeoutMs: 1e4
|
|
@@ -79672,7 +79773,7 @@ async function* createNativeStream(api, channel, profile, options) {
|
|
|
79672
79773
|
client = api.client;
|
|
79673
79774
|
}
|
|
79674
79775
|
}
|
|
79675
|
-
const videoStream = new
|
|
79776
|
+
const videoStream = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
79676
79777
|
client,
|
|
79677
79778
|
api,
|
|
79678
79779
|
channel,
|
|
@@ -80190,7 +80291,7 @@ var H264Flow = class extends BaseFlow {
|
|
|
80190
80291
|
super(transport, "H264");
|
|
80191
80292
|
}
|
|
80192
80293
|
extractParameterSets(accessUnitAnnexB) {
|
|
80193
|
-
const nals =
|
|
80294
|
+
const nals = require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads(accessUnitAnnexB);
|
|
80194
80295
|
for (const nal of nals) {
|
|
80195
80296
|
if (nal.length < 1) continue;
|
|
80196
80297
|
const nalType = (nal[0] ?? 0) & 31;
|
|
@@ -80235,9 +80336,9 @@ var H265Flow = class extends BaseFlow {
|
|
|
80235
80336
|
super(transport, "H265");
|
|
80236
80337
|
}
|
|
80237
80338
|
extractParameterSets(accessUnitAnnexB) {
|
|
80238
|
-
const vps =
|
|
80239
|
-
const sps =
|
|
80240
|
-
const pps =
|
|
80339
|
+
const vps = require_chunk_ZQFQRCLQ.extractVpsFromAnnexB(accessUnitAnnexB);
|
|
80340
|
+
const sps = require_chunk_ZQFQRCLQ.extractSpsFromAnnexB(accessUnitAnnexB);
|
|
80341
|
+
const pps = require_chunk_ZQFQRCLQ.extractPpsFromAnnexB(accessUnitAnnexB);
|
|
80241
80342
|
if (vps && !this.vps) this.vps = vps;
|
|
80242
80343
|
if (sps && !this.sps) this.sps = sps;
|
|
80243
80344
|
if (pps && !this.pps) this.pps = pps;
|
|
@@ -80621,8 +80722,8 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
80621
80722
|
/** Returns true if the raw (packed/Annex B) frame is an IDR (H.264) or IRAP (H.265). */
|
|
80622
80723
|
isRawFrameKeyframe(frame) {
|
|
80623
80724
|
try {
|
|
80624
|
-
if (frame.videoType === "H264") return _BaichuanRtspServer.splitAnnexBNals(
|
|
80625
|
-
if (frame.videoType === "H265") return
|
|
80725
|
+
if (frame.videoType === "H264") return _BaichuanRtspServer.splitAnnexBNals(require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data)).some((n) => n.length >= 1 && (n[0] & 31) === 5);
|
|
80726
|
+
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));
|
|
80626
80727
|
} catch {}
|
|
80627
80728
|
return false;
|
|
80628
80729
|
}
|
|
@@ -81522,13 +81623,13 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81522
81623
|
if (resources?.rtpAudioTimestamp !== void 0) resources.rtpAudioTimestamp = resources.rtpAudioTimestamp + 1024 >>> 0;
|
|
81523
81624
|
};
|
|
81524
81625
|
const isH265IrapAccessUnit = (annexB) => {
|
|
81525
|
-
const nals =
|
|
81626
|
+
const nals = require_chunk_ZQFQRCLQ.splitAnnexBToNalPayloads2(annexB);
|
|
81526
81627
|
for (const nal of nals) {
|
|
81527
81628
|
if (nal.length < 2) continue;
|
|
81528
81629
|
const b0 = nal[0];
|
|
81529
81630
|
if (b0 === void 0) continue;
|
|
81530
81631
|
if ((b0 & 128) !== 0) continue;
|
|
81531
|
-
if (
|
|
81632
|
+
if (require_chunk_ZQFQRCLQ.isH265Irap(b0 >> 1 & 63)) return true;
|
|
81532
81633
|
}
|
|
81533
81634
|
return false;
|
|
81534
81635
|
};
|
|
@@ -81684,7 +81785,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81684
81785
|
continue;
|
|
81685
81786
|
}
|
|
81686
81787
|
if (frame.videoType === "H264" || frame.videoType === "H265") {
|
|
81687
|
-
const normalizedVideoData = frame.videoType === "H264" ?
|
|
81788
|
+
const normalizedVideoData = frame.videoType === "H264" ? require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data) : require_chunk_ZQFQRCLQ.convertToAnnexB2(frame.data);
|
|
81688
81789
|
if (frameCount === 0) this.setFlowVideoType(frame.videoType, "first video frame");
|
|
81689
81790
|
if (!this.flow.getFmtp().hasParamSets) {
|
|
81690
81791
|
this.flow.extractParameterSets(normalizedVideoData);
|
|
@@ -81700,7 +81801,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81700
81801
|
}
|
|
81701
81802
|
if (useDirectRtp) {
|
|
81702
81803
|
const videoType = frame.videoType ?? this.flow.videoType;
|
|
81703
|
-
const normalizedVideoData = videoType === "H264" ?
|
|
81804
|
+
const normalizedVideoData = videoType === "H264" ? require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data) : require_chunk_ZQFQRCLQ.convertToAnnexB2(frame.data);
|
|
81704
81805
|
if (!resources?.seenFirstVideoKeyframe) if (videoType === "H265") {
|
|
81705
81806
|
const { hasParamSets } = this.flow.getFmtp();
|
|
81706
81807
|
if (!hasParamSets) {
|
|
@@ -81776,7 +81877,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81776
81877
|
const headHex = frame.data.subarray(0, 16).toString("hex");
|
|
81777
81878
|
this.rtspDebugLog(`First video frame written to ffmpeg stdin for client ${clientId} (len=${frame.data.length}, head=${headHex})`);
|
|
81778
81879
|
}
|
|
81779
|
-
if (!stdin.write(frame.videoType === "H264" ?
|
|
81880
|
+
if (!stdin.write(frame.videoType === "H264" ? require_chunk_ZQFQRCLQ.convertToAnnexB(frame.data) : frame.data)) await new Promise((resolve) => {
|
|
81780
81881
|
if (stdin) stdin.once("drain", () => resolve());
|
|
81781
81882
|
else resolve();
|
|
81782
81883
|
});
|
|
@@ -81888,7 +81989,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends events.EventEmitter {
|
|
|
81888
81989
|
ensureContinuousStream(dedicatedClient) {
|
|
81889
81990
|
if (this.continuousStream) return this.continuousStream;
|
|
81890
81991
|
const createLiveStream = async () => {
|
|
81891
|
-
return new
|
|
81992
|
+
return new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
81892
81993
|
client: dedicatedClient ?? this.api.client,
|
|
81893
81994
|
api: this.api,
|
|
81894
81995
|
channel: this.channel,
|
|
@@ -82584,29 +82685,29 @@ function parseSupportXml(xml) {
|
|
|
82584
82685
|
if (!match) return void 0;
|
|
82585
82686
|
const supportXml = match[1] ?? "";
|
|
82586
82687
|
const ptzMode = supportXml.match(/<ptzMode>([^<]*)<\/ptzMode>/i)?.[1];
|
|
82587
|
-
const topLevelInt = (
|
|
82588
|
-
return toNumberOrUndefined(supportXml.match(new RegExp(`<${
|
|
82688
|
+
const topLevelInt = (tag2) => {
|
|
82689
|
+
return toNumberOrUndefined(supportXml.match(new RegExp(`<${tag2}>([^<]*)<\\/${tag2}>`, "i"))?.[1]);
|
|
82589
82690
|
};
|
|
82590
|
-
const topLevelString = (
|
|
82591
|
-
return supportXml.match(new RegExp(`<${
|
|
82691
|
+
const topLevelString = (tag2) => {
|
|
82692
|
+
return supportXml.match(new RegExp(`<${tag2}>([^<]*)<\\/${tag2}>`, "i"))?.[1];
|
|
82592
82693
|
};
|
|
82593
82694
|
const items = [];
|
|
82594
82695
|
for (const itemMatch of supportXml.matchAll(/<item[^>]*>([\s\S]*?)<\/item>/gi)) {
|
|
82595
82696
|
const itemXml = itemMatch[1] ?? "";
|
|
82596
82697
|
const item = { chnID: toNumberOrUndefined(itemXml.match(/<chnID>([^<]*)<\/chnID>/i)?.[1]) ?? 0 };
|
|
82597
82698
|
for (const tagMatch of itemXml.matchAll(/<([A-Za-z0-9_]+)>([^<]*)<\/\1>/g)) {
|
|
82598
|
-
const
|
|
82699
|
+
const tag2 = tagMatch[1];
|
|
82599
82700
|
const value = tagMatch[2];
|
|
82600
|
-
if (!
|
|
82601
|
-
if (
|
|
82602
|
-
item[
|
|
82701
|
+
if (!tag2) continue;
|
|
82702
|
+
if (tag2 === "chnID") continue;
|
|
82703
|
+
item[tag2] = toNumberOrUndefined(value) ?? value;
|
|
82603
82704
|
}
|
|
82604
82705
|
items.push(item);
|
|
82605
82706
|
}
|
|
82606
82707
|
const support = { items };
|
|
82607
82708
|
if (ptzMode !== void 0) support.ptzMode = ptzMode;
|
|
82608
|
-
const assignInt = (key,
|
|
82609
|
-
const v = topLevelInt(
|
|
82709
|
+
const assignInt = (key, tag2) => {
|
|
82710
|
+
const v = topLevelInt(tag2);
|
|
82610
82711
|
if (v !== void 0) support[key] = v;
|
|
82611
82712
|
};
|
|
82612
82713
|
assignInt("IOInputPortNum", "IOInputPortNum");
|
|
@@ -82833,15 +82934,15 @@ function extractCanvasFromShelterXml(xml) {
|
|
|
82833
82934
|
const yMatch = xml.match(/<topLeftY>(\d+)<\/topLeftY>/g) ?? [];
|
|
82834
82935
|
let canvasX = 0;
|
|
82835
82936
|
let canvasY = 0;
|
|
82836
|
-
for (const
|
|
82837
|
-
const v = Number(
|
|
82937
|
+
for (const tag2 of xMatch) {
|
|
82938
|
+
const v = Number(tag2.replace(/<\/?topLeftX>/g, "")) | 0;
|
|
82838
82939
|
if (v > 0) {
|
|
82839
82940
|
canvasX = v & 65535;
|
|
82840
82941
|
break;
|
|
82841
82942
|
}
|
|
82842
82943
|
}
|
|
82843
|
-
for (const
|
|
82844
|
-
const v = Number(
|
|
82944
|
+
for (const tag2 of yMatch) {
|
|
82945
|
+
const v = Number(tag2.replace(/<\/?topLeftY>/g, "")) | 0;
|
|
82845
82946
|
if (v > 0) {
|
|
82846
82947
|
canvasY = v & 65535;
|
|
82847
82948
|
break;
|
|
@@ -82854,9 +82955,9 @@ function extractCanvasFromShelterXml(xml) {
|
|
|
82854
82955
|
}
|
|
82855
82956
|
function parseRectTags(block) {
|
|
82856
82957
|
const out = {};
|
|
82857
|
-
const grab = (
|
|
82858
|
-
const m = block.match(new RegExp(`<${
|
|
82859
|
-
if (m && m[1] !== void 0) out[
|
|
82958
|
+
const grab = (tag2) => {
|
|
82959
|
+
const m = block.match(new RegExp(`<${tag2}>([^<]*)<\\/${tag2}>`));
|
|
82960
|
+
if (m && m[1] !== void 0) out[tag2] = m[1];
|
|
82860
82961
|
};
|
|
82861
82962
|
grab("id");
|
|
82862
82963
|
grab("name");
|
|
@@ -83101,9 +83202,9 @@ var buildDetectionClasses = (parsed, recordType) => {
|
|
|
83101
83202
|
};
|
|
83102
83203
|
var getXmlTexts = (xml, tags) => {
|
|
83103
83204
|
const out = {};
|
|
83104
|
-
for (const
|
|
83105
|
-
const v = getXmlText(xml,
|
|
83106
|
-
if (v !== void 0) out[
|
|
83205
|
+
for (const tag2 of tags) {
|
|
83206
|
+
const v = getXmlText(xml, tag2);
|
|
83207
|
+
if (v !== void 0) out[tag2] = v;
|
|
83107
83208
|
}
|
|
83108
83209
|
return out;
|
|
83109
83210
|
};
|
|
@@ -83365,11 +83466,11 @@ function patchBlock(xml, block, fields) {
|
|
|
83365
83466
|
const end = xml.indexOf(`</${block}>`, start);
|
|
83366
83467
|
if (end < 0) return xml;
|
|
83367
83468
|
let body = xml.slice(start, end);
|
|
83368
|
-
for (const [
|
|
83469
|
+
for (const [tag2, value] of Object.entries(fields)) {
|
|
83369
83470
|
if (value === void 0) continue;
|
|
83370
83471
|
const escaped = escapeXmlText(typeof value === "boolean" ? value ? "1" : "0" : String(value));
|
|
83371
|
-
if (body.includes(`<${
|
|
83372
|
-
else body += `<${
|
|
83472
|
+
if (body.includes(`<${tag2}>`)) body = body.replace(new RegExp(`<${tag2}>[^<]*<\\/${tag2}>`), `<${tag2}>${escaped}</${tag2}>`);
|
|
83473
|
+
else body += `<${tag2}>${escaped}</${tag2}>`;
|
|
83373
83474
|
}
|
|
83374
83475
|
return xml.slice(0, start) + body + xml.slice(end);
|
|
83375
83476
|
}
|
|
@@ -83437,6 +83538,66 @@ var OSD_CORNER_LABELS = {
|
|
|
83437
83538
|
"bottom-left": "Bottom left",
|
|
83438
83539
|
"bottom-right": "Bottom right"
|
|
83439
83540
|
};
|
|
83541
|
+
function wireFloat(value) {
|
|
83542
|
+
return value.toExponential(6).replace(/e([+-])(\d)$/, "e$10$2");
|
|
83543
|
+
}
|
|
83544
|
+
function buildPtzGuardExtensionXml(channelId, direction) {
|
|
83545
|
+
return `<?xml version="1.0" encoding="UTF-8" ?>
|
|
83546
|
+
<Extension version="1.1">
|
|
83547
|
+
<channelId>${channelId}</channelId>${direction === "read" ? `
|
|
83548
|
+
<chnType>0</chnType>` : ""}
|
|
83549
|
+
</Extension>
|
|
83550
|
+
`;
|
|
83551
|
+
}
|
|
83552
|
+
function guardBody(channelId, command, fields) {
|
|
83553
|
+
return [
|
|
83554
|
+
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",
|
|
83555
|
+
"<body>",
|
|
83556
|
+
"<PtzGuard version=\"1.1\">",
|
|
83557
|
+
`<channelId>${channelId}</channelId>`,
|
|
83558
|
+
...fields,
|
|
83559
|
+
`<command>${command}</command>`,
|
|
83560
|
+
"<imageName></imageName>",
|
|
83561
|
+
`<xpos>${wireFloat(0)}</xpos>`,
|
|
83562
|
+
`<ypos>${wireFloat(0)}</ypos>`,
|
|
83563
|
+
`<height>${wireFloat(0)}</height>`,
|
|
83564
|
+
`<width>${wireFloat(0)}</width>`,
|
|
83565
|
+
"<mode>global</mode>",
|
|
83566
|
+
"</PtzGuard>",
|
|
83567
|
+
"</body>",
|
|
83568
|
+
""
|
|
83569
|
+
].join("\n");
|
|
83570
|
+
}
|
|
83571
|
+
function buildPtzGuardGoXml(channelId) {
|
|
83572
|
+
return guardBody(channelId, "toGrd", ["<benable>0</benable>", "<timeout>68</timeout>"]);
|
|
83573
|
+
}
|
|
83574
|
+
function buildPtzGuardSetXml(input) {
|
|
83575
|
+
return guardBody(input.channelId, "setGrd", [
|
|
83576
|
+
`<benable>${input.enabled ? 1 : 0}</benable>`,
|
|
83577
|
+
`<timeout>${Math.round(input.timeoutSeconds)}</timeout>`,
|
|
83578
|
+
...input.setPosition ? ["<needSetPos>1</needSetPos>"] : []
|
|
83579
|
+
]);
|
|
83580
|
+
}
|
|
83581
|
+
function tag(xml, name) {
|
|
83582
|
+
const m = new RegExp(`<${name}>([\\s\\S]*?)</${name}>`).exec(xml);
|
|
83583
|
+
return m === null ? null : (m[1] ?? "").trim();
|
|
83584
|
+
}
|
|
83585
|
+
function parsePtzGuardXml(xml) {
|
|
83586
|
+
if (!xml.includes("<PtzGuard")) return null;
|
|
83587
|
+
const enabled = tag(xml, "benable");
|
|
83588
|
+
const valid = tag(xml, "bvalid");
|
|
83589
|
+
const timeout = tag(xml, "timeout");
|
|
83590
|
+
if (enabled === null || valid === null || timeout === null) return null;
|
|
83591
|
+
const timeoutSeconds = Number.parseInt(timeout, 10);
|
|
83592
|
+
if (!Number.isFinite(timeoutSeconds)) return null;
|
|
83593
|
+
return {
|
|
83594
|
+
enabled: enabled === "1",
|
|
83595
|
+
valid: valid === "1",
|
|
83596
|
+
timeoutSeconds,
|
|
83597
|
+
mode: tag(xml, "mode") ?? "global",
|
|
83598
|
+
imageName: tag(xml, "imageName") ?? ""
|
|
83599
|
+
};
|
|
83600
|
+
}
|
|
83440
83601
|
var emitter = new events.EventEmitter();
|
|
83441
83602
|
var lastEventByCamera = /* @__PURE__ */ new Map();
|
|
83442
83603
|
var MAX_GLOBAL_EVENTS = 300;
|
|
@@ -84649,8 +84810,8 @@ var buildFileInfoListStopXml = (params) => {
|
|
|
84649
84810
|
</body>`;
|
|
84650
84811
|
};
|
|
84651
84812
|
var sleepMs = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
84652
|
-
var xmlDateTimePayload = (
|
|
84653
|
-
return `<${
|
|
84813
|
+
var xmlDateTimePayload = (tag2, d) => {
|
|
84814
|
+
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}>`;
|
|
84654
84815
|
};
|
|
84655
84816
|
var buildFileInfoListOpenXml = (params) => {
|
|
84656
84817
|
return `<?xml version="1.0" encoding="UTF-8" ?>
|
|
@@ -84838,10 +84999,10 @@ var isPlausibleStream = (s) => {
|
|
|
84838
84999
|
return s.width > 0 && s.height > 0 && (s.frameRate > 0 || s.bitRate > 0);
|
|
84839
85000
|
};
|
|
84840
85001
|
var logDebugStreamBlock = (params) => {
|
|
84841
|
-
const { logger, traceNativeStream, channel, tag, blockXml } = params;
|
|
85002
|
+
const { logger, traceNativeStream, channel, tag: tag2, blockXml } = params;
|
|
84842
85003
|
if (!traceNativeStream) return;
|
|
84843
85004
|
if (!blockXml) {
|
|
84844
|
-
(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}> missing`);
|
|
84845
85006
|
return;
|
|
84846
85007
|
}
|
|
84847
85008
|
const raw = blockXml;
|
|
@@ -84868,7 +85029,7 @@ var logDebugStreamBlock = (params) => {
|
|
|
84868
85029
|
const previewMax = 1400;
|
|
84869
85030
|
const xmlPreview = raw.length <= previewMax ? raw : raw.slice(0, previewMax) + `
|
|
84870
85031
|
...truncated (+${raw.length - previewMax} chars)`;
|
|
84871
|
-
(logger.warn ?? logger.log).call(logger, `[ReolinkBaichuanApi] getStreamMetadata(traceNativeStream): channel=${channel} tag=<${
|
|
85032
|
+
(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({
|
|
84872
85033
|
widthText,
|
|
84873
85034
|
heightText,
|
|
84874
85035
|
frameText,
|
|
@@ -84961,20 +85122,20 @@ var parseChannelStreamMetadataFromGetEncXml = (params) => {
|
|
|
84961
85122
|
audioEnabled = audioEnabled && s.audio === 1;
|
|
84962
85123
|
}
|
|
84963
85124
|
}
|
|
84964
|
-
for (const
|
|
85125
|
+
for (const tag2 of [
|
|
84965
85126
|
"extStream",
|
|
84966
85127
|
"thirdStream",
|
|
84967
85128
|
"externStream",
|
|
84968
85129
|
"extraStream"
|
|
84969
85130
|
]) {
|
|
84970
|
-
const extMatch = xml.match(new RegExp(`<${
|
|
85131
|
+
const extMatch = xml.match(new RegExp(`<${tag2}[^>]*>([\\s\\S]*?)<\\/${tag2}>`));
|
|
84971
85132
|
if (!extMatch) continue;
|
|
84972
85133
|
const extXml = extMatch[1] ?? "";
|
|
84973
85134
|
logDebugStreamBlock({
|
|
84974
85135
|
logger,
|
|
84975
85136
|
traceNativeStream,
|
|
84976
85137
|
channel,
|
|
84977
|
-
tag,
|
|
85138
|
+
tag: tag2,
|
|
84978
85139
|
blockXml: extXml
|
|
84979
85140
|
});
|
|
84980
85141
|
const s = buildStream({
|
|
@@ -85065,7 +85226,7 @@ var sendTalkConfigWithReset = async (params) => {
|
|
|
85065
85226
|
channel: params.channel,
|
|
85066
85227
|
...params.channelIdOverride != null ? { channelIdOverride: params.channelIdOverride } : {},
|
|
85067
85228
|
payloadXml: params.payloadXml,
|
|
85068
|
-
messageClass:
|
|
85229
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
85069
85230
|
})).header.responseCode;
|
|
85070
85231
|
};
|
|
85071
85232
|
const code = await trySend();
|
|
@@ -85075,7 +85236,7 @@ var sendTalkConfigWithReset = async (params) => {
|
|
|
85075
85236
|
channel: params.channel,
|
|
85076
85237
|
...params.channelIdOverride != null ? { channelIdOverride: params.channelIdOverride } : {},
|
|
85077
85238
|
payloadXml: "",
|
|
85078
|
-
messageClass:
|
|
85239
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
85079
85240
|
});
|
|
85080
85241
|
const retryCode = await trySend();
|
|
85081
85242
|
if (retryCode !== 200) throw new Error(`TalkConfig rejected after reset (responseCode ${retryCode})`);
|
|
@@ -85142,7 +85303,7 @@ var createBufferedTalkSession = (params) => {
|
|
|
85142
85303
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
85143
85304
|
extensionXml: buildBinaryExtensionXml(channel),
|
|
85144
85305
|
payload: Buffer.concat(parts),
|
|
85145
|
-
messageClass:
|
|
85306
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
85146
85307
|
});
|
|
85147
85308
|
const playLengthMs = samplesSent / info.audioConfig.sampleRate * 1e3;
|
|
85148
85309
|
const now = Date.now();
|
|
@@ -85188,7 +85349,7 @@ var createBufferedTalkSession = (params) => {
|
|
|
85188
85349
|
channel,
|
|
85189
85350
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
85190
85351
|
payloadXml: "",
|
|
85191
|
-
messageClass:
|
|
85352
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
85192
85353
|
});
|
|
85193
85354
|
if (frame.header.responseCode !== 200) throw new Error(`TalkReset rejected (responseCode ${frame.header.responseCode})`);
|
|
85194
85355
|
if (params.closeSocketOnStop) try {
|
|
@@ -86567,7 +86728,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86567
86728
|
* @param logger - Optional logger for debug output
|
|
86568
86729
|
* @returns The socket and a release function
|
|
86569
86730
|
*/
|
|
86570
|
-
async acquirePooledSocket(
|
|
86731
|
+
async acquirePooledSocket(tag2, logger) {
|
|
86571
86732
|
const log = logger ?? this.logger;
|
|
86572
86733
|
const now = Date.now();
|
|
86573
86734
|
const cooldownEntry = this.socketPoolCooldowns.get(this.host);
|
|
@@ -86578,12 +86739,12 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86578
86739
|
} else if (now < cooldownEntry.cooldownUntil) {
|
|
86579
86740
|
const remainingMs = cooldownEntry.cooldownUntil - now;
|
|
86580
86741
|
const reason = this.lastD2cDiscAtMs > 0 && now - this.lastD2cDiscAtMs < 12e4 ? "D2C_DISC (camera sleeping)" : "repeated login failures";
|
|
86581
|
-
const error = /* @__PURE__ */ new Error(`[SocketPool] Host ${this.host} is in cooldown for ${Math.ceil(remainingMs / 1e3)}s due to ${reason}. tag=${
|
|
86742
|
+
const error = /* @__PURE__ */ new Error(`[SocketPool] Host ${this.host} is in cooldown for ${Math.ceil(remainingMs / 1e3)}s due to ${reason}. tag=${tag2}`);
|
|
86582
86743
|
log?.debug?.(error.message);
|
|
86583
86744
|
throw error;
|
|
86584
86745
|
}
|
|
86585
86746
|
}
|
|
86586
|
-
const existing = this.socketPool.get(
|
|
86747
|
+
const existing = this.socketPool.get(tag2);
|
|
86587
86748
|
if (existing) {
|
|
86588
86749
|
if (existing.idleCloseTimer) {
|
|
86589
86750
|
clearTimeout(existing.idleCloseTimer);
|
|
@@ -86593,35 +86754,35 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86593
86754
|
const client2 = await existing.pendingPromise;
|
|
86594
86755
|
existing.refCount++;
|
|
86595
86756
|
existing.lastUsedAt = Date.now();
|
|
86596
|
-
log?.debug?.(`[SocketPool] Waited for pending socket creation for tag=${
|
|
86757
|
+
log?.debug?.(`[SocketPool] Waited for pending socket creation for tag=${tag2} (refCount=${existing.refCount})`);
|
|
86597
86758
|
return {
|
|
86598
86759
|
client: client2,
|
|
86599
|
-
release: () => this.releasePooledSocket(
|
|
86760
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86600
86761
|
};
|
|
86601
86762
|
}
|
|
86602
86763
|
if (existing.refCount === 0) {
|
|
86603
86764
|
existing.refCount = 1;
|
|
86604
86765
|
existing.lastUsedAt = Date.now();
|
|
86605
|
-
log?.debug?.(`[SocketPool] Reusing idle socket for tag=${
|
|
86766
|
+
log?.debug?.(`[SocketPool] Reusing idle socket for tag=${tag2}`);
|
|
86606
86767
|
try {
|
|
86607
86768
|
if (!existing.client.loggedIn) await existing.client.login();
|
|
86608
86769
|
} catch {}
|
|
86609
86770
|
if (existing.client.loggedIn) return {
|
|
86610
86771
|
client: existing.client,
|
|
86611
|
-
release: () => this.releasePooledSocket(
|
|
86772
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86612
86773
|
};
|
|
86613
|
-
} else if (
|
|
86774
|
+
} else if (tag2.startsWith("replay:")) log?.debug?.(`[SocketPool] Preempting active replay socket for tag=${tag2}`);
|
|
86614
86775
|
else {
|
|
86615
86776
|
existing.refCount++;
|
|
86616
86777
|
existing.lastUsedAt = Date.now();
|
|
86617
|
-
log?.debug?.(`[SocketPool] Reusing active socket for tag=${
|
|
86778
|
+
log?.debug?.(`[SocketPool] Reusing active socket for tag=${tag2} (refCount=${existing.refCount})`);
|
|
86618
86779
|
return {
|
|
86619
86780
|
client: existing.client,
|
|
86620
|
-
release: () => this.releasePooledSocket(
|
|
86781
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86621
86782
|
};
|
|
86622
86783
|
}
|
|
86623
|
-
log?.debug?.(`[SocketPool] Closing existing socket for tag=${
|
|
86624
|
-
this.socketPool.delete(
|
|
86784
|
+
log?.debug?.(`[SocketPool] Closing existing socket for tag=${tag2} (recreating)`);
|
|
86785
|
+
this.socketPool.delete(tag2);
|
|
86625
86786
|
if (existing.generalPermitRelease) {
|
|
86626
86787
|
try {
|
|
86627
86788
|
existing.generalPermitRelease();
|
|
@@ -86634,10 +86795,10 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86634
86795
|
skipLogout: true
|
|
86635
86796
|
});
|
|
86636
86797
|
} catch (e) {
|
|
86637
|
-
log?.warn?.(`[SocketPool] Error closing old socket for tag=${
|
|
86798
|
+
log?.warn?.(`[SocketPool] Error closing old socket for tag=${tag2}: ${e}`);
|
|
86638
86799
|
}
|
|
86639
86800
|
}
|
|
86640
|
-
log?.log?.(`[SocketPool] Creating new socket for tag=${
|
|
86801
|
+
log?.log?.(`[SocketPool] Creating new socket for tag=${tag2}`);
|
|
86641
86802
|
const entry = {
|
|
86642
86803
|
client: void 0,
|
|
86643
86804
|
refCount: 0,
|
|
@@ -86654,7 +86815,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86654
86815
|
} : this.clientOptions);
|
|
86655
86816
|
this.attachD2cDiscListener(newClient);
|
|
86656
86817
|
newClient.on("error", (err) => {
|
|
86657
|
-
log?.debug?.(`[SocketPool] tag=${
|
|
86818
|
+
log?.debug?.(`[SocketPool] tag=${tag2} client error: ${err?.message ?? err}`);
|
|
86658
86819
|
});
|
|
86659
86820
|
await newClient.login();
|
|
86660
86821
|
const existingCooldown = this.socketPoolCooldowns.get(this.host);
|
|
@@ -86666,10 +86827,10 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86666
86827
|
entry.refCount = 1;
|
|
86667
86828
|
entry.lastUsedAt = Date.now();
|
|
86668
86829
|
delete entry.pendingPromise;
|
|
86669
|
-
log?.log?.(`[SocketPool] Socket connected for tag=${
|
|
86670
|
-
if (
|
|
86830
|
+
log?.log?.(`[SocketPool] Socket connected for tag=${tag2}`);
|
|
86831
|
+
if (tag2 !== "general") try {
|
|
86671
86832
|
const generalEntry = this.socketPool.get("general");
|
|
86672
|
-
if (generalEntry?.client) entry.generalPermitRelease = generalEntry.client.acquirePermit(0, `streaming-peer:${
|
|
86833
|
+
if (generalEntry?.client) entry.generalPermitRelease = generalEntry.client.acquirePermit(0, `streaming-peer:${tag2}`);
|
|
86673
86834
|
} catch {}
|
|
86674
86835
|
if (this.sessionGuardEnabled) this.maybeRebootOnTooManySessions();
|
|
86675
86836
|
return newClient;
|
|
@@ -86680,21 +86841,21 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86680
86841
|
if (failureCount >= _ReolinkBaichuanApi.SOCKET_POOL_FAILURE_THRESHOLD) {
|
|
86681
86842
|
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);
|
|
86682
86843
|
cooldownUntil = now2 + backoffMs;
|
|
86683
|
-
log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}). Entering cooldown for ${Math.ceil(backoffMs / 1e3)}s. tag=${
|
|
86684
|
-
} else log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}/${_ReolinkBaichuanApi.SOCKET_POOL_FAILURE_THRESHOLD} before cooldown). tag=${
|
|
86844
|
+
log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}). Entering cooldown for ${Math.ceil(backoffMs / 1e3)}s. tag=${tag2}`);
|
|
86845
|
+
} else log?.warn?.(`[SocketPool] Login failed for host=${this.host} (failure #${failureCount}/${_ReolinkBaichuanApi.SOCKET_POOL_FAILURE_THRESHOLD} before cooldown). tag=${tag2}`);
|
|
86685
86846
|
this.socketPoolCooldowns.set(this.host, {
|
|
86686
86847
|
failureCount,
|
|
86687
86848
|
lastFailureAt: now2,
|
|
86688
86849
|
cooldownUntil
|
|
86689
86850
|
});
|
|
86690
|
-
this.socketPool.delete(
|
|
86851
|
+
this.socketPool.delete(tag2);
|
|
86691
86852
|
throw loginError;
|
|
86692
86853
|
}
|
|
86693
86854
|
})();
|
|
86694
|
-
this.socketPool.set(
|
|
86855
|
+
this.socketPool.set(tag2, entry);
|
|
86695
86856
|
return {
|
|
86696
86857
|
client: await entry.pendingPromise,
|
|
86697
|
-
release: () => this.releasePooledSocket(
|
|
86858
|
+
release: () => this.releasePooledSocket(tag2, logger)
|
|
86698
86859
|
};
|
|
86699
86860
|
}
|
|
86700
86861
|
/**
|
|
@@ -86702,31 +86863,31 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86702
86863
|
* For shared sockets (general, streaming), just decrements refCount.
|
|
86703
86864
|
* For replay sockets, schedules idle close.
|
|
86704
86865
|
*/
|
|
86705
|
-
async releasePooledSocket(
|
|
86866
|
+
async releasePooledSocket(tag2, logger) {
|
|
86706
86867
|
const log = logger ?? this.logger;
|
|
86707
|
-
const entry = this.socketPool.get(
|
|
86868
|
+
const entry = this.socketPool.get(tag2);
|
|
86708
86869
|
if (!entry) return;
|
|
86709
86870
|
entry.refCount = Math.max(0, entry.refCount - 1);
|
|
86710
86871
|
entry.lastUsedAt = Date.now();
|
|
86711
|
-
log?.debug?.(`[SocketPool] Released socket for tag=${
|
|
86872
|
+
log?.debug?.(`[SocketPool] Released socket for tag=${tag2} (refCount=${entry.refCount})`);
|
|
86712
86873
|
if (entry.refCount > 0) return;
|
|
86713
|
-
const isReplayTag =
|
|
86714
|
-
const isStreamingTag =
|
|
86715
|
-
if (
|
|
86874
|
+
const isReplayTag = tag2.startsWith("replay:");
|
|
86875
|
+
const isStreamingTag = tag2.startsWith("streaming:");
|
|
86876
|
+
if (tag2 === "general") return;
|
|
86716
86877
|
if (isStreamingTag) {
|
|
86717
86878
|
if (entry.idleCloseTimer) return;
|
|
86718
86879
|
entry.idleCloseTimer = setTimeout(async () => {
|
|
86719
|
-
const current = this.socketPool.get(
|
|
86880
|
+
const current = this.socketPool.get(tag2);
|
|
86720
86881
|
if (!current) return;
|
|
86721
86882
|
if (current.refCount > 0) return;
|
|
86722
|
-
this.socketPool.delete(
|
|
86883
|
+
this.socketPool.delete(tag2);
|
|
86723
86884
|
if (current.generalPermitRelease) {
|
|
86724
86885
|
try {
|
|
86725
86886
|
current.generalPermitRelease();
|
|
86726
86887
|
} catch {}
|
|
86727
86888
|
current.generalPermitRelease = void 0;
|
|
86728
86889
|
}
|
|
86729
|
-
log?.log?.(`[SocketPool] Closing idle streaming socket for tag=${
|
|
86890
|
+
log?.log?.(`[SocketPool] Closing idle streaming socket for tag=${tag2}`);
|
|
86730
86891
|
try {
|
|
86731
86892
|
await current.client.close({
|
|
86732
86893
|
reason: "streaming idle close",
|
|
@@ -86739,11 +86900,11 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86739
86900
|
if (isReplayTag) {
|
|
86740
86901
|
if (entry.idleCloseTimer) return;
|
|
86741
86902
|
entry.idleCloseTimer = setTimeout(async () => {
|
|
86742
|
-
const current = this.socketPool.get(
|
|
86903
|
+
const current = this.socketPool.get(tag2);
|
|
86743
86904
|
if (!current) return;
|
|
86744
86905
|
if (current.refCount > 0) return;
|
|
86745
|
-
this.socketPool.delete(
|
|
86746
|
-
log?.debug?.(`[SocketPool] Closing idle replay socket for tag=${
|
|
86906
|
+
this.socketPool.delete(tag2);
|
|
86907
|
+
log?.debug?.(`[SocketPool] Closing idle replay socket for tag=${tag2} (keepalive expired)`);
|
|
86747
86908
|
try {
|
|
86748
86909
|
await current.client.close({
|
|
86749
86910
|
reason: "replay idle keepalive expired",
|
|
@@ -86753,24 +86914,24 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86753
86914
|
}, _ReolinkBaichuanApi.SOCKET_POOL_KEEPALIVE_MS);
|
|
86754
86915
|
return;
|
|
86755
86916
|
}
|
|
86756
|
-
this.socketPool.delete(
|
|
86917
|
+
this.socketPool.delete(tag2);
|
|
86757
86918
|
try {
|
|
86758
86919
|
await entry.client.close({
|
|
86759
86920
|
reason: "socket pool release",
|
|
86760
86921
|
skipLogout: true
|
|
86761
86922
|
});
|
|
86762
|
-
log?.log?.(`[SocketPool] Closed socket for tag=${
|
|
86923
|
+
log?.log?.(`[SocketPool] Closed socket for tag=${tag2}`);
|
|
86763
86924
|
} catch (e) {
|
|
86764
|
-
log?.warn?.(`[SocketPool] Error closing socket for tag=${
|
|
86925
|
+
log?.warn?.(`[SocketPool] Error closing socket for tag=${tag2}: ${e}`);
|
|
86765
86926
|
}
|
|
86766
86927
|
}
|
|
86767
86928
|
/**
|
|
86768
86929
|
* Force-close a socket by tag.
|
|
86769
86930
|
* Used to preempt existing connections before acquiring a new one.
|
|
86770
86931
|
*/
|
|
86771
|
-
async forceClosePooledSocket(
|
|
86932
|
+
async forceClosePooledSocket(tag2, logger) {
|
|
86772
86933
|
const log = logger ?? this.logger;
|
|
86773
|
-
const entry = this.socketPool.get(
|
|
86934
|
+
const entry = this.socketPool.get(tag2);
|
|
86774
86935
|
if (!entry) return false;
|
|
86775
86936
|
if (entry.idleCloseTimer) {
|
|
86776
86937
|
clearTimeout(entry.idleCloseTimer);
|
|
@@ -86782,16 +86943,16 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86782
86943
|
} catch {}
|
|
86783
86944
|
entry.generalPermitRelease = void 0;
|
|
86784
86945
|
}
|
|
86785
|
-
log?.debug?.(`[SocketPool] Force-closing socket for tag=${
|
|
86786
|
-
this.socketPool.delete(
|
|
86946
|
+
log?.debug?.(`[SocketPool] Force-closing socket for tag=${tag2}`);
|
|
86947
|
+
this.socketPool.delete(tag2);
|
|
86787
86948
|
try {
|
|
86788
86949
|
await entry.client.close({
|
|
86789
86950
|
reason: "force closed",
|
|
86790
86951
|
skipLogout: true
|
|
86791
86952
|
});
|
|
86792
|
-
log?.log?.(`[SocketPool] Force-closed socket for tag=${
|
|
86953
|
+
log?.log?.(`[SocketPool] Force-closed socket for tag=${tag2}`);
|
|
86793
86954
|
} catch (e) {
|
|
86794
|
-
log?.warn?.(`[SocketPool] Error during force-close for tag=${
|
|
86955
|
+
log?.warn?.(`[SocketPool] Error during force-close for tag=${tag2}: ${e}`);
|
|
86795
86956
|
}
|
|
86796
86957
|
return true;
|
|
86797
86958
|
}
|
|
@@ -86801,7 +86962,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86801
86962
|
async cleanupSocketPool() {
|
|
86802
86963
|
const entries = Array.from(this.socketPool.entries());
|
|
86803
86964
|
this.socketPool.clear();
|
|
86804
|
-
await Promise.allSettled(entries.map(async ([
|
|
86965
|
+
await Promise.allSettled(entries.map(async ([tag2, entry]) => {
|
|
86805
86966
|
try {
|
|
86806
86967
|
if (entry.idleCloseTimer) clearTimeout(entry.idleCloseTimer);
|
|
86807
86968
|
if (entry.generalPermitRelease) {
|
|
@@ -86810,7 +86971,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86810
86971
|
} catch {}
|
|
86811
86972
|
entry.generalPermitRelease = void 0;
|
|
86812
86973
|
}
|
|
86813
|
-
this.logger?.debug?.(`[SocketPool] Cleanup: closing tag=${
|
|
86974
|
+
this.logger?.debug?.(`[SocketPool] Cleanup: closing tag=${tag2}`);
|
|
86814
86975
|
await entry.client.close({
|
|
86815
86976
|
reason: "API cleanup",
|
|
86816
86977
|
skipLogout: true
|
|
@@ -86843,17 +87004,17 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86843
87004
|
* ```
|
|
86844
87005
|
*/
|
|
86845
87006
|
async createDedicatedSession(sessionKey, logger) {
|
|
86846
|
-
const
|
|
86847
|
-
(logger ?? this.logger)?.debug?.(`[SocketPool] createDedicatedSession sessionKey=${sessionKey} \u2192 tag=${
|
|
86848
|
-
return await this.acquirePooledSocket(
|
|
87007
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
87008
|
+
(logger ?? this.logger)?.debug?.(`[SocketPool] createDedicatedSession sessionKey=${sessionKey} \u2192 tag=${tag2}`);
|
|
87009
|
+
return await this.acquirePooledSocket(tag2, logger);
|
|
86849
87010
|
}
|
|
86850
87011
|
/**
|
|
86851
87012
|
* @deprecated Use forceClosePooledSocket via createDedicatedSession instead.
|
|
86852
87013
|
* Force-close a dedicated client if it exists.
|
|
86853
87014
|
*/
|
|
86854
87015
|
async forceCloseDedicatedClient(sessionKey, logger) {
|
|
86855
|
-
const
|
|
86856
|
-
return await this.forceClosePooledSocket(
|
|
87016
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
87017
|
+
return await this.forceClosePooledSocket(tag2, logger);
|
|
86857
87018
|
}
|
|
86858
87019
|
/**
|
|
86859
87020
|
* @deprecated Cleanup handled by cleanupSocketPool now.
|
|
@@ -86868,8 +87029,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86868
87029
|
const debugCfg = this.client.getDebugConfig?.();
|
|
86869
87030
|
if (debugCfg) {
|
|
86870
87031
|
const sid = this.client.getSocketSessionId?.();
|
|
86871
|
-
const
|
|
86872
|
-
|
|
87032
|
+
const tag2 = sid ? `ReolinkSimpleEvent sid=${sid}` : "ReolinkSimpleEvent";
|
|
87033
|
+
require_chunk_ZQFQRCLQ.eventTraceLog(debugCfg, this.logger, tag2, `dispatch type=${evt.type} channel=${evt.channel} timestamp=${evt.timestamp}`);
|
|
86873
87034
|
}
|
|
86874
87035
|
for (const cb of this.simpleEventListeners) try {
|
|
86875
87036
|
Promise.resolve(cb(evt)).catch((e) => {
|
|
@@ -86880,7 +87041,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
86880
87041
|
}
|
|
86881
87042
|
}
|
|
86882
87043
|
constructor(opts) {
|
|
86883
|
-
const dbg =
|
|
87044
|
+
const dbg = require_chunk_ZQFQRCLQ.normalizeDebugOptions(opts.debugOptions);
|
|
86884
87045
|
this.logger = createDebugGateLogger(opts.logger, dbg.general || dbg.traceNativeStream || dbg.traceRecordings || dbg.traceTalk || dbg.traceEvents || dbg.debugRtsp);
|
|
86885
87046
|
this.clientOptions = {
|
|
86886
87047
|
host: opts.host,
|
|
@@ -87467,7 +87628,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87467
87628
|
return;
|
|
87468
87629
|
}
|
|
87469
87630
|
entry.startInFlight = (async () => {
|
|
87470
|
-
const { BaichuanVideoStream: BaichuanVideoStream2 } = await Promise.resolve().then(() => require("./BaichuanVideoStream-
|
|
87631
|
+
const { BaichuanVideoStream: BaichuanVideoStream2 } = await Promise.resolve().then(() => require("./BaichuanVideoStream-2M4UO7MB-Cqjt1oxu.js"));
|
|
87471
87632
|
const sessionKey = `live:object-detections:ch${entry.channel}:${entry.profile}`;
|
|
87472
87633
|
const dedicated = await this.createDedicatedSession(sessionKey);
|
|
87473
87634
|
const stream$12 = new BaichuanVideoStream2({
|
|
@@ -87944,7 +88105,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87944
88105
|
channel: ch,
|
|
87945
88106
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
87946
88107
|
payloadXml: "",
|
|
87947
|
-
messageClass:
|
|
88108
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
87948
88109
|
});
|
|
87949
88110
|
if (frame.header.responseCode !== 200) throw new Error(`TalkReset rejected (responseCode ${frame.header.responseCode})`);
|
|
87950
88111
|
}
|
|
@@ -87963,7 +88124,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
87963
88124
|
channel: ch,
|
|
87964
88125
|
...channelIdOverride != null ? { channelIdOverride } : {},
|
|
87965
88126
|
payloadXml,
|
|
87966
|
-
messageClass:
|
|
88127
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
87967
88128
|
})).header.responseCode;
|
|
87968
88129
|
};
|
|
87969
88130
|
const code = await trySend();
|
|
@@ -88034,8 +88195,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
88034
88195
|
const idleTimeoutMs = options?.idleTimeoutMs ?? 3e4;
|
|
88035
88196
|
const sessionKey = `talk:${options?.deviceId ?? "unknown"}:ch${channel}:${Date.now()}`;
|
|
88036
88197
|
logger?.info?.(`[DedicatedTalk] Creating session: ${sessionKey} (idleTimeout=${idleTimeoutMs}ms)`);
|
|
88037
|
-
const
|
|
88038
|
-
const { client: dedicatedClient, release } = await this.acquirePooledSocket(
|
|
88198
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
88199
|
+
const { client: dedicatedClient, release } = await this.acquirePooledSocket(tag2, logger);
|
|
88039
88200
|
const summary = this.getSocketPoolSummary();
|
|
88040
88201
|
logger?.info?.(`[DedicatedTalk] Session created [sessions: ${summary.count} active${summary.count > 0 ? ` (${summary.tags.join(", ")})` : ""}]`);
|
|
88041
88202
|
try {
|
|
@@ -88115,7 +88276,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
88115
88276
|
cmdId: 10,
|
|
88116
88277
|
channel,
|
|
88117
88278
|
payloadXml: "",
|
|
88118
|
-
messageClass:
|
|
88279
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
88119
88280
|
});
|
|
88120
88281
|
return parseTalkAbilityXml(frame.body.length === 0 ? "" : client.tryDecryptXml(frame.body, frame.header.channelId, client.enc));
|
|
88121
88282
|
}
|
|
@@ -88148,8 +88309,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
88148
88309
|
}
|
|
88149
88310
|
/** SetNetPort via Baichuan: cmd_id 36 (enable/disable rtsp/rtmp/onvif/http/https) */
|
|
88150
88311
|
async setPortEnabled(params) {
|
|
88151
|
-
const
|
|
88152
|
-
const xml = `<?xml version="1.0" encoding="UTF-8" ?><body><${
|
|
88312
|
+
const tag2 = `${params.port[0].toUpperCase()}${params.port.slice(1)}Port`;
|
|
88313
|
+
const xml = `<?xml version="1.0" encoding="UTF-8" ?><body><${tag2} version="1.1"><enable>${params.enable ? 1 : 0}</enable></${tag2}></body>`;
|
|
88153
88314
|
await this.sendXml({
|
|
88154
88315
|
cmdId: 36,
|
|
88155
88316
|
payloadXml: xml
|
|
@@ -88180,13 +88341,13 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
88180
88341
|
*/
|
|
88181
88342
|
async setPortConfig(patch) {
|
|
88182
88343
|
const blocks = [];
|
|
88183
|
-
const append = (
|
|
88344
|
+
const append = (tag2, portField, cfg) => {
|
|
88184
88345
|
if (!cfg) return;
|
|
88185
88346
|
if (cfg.port === void 0 && cfg.enable === void 0) return;
|
|
88186
88347
|
const inner = [];
|
|
88187
88348
|
if (cfg.port !== void 0) inner.push(`<${portField}>${cfg.port}</${portField}>`);
|
|
88188
88349
|
if (cfg.enable !== void 0) inner.push(`<enable>${cfg.enable ? 1 : 0}</enable>`);
|
|
88189
|
-
blocks.push(`<${
|
|
88350
|
+
blocks.push(`<${tag2} version="1.1">${inner.join("")}</${tag2}>`);
|
|
88190
88351
|
};
|
|
88191
88352
|
append("ServerPort", "serverPort", patch.server);
|
|
88192
88353
|
append("HttpPort", "httpPort", patch.http);
|
|
@@ -88700,8 +88861,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
88700
88861
|
];
|
|
88701
88862
|
const current = await this.getEncXml(ch);
|
|
88702
88863
|
let updated = null;
|
|
88703
|
-
for (const
|
|
88704
|
-
const sectionRe = new RegExp(`(<${
|
|
88864
|
+
for (const tag2 of candidateTags) {
|
|
88865
|
+
const sectionRe = new RegExp(`(<${tag2}[^>]*>[\\s\\S]*?<videoEncType>)(\\d+)(</videoEncType>)`);
|
|
88705
88866
|
if (!sectionRe.test(current)) continue;
|
|
88706
88867
|
const next = current.replace(sectionRe, `$1${desired}$3`);
|
|
88707
88868
|
if (next !== current) {
|
|
@@ -89187,8 +89348,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89187
89348
|
const start = params.start;
|
|
89188
89349
|
const endOfStartDay = new Date(start.getFullYear(), start.getMonth(), start.getDate(), 23, 59, 59, 999);
|
|
89189
89350
|
const end = params.end.getTime() > endOfStartDay.getTime() ? endOfStartDay : params.end;
|
|
89190
|
-
|
|
89191
|
-
|
|
89351
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclips", `Query: start=${start.toISOString()}, end=${end.toISOString()} (forced same day)`);
|
|
89352
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclips", `Using UID for channel ${channel}: ${uid}`);
|
|
89192
89353
|
const streamType = params.streamType ?? "subStream";
|
|
89193
89354
|
const recordType = params.recordType ?? "manual, sched, io, md, people, face, vehicle, dog_cat, visitor, other, package";
|
|
89194
89355
|
const maxIterations = params.maxIterations ?? 50;
|
|
@@ -89208,7 +89369,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89208
89369
|
...params.timeoutMs != null ? { timeoutMs: params.timeoutMs } : {}
|
|
89209
89370
|
});
|
|
89210
89371
|
const unique = dedupeRecordingFiles(files);
|
|
89211
|
-
|
|
89372
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclips", `FileInfoList complete: ${unique.length} unique files (from ${files.length} total)`);
|
|
89212
89373
|
return unique;
|
|
89213
89374
|
});
|
|
89214
89375
|
}
|
|
@@ -89231,9 +89392,9 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89231
89392
|
const streamType = params.streamType;
|
|
89232
89393
|
const logger = params.logger ?? this.logger;
|
|
89233
89394
|
const sessionKey = params.deviceId ? `replay:${params.deviceId}:ch${channel}` : `replay:standalone:ch${channel}:${Date.now()}`;
|
|
89234
|
-
const
|
|
89235
|
-
logger?.debug?.(`[startRecordingReplayStreamStandalone] sessionKey=${sessionKey} -> tag=${
|
|
89236
|
-
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(
|
|
89395
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
89396
|
+
logger?.debug?.(`[startRecordingReplayStreamStandalone] sessionKey=${sessionKey} -> tag=${tag2}`);
|
|
89397
|
+
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(tag2, logger);
|
|
89237
89398
|
const uid = await this.ensureUidForRecordings(channel, void 0);
|
|
89238
89399
|
const payloadXml = buildFileInfoListReplayByNameXml({
|
|
89239
89400
|
channel,
|
|
@@ -89244,7 +89405,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89244
89405
|
});
|
|
89245
89406
|
const msgNum = 0;
|
|
89246
89407
|
dedicatedClient.subscribeVideoStream(5, msgNum);
|
|
89247
|
-
const stream$14 = new
|
|
89408
|
+
const stream$14 = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
89248
89409
|
client: dedicatedClient,
|
|
89249
89410
|
channel,
|
|
89250
89411
|
profile: streamType === "subStream" ? "sub" : "main",
|
|
@@ -89263,7 +89424,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89263
89424
|
channel,
|
|
89264
89425
|
channelIdOverride: sessionCounter,
|
|
89265
89426
|
payloadXml,
|
|
89266
|
-
messageClass:
|
|
89427
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89267
89428
|
msgNumOverride: 0,
|
|
89268
89429
|
timeoutMs: params.timeoutMs,
|
|
89269
89430
|
internal: true
|
|
@@ -89295,7 +89456,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89295
89456
|
cmdId: 7,
|
|
89296
89457
|
channel,
|
|
89297
89458
|
payloadXml: stopXml,
|
|
89298
|
-
messageClass:
|
|
89459
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89299
89460
|
timeoutMs: 2e3,
|
|
89300
89461
|
internal: true
|
|
89301
89462
|
});
|
|
@@ -89336,8 +89497,8 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89336
89497
|
const streamType = params.streamType;
|
|
89337
89498
|
const logger = params.logger ?? this.logger;
|
|
89338
89499
|
const sessionKey = params.deviceId ? `replay:${params.deviceId}:ch${channel}` : `replay:nvr:ch${channel}:${Date.now()}`;
|
|
89339
|
-
const
|
|
89340
|
-
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(
|
|
89500
|
+
const tag2 = this.resolveSocketTag(sessionKey);
|
|
89501
|
+
const { client: dedicatedClient, release: releaseDedicatedClient } = await this.acquirePooledSocket(tag2, logger);
|
|
89341
89502
|
let uid;
|
|
89342
89503
|
try {
|
|
89343
89504
|
uid = await this.ensureUidForRecordings(channel, void 0);
|
|
@@ -89352,7 +89513,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89352
89513
|
});
|
|
89353
89514
|
const msgNum = 0;
|
|
89354
89515
|
dedicatedClient.subscribeVideoStream(5, msgNum);
|
|
89355
|
-
const stream$15 = new
|
|
89516
|
+
const stream$15 = new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
89356
89517
|
client: dedicatedClient,
|
|
89357
89518
|
channel,
|
|
89358
89519
|
profile: streamType === "subStream" ? "sub" : "main",
|
|
@@ -89372,7 +89533,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89372
89533
|
channelIdOverride,
|
|
89373
89534
|
payloadXml,
|
|
89374
89535
|
extensionXml: "",
|
|
89375
|
-
messageClass:
|
|
89536
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89376
89537
|
msgNumOverride: msgNum,
|
|
89377
89538
|
timeoutMs: params.timeoutMs,
|
|
89378
89539
|
internal: true
|
|
@@ -89404,7 +89565,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89404
89565
|
cmdId: 7,
|
|
89405
89566
|
channel,
|
|
89406
89567
|
payloadXml: stopXml,
|
|
89407
|
-
messageClass:
|
|
89568
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89408
89569
|
timeoutMs: 2e3,
|
|
89409
89570
|
internal: true
|
|
89410
89571
|
});
|
|
@@ -89491,30 +89652,30 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89491
89652
|
async ensureUidForRecordings(channel, explicitUid) {
|
|
89492
89653
|
const dbg = this.client.getDebugConfig?.();
|
|
89493
89654
|
const logger = this.logger;
|
|
89494
|
-
|
|
89655
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Checking UID: explicitUid=${explicitUid}, this.uid=${this.uid}`);
|
|
89495
89656
|
const trimmedExplicit = explicitUid?.trim();
|
|
89496
89657
|
if (trimmedExplicit) {
|
|
89497
|
-
|
|
89658
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using explicit UID: ${trimmedExplicit}`);
|
|
89498
89659
|
return trimmedExplicit;
|
|
89499
89660
|
}
|
|
89500
89661
|
const perChannel = await this.discoverUidForRecordingsForChannel(channel);
|
|
89501
89662
|
if (perChannel) {
|
|
89502
|
-
|
|
89663
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using per-channel UID: ${perChannel}`);
|
|
89503
89664
|
return perChannel;
|
|
89504
89665
|
}
|
|
89505
89666
|
const configured = this.uid?.trim();
|
|
89506
89667
|
if (configured) {
|
|
89507
|
-
|
|
89668
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using configured UID: ${configured}`);
|
|
89508
89669
|
return configured;
|
|
89509
89670
|
}
|
|
89510
89671
|
if (this.nativeOnly) {
|
|
89511
|
-
|
|
89672
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Native-only: no UID available (channel=${channel})`);
|
|
89512
89673
|
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.");
|
|
89513
89674
|
}
|
|
89514
|
-
|
|
89675
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `No UID available, attempting device auto-discovery (ch=${channel})`);
|
|
89515
89676
|
const discovered = await this.discoverDeviceUidForRecordings(channel);
|
|
89516
89677
|
if (discovered) return discovered;
|
|
89517
|
-
|
|
89678
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Auto-discovery failed - no UID found`);
|
|
89518
89679
|
throw new Error("UID is required to access recordings. Provide a UID explicitly or configure the client with a UID.");
|
|
89519
89680
|
}
|
|
89520
89681
|
cacheChannelUid(channel, uid) {
|
|
@@ -89537,35 +89698,35 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89537
89698
|
const logger = this.logger;
|
|
89538
89699
|
const fromPush = this.getUidFromPushCacheForChannel(channel);
|
|
89539
89700
|
if (fromPush) {
|
|
89540
|
-
|
|
89701
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using per-channel UID from push cache: ${fromPush}`);
|
|
89541
89702
|
return fromPush;
|
|
89542
89703
|
}
|
|
89543
89704
|
if (this.nativeOnly) {
|
|
89544
|
-
|
|
89705
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Native-only: skipping per-channel UID discovery via HTTP/CGI (channel=${channel})`);
|
|
89545
89706
|
return;
|
|
89546
89707
|
}
|
|
89547
89708
|
try {
|
|
89548
|
-
|
|
89709
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Attempting per-channel UID discovery via HTTP CGI GetChannelstatus (channel=${channel})`);
|
|
89549
89710
|
const uidCandidate = await discoverPerChannelUidViaCgiChannelstatus({
|
|
89550
89711
|
channel,
|
|
89551
89712
|
login: () => this.cgiApi.login(),
|
|
89552
89713
|
getChannelstatus: () => this.cgiApi.GetChannelstatus()
|
|
89553
89714
|
});
|
|
89554
|
-
|
|
89715
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `[HTTP CGI] GetChannelstatus channel=${channel} uid=${uidCandidate || "(missing)"}`);
|
|
89555
89716
|
if (uidCandidate) {
|
|
89556
89717
|
this.cacheChannelUid(channel, uidCandidate);
|
|
89557
|
-
|
|
89718
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `Using per-channel UID from GetChannelstatus: ${uidCandidate}`);
|
|
89558
89719
|
return uidCandidate;
|
|
89559
89720
|
}
|
|
89560
89721
|
} catch (e) {
|
|
89561
|
-
|
|
89722
|
+
require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", `[HTTP CGI] GetChannelstatus failed: ${formatErrorForLog(e)}`);
|
|
89562
89723
|
}
|
|
89563
89724
|
}
|
|
89564
89725
|
async discoverDeviceUidForRecordings(channel) {
|
|
89565
89726
|
if (this.nativeOnly) return void 0;
|
|
89566
89727
|
const dbg = this.client.getDebugConfig?.();
|
|
89567
89728
|
const logger = this.logger;
|
|
89568
|
-
const trace = (message) =>
|
|
89729
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "ensureUidForRecordings", message);
|
|
89569
89730
|
const discoveredUid = await discoverDeviceUidForRecordings({
|
|
89570
89731
|
channel,
|
|
89571
89732
|
getInfo: () => this.getInfo(),
|
|
@@ -89640,7 +89801,7 @@ var ReolinkBaichuanApi = class _ReolinkBaichuanApi {
|
|
|
89640
89801
|
await this.client.login();
|
|
89641
89802
|
const dbg = this.client.getDebugConfig?.();
|
|
89642
89803
|
const logger = this.logger;
|
|
89643
|
-
const trace = (message) =>
|
|
89804
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "getVideoclipThumbnail", message);
|
|
89644
89805
|
const channel = this.normalizeChannel(params.channel);
|
|
89645
89806
|
const snapStreamType = (params.snapType ?? "sub") === "main" ? "mainStream" : "subStream";
|
|
89646
89807
|
const timeoutMs = params.timeoutMs ?? 3e4;
|
|
@@ -89691,7 +89852,7 @@ ${xml}`);
|
|
|
89691
89852
|
cmdId: 298,
|
|
89692
89853
|
...isNvr && headerChannelIdOverride != null ? { channelIdOverride: headerChannelIdOverride } : {},
|
|
89693
89854
|
msgNumOverride: 0,
|
|
89694
|
-
messageClass:
|
|
89855
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
89695
89856
|
streamType: 0,
|
|
89696
89857
|
payloadXml: xml,
|
|
89697
89858
|
timeoutMs
|
|
@@ -90168,7 +90329,7 @@ ${stderr}`));
|
|
|
90168
90329
|
await this.client.login();
|
|
90169
90330
|
const dbg = this.client.getDebugConfig?.();
|
|
90170
90331
|
const logger = this.logger;
|
|
90171
|
-
const trace = (message) =>
|
|
90332
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "fileInfoListDownload", message);
|
|
90172
90333
|
const channel = this.normalizeChannel(params.channel);
|
|
90173
90334
|
const uid = await this.ensureUidForRecordings(channel, params.uid);
|
|
90174
90335
|
const headerChannelIdOverride = this.resolveHeaderChannelIdForLogicalChannel(channel);
|
|
@@ -90214,7 +90375,7 @@ ${stderr}`));
|
|
|
90214
90375
|
cmdId: 13,
|
|
90215
90376
|
channel,
|
|
90216
90377
|
...typeof chId === "number" ? { channelIdOverride: chId } : {},
|
|
90217
|
-
messageClass:
|
|
90378
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_FILE_DOWNLOAD,
|
|
90218
90379
|
extensionXml: buildBinaryExtensionXml(channel),
|
|
90219
90380
|
payloadXml,
|
|
90220
90381
|
streamType: st,
|
|
@@ -90243,7 +90404,7 @@ ${stderr}`));
|
|
|
90243
90404
|
await this.client.login();
|
|
90244
90405
|
const dbg = this.client.getDebugConfig?.();
|
|
90245
90406
|
const logger = this.logger;
|
|
90246
|
-
const trace = (message) =>
|
|
90407
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "fileInfoListPagedDownload", message);
|
|
90247
90408
|
const channel = this.normalizeChannel(params.channel);
|
|
90248
90409
|
const uid = await this.ensureUidForRecordings(channel, params.uid);
|
|
90249
90410
|
trace(`Starting paged download: channel=${channel}, uid=${uid}, fileName=${params.fileName}`);
|
|
@@ -90280,7 +90441,7 @@ ${stderr}`));
|
|
|
90280
90441
|
await this.client.login();
|
|
90281
90442
|
const dbg = this.client.getDebugConfig?.();
|
|
90282
90443
|
const logger = this.logger;
|
|
90283
|
-
const trace = (message) =>
|
|
90444
|
+
const trace = (message) => require_chunk_ZQFQRCLQ.recordingsTraceLog(dbg, logger, "fileInfoListReplayBinaryDownload", message);
|
|
90284
90445
|
const channel = this.normalizeChannel(params.channel);
|
|
90285
90446
|
const headerChannelIdOverride = this.resolveHeaderChannelIdForLogicalChannel(channel);
|
|
90286
90447
|
const ident = params.fileName;
|
|
@@ -90309,7 +90470,7 @@ ${stderr}`));
|
|
|
90309
90470
|
channel,
|
|
90310
90471
|
...isNvr ? { channelIdOverride: headerChannelIdOverride ?? 82 } : {},
|
|
90311
90472
|
msgNumOverride: 0,
|
|
90312
|
-
messageClass:
|
|
90473
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
90313
90474
|
payloadXml,
|
|
90314
90475
|
streamType: 0,
|
|
90315
90476
|
timeoutMs
|
|
@@ -90393,7 +90554,7 @@ ${stderr}`));
|
|
|
90393
90554
|
async downloadRecordingDemuxed(params) {
|
|
90394
90555
|
const raw = await this.downloadRecording(params);
|
|
90395
90556
|
const frames = [];
|
|
90396
|
-
const decoder = new
|
|
90557
|
+
const decoder = new require_chunk_ZQFQRCLQ.BcMediaAnnexBDecoder({
|
|
90397
90558
|
strict: false,
|
|
90398
90559
|
logger: this.logger,
|
|
90399
90560
|
onVideoAccessUnit: ({ annexB }) => {
|
|
@@ -90440,7 +90601,7 @@ ${stderr}`));
|
|
|
90440
90601
|
const videoFrames = [];
|
|
90441
90602
|
const audioFrames = [];
|
|
90442
90603
|
let audioCodec = null;
|
|
90443
|
-
const decoder = new
|
|
90604
|
+
const decoder = new require_chunk_ZQFQRCLQ.BcMediaAnnexBDecoder({
|
|
90444
90605
|
strict: false,
|
|
90445
90606
|
logger: this.logger,
|
|
90446
90607
|
onVideoAccessUnit: ({ annexB, microseconds }) => {
|
|
@@ -90854,7 +91015,7 @@ ${stderr}`));
|
|
|
90854
91015
|
params: {
|
|
90855
91016
|
cmdId: 31,
|
|
90856
91017
|
channelIdOverride: channel,
|
|
90857
|
-
messageClass:
|
|
91018
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
90858
91019
|
}
|
|
90859
91020
|
},
|
|
90860
91021
|
{
|
|
@@ -90862,7 +91023,7 @@ ${stderr}`));
|
|
|
90862
91023
|
params: {
|
|
90863
91024
|
cmdId: 31,
|
|
90864
91025
|
channelIdOverride: 251,
|
|
90865
|
-
messageClass:
|
|
91026
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
90866
91027
|
}
|
|
90867
91028
|
},
|
|
90868
91029
|
{
|
|
@@ -90870,7 +91031,7 @@ ${stderr}`));
|
|
|
90870
91031
|
params: {
|
|
90871
91032
|
cmdId: 31,
|
|
90872
91033
|
channelIdOverride: 250,
|
|
90873
|
-
messageClass:
|
|
91034
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
90874
91035
|
}
|
|
90875
91036
|
},
|
|
90876
91037
|
{
|
|
@@ -90878,7 +91039,7 @@ ${stderr}`));
|
|
|
90878
91039
|
params: {
|
|
90879
91040
|
cmdId: 31,
|
|
90880
91041
|
channelIdOverride: 250,
|
|
90881
|
-
messageClass:
|
|
91042
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
90882
91043
|
extensionXml: `<?xml version="1.0" encoding="UTF-8" ?><Extension version="1.1"><channelId>251</channelId></Extension>`
|
|
90883
91044
|
}
|
|
90884
91045
|
}
|
|
@@ -90921,7 +91082,7 @@ ${stderr}`));
|
|
|
90921
91082
|
const frame = await this.client.sendFrame({
|
|
90922
91083
|
cmdId: 31,
|
|
90923
91084
|
channelIdOverride: Number(channel),
|
|
90924
|
-
messageClass:
|
|
91085
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
90925
91086
|
timeoutMs
|
|
90926
91087
|
});
|
|
90927
91088
|
lastCode = frame.header.responseCode;
|
|
@@ -91202,7 +91363,7 @@ ${stderr}`));
|
|
|
91202
91363
|
msgNumOverride: msgNum,
|
|
91203
91364
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91204
91365
|
payloadXml,
|
|
91205
|
-
messageClass:
|
|
91366
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91206
91367
|
streamType: config.streamType,
|
|
91207
91368
|
timeoutMs: 2e4
|
|
91208
91369
|
};
|
|
@@ -91334,7 +91495,7 @@ ${stderr}`));
|
|
|
91334
91495
|
channelIdOverride: channelId,
|
|
91335
91496
|
extensionXml: a.extensionXml,
|
|
91336
91497
|
payloadXml: a.payloadXml,
|
|
91337
|
-
messageClass:
|
|
91498
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91338
91499
|
streamType: a.streamType,
|
|
91339
91500
|
...msgNum !== void 0 ? { msgNumOverride: msgNum } : {},
|
|
91340
91501
|
timeoutMs: 2e3
|
|
@@ -91364,7 +91525,7 @@ ${stderr}`));
|
|
|
91364
91525
|
channel: ch,
|
|
91365
91526
|
channelIdOverride: channelId,
|
|
91366
91527
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91367
|
-
messageClass:
|
|
91528
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91368
91529
|
streamType: 0
|
|
91369
91530
|
});
|
|
91370
91531
|
} catch (e) {
|
|
@@ -91406,7 +91567,7 @@ ${stderr}`));
|
|
|
91406
91567
|
channel: ch,
|
|
91407
91568
|
channelIdOverride: channelId,
|
|
91408
91569
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91409
|
-
messageClass:
|
|
91570
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91410
91571
|
streamType: 0
|
|
91411
91572
|
});
|
|
91412
91573
|
} catch (e) {
|
|
@@ -91428,7 +91589,7 @@ ${stderr}`));
|
|
|
91428
91589
|
channelIdOverride: channelId,
|
|
91429
91590
|
extensionXml,
|
|
91430
91591
|
payloadXml,
|
|
91431
|
-
messageClass:
|
|
91592
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91432
91593
|
streamType: 0
|
|
91433
91594
|
});
|
|
91434
91595
|
if (frame.header.responseCode !== 200) {
|
|
@@ -91460,7 +91621,7 @@ ${stderr}`));
|
|
|
91460
91621
|
channelIdOverride: channelId,
|
|
91461
91622
|
extensionXml,
|
|
91462
91623
|
payloadXml,
|
|
91463
|
-
messageClass:
|
|
91624
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91464
91625
|
streamType: 0
|
|
91465
91626
|
});
|
|
91466
91627
|
if (frame.header.responseCode !== 200) throw new Error(`PTZ preset move rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91481,7 +91642,7 @@ ${stderr}`));
|
|
|
91481
91642
|
channelIdOverride: channelId,
|
|
91482
91643
|
extensionXml,
|
|
91483
91644
|
payloadXml,
|
|
91484
|
-
messageClass:
|
|
91645
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91485
91646
|
streamType: 0
|
|
91486
91647
|
});
|
|
91487
91648
|
if (frame.header.responseCode !== 200) throw new Error(`PTZ preset save rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91498,7 +91659,7 @@ ${stderr}`));
|
|
|
91498
91659
|
channelIdOverride: channelId,
|
|
91499
91660
|
extensionXml,
|
|
91500
91661
|
payloadXml,
|
|
91501
|
-
messageClass:
|
|
91662
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91502
91663
|
streamType: 0
|
|
91503
91664
|
});
|
|
91504
91665
|
if (frame.header.responseCode !== 200) throw new Error(`PTZ goto preset rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91525,7 +91686,7 @@ ${stderr}`));
|
|
|
91525
91686
|
channelIdOverride: channelId,
|
|
91526
91687
|
extensionXml,
|
|
91527
91688
|
payloadXml,
|
|
91528
|
-
messageClass:
|
|
91689
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91529
91690
|
streamType: 0
|
|
91530
91691
|
})).header.responseCode };
|
|
91531
91692
|
},
|
|
@@ -91564,6 +91725,73 @@ ${stderr}`));
|
|
|
91564
91725
|
return result;
|
|
91565
91726
|
}
|
|
91566
91727
|
/**
|
|
91728
|
+
* Read the PTZ guard point ("monitoring point" in the app).
|
|
91729
|
+
*
|
|
91730
|
+
* cmd_id: 332
|
|
91731
|
+
*
|
|
91732
|
+
* Returns `null` when the camera has no readable guard configuration — never
|
|
91733
|
+
* a fabricated "none", because that answer is what a consumer uses to decide
|
|
91734
|
+
* whether to move the head.
|
|
91735
|
+
*/
|
|
91736
|
+
async getPtzGuard(channel) {
|
|
91737
|
+
const ch = this.normalizeChannel(channel);
|
|
91738
|
+
return parsePtzGuardXml(await this.sendXml({
|
|
91739
|
+
cmdId: 332,
|
|
91740
|
+
channel: ch,
|
|
91741
|
+
channelIdOverride: ch,
|
|
91742
|
+
extensionXml: buildPtzGuardExtensionXml(ch, "read"),
|
|
91743
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91744
|
+
streamType: 0
|
|
91745
|
+
}));
|
|
91746
|
+
}
|
|
91747
|
+
/**
|
|
91748
|
+
* Configure the PTZ guard point.
|
|
91749
|
+
*
|
|
91750
|
+
* cmd_id: 331 with `<command>setGrd</command>`
|
|
91751
|
+
*
|
|
91752
|
+
* `setPosition` pins the guard point to the head's CURRENT position. Leave it
|
|
91753
|
+
* false when only changing the timeout or the enable flag: re-sending it
|
|
91754
|
+
* would silently move a point the operator had already placed.
|
|
91755
|
+
*/
|
|
91756
|
+
async setPtzGuard(options, channel) {
|
|
91757
|
+
const ch = this.normalizeChannel(channel);
|
|
91758
|
+
await this.sendXml({
|
|
91759
|
+
cmdId: 331,
|
|
91760
|
+
channel: ch,
|
|
91761
|
+
channelIdOverride: ch,
|
|
91762
|
+
extensionXml: buildPtzGuardExtensionXml(ch, "write"),
|
|
91763
|
+
payloadXml: buildPtzGuardSetXml({
|
|
91764
|
+
channelId: ch,
|
|
91765
|
+
enabled: options.enabled,
|
|
91766
|
+
timeoutSeconds: options.timeoutSeconds,
|
|
91767
|
+
setPosition: options.setPosition === true
|
|
91768
|
+
}),
|
|
91769
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91770
|
+
streamType: 0
|
|
91771
|
+
});
|
|
91772
|
+
}
|
|
91773
|
+
/**
|
|
91774
|
+
* Send the head to the guard point NOW.
|
|
91775
|
+
*
|
|
91776
|
+
* cmd_id: 331 with `<command>toGrd</command>`
|
|
91777
|
+
*
|
|
91778
|
+
* This is the closest thing Baichuan has to a "go home": the guard point is
|
|
91779
|
+
* an operator-placed position, unlike preset slot 0 which merely happens to
|
|
91780
|
+
* be first.
|
|
91781
|
+
*/
|
|
91782
|
+
async goToPtzGuard(channel) {
|
|
91783
|
+
const ch = this.normalizeChannel(channel);
|
|
91784
|
+
await this.sendXml({
|
|
91785
|
+
cmdId: 331,
|
|
91786
|
+
channel: ch,
|
|
91787
|
+
channelIdOverride: ch,
|
|
91788
|
+
extensionXml: buildPtzGuardExtensionXml(ch, "write"),
|
|
91789
|
+
payloadXml: buildPtzGuardGoXml(ch),
|
|
91790
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91791
|
+
streamType: 0
|
|
91792
|
+
});
|
|
91793
|
+
}
|
|
91794
|
+
/**
|
|
91567
91795
|
* Read zoom/focus min/max/current positions.
|
|
91568
91796
|
* cmd_id: 294 (MSG_ID_GET_ZOOM_FOCUS)
|
|
91569
91797
|
*/
|
|
@@ -91575,7 +91803,7 @@ ${stderr}`));
|
|
|
91575
91803
|
channel: ch,
|
|
91576
91804
|
channelIdOverride: channelId,
|
|
91577
91805
|
extensionXml: buildChannelExtensionXml(channelId),
|
|
91578
|
-
messageClass:
|
|
91806
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91579
91807
|
streamType: 0
|
|
91580
91808
|
});
|
|
91581
91809
|
const parseTriplet = (sectionTag) => {
|
|
@@ -91613,7 +91841,7 @@ ${stderr}`));
|
|
|
91613
91841
|
channelIdOverride: channelId,
|
|
91614
91842
|
extensionXml,
|
|
91615
91843
|
payloadXml,
|
|
91616
|
-
messageClass:
|
|
91844
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24,
|
|
91617
91845
|
streamType: 0
|
|
91618
91846
|
});
|
|
91619
91847
|
if (frame.header.responseCode !== 200) throw new Error(`Zoom rejected (response_code ${frame.header.responseCode})`);
|
|
@@ -91656,10 +91884,10 @@ ${stderr}`));
|
|
|
91656
91884
|
notifyD2cDisc() {
|
|
91657
91885
|
const now = Date.now();
|
|
91658
91886
|
this.lastD2cDiscAtMs = now;
|
|
91659
|
-
const streamingTags = Array.from(this.socketPool.keys()).filter((
|
|
91887
|
+
const streamingTags = Array.from(this.socketPool.keys()).filter((tag2) => tag2.startsWith("streaming:"));
|
|
91660
91888
|
if (streamingTags.length > 0) {
|
|
91661
91889
|
this.logger?.log?.(`[D2C_DISC] Force-closing ${streamingTags.length} streaming socket(s): ${streamingTags.join(", ")}`);
|
|
91662
|
-
for (const
|
|
91890
|
+
for (const tag2 of streamingTags) this.forceClosePooledSocket(tag2, this.logger).catch(() => {});
|
|
91663
91891
|
}
|
|
91664
91892
|
const immediateCooldownUntil = now + _ReolinkBaichuanApi.D2C_DISC_IMMEDIATE_COOLDOWN_MS;
|
|
91665
91893
|
const existing = this.socketPoolCooldowns.get(this.host);
|
|
@@ -91692,15 +91920,15 @@ ${stderr}`));
|
|
|
91692
91920
|
* Returns undefined if the client is not in the pool (e.g. it's the general socket used directly).
|
|
91693
91921
|
*/
|
|
91694
91922
|
findSocketTagForClient(client) {
|
|
91695
|
-
for (const [
|
|
91923
|
+
for (const [tag2, entry] of this.socketPool) if (entry.client === client) return tag2;
|
|
91696
91924
|
}
|
|
91697
91925
|
/**
|
|
91698
91926
|
* Reset the consecutive stream-start timeout counter for a streaming socket.
|
|
91699
91927
|
* Called on successful stream start.
|
|
91700
91928
|
*/
|
|
91701
91929
|
resetStreamTimeoutCounter(client) {
|
|
91702
|
-
const
|
|
91703
|
-
if (
|
|
91930
|
+
const tag2 = this.findSocketTagForClient(client);
|
|
91931
|
+
if (tag2) this.consecutiveStreamTimeouts.delete(tag2);
|
|
91704
91932
|
}
|
|
91705
91933
|
/**
|
|
91706
91934
|
* Track a stream-start timeout on a streaming socket.
|
|
@@ -91708,14 +91936,14 @@ ${stderr}`));
|
|
|
91708
91936
|
* socket so the next attempt creates a fresh connection.
|
|
91709
91937
|
*/
|
|
91710
91938
|
trackStreamTimeout(client) {
|
|
91711
|
-
const
|
|
91712
|
-
if (!
|
|
91713
|
-
const count = (this.consecutiveStreamTimeouts.get(
|
|
91714
|
-
this.consecutiveStreamTimeouts.set(
|
|
91939
|
+
const tag2 = this.findSocketTagForClient(client);
|
|
91940
|
+
if (!tag2 || !tag2.startsWith("streaming:")) return;
|
|
91941
|
+
const count = (this.consecutiveStreamTimeouts.get(tag2) ?? 0) + 1;
|
|
91942
|
+
this.consecutiveStreamTimeouts.set(tag2, count);
|
|
91715
91943
|
if (count >= _ReolinkBaichuanApi.MAX_CONSECUTIVE_STREAM_TIMEOUTS) {
|
|
91716
|
-
this.logger?.warn?.(`[SocketPool] ${count} consecutive stream timeouts on tag=${
|
|
91717
|
-
this.consecutiveStreamTimeouts.delete(
|
|
91718
|
-
this.forceClosePooledSocket(
|
|
91944
|
+
this.logger?.warn?.(`[SocketPool] ${count} consecutive stream timeouts on tag=${tag2}, force-closing socket`);
|
|
91945
|
+
this.consecutiveStreamTimeouts.delete(tag2);
|
|
91946
|
+
this.forceClosePooledSocket(tag2, this.logger).catch(() => {});
|
|
91719
91947
|
}
|
|
91720
91948
|
}
|
|
91721
91949
|
/**
|
|
@@ -92582,8 +92810,20 @@ ${xml}`);
|
|
|
92582
92810
|
const support = supportResult.status === "fulfilled" ? supportResult.value : void 0;
|
|
92583
92811
|
const abilities = abilitiesResult.status === "fulfilled" ? abilitiesResult.value : void 0;
|
|
92584
92812
|
const supportItem = getSupportItemForChannel(support, ch);
|
|
92813
|
+
let model;
|
|
92814
|
+
try {
|
|
92815
|
+
const info = await this.getInfo(void 0, { timeoutMs: 5e3 });
|
|
92816
|
+
model = typeof info?.type === "string" ? info.type : void 0;
|
|
92817
|
+
} catch (e) {
|
|
92818
|
+
this.logger.debug("[ReolinkBaichuanApi] getDeviceCapabilities: getInfo(type) failed", {
|
|
92819
|
+
host: this.host,
|
|
92820
|
+
channel: ch,
|
|
92821
|
+
err: e instanceof Error ? e.message : String(e)
|
|
92822
|
+
});
|
|
92823
|
+
}
|
|
92585
92824
|
const capabilities = computeDeviceCapabilities({
|
|
92586
92825
|
channel: ch,
|
|
92826
|
+
...model != null && { model },
|
|
92587
92827
|
...support != null && { support },
|
|
92588
92828
|
...abilities != null && { abilities }
|
|
92589
92829
|
});
|
|
@@ -93352,7 +93592,7 @@ ${xml}`);
|
|
|
93352
93592
|
* @returns Test results for all stream types and profiles
|
|
93353
93593
|
*/
|
|
93354
93594
|
async testChannelStreams(channel, logger) {
|
|
93355
|
-
const { testChannelStreams } = await Promise.resolve().then(() => require("./DiagnosticsTools-
|
|
93595
|
+
const { testChannelStreams } = await Promise.resolve().then(() => require("./DiagnosticsTools-GOFDNGAY-CD4rRF8a.js"));
|
|
93356
93596
|
return await testChannelStreams({
|
|
93357
93597
|
api: this,
|
|
93358
93598
|
channel: this.normalizeChannel(channel),
|
|
@@ -93368,7 +93608,7 @@ ${xml}`);
|
|
|
93368
93608
|
* @returns Complete diagnostics for all channels and streams
|
|
93369
93609
|
*/
|
|
93370
93610
|
async collectMultifocalDiagnostics(logger) {
|
|
93371
|
-
const { collectMultifocalDiagnostics } = await Promise.resolve().then(() => require("./DiagnosticsTools-
|
|
93611
|
+
const { collectMultifocalDiagnostics } = await Promise.resolve().then(() => require("./DiagnosticsTools-GOFDNGAY-CD4rRF8a.js"));
|
|
93372
93612
|
return await collectMultifocalDiagnostics({
|
|
93373
93613
|
api: this,
|
|
93374
93614
|
logger
|
|
@@ -95402,7 +95642,7 @@ ${scheduleItems}
|
|
|
95402
95642
|
if (raw.length === 0) throw new Error("Downloaded recording is empty");
|
|
95403
95643
|
const videoFrames = [];
|
|
95404
95644
|
let videoType = null;
|
|
95405
|
-
const decoder = new
|
|
95645
|
+
const decoder = new require_chunk_ZQFQRCLQ.BcMediaAnnexBDecoder({
|
|
95406
95646
|
strict: false,
|
|
95407
95647
|
logger: this.logger,
|
|
95408
95648
|
onVideoAccessUnit: ({ annexB: annexB2, microseconds }) => {
|
|
@@ -95750,7 +95990,7 @@ ${scheduleItems}
|
|
|
95750
95990
|
return {
|
|
95751
95991
|
getPlaylist: () => {
|
|
95752
95992
|
try {
|
|
95753
|
-
const { readFileSync } =
|
|
95993
|
+
const { readFileSync } = require_chunk_ZQFQRCLQ.__require("fs");
|
|
95754
95994
|
return readFileSync(playlistPath, "utf8");
|
|
95755
95995
|
} catch {
|
|
95756
95996
|
return "#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:4\n";
|
|
@@ -95759,7 +95999,7 @@ ${scheduleItems}
|
|
|
95759
95999
|
getSegment: (name) => {
|
|
95760
96000
|
if (segments.has(name)) return segments.get(name);
|
|
95761
96001
|
try {
|
|
95762
|
-
const { readFileSync } =
|
|
96002
|
+
const { readFileSync } = require_chunk_ZQFQRCLQ.__require("fs");
|
|
95763
96003
|
const data = readFileSync(path$3.join(tempDir, name));
|
|
95764
96004
|
segments.set(name, data);
|
|
95765
96005
|
return data;
|
|
@@ -95769,7 +96009,7 @@ ${scheduleItems}
|
|
|
95769
96009
|
},
|
|
95770
96010
|
listSegments: () => {
|
|
95771
96011
|
try {
|
|
95772
|
-
const { readdirSync } =
|
|
96012
|
+
const { readdirSync } = require_chunk_ZQFQRCLQ.__require("fs");
|
|
95773
96013
|
return readdirSync(tempDir).filter((f) => f.endsWith(".ts"));
|
|
95774
96014
|
} catch {
|
|
95775
96015
|
return [];
|
|
@@ -97354,41 +97594,41 @@ async function autoDetectDeviceType(inputs) {
|
|
|
97354
97594
|
variant: "cmd80 class=0x6414",
|
|
97355
97595
|
op: () => api.getInfo(void 0, {
|
|
97356
97596
|
timeoutMs: 2500,
|
|
97357
|
-
messageClass:
|
|
97597
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
97358
97598
|
})
|
|
97359
97599
|
},
|
|
97360
97600
|
{
|
|
97361
97601
|
variant: "cmd80 class=0x6614",
|
|
97362
97602
|
op: () => api.getInfo(void 0, {
|
|
97363
97603
|
timeoutMs: 3e3,
|
|
97364
|
-
messageClass:
|
|
97604
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_20
|
|
97365
97605
|
})
|
|
97366
97606
|
},
|
|
97367
97607
|
{
|
|
97368
97608
|
variant: "cmd318(ch0) class=0x6414",
|
|
97369
97609
|
op: () => api.getInfo(0, {
|
|
97370
97610
|
timeoutMs: 3e3,
|
|
97371
|
-
messageClass:
|
|
97611
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
97372
97612
|
})
|
|
97373
97613
|
},
|
|
97374
97614
|
{
|
|
97375
97615
|
variant: "cmd318(ch0) class=0x6614",
|
|
97376
97616
|
op: () => api.getInfo(0, {
|
|
97377
97617
|
timeoutMs: 3500,
|
|
97378
|
-
messageClass:
|
|
97618
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_20
|
|
97379
97619
|
})
|
|
97380
97620
|
}
|
|
97381
97621
|
]), runProbeVariants("getSupportInfo", [{
|
|
97382
97622
|
variant: "cmd199 class=0x6414",
|
|
97383
97623
|
op: () => api.getSupportInfo({
|
|
97384
97624
|
timeoutMs: 2500,
|
|
97385
|
-
messageClass:
|
|
97625
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_24
|
|
97386
97626
|
})
|
|
97387
97627
|
}, {
|
|
97388
97628
|
variant: "cmd199 class=0x6614",
|
|
97389
97629
|
op: () => api.getSupportInfo({
|
|
97390
97630
|
timeoutMs: 3500,
|
|
97391
|
-
messageClass:
|
|
97631
|
+
messageClass: require_chunk_ZQFQRCLQ.BC_CLASS_MODERN_20
|
|
97392
97632
|
})
|
|
97393
97633
|
}])]);
|
|
97394
97634
|
const deviceInfo = infoProbe?.value;
|
|
@@ -143917,7 +144157,7 @@ async function createRfc4571TcpServerInternal(options) {
|
|
|
143917
144157
|
streamClient = dedicatedSession.client;
|
|
143918
144158
|
logSessionsSummary(`dedicated session created: ${sessionKey}`);
|
|
143919
144159
|
} else streamClient = baseApi.client;
|
|
143920
|
-
const createLiveStream = async () => new
|
|
144160
|
+
const createLiveStream = async () => new require_chunk_ZQFQRCLQ.BaichuanVideoStream({
|
|
143921
144161
|
client: streamClient,
|
|
143922
144162
|
api: baseApi,
|
|
143923
144163
|
channel: ch,
|
|
@@ -150160,15 +150400,39 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
150160
150400
|
*/
|
|
150161
150401
|
async resolveHomePreset() {
|
|
150162
150402
|
const chosen = this.config.get("homePresetId") ?? "";
|
|
150163
|
-
if (chosen
|
|
150403
|
+
if (chosen !== "") return {
|
|
150404
|
+
presetId: chosen,
|
|
150405
|
+
source: "operator"
|
|
150406
|
+
};
|
|
150407
|
+
if ((await this.readGuardStatus())?.valid === true) return {
|
|
150164
150408
|
presetId: null,
|
|
150165
|
-
source: "
|
|
150409
|
+
source: "native"
|
|
150166
150410
|
};
|
|
150167
150411
|
return {
|
|
150168
|
-
presetId:
|
|
150169
|
-
source: "
|
|
150412
|
+
presetId: null,
|
|
150413
|
+
source: "none"
|
|
150170
150414
|
};
|
|
150171
150415
|
}
|
|
150416
|
+
/**
|
|
150417
|
+
* The camera's guard-point configuration, or `null` when it cannot be read.
|
|
150418
|
+
*
|
|
150419
|
+
* Never a fabricated "no guard configured": that answer decides whether
|
|
150420
|
+
* `goHome` moves the head, and an unreadable camera is not evidence that no
|
|
150421
|
+
* guard point exists (D393).
|
|
150422
|
+
*/
|
|
150423
|
+
async readGuardStatus() {
|
|
150424
|
+
try {
|
|
150425
|
+
const api = await this.ensureApi();
|
|
150426
|
+
const channel = this.getChannel();
|
|
150427
|
+
return await api.getPtzGuard(channel);
|
|
150428
|
+
} catch (err) {
|
|
150429
|
+
this.ctx.logger.warn("reolink guard point unreadable — goHome will fall back", {
|
|
150430
|
+
tags: { deviceId: this.id },
|
|
150431
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
150432
|
+
});
|
|
150433
|
+
return null;
|
|
150434
|
+
}
|
|
150435
|
+
}
|
|
150172
150436
|
getChannel() {
|
|
150173
150437
|
const ch = this.config.get("channel");
|
|
150174
150438
|
if (typeof ch === "number" && ch >= 0) return ch;
|
|
@@ -153621,7 +153885,11 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
153621
153885
|
goHome: async ({ deviceId }) => {
|
|
153622
153886
|
if (deviceId !== this.id) return;
|
|
153623
153887
|
const home = await this.resolveHomePreset();
|
|
153624
|
-
if (home.source === "
|
|
153888
|
+
if (home.source === "native") {
|
|
153889
|
+
await (await this.ensureApi()).goToPtzGuard(this.getChannel());
|
|
153890
|
+
return;
|
|
153891
|
+
}
|
|
153892
|
+
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");
|
|
153625
153893
|
const id = Number(home.presetId);
|
|
153626
153894
|
if (!Number.isFinite(id)) throw new Error(`Configured home preset is not a Baichuan id: ${home.presetId}`);
|
|
153627
153895
|
const api = await this.ensureApi();
|
|
@@ -153635,6 +153903,41 @@ var ReolinkCamera = class ReolinkCamera extends BaseDevice {
|
|
|
153635
153903
|
};
|
|
153636
153904
|
return this.resolveHomePreset();
|
|
153637
153905
|
},
|
|
153906
|
+
captureHomeHere: async ({ deviceId }) => {
|
|
153907
|
+
if (deviceId !== this.id) return;
|
|
153908
|
+
const current = await this.readGuardStatus();
|
|
153909
|
+
const api = await this.ensureApi();
|
|
153910
|
+
const channel = this.getChannel();
|
|
153911
|
+
await api.setPtzGuard({
|
|
153912
|
+
enabled: current?.enabled ?? false,
|
|
153913
|
+
timeoutSeconds: current?.timeoutSeconds ?? 60,
|
|
153914
|
+
setPosition: true
|
|
153915
|
+
}, channel);
|
|
153916
|
+
this.ctx.logger.info("reolink: guard point pinned to the current position", { tags: { deviceId: this.id } });
|
|
153917
|
+
},
|
|
153918
|
+
getHomeReturn: async ({ deviceId }) => {
|
|
153919
|
+
if (deviceId !== this.id) return null;
|
|
153920
|
+
const guard = await this.readGuardStatus();
|
|
153921
|
+
return guard === null ? null : {
|
|
153922
|
+
enabled: guard.enabled,
|
|
153923
|
+
seconds: guard.timeoutSeconds
|
|
153924
|
+
};
|
|
153925
|
+
},
|
|
153926
|
+
setHomeReturn: async ({ deviceId, enabled, seconds }) => {
|
|
153927
|
+
if (deviceId !== this.id) return;
|
|
153928
|
+
await (await this.ensureApi()).setPtzGuard({
|
|
153929
|
+
enabled,
|
|
153930
|
+
timeoutSeconds: seconds,
|
|
153931
|
+
setPosition: false
|
|
153932
|
+
}, this.getChannel());
|
|
153933
|
+
this.ctx.logger.info("reolink: guard point idle-return updated", {
|
|
153934
|
+
tags: { deviceId: this.id },
|
|
153935
|
+
meta: {
|
|
153936
|
+
enabled,
|
|
153937
|
+
seconds
|
|
153938
|
+
}
|
|
153939
|
+
});
|
|
153940
|
+
},
|
|
153638
153941
|
setHomePreset: async ({ deviceId, presetId }) => {
|
|
153639
153942
|
if (deviceId !== this.id) return;
|
|
153640
153943
|
await this.config.setAll({ homePresetId: presetId ?? "" });
|