@apocaliss92/nodelink-js 0.6.1 → 0.6.2
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/{DiagnosticsTools-K4MF2VXZ.js → DiagnosticsTools-QJ3CRYGA.js} +2 -2
- package/dist/{chunk-EAHRVNEX.js → chunk-D4TKRGUP.js} +64 -10
- package/dist/chunk-D4TKRGUP.js.map +1 -0
- package/dist/{chunk-XDVBNZGR.js → chunk-IQVVVSXO.js} +48 -16
- package/dist/{chunk-XDVBNZGR.js.map → chunk-IQVVVSXO.js.map} +1 -1
- package/dist/cli/rtsp-server.cjs +108 -22
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +2 -2
- package/dist/index.cjs +108 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-EAHRVNEX.js.map +0 -1
- /package/dist/{DiagnosticsTools-K4MF2VXZ.js.map → DiagnosticsTools-QJ3CRYGA.js.map} +0 -0
package/dist/cli/rtsp-server.js
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
BaichuanRtspServer,
|
|
4
4
|
ReolinkBaichuanApi,
|
|
5
5
|
autoDetectDeviceType
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import "../chunk-
|
|
6
|
+
} from "../chunk-D4TKRGUP.js";
|
|
7
|
+
import "../chunk-IQVVVSXO.js";
|
|
8
8
|
import {
|
|
9
9
|
__require
|
|
10
10
|
} from "../chunk-MZUSWKF3.js";
|
package/dist/index.cjs
CHANGED
|
@@ -268,6 +268,41 @@ var init_crypto = __esm({
|
|
|
268
268
|
});
|
|
269
269
|
|
|
270
270
|
// src/protocol/xml.ts
|
|
271
|
+
function xmlTextRe(tag) {
|
|
272
|
+
let re = xmlTextReCache.get(tag);
|
|
273
|
+
if (re === void 0) {
|
|
274
|
+
re = new RegExp(`<${tag}>([^<]*)</${tag}>`);
|
|
275
|
+
xmlTextReCache.set(tag, re);
|
|
276
|
+
}
|
|
277
|
+
return re;
|
|
278
|
+
}
|
|
279
|
+
function xmlTagRe(tag) {
|
|
280
|
+
let re = xmlTagReCache.get(tag);
|
|
281
|
+
if (re === void 0) {
|
|
282
|
+
re = new RegExp(`<${tag}>[^<]*</${tag}>`);
|
|
283
|
+
xmlTagReCache.set(tag, re);
|
|
284
|
+
}
|
|
285
|
+
return re;
|
|
286
|
+
}
|
|
287
|
+
function xmlNestedRe(parent, child) {
|
|
288
|
+
const key = `${parent}\0${child}`;
|
|
289
|
+
let re = xmlNestedReCache.get(key);
|
|
290
|
+
if (re === void 0) {
|
|
291
|
+
re = new RegExp(
|
|
292
|
+
`(<${parent}[^>]*>[\\s\\S]*?<${child}>)[^<]*(</${child}>[\\s\\S]*?</${parent}>)`
|
|
293
|
+
);
|
|
294
|
+
xmlNestedReCache.set(key, re);
|
|
295
|
+
}
|
|
296
|
+
return re;
|
|
297
|
+
}
|
|
298
|
+
function xmlStreamBlockRe(streamTag) {
|
|
299
|
+
let re = xmlStreamBlockReCache.get(streamTag);
|
|
300
|
+
if (re === void 0) {
|
|
301
|
+
re = new RegExp(`(<${streamTag}[^>]*>)([\\s\\S]*?)(</${streamTag}>)`);
|
|
302
|
+
xmlStreamBlockReCache.set(streamTag, re);
|
|
303
|
+
}
|
|
304
|
+
return re;
|
|
305
|
+
}
|
|
271
306
|
function xmlEscape(text) {
|
|
272
307
|
if (text === void 0 || text === null || typeof text !== "string") {
|
|
273
308
|
const error = new Error(
|
|
@@ -388,8 +423,7 @@ function buildPreviewStopXmlV11(params) {
|
|
|
388
423
|
</body>`;
|
|
389
424
|
}
|
|
390
425
|
function getXmlText(xml, tagName) {
|
|
391
|
-
const
|
|
392
|
-
const m = re.exec(xml);
|
|
426
|
+
const m = xmlTextRe(tagName).exec(xml);
|
|
393
427
|
return m?.[1];
|
|
394
428
|
}
|
|
395
429
|
function buildPtzControlXml(channelId, command, speed) {
|
|
@@ -493,13 +527,12 @@ ${xml}`;
|
|
|
493
527
|
function applyXmlTagPatch(xml, tag, value) {
|
|
494
528
|
if (value === void 0) return xml;
|
|
495
529
|
const v = typeof value === "boolean" ? value ? 1 : 0 : value;
|
|
496
|
-
|
|
497
|
-
return xml.replace(re, `<${tag}>${v}</${tag}>`);
|
|
530
|
+
return xml.replace(xmlTagRe(tag), `<${tag}>${v}</${tag}>`);
|
|
498
531
|
}
|
|
499
532
|
function upsertXmlTag(xml, tag, value) {
|
|
500
533
|
if (value === void 0) return xml;
|
|
501
534
|
const v = typeof value === "boolean" ? value ? 1 : 0 : value;
|
|
502
|
-
const re =
|
|
535
|
+
const re = xmlTagRe(tag);
|
|
503
536
|
if (re.test(xml)) {
|
|
504
537
|
return xml.replace(re, `<${tag}>${v}</${tag}>`);
|
|
505
538
|
}
|
|
@@ -508,16 +541,11 @@ function upsertXmlTag(xml, tag, value) {
|
|
|
508
541
|
function patchNestedTag(xml, parent, child, value) {
|
|
509
542
|
if (value === void 0) return xml;
|
|
510
543
|
const v = typeof value === "boolean" ? value ? 1 : 0 : value;
|
|
511
|
-
|
|
512
|
-
`(<${parent}[^>]*>[\\s\\S]*?<${child}>)[^<]*(</${child}>[\\s\\S]*?</${parent}>)`
|
|
513
|
-
);
|
|
514
|
-
return xml.replace(re, `$1${v}$2`);
|
|
544
|
+
return xml.replace(xmlNestedRe(parent, child), `$1${v}$2`);
|
|
515
545
|
}
|
|
516
546
|
function applyStreamPatch(xml, streamTag, patch) {
|
|
517
547
|
if (!patch) return xml;
|
|
518
|
-
const re =
|
|
519
|
-
`(<${streamTag}[^>]*>)([\\s\\S]*?)(</${streamTag}>)`
|
|
520
|
-
);
|
|
548
|
+
const re = xmlStreamBlockRe(streamTag);
|
|
521
549
|
return xml.replace(re, (_match, open, body, close) => {
|
|
522
550
|
let next = body;
|
|
523
551
|
if (patch.audio !== void 0) {
|
|
@@ -547,10 +575,9 @@ function applyStreamPatch(xml, streamTag, patch) {
|
|
|
547
575
|
next = upsertXmlTag(next, "encoderProfile", patch.encoderProfile);
|
|
548
576
|
}
|
|
549
577
|
if (patch.gop !== void 0) {
|
|
550
|
-
|
|
551
|
-
if (gopBlockRe.test(next)) {
|
|
578
|
+
if (GOP_BLOCK_RE.test(next)) {
|
|
552
579
|
next = next.replace(
|
|
553
|
-
|
|
580
|
+
GOP_BLOCK_RE,
|
|
554
581
|
(_m, gOpen, gBody, gClose) => `${gOpen}${applyXmlTagPatch(gBody, "cur", patch.gop)}${gClose}`
|
|
555
582
|
);
|
|
556
583
|
} else {
|
|
@@ -579,10 +606,15 @@ function buildAbilityInfoExtensionXml(username) {
|
|
|
579
606
|
<token>system, streaming, PTZ, IO, security, replay, disk, network, alarm, record, video, image</token>
|
|
580
607
|
</Extension>`;
|
|
581
608
|
}
|
|
582
|
-
var XML_HEADER;
|
|
609
|
+
var xmlTextReCache, xmlTagReCache, xmlNestedReCache, GOP_BLOCK_RE, xmlStreamBlockReCache, XML_HEADER;
|
|
583
610
|
var init_xml = __esm({
|
|
584
611
|
"src/protocol/xml.ts"() {
|
|
585
612
|
"use strict";
|
|
613
|
+
xmlTextReCache = /* @__PURE__ */ new Map();
|
|
614
|
+
xmlTagReCache = /* @__PURE__ */ new Map();
|
|
615
|
+
xmlNestedReCache = /* @__PURE__ */ new Map();
|
|
616
|
+
GOP_BLOCK_RE = /(<gop[^>]*>)([\s\S]*?)(<\/gop>)/;
|
|
617
|
+
xmlStreamBlockReCache = /* @__PURE__ */ new Map();
|
|
586
618
|
XML_HEADER = `<?xml version="1.0" encoding="UTF-8" ?>`;
|
|
587
619
|
}
|
|
588
620
|
});
|
|
@@ -8625,35 +8657,88 @@ function decodeHeader(buf) {
|
|
|
8625
8657
|
return { header, headerLen, messageKey };
|
|
8626
8658
|
}
|
|
8627
8659
|
var BaichuanFrameParser = class {
|
|
8660
|
+
/** Retained-but-unconsumed contiguous bytes from previous push() calls. */
|
|
8628
8661
|
buffer = Buffer.alloc(0);
|
|
8662
|
+
/** Chunks received since the last materialization, not yet concatenated. */
|
|
8663
|
+
pending = [];
|
|
8664
|
+
/** Total bytes held in `pending` (kept in sync to avoid re-summing). */
|
|
8665
|
+
pendingLen = 0;
|
|
8666
|
+
/**
|
|
8667
|
+
* Total contiguous bytes (`buffer` + `pending`) required before the next
|
|
8668
|
+
* parse attempt can make progress. While buffered bytes stay below this,
|
|
8669
|
+
* incoming chunks are merely stashed in `pending` with no copy. This is
|
|
8670
|
+
* the mechanism that turns the worst case (a large frame fragmented over
|
|
8671
|
+
* many small TCP chunks) from O(n²) into O(n): we concatenate once, when
|
|
8672
|
+
* enough bytes have arrived, instead of on every chunk.
|
|
8673
|
+
*
|
|
8674
|
+
* Starts at 4 — the minimum needed to inspect the magic header.
|
|
8675
|
+
*/
|
|
8676
|
+
needed = 4;
|
|
8677
|
+
/**
|
|
8678
|
+
* Collapse `this.buffer` + all `pending` chunks into a single contiguous
|
|
8679
|
+
* buffer. The retained leftover is copied at most once per materialize(),
|
|
8680
|
+
* and materialize() only runs when `needed` bytes are available — so a
|
|
8681
|
+
* fragmented frame is assembled with a single concat, not one per chunk.
|
|
8682
|
+
*/
|
|
8683
|
+
materialize() {
|
|
8684
|
+
if (this.pendingLen === 0) return;
|
|
8685
|
+
if (this.buffer.length === 0 && this.pending.length === 1) {
|
|
8686
|
+
this.buffer = this.pending[0];
|
|
8687
|
+
} else {
|
|
8688
|
+
const parts = this.buffer.length === 0 ? this.pending : [this.buffer, ...this.pending];
|
|
8689
|
+
this.buffer = Buffer.concat(parts);
|
|
8690
|
+
}
|
|
8691
|
+
this.pending = [];
|
|
8692
|
+
this.pendingLen = 0;
|
|
8693
|
+
}
|
|
8694
|
+
/** Total buffered bytes, whether materialized or still pending. */
|
|
8695
|
+
get available() {
|
|
8696
|
+
return this.buffer.length + this.pendingLen;
|
|
8697
|
+
}
|
|
8629
8698
|
push(chunk) {
|
|
8630
8699
|
if (chunk.length === 0) return [];
|
|
8631
|
-
|
|
8632
|
-
this.
|
|
8700
|
+
this.pending.push(chunk);
|
|
8701
|
+
this.pendingLen += chunk.length;
|
|
8702
|
+
if (this.available < this.needed) return [];
|
|
8703
|
+
this.materialize();
|
|
8633
8704
|
const out = [];
|
|
8634
8705
|
while (true) {
|
|
8635
|
-
if (this.buffer.length < 4)
|
|
8706
|
+
if (this.buffer.length < 4) {
|
|
8707
|
+
this.needed = 4;
|
|
8708
|
+
break;
|
|
8709
|
+
}
|
|
8636
8710
|
if (!this.buffer.subarray(0, 4).equals(BC_MAGIC) && !this.buffer.subarray(0, 4).equals(BC_MAGIC_REV)) {
|
|
8637
8711
|
const idx = this.buffer.indexOf(BC_MAGIC);
|
|
8638
8712
|
const idxRev = this.buffer.indexOf(BC_MAGIC_REV);
|
|
8639
8713
|
const next = idx === -1 ? idxRev : idxRev === -1 ? idx : Math.min(idx, idxRev);
|
|
8640
8714
|
if (next === -1) {
|
|
8641
8715
|
this.buffer = this.buffer.subarray(Math.max(0, this.buffer.length - 3));
|
|
8716
|
+
this.needed = 4;
|
|
8642
8717
|
break;
|
|
8643
8718
|
}
|
|
8644
8719
|
this.buffer = this.buffer.subarray(next);
|
|
8645
|
-
if (this.buffer.length < 20)
|
|
8720
|
+
if (this.buffer.length < 20) {
|
|
8721
|
+
this.needed = 20;
|
|
8722
|
+
break;
|
|
8723
|
+
}
|
|
8724
|
+
}
|
|
8725
|
+
if (this.buffer.length < 20) {
|
|
8726
|
+
this.needed = 20;
|
|
8727
|
+
break;
|
|
8646
8728
|
}
|
|
8647
|
-
if (this.buffer.length < 20) break;
|
|
8648
8729
|
let headerInfo;
|
|
8649
8730
|
try {
|
|
8650
8731
|
headerInfo = decodeHeader(this.buffer);
|
|
8651
8732
|
} catch {
|
|
8733
|
+
this.needed = 24;
|
|
8652
8734
|
break;
|
|
8653
8735
|
}
|
|
8654
8736
|
const { header, headerLen, messageKey } = headerInfo;
|
|
8655
8737
|
const frameLen = headerLen + header.bodyLen;
|
|
8656
|
-
if (this.buffer.length < frameLen)
|
|
8738
|
+
if (this.buffer.length < frameLen) {
|
|
8739
|
+
this.needed = frameLen;
|
|
8740
|
+
break;
|
|
8741
|
+
}
|
|
8657
8742
|
const raw = this.buffer.subarray(0, frameLen);
|
|
8658
8743
|
const body = raw.subarray(headerLen);
|
|
8659
8744
|
let extLen = 0;
|
|
@@ -8665,6 +8750,7 @@ var BaichuanFrameParser = class {
|
|
|
8665
8750
|
const payload = body.subarray(extLen);
|
|
8666
8751
|
out.push({ header, body, extension, payload, messageKey, raw });
|
|
8667
8752
|
this.buffer = this.buffer.subarray(frameLen);
|
|
8753
|
+
this.needed = 4;
|
|
8668
8754
|
}
|
|
8669
8755
|
return out;
|
|
8670
8756
|
}
|