@apocaliss92/nodelink-js 0.5.1-beta.7 → 0.5.1-beta.9
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/index.cjs +63 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +63 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -41759,6 +41759,20 @@ var import_node_events15 = require("events");
|
|
|
41759
41759
|
var net6 = __toESM(require("net"), 1);
|
|
41760
41760
|
var crypto3 = __toESM(require("crypto"), 1);
|
|
41761
41761
|
var md5Hex = (s) => crypto3.createHash("md5").update(s).digest("hex");
|
|
41762
|
+
var RTCP_KEEPALIVE_INTERVAL_MS = 1e4;
|
|
41763
|
+
function buildInterleavedRtcpRr(channel, ssrc) {
|
|
41764
|
+
const rtcp = Buffer.alloc(8);
|
|
41765
|
+
rtcp[0] = 128;
|
|
41766
|
+
rtcp[1] = 201;
|
|
41767
|
+
rtcp.writeUInt16BE(1, 2);
|
|
41768
|
+
rtcp.writeUInt32BE(ssrc >>> 0, 4);
|
|
41769
|
+
const frame = Buffer.alloc(4 + rtcp.length);
|
|
41770
|
+
frame[0] = 36;
|
|
41771
|
+
frame[1] = channel & 255;
|
|
41772
|
+
frame.writeUInt16BE(rtcp.length, 2);
|
|
41773
|
+
rtcp.copy(frame, 4);
|
|
41774
|
+
return frame;
|
|
41775
|
+
}
|
|
41762
41776
|
function normalizePath(path7) {
|
|
41763
41777
|
if (!path7) return "/";
|
|
41764
41778
|
let p = path7;
|
|
@@ -41955,6 +41969,7 @@ var BaichuanRtspBackchannelServer = class _BaichuanRtspBackchannelServer extends
|
|
|
41955
41969
|
this.server = void 0;
|
|
41956
41970
|
for (const session of this.sessionByClient.values()) {
|
|
41957
41971
|
this.sessionByClient.delete(session.clientId);
|
|
41972
|
+
this.stopRtcpKeepalive(session);
|
|
41958
41973
|
if (session.handler) {
|
|
41959
41974
|
void session.handler.stop();
|
|
41960
41975
|
}
|
|
@@ -41981,6 +41996,7 @@ var BaichuanRtspBackchannelServer = class _BaichuanRtspBackchannelServer extends
|
|
|
41981
41996
|
const durationMs = Date.now() - connectedAt;
|
|
41982
41997
|
if (session) {
|
|
41983
41998
|
this.sessionByClient.delete(clientId);
|
|
41999
|
+
this.stopRtcpKeepalive(session);
|
|
41984
42000
|
if (session.handler) {
|
|
41985
42001
|
const stats = session.handler.stats;
|
|
41986
42002
|
this.logger.info?.(
|
|
@@ -42137,9 +42153,20 @@ CSeq: ${cseq}\r
|
|
|
42137
42153
|
switch (method) {
|
|
42138
42154
|
case "OPTIONS":
|
|
42139
42155
|
send(200, "OK", {
|
|
42140
|
-
Public: "OPTIONS, DESCRIBE, SETUP, PLAY, RECORD, TEARDOWN"
|
|
42156
|
+
Public: "OPTIONS, DESCRIBE, SETUP, PLAY, RECORD, TEARDOWN, GET_PARAMETER, SET_PARAMETER"
|
|
42141
42157
|
});
|
|
42142
42158
|
return;
|
|
42159
|
+
// RFC 2326 §10.8 keepalive. Frigate's bundled go2rtc 1.9.10 sets a
|
|
42160
|
+
// ~30s read deadline on the producer socket during RECORD; without
|
|
42161
|
+
// a periodic reply on the same TCP connection that deadline fires
|
|
42162
|
+
// and the client gives up with "i/o timeout". go2rtc sends an empty
|
|
42163
|
+
// GET_PARAMETER (no body) as the keepalive — we just need to
|
|
42164
|
+
// acknowledge it. SET_PARAMETER is accepted for symmetry with
|
|
42165
|
+
// clients that prefer it for keepalive.
|
|
42166
|
+
case "GET_PARAMETER":
|
|
42167
|
+
case "SET_PARAMETER":
|
|
42168
|
+
send(200, "OK", sessionId ? { Session: sessionId } : {});
|
|
42169
|
+
return;
|
|
42143
42170
|
case "DESCRIBE": {
|
|
42144
42171
|
const resolved = this.resolveRouteForRequest(url);
|
|
42145
42172
|
if (!resolved) {
|
|
@@ -42274,12 +42301,14 @@ ${sdp.trimEnd()}`
|
|
|
42274
42301
|
}
|
|
42275
42302
|
session.handler = handler;
|
|
42276
42303
|
send(200, "OK", { Session: session.sessionId });
|
|
42304
|
+
this.startRtcpKeepalive(session);
|
|
42277
42305
|
return;
|
|
42278
42306
|
}
|
|
42279
42307
|
case "TEARDOWN": {
|
|
42280
42308
|
const session = this.sessionByClient.get(clientId);
|
|
42281
42309
|
if (session) {
|
|
42282
42310
|
this.sessionByClient.delete(clientId);
|
|
42311
|
+
this.stopRtcpKeepalive(session);
|
|
42283
42312
|
if (session.handler) {
|
|
42284
42313
|
const stats = session.handler.stats;
|
|
42285
42314
|
this.logger.info?.(
|
|
@@ -42310,6 +42339,39 @@ ${sdp.trimEnd()}`
|
|
|
42310
42339
|
send(501, "Not Implemented");
|
|
42311
42340
|
}
|
|
42312
42341
|
}
|
|
42342
|
+
/**
|
|
42343
|
+
* Start emitting an interleaved RTCP RR every
|
|
42344
|
+
* {@link RTCP_KEEPALIVE_INTERVAL_MS}. The RR carries no report blocks —
|
|
42345
|
+
* its purpose is to push *some* bytes back onto the TCP connection so
|
|
42346
|
+
* the producer's read deadline keeps resetting. Idempotent.
|
|
42347
|
+
*/
|
|
42348
|
+
startRtcpKeepalive(session) {
|
|
42349
|
+
if (session.rtcpKeepaliveTimer) return;
|
|
42350
|
+
session.rtcpSsrc = Math.floor(Math.random() * 4294967295) >>> 0;
|
|
42351
|
+
const frame = buildInterleavedRtcpRr(session.rtcpChannel, session.rtcpSsrc);
|
|
42352
|
+
const writeOne = () => {
|
|
42353
|
+
if (!session.socket.writable) return;
|
|
42354
|
+
try {
|
|
42355
|
+
session.socket.write(frame);
|
|
42356
|
+
} catch (e) {
|
|
42357
|
+
this.logger.debug?.(
|
|
42358
|
+
`[BaichuanRtspBackchannelServer] RTCP RR write failed client=${session.clientId} session=${session.sessionId} error="${e.message}"`
|
|
42359
|
+
);
|
|
42360
|
+
}
|
|
42361
|
+
};
|
|
42362
|
+
session.rtcpKeepaliveTimer = setInterval(writeOne, RTCP_KEEPALIVE_INTERVAL_MS);
|
|
42363
|
+
if (typeof session.rtcpKeepaliveTimer.unref === "function") {
|
|
42364
|
+
session.rtcpKeepaliveTimer.unref();
|
|
42365
|
+
}
|
|
42366
|
+
this.logger.debug?.(
|
|
42367
|
+
`[BaichuanRtspBackchannelServer] RTCP RR keepalive started client=${session.clientId} session=${session.sessionId} channel=${session.rtcpChannel} ssrc=${session.rtcpSsrc?.toString(16)} interval=${RTCP_KEEPALIVE_INTERVAL_MS}ms`
|
|
42368
|
+
);
|
|
42369
|
+
}
|
|
42370
|
+
stopRtcpKeepalive(session) {
|
|
42371
|
+
if (!session.rtcpKeepaliveTimer) return;
|
|
42372
|
+
clearInterval(session.rtcpKeepaliveTimer);
|
|
42373
|
+
delete session.rtcpKeepaliveTimer;
|
|
42374
|
+
}
|
|
42313
42375
|
buildSdp() {
|
|
42314
42376
|
return `v=0\r
|
|
42315
42377
|
o=- ${Date.now()} ${Date.now()} IN IP4 ${this.listenHost}\r
|