@apocaliss92/nodelink-js 0.4.1 → 0.4.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/{chunk-SDRNJQ5U.js → chunk-TJNPGYJA.js} +88 -34
- package/dist/chunk-TJNPGYJA.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +87 -33
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +1 -1
- package/dist/index.cjs +87 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -5
- package/dist/index.d.ts +47 -5
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-SDRNJQ5U.js.map +0 -1
package/dist/cli/rtsp-server.cjs
CHANGED
|
@@ -8070,6 +8070,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends import_node_events2.E
|
|
|
8070
8070
|
flow;
|
|
8071
8071
|
deviceId;
|
|
8072
8072
|
dedicatedSessionRelease;
|
|
8073
|
+
externalListener;
|
|
8073
8074
|
// Authentication
|
|
8074
8075
|
authCredentials = [];
|
|
8075
8076
|
requireAuth;
|
|
@@ -8237,6 +8238,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends import_node_events2.E
|
|
|
8237
8238
|
this.logger = options.logger ?? console;
|
|
8238
8239
|
this.tcpRtpFraming = options.tcpRtpFraming ?? "rfc4571";
|
|
8239
8240
|
this.deviceId = options.deviceId;
|
|
8241
|
+
this.externalListener = options.externalListener ?? false;
|
|
8240
8242
|
this.authCredentials = options.credentials ?? [];
|
|
8241
8243
|
this.requireAuth = options.requireAuth ?? this.authCredentials.length > 0;
|
|
8242
8244
|
const transport = this.api.client.getTransport();
|
|
@@ -8367,41 +8369,56 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends import_node_events2.E
|
|
|
8367
8369
|
this.streamMetadata = { frameRate: 25 };
|
|
8368
8370
|
this.setFlowVideoType("H264", "metadata unavailable");
|
|
8369
8371
|
}
|
|
8370
|
-
this.
|
|
8371
|
-
this.
|
|
8372
|
-
|
|
8373
|
-
|
|
8374
|
-
|
|
8375
|
-
this.
|
|
8376
|
-
|
|
8377
|
-
|
|
8378
|
-
|
|
8379
|
-
|
|
8380
|
-
|
|
8372
|
+
if (!this.externalListener) {
|
|
8373
|
+
this.clientConnectionServer = net.createServer((socket) => {
|
|
8374
|
+
this.handleRtspConnection(socket);
|
|
8375
|
+
});
|
|
8376
|
+
await new Promise((resolve, reject) => {
|
|
8377
|
+
this.clientConnectionServer.listen(
|
|
8378
|
+
this.listenPort,
|
|
8379
|
+
this.listenHost,
|
|
8380
|
+
() => {
|
|
8381
|
+
const address = this.clientConnectionServer.address();
|
|
8382
|
+
if (address && typeof address === "object" && "port" in address) {
|
|
8383
|
+
this.listenPort = address.port;
|
|
8384
|
+
}
|
|
8385
|
+
resolve();
|
|
8381
8386
|
}
|
|
8382
|
-
|
|
8383
|
-
|
|
8384
|
-
|
|
8385
|
-
|
|
8386
|
-
reject(error);
|
|
8387
|
+
);
|
|
8388
|
+
this.clientConnectionServer.on("error", (error) => {
|
|
8389
|
+
reject(error);
|
|
8390
|
+
});
|
|
8387
8391
|
});
|
|
8388
|
-
}
|
|
8392
|
+
}
|
|
8389
8393
|
this.active = true;
|
|
8390
8394
|
this.logger.info(
|
|
8391
8395
|
`[BaichuanRtspServer] RTSP server started on ${this.listenHost}:${this.listenPort}, path: ${this.path}`
|
|
8392
8396
|
);
|
|
8393
8397
|
}
|
|
8398
|
+
/**
|
|
8399
|
+
* Accept an externally-routed RTSP connection.
|
|
8400
|
+
* Used in directHandoff mode where RtspProxyServer routes sockets here.
|
|
8401
|
+
* @param socket - The client TCP socket (already authenticated by proxy)
|
|
8402
|
+
* @param initialBuffer - Any bytes already read during path parsing/auth
|
|
8403
|
+
*/
|
|
8404
|
+
acceptConnection(socket, initialBuffer) {
|
|
8405
|
+
if (!this.active) {
|
|
8406
|
+
socket.end("RTSP/1.0 503 Service Unavailable\r\n\r\n");
|
|
8407
|
+
return;
|
|
8408
|
+
}
|
|
8409
|
+
this.handleRtspConnection(socket, initialBuffer);
|
|
8410
|
+
}
|
|
8394
8411
|
/**
|
|
8395
8412
|
* Handle RTSP connection from a client.
|
|
8396
8413
|
*/
|
|
8397
|
-
handleRtspConnection(socket) {
|
|
8414
|
+
handleRtspConnection(socket, initialBuffer) {
|
|
8398
8415
|
const clientId = `${socket.remoteAddress}:${socket.remotePort}`;
|
|
8399
8416
|
const connectTime = Date.now();
|
|
8400
8417
|
this.logger.info(
|
|
8401
8418
|
`[rebroadcast] client connected client=${clientId} path=${this.path} profile=${this.profile} channel=${this.channel}`
|
|
8402
8419
|
);
|
|
8403
8420
|
let sessionId = "";
|
|
8404
|
-
let buffer = Buffer.alloc(0);
|
|
8421
|
+
let buffer = initialBuffer ?? Buffer.alloc(0);
|
|
8405
8422
|
let clientFfmpeg;
|
|
8406
8423
|
let useTcpInterleaved = false;
|
|
8407
8424
|
let clientUdpSocket = null;
|
|
@@ -8486,8 +8503,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends import_node_events2.E
|
|
|
8486
8503
|
}
|
|
8487
8504
|
cleanup();
|
|
8488
8505
|
});
|
|
8489
|
-
|
|
8490
|
-
buffer = Buffer.concat([buffer, data]);
|
|
8506
|
+
const processBuffer = async () => {
|
|
8491
8507
|
while (buffer.includes("\r\n\r\n")) {
|
|
8492
8508
|
const endIndex = buffer.indexOf("\r\n\r\n");
|
|
8493
8509
|
const requestText = buffer.subarray(0, endIndex).toString();
|
|
@@ -8762,7 +8778,14 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends import_node_events2.E
|
|
|
8762
8778
|
sendResponse(501, "Not Implemented");
|
|
8763
8779
|
}
|
|
8764
8780
|
}
|
|
8781
|
+
};
|
|
8782
|
+
socket.on("data", (data) => {
|
|
8783
|
+
buffer = Buffer.concat([buffer, data]);
|
|
8784
|
+
void processBuffer();
|
|
8765
8785
|
});
|
|
8786
|
+
if (buffer.includes("\r\n\r\n")) {
|
|
8787
|
+
void processBuffer();
|
|
8788
|
+
}
|
|
8766
8789
|
}
|
|
8767
8790
|
/**
|
|
8768
8791
|
* Generate SDP (Session Description Protocol) for RTSP DESCRIBE.
|
|
@@ -9730,21 +9753,27 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends import_node_events2.E
|
|
|
9730
9753
|
res.seenFirstVideoKeyframe = false;
|
|
9731
9754
|
res.rtpSentVideoConfig = false;
|
|
9732
9755
|
}
|
|
9733
|
-
if (this.dedicatedSessionRelease) {
|
|
9734
|
-
const release = this.dedicatedSessionRelease;
|
|
9735
|
-
this.dedicatedSessionRelease = void 0;
|
|
9736
|
-
release().catch(() => {
|
|
9737
|
-
});
|
|
9738
|
-
}
|
|
9739
9756
|
this.logger.info(
|
|
9740
9757
|
`[rebroadcast] native stream ended (camera sleeping or connection lost) profile=${this.profile} channel=${this.channel} clients=${this.connectedClients.size}`
|
|
9741
9758
|
);
|
|
9742
|
-
|
|
9743
|
-
this.
|
|
9744
|
-
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9759
|
+
const releaseAndRestart = async () => {
|
|
9760
|
+
if (this.dedicatedSessionRelease) {
|
|
9761
|
+
const release = this.dedicatedSessionRelease;
|
|
9762
|
+
this.dedicatedSessionRelease = void 0;
|
|
9763
|
+
try {
|
|
9764
|
+
await release();
|
|
9765
|
+
} catch {
|
|
9766
|
+
}
|
|
9767
|
+
}
|
|
9768
|
+
if (this.connectedClients.size > 0) {
|
|
9769
|
+
this.logger.info(
|
|
9770
|
+
`[rebroadcast] restarting native stream for ${this.connectedClients.size} active client(s)`
|
|
9771
|
+
);
|
|
9772
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
9773
|
+
void this.startNativeStream();
|
|
9774
|
+
}
|
|
9775
|
+
};
|
|
9776
|
+
void releaseAndRestart();
|
|
9748
9777
|
}
|
|
9749
9778
|
});
|
|
9750
9779
|
this.nativeFanout.start();
|
|
@@ -9968,6 +9997,31 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends import_node_events2.E
|
|
|
9968
9997
|
getClientCount() {
|
|
9969
9998
|
return this.connectedClients.size;
|
|
9970
9999
|
}
|
|
10000
|
+
/**
|
|
10001
|
+
* Subscribe to the raw native stream for diagnostic purposes.
|
|
10002
|
+
* The subscriber receives the same frames as RTSP clients.
|
|
10003
|
+
* Counts as a "consumer" for lifecycle — prevents auto-stop while subscribed.
|
|
10004
|
+
* If the native stream is not active, starts it automatically.
|
|
10005
|
+
*/
|
|
10006
|
+
async subscribeDiagnostic(id) {
|
|
10007
|
+
this.connectedClients.add(`diag:${id}`);
|
|
10008
|
+
if (!this.nativeStreamActive) {
|
|
10009
|
+
await this.startNativeStream();
|
|
10010
|
+
}
|
|
10011
|
+
return this.nativeFanout.subscribe(`diag:${id}`);
|
|
10012
|
+
}
|
|
10013
|
+
/**
|
|
10014
|
+
* Unsubscribe a diagnostic session.
|
|
10015
|
+
*/
|
|
10016
|
+
unsubscribeDiagnostic(id) {
|
|
10017
|
+
this.removeClient(`diag:${id}`);
|
|
10018
|
+
}
|
|
10019
|
+
/**
|
|
10020
|
+
* Returns detected audio metadata (available after first audio frame).
|
|
10021
|
+
*/
|
|
10022
|
+
getAudioInfo() {
|
|
10023
|
+
return this.audioInfo;
|
|
10024
|
+
}
|
|
9971
10025
|
};
|
|
9972
10026
|
|
|
9973
10027
|
// src/reolink/baichuan/ReolinkBaichuanApi.ts
|