@apocaliss92/nodelink-js 0.2.3 → 0.2.5
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/README.md +6 -2
- package/dist/{DiagnosticsTools-FNLGCOVA.js → DiagnosticsTools-2JQRV5FE.js} +2 -2
- package/dist/{chunk-NLTB7GTA.js → chunk-APEEZ4UN.js} +10 -9
- package/dist/{chunk-NLTB7GTA.js.map → chunk-APEEZ4UN.js.map} +1 -1
- package/dist/{chunk-RWYEGEWG.js → chunk-EG5IY3CM.js} +77 -9
- package/dist/chunk-EG5IY3CM.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +82 -13
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +2 -2
- package/dist/index.cjs +144 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +64 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-RWYEGEWG.js.map +0 -1
- /package/dist/{DiagnosticsTools-FNLGCOVA.js.map → DiagnosticsTools-2JQRV5FE.js.map} +0 -0
|
@@ -144,7 +144,7 @@ import {
|
|
|
144
144
|
talkTraceLog,
|
|
145
145
|
traceLog,
|
|
146
146
|
xmlEscape
|
|
147
|
-
} from "./chunk-
|
|
147
|
+
} from "./chunk-APEEZ4UN.js";
|
|
148
148
|
|
|
149
149
|
// src/protocol/framing.ts
|
|
150
150
|
function encodeHeader(h) {
|
|
@@ -5089,8 +5089,24 @@ var BaichuanEventEmitter = class {
|
|
|
5089
5089
|
}
|
|
5090
5090
|
};
|
|
5091
5091
|
async function* createNativeStream(api, channel, profile, options) {
|
|
5092
|
+
let client = options?.client;
|
|
5093
|
+
let dedicatedRelease;
|
|
5094
|
+
if (!client) {
|
|
5095
|
+
const variantSuffix = options?.variant && options.variant !== "default" ? `:${options.variant}` : "";
|
|
5096
|
+
const sessionKey = `live:native${variantSuffix}:ch${channel}:${profile}`;
|
|
5097
|
+
try {
|
|
5098
|
+
api.logger?.info?.(`[createNativeStream] acquiring dedicated session key=${sessionKey}`);
|
|
5099
|
+
const session = await api.createDedicatedSession(sessionKey);
|
|
5100
|
+
client = session.client;
|
|
5101
|
+
dedicatedRelease = session.release;
|
|
5102
|
+
api.logger?.info?.(`[createNativeStream] dedicated session acquired key=${sessionKey}`);
|
|
5103
|
+
} catch (e) {
|
|
5104
|
+
api.logger?.warn?.(`[createNativeStream] dedicated session failed, using shared client: ${e instanceof Error ? e.message : e}`);
|
|
5105
|
+
client = api.client;
|
|
5106
|
+
}
|
|
5107
|
+
}
|
|
5092
5108
|
const videoStream = new BaichuanVideoStream({
|
|
5093
|
-
client
|
|
5109
|
+
client,
|
|
5094
5110
|
api,
|
|
5095
5111
|
channel,
|
|
5096
5112
|
profile,
|
|
@@ -5104,9 +5120,15 @@ async function* createNativeStream(api, channel, profile, options) {
|
|
|
5104
5120
|
let closed = false;
|
|
5105
5121
|
const onError = (_error) => {
|
|
5106
5122
|
closed = true;
|
|
5123
|
+
api.logger?.warn?.(
|
|
5124
|
+
`[createNativeStream] stream error \u2192 closed channel=${channel} profile=${profile} error=${_error?.message ?? _error}`
|
|
5125
|
+
);
|
|
5107
5126
|
};
|
|
5108
5127
|
const onClose = () => {
|
|
5109
5128
|
closed = true;
|
|
5129
|
+
api.logger?.warn?.(
|
|
5130
|
+
`[createNativeStream] stream close \u2192 closed channel=${channel} profile=${profile}`
|
|
5131
|
+
);
|
|
5110
5132
|
};
|
|
5111
5133
|
try {
|
|
5112
5134
|
videoStream.on("error", onError);
|
|
@@ -5217,6 +5239,10 @@ async function* createNativeStream(api, channel, profile, options) {
|
|
|
5217
5239
|
}
|
|
5218
5240
|
videoStream.removeListener("error", onError);
|
|
5219
5241
|
videoStream.removeListener("close", onClose);
|
|
5242
|
+
if (dedicatedRelease) {
|
|
5243
|
+
dedicatedRelease().catch(() => {
|
|
5244
|
+
});
|
|
5245
|
+
}
|
|
5220
5246
|
}
|
|
5221
5247
|
}
|
|
5222
5248
|
|
|
@@ -5459,6 +5485,8 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends EventEmitter3 {
|
|
|
5459
5485
|
tcpRtpFraming;
|
|
5460
5486
|
active = false;
|
|
5461
5487
|
flow;
|
|
5488
|
+
deviceId;
|
|
5489
|
+
dedicatedSessionRelease;
|
|
5462
5490
|
// Authentication
|
|
5463
5491
|
authCredentials = [];
|
|
5464
5492
|
requireAuth;
|
|
@@ -5625,6 +5653,7 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends EventEmitter3 {
|
|
|
5625
5653
|
this.path = options.path ?? `/stream/${this.profile}`;
|
|
5626
5654
|
this.logger = options.logger ?? console;
|
|
5627
5655
|
this.tcpRtpFraming = options.tcpRtpFraming ?? "rfc4571";
|
|
5656
|
+
this.deviceId = options.deviceId;
|
|
5628
5657
|
this.authCredentials = options.credentials ?? [];
|
|
5629
5658
|
this.requireAuth = options.requireAuth ?? this.authCredentials.length > 0;
|
|
5630
5659
|
const transport = this.api.client.getTransport();
|
|
@@ -7010,14 +7039,31 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends EventEmitter3 {
|
|
|
7010
7039
|
this.firstAudioPromise = new Promise((resolve) => {
|
|
7011
7040
|
this.firstAudioResolve = resolve;
|
|
7012
7041
|
});
|
|
7042
|
+
let dedicatedClient;
|
|
7043
|
+
const variantSuffix = this.variant && this.variant !== "default" ? `:${this.variant}` : "";
|
|
7044
|
+
const deviceIdPart = this.deviceId ?? "rtsp-server";
|
|
7045
|
+
const sessionKey = `live:${deviceIdPart}:ch${this.channel}:${this.profile}${variantSuffix}`;
|
|
7046
|
+
try {
|
|
7047
|
+
const session = await this.api.createDedicatedSession(sessionKey, this.logger);
|
|
7048
|
+
dedicatedClient = session.client;
|
|
7049
|
+
this.dedicatedSessionRelease = session.release;
|
|
7050
|
+
this.logger.info(
|
|
7051
|
+
`[rebroadcast] dedicated session acquired sessionKey=${sessionKey}`
|
|
7052
|
+
);
|
|
7053
|
+
} catch (e) {
|
|
7054
|
+
this.logger.warn(
|
|
7055
|
+
`[rebroadcast] failed to acquire dedicated session, falling back to shared socket: ${e}`
|
|
7056
|
+
);
|
|
7057
|
+
}
|
|
7013
7058
|
this.logger.info(
|
|
7014
|
-
`[rebroadcast] native stream starting profile=${this.profile} channel=${this.channel} clients=${this.connectedClients.size}`
|
|
7059
|
+
`[rebroadcast] native stream starting profile=${this.profile} channel=${this.channel} clients=${this.connectedClients.size} dedicated=${!!dedicatedClient}`
|
|
7015
7060
|
);
|
|
7016
7061
|
await this.flow.startKeepAlive(this.api);
|
|
7017
7062
|
this.nativeFanout = new NativeStreamFanout({
|
|
7018
7063
|
maxQueueItems: 200,
|
|
7019
7064
|
createSource: () => createNativeStream(this.api, this.channel, this.profile, {
|
|
7020
|
-
variant: this.variant
|
|
7065
|
+
variant: this.variant,
|
|
7066
|
+
...dedicatedClient ? { client: dedicatedClient } : {}
|
|
7021
7067
|
}),
|
|
7022
7068
|
onFrame: (frame) => {
|
|
7023
7069
|
if (frame.audio) {
|
|
@@ -7075,6 +7121,12 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends EventEmitter3 {
|
|
|
7075
7121
|
this.firstFrameResolve = null;
|
|
7076
7122
|
this.nativeFanout = null;
|
|
7077
7123
|
this.prebuffer = [];
|
|
7124
|
+
if (this.dedicatedSessionRelease) {
|
|
7125
|
+
const release = this.dedicatedSessionRelease;
|
|
7126
|
+
this.dedicatedSessionRelease = void 0;
|
|
7127
|
+
release().catch(() => {
|
|
7128
|
+
});
|
|
7129
|
+
}
|
|
7078
7130
|
this.logger.info(
|
|
7079
7131
|
`[rebroadcast] native stream ended (camera sleeping or connection lost) profile=${this.profile} channel=${this.channel} clients=${this.connectedClients.size}`
|
|
7080
7132
|
);
|
|
@@ -7144,6 +7196,14 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends EventEmitter3 {
|
|
|
7144
7196
|
await fanout.stop();
|
|
7145
7197
|
}
|
|
7146
7198
|
this.prebuffer = [];
|
|
7199
|
+
if (this.dedicatedSessionRelease) {
|
|
7200
|
+
const release = this.dedicatedSessionRelease;
|
|
7201
|
+
this.dedicatedSessionRelease = void 0;
|
|
7202
|
+
try {
|
|
7203
|
+
await release();
|
|
7204
|
+
} catch {
|
|
7205
|
+
}
|
|
7206
|
+
}
|
|
7147
7207
|
if (this.tempStreamGenerator) {
|
|
7148
7208
|
try {
|
|
7149
7209
|
await this.tempStreamGenerator.return(void 0);
|
|
@@ -7153,14 +7213,22 @@ var BaichuanRtspServer = class _BaichuanRtspServer extends EventEmitter3 {
|
|
|
7153
7213
|
}
|
|
7154
7214
|
}
|
|
7155
7215
|
/**
|
|
7156
|
-
* Remove a client and
|
|
7216
|
+
* Remove a client and schedule native stream stop if no clients remain.
|
|
7217
|
+
* Uses a grace period so rapid reconnects (e.g. Frigate polling) reuse the running stream
|
|
7218
|
+
* and benefit from the prebuffer instead of waiting for a fresh keyframe.
|
|
7157
7219
|
*/
|
|
7158
7220
|
removeClient(clientId) {
|
|
7159
7221
|
if (this.connectedClients.has(clientId)) {
|
|
7160
7222
|
this.connectedClients.delete(clientId);
|
|
7161
7223
|
this.emit("clientDisconnected", clientId);
|
|
7162
7224
|
if (this.connectedClients.size === 0) {
|
|
7163
|
-
|
|
7225
|
+
this.clearNoClientAutoStopTimer();
|
|
7226
|
+
this.noClientAutoStopTimer = setTimeout(() => {
|
|
7227
|
+
if (this.connectedClients.size === 0) {
|
|
7228
|
+
void this.stopNativeStream();
|
|
7229
|
+
}
|
|
7230
|
+
}, 3e4);
|
|
7231
|
+
this.noClientAutoStopTimer?.unref?.();
|
|
7164
7232
|
}
|
|
7165
7233
|
}
|
|
7166
7234
|
}
|
|
@@ -17684,7 +17752,7 @@ ${xml}`
|
|
|
17684
17752
|
* @returns Test results for all stream types and profiles
|
|
17685
17753
|
*/
|
|
17686
17754
|
async testChannelStreams(channel, logger) {
|
|
17687
|
-
const { testChannelStreams } = await import("./DiagnosticsTools-
|
|
17755
|
+
const { testChannelStreams } = await import("./DiagnosticsTools-2JQRV5FE.js");
|
|
17688
17756
|
return await testChannelStreams({
|
|
17689
17757
|
api: this,
|
|
17690
17758
|
channel: this.normalizeChannel(channel),
|
|
@@ -17700,7 +17768,7 @@ ${xml}`
|
|
|
17700
17768
|
* @returns Complete diagnostics for all channels and streams
|
|
17701
17769
|
*/
|
|
17702
17770
|
async collectMultifocalDiagnostics(logger) {
|
|
17703
|
-
const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-
|
|
17771
|
+
const { collectMultifocalDiagnostics } = await import("./DiagnosticsTools-2JQRV5FE.js");
|
|
17704
17772
|
return await collectMultifocalDiagnostics({
|
|
17705
17773
|
api: this,
|
|
17706
17774
|
logger
|
|
@@ -21014,4 +21082,4 @@ export {
|
|
|
21014
21082
|
isTcpFailureThatShouldFallbackToUdp,
|
|
21015
21083
|
autoDetectDeviceType
|
|
21016
21084
|
};
|
|
21017
|
-
//# sourceMappingURL=chunk-
|
|
21085
|
+
//# sourceMappingURL=chunk-EG5IY3CM.js.map
|