@camstack/addon-pipeline 0.1.11 → 0.1.12
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/assets/icon.svg +6 -0
- package/dist/audio-analyzer/index.js +16 -16
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/audio-codec-nodeav/index.js +7 -7
- package/dist/audio-codec-nodeav/index.mjs +1 -1
- package/dist/decoder-nodeav/index.js +12 -12
- package/dist/decoder-nodeav/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +45 -45
- package/dist/detection-pipeline/index.js.map +1 -1
- package/dist/detection-pipeline/index.mjs +1 -1
- package/dist/index-BhOycEVH.js +13867 -0
- package/dist/index-BhOycEVH.js.map +1 -0
- package/dist/index-FxfFGsiL.mjs +13868 -0
- package/dist/index-FxfFGsiL.mjs.map +1 -0
- package/dist/motion-wasm/index.js +8 -8
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +76 -77
- package/dist/pipeline-runner/index.js.map +1 -1
- package/dist/pipeline-runner/index.mjs +50 -51
- package/dist/pipeline-runner/index.mjs.map +1 -1
- package/dist/stream-broker/@mf-types.zip +0 -0
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BvJPhiY_.mjs +20 -0
- package/dist/stream-broker/_stub.js +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BuV9ar3i.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Czwg8GUO.mjs} +6 -6
- package/dist/stream-broker/{hostInit-CjVI5LuK.mjs → hostInit-fG6oFw4t.mjs} +6 -6
- package/dist/stream-broker/{index-BF5Qr03x.mjs → index-BOmtakNy.mjs} +66 -43
- package/dist/stream-broker/{index-DUJwOcGq.mjs → index-Bpv0NSqI.mjs} +1733 -1569
- package/dist/stream-broker/{index-DuBCn5us.mjs → index-l13fl8lu.mjs} +378 -373
- package/dist/stream-broker/index.js +100 -100
- package/dist/stream-broker/index.js.map +1 -1
- package/dist/stream-broker/index.mjs +1 -1
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +24 -9
- package/dist/stream-broker/__mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-DbMNirr7.mjs +0 -20
|
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
24
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
25
|
-
const
|
|
25
|
+
const index = require("../index-BhOycEVH.js");
|
|
26
26
|
const net = require("node:net");
|
|
27
27
|
const crypto = require("node:crypto");
|
|
28
28
|
const net$1 = require("net");
|
|
@@ -201,7 +201,7 @@ const TARGET_CHUNK_MS = 500;
|
|
|
201
201
|
const F32_BYTES = 4;
|
|
202
202
|
const SESSION_NOT_FOUND_RE = /decode session\b.*\bnot found\b/;
|
|
203
203
|
function isSessionGone(err) {
|
|
204
|
-
return SESSION_NOT_FOUND_RE.test(
|
|
204
|
+
return SESSION_NOT_FOUND_RE.test(index.errMsg(err));
|
|
205
205
|
}
|
|
206
206
|
class AudioCodecSession {
|
|
207
207
|
constructor(api, cfg, emit, logger) {
|
|
@@ -303,7 +303,7 @@ class AudioCodecSession {
|
|
|
303
303
|
await this.api.closeSession({ sessionId: sid, ...nodeId ? { nodeId } : {} });
|
|
304
304
|
} catch (err) {
|
|
305
305
|
this.logger?.warn("audio-codec: closeSession failed", {
|
|
306
|
-
meta: { error:
|
|
306
|
+
meta: { error: index.errMsg(err) }
|
|
307
307
|
});
|
|
308
308
|
}
|
|
309
309
|
this.sessionId = null;
|
|
@@ -339,7 +339,7 @@ class AudioCodecSession {
|
|
|
339
339
|
return res.sessionId;
|
|
340
340
|
} catch (err) {
|
|
341
341
|
this.logger?.error("audio-codec: createDecodeSession failed", {
|
|
342
|
-
meta: { codec: this.cfg.codec, error:
|
|
342
|
+
meta: { codec: this.cfg.codec, error: index.errMsg(err) }
|
|
343
343
|
});
|
|
344
344
|
return null;
|
|
345
345
|
} finally {
|
|
@@ -373,7 +373,7 @@ class AudioCodecSession {
|
|
|
373
373
|
this.handleSessionGone(sid);
|
|
374
374
|
return;
|
|
375
375
|
}
|
|
376
|
-
this.warnThrottled("audio-codec: pullPcm failed",
|
|
376
|
+
this.warnThrottled("audio-codec: pullPcm failed", index.errMsg(err));
|
|
377
377
|
}
|
|
378
378
|
}
|
|
379
379
|
// ── Sample accumulator ──────────────────────────────────────────────────
|
|
@@ -450,7 +450,7 @@ class AudioCodecSession {
|
|
|
450
450
|
this.handleSessionGone(sid);
|
|
451
451
|
return;
|
|
452
452
|
}
|
|
453
|
-
this.warnThrottled(label,
|
|
453
|
+
this.warnThrottled(label, index.errMsg(err));
|
|
454
454
|
}
|
|
455
455
|
/**
|
|
456
456
|
* Logs at most once per WARN_THROTTLE_MS per (label,detail) pair and
|
|
@@ -2212,8 +2212,8 @@ const AAC_SAMPLE_RATES = [
|
|
|
2212
2212
|
8e3,
|
|
2213
2213
|
7350
|
|
2214
2214
|
];
|
|
2215
|
-
function aacSamplingIndexToHz(
|
|
2216
|
-
return AAC_SAMPLE_RATES[
|
|
2215
|
+
function aacSamplingIndexToHz(index2) {
|
|
2216
|
+
return AAC_SAMPLE_RATES[index2] ?? null;
|
|
2217
2217
|
}
|
|
2218
2218
|
class StreamEndError extends Error {
|
|
2219
2219
|
constructor(where) {
|
|
@@ -3430,7 +3430,7 @@ class StreamBroker {
|
|
|
3430
3430
|
*/
|
|
3431
3431
|
sourceMetaForLog() {
|
|
3432
3432
|
const src = this.source;
|
|
3433
|
-
const url = src && src.type !== "placeholder" && src.type !== "push" && src.type !== "push-rtp" ?
|
|
3433
|
+
const url = src && src.type !== "placeholder" && src.type !== "push" && src.type !== "push-rtp" ? index.maskUrlCredentials(src.url ?? "") : "";
|
|
3434
3434
|
return {
|
|
3435
3435
|
brokerId: this.deviceId,
|
|
3436
3436
|
sourceType: src?.type ?? "unknown",
|
|
@@ -3524,7 +3524,7 @@ class StreamBroker {
|
|
|
3524
3524
|
this.logger?.info("Broker starting", {
|
|
3525
3525
|
meta: {
|
|
3526
3526
|
sourceType: source.type,
|
|
3527
|
-
...source.type !== "placeholder" ? { url:
|
|
3527
|
+
...source.type !== "placeholder" ? { url: index.maskUrlCredentials(source.url) } : {},
|
|
3528
3528
|
...this.detectedCodec ? { codec: this.detectedCodec } : {}
|
|
3529
3529
|
}
|
|
3530
3530
|
});
|
|
@@ -3671,7 +3671,7 @@ class StreamBroker {
|
|
|
3671
3671
|
});
|
|
3672
3672
|
this.decoderOutputFormat = needed;
|
|
3673
3673
|
this.decoderProxy.updateConfig({ outputFormat: needed }).catch((err) => {
|
|
3674
|
-
this.logger?.warn("decoder format upgrade failed", { meta: { error:
|
|
3674
|
+
this.logger?.warn("decoder format upgrade failed", { meta: { error: index.errMsg(err) } });
|
|
3675
3675
|
});
|
|
3676
3676
|
}
|
|
3677
3677
|
/**
|
|
@@ -3723,7 +3723,7 @@ class StreamBroker {
|
|
|
3723
3723
|
}).catch((err) => {
|
|
3724
3724
|
subscriber.framesDropped++;
|
|
3725
3725
|
this.logger?.warn("frame conversion failed", {
|
|
3726
|
-
meta: { tag: subscriber.tag, target: subscriber.format, error:
|
|
3726
|
+
meta: { tag: subscriber.tag, target: subscriber.format, error: index.errMsg(err) }
|
|
3727
3727
|
});
|
|
3728
3728
|
});
|
|
3729
3729
|
return;
|
|
@@ -3737,7 +3737,7 @@ class StreamBroker {
|
|
|
3737
3737
|
}).catch((err) => {
|
|
3738
3738
|
subscriber.framesDropped++;
|
|
3739
3739
|
this.logger?.warn("frame conversion failed", {
|
|
3740
|
-
meta: { tag: subscriber.tag, target: subscriber.format, error:
|
|
3740
|
+
meta: { tag: subscriber.tag, target: subscriber.format, error: index.errMsg(err) }
|
|
3741
3741
|
});
|
|
3742
3742
|
});
|
|
3743
3743
|
}
|
|
@@ -3793,7 +3793,7 @@ class StreamBroker {
|
|
|
3793
3793
|
this._suspended = false;
|
|
3794
3794
|
this.logger?.info("demand detected — resuming stream");
|
|
3795
3795
|
this.start(fresh).catch((err) => {
|
|
3796
|
-
this.logger?.error("resume failed", { meta: { error:
|
|
3796
|
+
this.logger?.error("resume failed", { meta: { error: index.errMsg(err) } });
|
|
3797
3797
|
this._suspended = true;
|
|
3798
3798
|
this._status = "idle";
|
|
3799
3799
|
});
|
|
@@ -3854,7 +3854,7 @@ class StreamBroker {
|
|
|
3854
3854
|
this.audioCodecSession = null;
|
|
3855
3855
|
void session.close().catch((err) => {
|
|
3856
3856
|
this.logger?.warn("audio-codec: push session close failed", {
|
|
3857
|
-
meta: { error:
|
|
3857
|
+
meta: { error: index.errMsg(err) }
|
|
3858
3858
|
});
|
|
3859
3859
|
});
|
|
3860
3860
|
}
|
|
@@ -3893,7 +3893,7 @@ class StreamBroker {
|
|
|
3893
3893
|
this.audioCodecSession = null;
|
|
3894
3894
|
void prior.close().catch((err) => {
|
|
3895
3895
|
this.logger?.debug("audio-codec: prior session close failed", {
|
|
3896
|
-
meta: { error:
|
|
3896
|
+
meta: { error: index.errMsg(err) }
|
|
3897
3897
|
});
|
|
3898
3898
|
});
|
|
3899
3899
|
}
|
|
@@ -3989,7 +3989,7 @@ class StreamBroker {
|
|
|
3989
3989
|
});
|
|
3990
3990
|
}
|
|
3991
3991
|
this.decoderProxy.pushPacket(packet).catch((err) => {
|
|
3992
|
-
this.logger?.warn("decoder push error", { meta: { error:
|
|
3992
|
+
this.logger?.warn("decoder push error", { meta: { error: index.errMsg(err) } });
|
|
3993
3993
|
});
|
|
3994
3994
|
}
|
|
3995
3995
|
}
|
|
@@ -4073,7 +4073,7 @@ class StreamBroker {
|
|
|
4073
4073
|
callback(this.sdpParameterSets);
|
|
4074
4074
|
} catch (err) {
|
|
4075
4075
|
this.logger?.warn("sdp param-set subscriber threw on initial delivery", {
|
|
4076
|
-
meta: { error:
|
|
4076
|
+
meta: { error: index.errMsg(err) }
|
|
4077
4077
|
});
|
|
4078
4078
|
}
|
|
4079
4079
|
}
|
|
@@ -4090,7 +4090,7 @@ class StreamBroker {
|
|
|
4090
4090
|
cb(ps);
|
|
4091
4091
|
} catch (err) {
|
|
4092
4092
|
this.logger?.warn("sdp param-set subscriber threw", {
|
|
4093
|
-
meta: { error:
|
|
4093
|
+
meta: { error: index.errMsg(err) }
|
|
4094
4094
|
});
|
|
4095
4095
|
}
|
|
4096
4096
|
}
|
|
@@ -4154,7 +4154,7 @@ class StreamBroker {
|
|
|
4154
4154
|
cb(rtpData);
|
|
4155
4155
|
} catch (err) {
|
|
4156
4156
|
this.logger?.warn("rtp video subscriber threw", {
|
|
4157
|
-
meta: { error:
|
|
4157
|
+
meta: { error: index.errMsg(err) }
|
|
4158
4158
|
});
|
|
4159
4159
|
}
|
|
4160
4160
|
}
|
|
@@ -4362,7 +4362,7 @@ class StreamBroker {
|
|
|
4362
4362
|
* backoff used by the RTSP path.
|
|
4363
4363
|
*/
|
|
4364
4364
|
startRtmpReader(source) {
|
|
4365
|
-
this.logger?.info("starting RTMP reader", { meta: { url:
|
|
4365
|
+
this.logger?.info("starting RTMP reader", { meta: { url: index.maskUrlCredentials(source.url) } });
|
|
4366
4366
|
this.destroyRtmpReader();
|
|
4367
4367
|
const reader = new RtmpReader(source.url, this.logger?.child("rtmp"), {
|
|
4368
4368
|
onVideoCodec: (codec) => {
|
|
@@ -4398,7 +4398,7 @@ class StreamBroker {
|
|
|
4398
4398
|
reader.connect().catch((err) => {
|
|
4399
4399
|
if (this.manualStop || this._suspended) return;
|
|
4400
4400
|
this.logger?.warn("rtmp connect failed", {
|
|
4401
|
-
meta: { error:
|
|
4401
|
+
meta: { error: index.errMsg(err), ...this.sourceMetaForLog() }
|
|
4402
4402
|
});
|
|
4403
4403
|
this.destroyRtmpReader();
|
|
4404
4404
|
this._status = "error";
|
|
@@ -4489,7 +4489,7 @@ class StreamBroker {
|
|
|
4489
4489
|
cb(rtpData);
|
|
4490
4490
|
} catch (err) {
|
|
4491
4491
|
this.logger?.warn("rtp video subscriber threw", {
|
|
4492
|
-
meta: { error:
|
|
4492
|
+
meta: { error: index.errMsg(err) }
|
|
4493
4493
|
});
|
|
4494
4494
|
}
|
|
4495
4495
|
}
|
|
@@ -4535,7 +4535,7 @@ class StreamBroker {
|
|
|
4535
4535
|
this.audioCodecSession = null;
|
|
4536
4536
|
void prior.close().catch((err) => {
|
|
4537
4537
|
this.logger?.debug("audio-codec: prior RTSP session close failed", {
|
|
4538
|
-
meta: { error:
|
|
4538
|
+
meta: { error: index.errMsg(err) }
|
|
4539
4539
|
});
|
|
4540
4540
|
});
|
|
4541
4541
|
}
|
|
@@ -4643,7 +4643,7 @@ class StreamBroker {
|
|
|
4643
4643
|
client.connect().catch((err) => {
|
|
4644
4644
|
if (this.manualStop || this._suspended) return;
|
|
4645
4645
|
this.logger?.warn("native RTSP connect failed", {
|
|
4646
|
-
meta: { error:
|
|
4646
|
+
meta: { error: index.errMsg(err), ...this.sourceMetaForLog() }
|
|
4647
4647
|
});
|
|
4648
4648
|
this.destroyNativeClient();
|
|
4649
4649
|
this._status = "error";
|
|
@@ -4967,7 +4967,7 @@ class StreamBroker {
|
|
|
4967
4967
|
const codec = this.detectedCodec ?? this.source.videoCodec;
|
|
4968
4968
|
if (codec) {
|
|
4969
4969
|
this.createSharedDecoderSession(this.pendingDecodeOptions).catch((err) => {
|
|
4970
|
-
this.logger?.warn("decoder session rebuild after rotation failed", { meta: { error:
|
|
4970
|
+
this.logger?.warn("decoder session rebuild after rotation failed", { meta: { error: index.errMsg(err) } });
|
|
4971
4971
|
});
|
|
4972
4972
|
}
|
|
4973
4973
|
}
|
|
@@ -5066,7 +5066,7 @@ class StreamBroker {
|
|
|
5066
5066
|
reader.connect().catch((err) => {
|
|
5067
5067
|
if (this.manualStop || this._suspended) return;
|
|
5068
5068
|
this.logger?.warn("rfc4571 connect failed", {
|
|
5069
|
-
meta: { error:
|
|
5069
|
+
meta: { error: index.errMsg(err), ...this.sourceMetaForLog() }
|
|
5070
5070
|
});
|
|
5071
5071
|
this.destroyRfc4571Reader();
|
|
5072
5072
|
this._status = "error";
|
|
@@ -5097,7 +5097,7 @@ class StreamBroker {
|
|
|
5097
5097
|
this.audioCodecSession = null;
|
|
5098
5098
|
void session.close().catch((err) => {
|
|
5099
5099
|
this.logger?.warn("audio-codec: session close failed", {
|
|
5100
|
-
meta: { error:
|
|
5100
|
+
meta: { error: index.errMsg(err) }
|
|
5101
5101
|
});
|
|
5102
5102
|
});
|
|
5103
5103
|
}
|
|
@@ -5151,7 +5151,7 @@ class StreamBroker {
|
|
|
5151
5151
|
this.fanoutDecodedFrame(frame);
|
|
5152
5152
|
};
|
|
5153
5153
|
proxy.startPolling(onFrame).catch((err) => {
|
|
5154
|
-
this.logger?.warn("decoder polling error", { meta: { error:
|
|
5154
|
+
this.logger?.warn("decoder polling error", { meta: { error: index.errMsg(err) } });
|
|
5155
5155
|
});
|
|
5156
5156
|
const info = await this.decoderApi.getInfo();
|
|
5157
5157
|
if (info.isPullMode) {
|
|
@@ -5163,7 +5163,7 @@ class StreamBroker {
|
|
|
5163
5163
|
meta: { localUrl, codec }
|
|
5164
5164
|
});
|
|
5165
5165
|
proxy.openStream(inputUrl).catch((err) => {
|
|
5166
|
-
this.logger?.error("Pull mode decoder failed", { meta: { error:
|
|
5166
|
+
this.logger?.error("Pull mode decoder failed", { meta: { error: index.errMsg(err) } });
|
|
5167
5167
|
});
|
|
5168
5168
|
};
|
|
5169
5169
|
if (this.firstKeyframeReceived) {
|
|
@@ -5280,7 +5280,7 @@ class StreamBroker {
|
|
|
5280
5280
|
extraData = hexToBytes(configHex);
|
|
5281
5281
|
} catch (err) {
|
|
5282
5282
|
this.logger?.warn("audio-codec: AudioSpecificConfig parse failed", {
|
|
5283
|
-
meta: { configHex, error:
|
|
5283
|
+
meta: { configHex, error: index.errMsg(err) }
|
|
5284
5284
|
});
|
|
5285
5285
|
}
|
|
5286
5286
|
}
|
|
@@ -6035,7 +6035,7 @@ class TranscodePipelineManager {
|
|
|
6035
6035
|
return await callable();
|
|
6036
6036
|
} catch (err) {
|
|
6037
6037
|
this.logger.warn("platformProbe.getHardwareEncoders failed — using software fallback", {
|
|
6038
|
-
meta: { error:
|
|
6038
|
+
meta: { error: index.errMsg(err) }
|
|
6039
6039
|
});
|
|
6040
6040
|
return null;
|
|
6041
6041
|
}
|
|
@@ -6068,13 +6068,13 @@ class TranscodePipelineManager {
|
|
|
6068
6068
|
});
|
|
6069
6069
|
child.once("error", (err) => {
|
|
6070
6070
|
this.logger.error("ffmpeg spawn error", {
|
|
6071
|
-
meta: { tag: opts.tag, error:
|
|
6071
|
+
meta: { tag: opts.tag, error: index.errMsg(err) }
|
|
6072
6072
|
});
|
|
6073
6073
|
});
|
|
6074
6074
|
return child;
|
|
6075
6075
|
} catch (err) {
|
|
6076
6076
|
this.logger.error("Failed to spawn ffmpeg", {
|
|
6077
|
-
meta: { tag: opts.tag, error:
|
|
6077
|
+
meta: { tag: opts.tag, error: index.errMsg(err) }
|
|
6078
6078
|
});
|
|
6079
6079
|
return null;
|
|
6080
6080
|
}
|
|
@@ -6108,7 +6108,7 @@ class TranscodePipelineManager {
|
|
|
6108
6108
|
entry.child.kill("SIGTERM");
|
|
6109
6109
|
} catch (err) {
|
|
6110
6110
|
this.logger.warn("ffmpeg kill error", {
|
|
6111
|
-
meta: { key: entry.key, error:
|
|
6111
|
+
meta: { key: entry.key, error: index.errMsg(err) }
|
|
6112
6112
|
});
|
|
6113
6113
|
}
|
|
6114
6114
|
}
|
|
@@ -6117,7 +6117,7 @@ class TranscodePipelineManager {
|
|
|
6117
6117
|
}
|
|
6118
6118
|
const PUSH_KINDS = /* @__PURE__ */ new Set(["push-annexb"]);
|
|
6119
6119
|
function findProfileForStream(map, camStreamId) {
|
|
6120
|
-
for (const profile of
|
|
6120
|
+
for (const profile of index.CAM_PROFILE_ORDER) {
|
|
6121
6121
|
if (map[profile] === camStreamId) return profile;
|
|
6122
6122
|
}
|
|
6123
6123
|
return null;
|
|
@@ -6318,7 +6318,7 @@ class StreamBrokerManager {
|
|
|
6318
6318
|
const session = await provider.createSession(config);
|
|
6319
6319
|
const sessionId = `dec-${++nextId}`;
|
|
6320
6320
|
sessions.set(sessionId, session);
|
|
6321
|
-
const buffer = new
|
|
6321
|
+
const buffer = new index.RingBuffer(FRAME_BUFFER_CAPACITY);
|
|
6322
6322
|
frameBuffers.set(sessionId, buffer);
|
|
6323
6323
|
const unsub = session.onFrame((frame) => {
|
|
6324
6324
|
buffer.push(frame);
|
|
@@ -6399,7 +6399,7 @@ class StreamBrokerManager {
|
|
|
6399
6399
|
* client-side and we get a typed payload.
|
|
6400
6400
|
*/
|
|
6401
6401
|
subscribePlaceholderStateSources(bus) {
|
|
6402
|
-
bus.subscribe({ category:
|
|
6402
|
+
bus.subscribe({ category: index.EventCategory.BatteryOnStatusChanged }, (event) => {
|
|
6403
6403
|
const data = event.data;
|
|
6404
6404
|
const deviceId = typeof data.deviceId === "number" ? data.deviceId : null;
|
|
6405
6405
|
if (deviceId === null) return;
|
|
@@ -6412,8 +6412,8 @@ class StreamBrokerManager {
|
|
|
6412
6412
|
if (deviceId === null) return;
|
|
6413
6413
|
this.applyPlaceholderReasonToDevice(deviceId, reason);
|
|
6414
6414
|
};
|
|
6415
|
-
bus.subscribe({ category:
|
|
6416
|
-
bus.subscribe({ category:
|
|
6415
|
+
bus.subscribe({ category: index.EventCategory.DeviceOffline }, handlerForReason("offline"));
|
|
6416
|
+
bus.subscribe({ category: index.EventCategory.DeviceDisabled }, handlerForReason("disabled"));
|
|
6417
6417
|
}
|
|
6418
6418
|
setWebrtcServer(server) {
|
|
6419
6419
|
this.webrtcServer = server;
|
|
@@ -6510,7 +6510,7 @@ class StreamBrokerManager {
|
|
|
6510
6510
|
if (!streamMap?.has(camStreamId)) return { success: true };
|
|
6511
6511
|
const current = this.assignments.get(deviceId) ?? { map: {}, auto: true };
|
|
6512
6512
|
let newMap = { ...current.map };
|
|
6513
|
-
for (const profile of
|
|
6513
|
+
for (const profile of index.CAM_PROFILE_ORDER) {
|
|
6514
6514
|
if (newMap[profile] === camStreamId) delete newMap[profile];
|
|
6515
6515
|
}
|
|
6516
6516
|
if (current.auto) {
|
|
@@ -6651,7 +6651,7 @@ class StreamBrokerManager {
|
|
|
6651
6651
|
rotated++;
|
|
6652
6652
|
} catch (err) {
|
|
6653
6653
|
this.logger.warn("decoder rotation failed", {
|
|
6654
|
-
meta: { brokerId: broker.deviceId, agentNodeId, reason, error:
|
|
6654
|
+
meta: { brokerId: broker.deviceId, agentNodeId, reason, error: index.errMsg(err) }
|
|
6655
6655
|
});
|
|
6656
6656
|
}
|
|
6657
6657
|
}
|
|
@@ -6847,7 +6847,7 @@ class StreamBrokerManager {
|
|
|
6847
6847
|
return enabled ? perStream.seconds : 0;
|
|
6848
6848
|
}
|
|
6849
6849
|
if (override?.preBufferSecOverride !== void 0) return override.preBufferSecOverride;
|
|
6850
|
-
if (this.deviceHasFeature(deviceId,
|
|
6850
|
+
if (this.deviceHasFeature(deviceId, index.DeviceFeature.BatteryOperated)) return 0;
|
|
6851
6851
|
return addonDefault;
|
|
6852
6852
|
}
|
|
6853
6853
|
/**
|
|
@@ -7022,7 +7022,7 @@ class StreamBrokerManager {
|
|
|
7022
7022
|
for (const [fieldKey, value] of Object.entries(input.patch)) {
|
|
7023
7023
|
if (fieldKey.startsWith("streamProfile:")) {
|
|
7024
7024
|
const profile = fieldKey.slice("streamProfile:".length);
|
|
7025
|
-
if (!
|
|
7025
|
+
if (!index.CAM_PROFILE_ORDER.includes(profile)) continue;
|
|
7026
7026
|
const newCamId = typeof value === "string" && value !== "" ? value : null;
|
|
7027
7027
|
if (newCamId === null) {
|
|
7028
7028
|
await this.unassignProfile({ deviceId, profile });
|
|
@@ -7163,7 +7163,7 @@ class StreamBrokerManager {
|
|
|
7163
7163
|
}
|
|
7164
7164
|
wouldChangeAutoMap(current, streams) {
|
|
7165
7165
|
const computed = this.computeInitialAssignment(streams);
|
|
7166
|
-
for (const p of
|
|
7166
|
+
for (const p of index.CAM_PROFILE_ORDER) {
|
|
7167
7167
|
if (current[p] !== computed[p]) return true;
|
|
7168
7168
|
}
|
|
7169
7169
|
return false;
|
|
@@ -7182,7 +7182,7 @@ class StreamBrokerManager {
|
|
|
7182
7182
|
const oldPushConsumers = this.countPushConsumers(current.map, deviceId);
|
|
7183
7183
|
const newPushConsumers = this.countPushConsumers(newMap, deviceId);
|
|
7184
7184
|
let anyChange = false;
|
|
7185
|
-
for (const profile of
|
|
7185
|
+
for (const profile of index.CAM_PROFILE_ORDER) {
|
|
7186
7186
|
if (current.map[profile] !== newMap[profile]) {
|
|
7187
7187
|
anyChange = true;
|
|
7188
7188
|
break;
|
|
@@ -7197,7 +7197,7 @@ class StreamBrokerManager {
|
|
|
7197
7197
|
for (const [camId, nextCount] of newPushConsumers) {
|
|
7198
7198
|
if ((oldPushConsumers.get(camId) ?? 0) === 0 && nextCount > 0) {
|
|
7199
7199
|
let triggerProfile = "mid";
|
|
7200
|
-
for (const p of
|
|
7200
|
+
for (const p of index.CAM_PROFILE_ORDER) {
|
|
7201
7201
|
if (newMap[p] === camId) {
|
|
7202
7202
|
triggerProfile = p;
|
|
7203
7203
|
break;
|
|
@@ -7216,7 +7216,7 @@ class StreamBrokerManager {
|
|
|
7216
7216
|
countPushConsumers(map, deviceId) {
|
|
7217
7217
|
const out = /* @__PURE__ */ new Map();
|
|
7218
7218
|
const streamMap = this.cameraStreams.get(deviceId);
|
|
7219
|
-
for (const profile of
|
|
7219
|
+
for (const profile of index.CAM_PROFILE_ORDER) {
|
|
7220
7220
|
const camId = map[profile];
|
|
7221
7221
|
if (!camId) continue;
|
|
7222
7222
|
const cam = streamMap?.get(camId);
|
|
@@ -7231,7 +7231,7 @@ class StreamBrokerManager {
|
|
|
7231
7231
|
buildSourceFromCamStream(cam) {
|
|
7232
7232
|
const label = cam.label ?? cam.camStreamId;
|
|
7233
7233
|
const codec = cam.codec !== void 0 ? { videoCodec: cam.codec } : {};
|
|
7234
|
-
const stall = cam.deviceFeatures.includes(
|
|
7234
|
+
const stall = cam.deviceFeatures.includes(index.DeviceFeature.BatteryOperated) ? { allowStall: true } : {};
|
|
7235
7235
|
const passthroughMeta = cam.metadata ?? {};
|
|
7236
7236
|
switch (cam.kind) {
|
|
7237
7237
|
case "push-annexb":
|
|
@@ -7355,7 +7355,7 @@ class StreamBrokerManager {
|
|
|
7355
7355
|
]);
|
|
7356
7356
|
} catch (err) {
|
|
7357
7357
|
log.error("Failed to register with restreamer", {
|
|
7358
|
-
meta: { restreamerId: restreamer.id, error:
|
|
7358
|
+
meta: { restreamerId: restreamer.id, error: index.errMsg(err) }
|
|
7359
7359
|
});
|
|
7360
7360
|
}
|
|
7361
7361
|
}
|
|
@@ -7370,7 +7370,7 @@ class StreamBrokerManager {
|
|
|
7370
7370
|
await restreamer.unregisterDevice(deviceId);
|
|
7371
7371
|
} catch (err) {
|
|
7372
7372
|
log.error("Failed to unregister from restreamer", {
|
|
7373
|
-
meta: { restreamerId: restreamer.id, error:
|
|
7373
|
+
meta: { restreamerId: restreamer.id, error: index.errMsg(err) }
|
|
7374
7374
|
});
|
|
7375
7375
|
}
|
|
7376
7376
|
}
|
|
@@ -7386,7 +7386,7 @@ class StreamBrokerManager {
|
|
|
7386
7386
|
const assignment = this.assignments.get(deviceId) ?? { map: {} };
|
|
7387
7387
|
const streamMap = this.cameraStreams.get(deviceId);
|
|
7388
7388
|
const slots = [];
|
|
7389
|
-
for (const profile of
|
|
7389
|
+
for (const profile of index.CAM_PROFILE_ORDER) {
|
|
7390
7390
|
const camId = assignment.map[profile] ?? null;
|
|
7391
7391
|
const brokerId = camId ? brokerIdFor(deviceId, camId) : `${deviceId}/${profile}`;
|
|
7392
7392
|
const broker = camId ? this.brokers.get(brokerId) : void 0;
|
|
@@ -7421,13 +7421,13 @@ class StreamBrokerManager {
|
|
|
7421
7421
|
});
|
|
7422
7422
|
}
|
|
7423
7423
|
emitCamStreamDemand(deviceId, camStreamId, profile) {
|
|
7424
|
-
this.emitCapEvent(
|
|
7424
|
+
this.emitCapEvent(index.EventCategory.StreamBrokerOnCamStreamDemand, deviceId, { deviceId, camStreamId, profile });
|
|
7425
7425
|
}
|
|
7426
7426
|
emitCamStreamIdle(deviceId, camStreamId) {
|
|
7427
|
-
this.emitCapEvent(
|
|
7427
|
+
this.emitCapEvent(index.EventCategory.StreamBrokerOnCamStreamIdle, deviceId, { deviceId, camStreamId });
|
|
7428
7428
|
}
|
|
7429
7429
|
emitRequestStreamSourceRefresh(deviceId, camStreamId, brokerId) {
|
|
7430
|
-
this.emitCapEvent(
|
|
7430
|
+
this.emitCapEvent(index.EventCategory.StreamBrokerOnRequestStreamSourceRefresh, deviceId, {
|
|
7431
7431
|
deviceId,
|
|
7432
7432
|
camStreamId,
|
|
7433
7433
|
brokerId
|
|
@@ -7814,7 +7814,7 @@ async function resolveMdnsCandidatesInSdp(sdp, logger, sessionTag) {
|
|
|
7814
7814
|
logger.info("mDNS resolve succeeded", { meta: { sessionTag, host, address } });
|
|
7815
7815
|
return [host, address];
|
|
7816
7816
|
} catch (err) {
|
|
7817
|
-
logger.warn("mDNS resolve failed", { meta: { sessionTag, host, error:
|
|
7817
|
+
logger.warn("mDNS resolve failed", { meta: { sessionTag, host, error: index.errMsg(err) } });
|
|
7818
7818
|
return [host, null];
|
|
7819
7819
|
}
|
|
7820
7820
|
})
|
|
@@ -7859,18 +7859,18 @@ class JitterBuffer {
|
|
|
7859
7859
|
return ret;
|
|
7860
7860
|
const start = nextSequenceNumber(afterSequenceNumber);
|
|
7861
7861
|
for (let i = 0; i < this.jitterSize; i++) {
|
|
7862
|
-
const
|
|
7863
|
-
const packet = this.pending[
|
|
7862
|
+
const index2 = (start + i) % this.jitterSize;
|
|
7863
|
+
const packet = this.pending[index2];
|
|
7864
7864
|
if (!packet)
|
|
7865
7865
|
continue;
|
|
7866
7866
|
const { sequenceNumber } = packet.header;
|
|
7867
7867
|
const sd = sequenceNumberDistance(this.lastSequenceNumber ?? sequenceNumber, sequenceNumber);
|
|
7868
7868
|
if (sd <= 0) {
|
|
7869
7869
|
this.console.log("jitter buffer purged packet:", sequenceNumber);
|
|
7870
|
-
this.pending[
|
|
7870
|
+
this.pending[index2] = void 0;
|
|
7871
7871
|
ret.push(packet);
|
|
7872
7872
|
} else if (sd === 1) {
|
|
7873
|
-
this.pending[
|
|
7873
|
+
this.pending[index2] = void 0;
|
|
7874
7874
|
this.lastSequenceNumber = sequenceNumber;
|
|
7875
7875
|
ret.push(packet);
|
|
7876
7876
|
} else ;
|
|
@@ -8188,10 +8188,10 @@ class H265Repacketizer {
|
|
|
8188
8188
|
this.pendingFU = void 0;
|
|
8189
8189
|
}
|
|
8190
8190
|
createRtpPackets(packet, nalus, ret, hadMarker = packet.header.marker) {
|
|
8191
|
-
nalus.forEach((packetized,
|
|
8192
|
-
if (
|
|
8191
|
+
nalus.forEach((packetized, index2) => {
|
|
8192
|
+
if (index2 !== 0)
|
|
8193
8193
|
this.extraPackets++;
|
|
8194
|
-
const marker = hadMarker &&
|
|
8194
|
+
const marker = hadMarker && index2 === nalus.length - 1;
|
|
8195
8195
|
ret.push(this.createPacket(packet, packetized, marker));
|
|
8196
8196
|
});
|
|
8197
8197
|
}
|
|
@@ -8583,7 +8583,7 @@ class AdaptiveSession {
|
|
|
8583
8583
|
const payload = pkt.payload;
|
|
8584
8584
|
if (payload?.length > 0) void cb(payload, "Opus");
|
|
8585
8585
|
} catch (err) {
|
|
8586
|
-
this.logger.error("Intercom error", { meta: { phase: "session", sessionId: this.sessionId, error:
|
|
8586
|
+
this.logger.error("Intercom error", { meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(err) } });
|
|
8587
8587
|
}
|
|
8588
8588
|
});
|
|
8589
8589
|
});
|
|
@@ -8844,7 +8844,7 @@ class AdaptiveSession {
|
|
|
8844
8844
|
srcPkt = werift.RtpPacket.deSerialize(rtpData);
|
|
8845
8845
|
} catch (err) {
|
|
8846
8846
|
this.logger.warn("H265 RTP deserialize failed", {
|
|
8847
|
-
meta: { phase: "session", sessionId: this.sessionId, error:
|
|
8847
|
+
meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(err), len: rtpData.length }
|
|
8848
8848
|
});
|
|
8849
8849
|
return;
|
|
8850
8850
|
}
|
|
@@ -8858,7 +8858,7 @@ class AdaptiveSession {
|
|
|
8858
8858
|
outPkts = rep.repacketize(srcPkt);
|
|
8859
8859
|
} catch (err) {
|
|
8860
8860
|
this.logger.warn("H265 repacketize failed", {
|
|
8861
|
-
meta: { phase: "session", sessionId: this.sessionId, error:
|
|
8861
|
+
meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(err) }
|
|
8862
8862
|
});
|
|
8863
8863
|
return;
|
|
8864
8864
|
}
|
|
@@ -8873,7 +8873,7 @@ class AdaptiveSession {
|
|
|
8873
8873
|
);
|
|
8874
8874
|
} catch (e) {
|
|
8875
8875
|
this.logger.warn("replaceRTP failed (non-fatal)", {
|
|
8876
|
-
meta: { phase: "session", sessionId: this.sessionId, error:
|
|
8876
|
+
meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(e) }
|
|
8877
8877
|
});
|
|
8878
8878
|
}
|
|
8879
8879
|
}
|
|
@@ -8888,7 +8888,7 @@ class AdaptiveSession {
|
|
|
8888
8888
|
} catch (err) {
|
|
8889
8889
|
if (this.rtpPacketsSent <= 10) {
|
|
8890
8890
|
this.logger.error("sendRtp (h265 forward) error", {
|
|
8891
|
-
meta: { phase: "session", sessionId: this.sessionId, error:
|
|
8891
|
+
meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(err) }
|
|
8892
8892
|
});
|
|
8893
8893
|
}
|
|
8894
8894
|
}
|
|
@@ -9115,7 +9115,7 @@ class AdaptiveSession {
|
|
|
9115
9115
|
}
|
|
9116
9116
|
} catch (err) {
|
|
9117
9117
|
if (!signal.aborted && !this.closed) {
|
|
9118
|
-
this.logger.error("Feed error", { meta: { phase: "session", sessionId: this.sessionId, error:
|
|
9118
|
+
this.logger.error("Feed error", { meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(err) } });
|
|
9119
9119
|
}
|
|
9120
9120
|
} finally {
|
|
9121
9121
|
if (!this.closed) {
|
|
@@ -9199,7 +9199,7 @@ class AdaptiveSession {
|
|
|
9199
9199
|
}
|
|
9200
9200
|
} catch (err) {
|
|
9201
9201
|
if (!signal.aborted && !this.closed) {
|
|
9202
|
-
this.logger.error("Transcode feed error", { meta: { sessionId: this.sessionId, error:
|
|
9202
|
+
this.logger.error("Transcode feed error", { meta: { sessionId: this.sessionId, error: index.errMsg(err) } });
|
|
9203
9203
|
}
|
|
9204
9204
|
} finally {
|
|
9205
9205
|
if (!ff.stdin.destroyed) ff.stdin.end();
|
|
@@ -9242,7 +9242,7 @@ class AdaptiveSession {
|
|
|
9242
9242
|
this.videoSender.replaceRTP(header, true);
|
|
9243
9243
|
} catch (e) {
|
|
9244
9244
|
this.logger.warn("replaceRTP failed (non-fatal)", {
|
|
9245
|
-
meta: { phase: "session", sessionId: this.sessionId, error:
|
|
9245
|
+
meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(e) }
|
|
9246
9246
|
});
|
|
9247
9247
|
}
|
|
9248
9248
|
}
|
|
@@ -9273,7 +9273,7 @@ class AdaptiveSession {
|
|
|
9273
9273
|
} catch (err) {
|
|
9274
9274
|
if (this.rtpPacketsSent <= 10) {
|
|
9275
9275
|
this.logger.error("sendRtp error", {
|
|
9276
|
-
meta: { phase: "session", sessionId: this.sessionId, packetIndex: this.rtpPacketsSent, error:
|
|
9276
|
+
meta: { phase: "session", sessionId: this.sessionId, packetIndex: this.rtpPacketsSent, error: index.errMsg(err) }
|
|
9277
9277
|
});
|
|
9278
9278
|
}
|
|
9279
9279
|
}
|
|
@@ -9347,7 +9347,7 @@ class AdaptiveSession {
|
|
|
9347
9347
|
const pkt = new werift.RtpPacket(header, data);
|
|
9348
9348
|
this.audioSender.sendRtp(pkt);
|
|
9349
9349
|
} catch (err) {
|
|
9350
|
-
this.logger.debug("Audio write error", { meta: { phase: "session", sessionId: this.sessionId, error:
|
|
9350
|
+
this.logger.debug("Audio write error", { meta: { phase: "session", sessionId: this.sessionId, error: index.errMsg(err) } });
|
|
9351
9351
|
}
|
|
9352
9352
|
}
|
|
9353
9353
|
// -----------------------------------------------------------------------
|
|
@@ -9708,7 +9708,7 @@ class BrokerWebrtcServer {
|
|
|
9708
9708
|
});
|
|
9709
9709
|
} catch (err) {
|
|
9710
9710
|
sessionLogger.warn("seedH265CodecInfoFromSdp threw", {
|
|
9711
|
-
meta: { sessionId, error:
|
|
9711
|
+
meta: { sessionId, error: index.errMsg(err) }
|
|
9712
9712
|
});
|
|
9713
9713
|
}
|
|
9714
9714
|
});
|
|
@@ -9725,7 +9725,7 @@ class BrokerWebrtcServer {
|
|
|
9725
9725
|
session.forwardSourceRtpVideo(rtpData);
|
|
9726
9726
|
} catch (err) {
|
|
9727
9727
|
sessionLogger.warn("forwardSourceRtpVideo threw", {
|
|
9728
|
-
meta: { sessionId, error:
|
|
9728
|
+
meta: { sessionId, error: index.errMsg(err) }
|
|
9729
9729
|
});
|
|
9730
9730
|
}
|
|
9731
9731
|
});
|
|
@@ -9844,7 +9844,7 @@ class BrokerWebrtcServer {
|
|
|
9844
9844
|
try {
|
|
9845
9845
|
return await this.getIceServersFn();
|
|
9846
9846
|
} catch (err) {
|
|
9847
|
-
this.logger.warn("getIceServers failed", { meta: { error:
|
|
9847
|
+
this.logger.warn("getIceServers failed", { meta: { error: index.errMsg(err) } });
|
|
9848
9848
|
}
|
|
9849
9849
|
}
|
|
9850
9850
|
return this.staticIceServers ?? [];
|
|
@@ -10060,7 +10060,7 @@ function stableSnapshotKey(payload, dropKeys) {
|
|
|
10060
10060
|
return JSON.stringify(strip(payload));
|
|
10061
10061
|
}
|
|
10062
10062
|
const BROKER_METRICS_HEARTBEAT_MS = 3e4;
|
|
10063
|
-
class StreamBrokerAddon extends
|
|
10063
|
+
class StreamBrokerAddon extends index.BaseAddon {
|
|
10064
10064
|
brokerManager = null;
|
|
10065
10065
|
metricsSnapshotTimer = null;
|
|
10066
10066
|
/**
|
|
@@ -10097,7 +10097,7 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10097
10097
|
const rtspProvider = this.brokerManager.getRtspRestreamProvider();
|
|
10098
10098
|
try {
|
|
10099
10099
|
const addonStore = await this.ctx.settings?.readAddonStore() ?? {};
|
|
10100
|
-
const tokenData =
|
|
10100
|
+
const tokenData = index.asJsonObject(addonStore["rtspTokens"]);
|
|
10101
10101
|
if (tokenData) {
|
|
10102
10102
|
const tokens = /* @__PURE__ */ new Map();
|
|
10103
10103
|
for (const [k, v] of Object.entries(tokenData)) {
|
|
@@ -10106,7 +10106,7 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10106
10106
|
this.brokerManager.loadPersistedTokens(tokens);
|
|
10107
10107
|
this.ctx.logger.info("Loaded persisted RTSP tokens", { meta: { tokenCount: tokens.size } });
|
|
10108
10108
|
}
|
|
10109
|
-
const enabledData =
|
|
10109
|
+
const enabledData = index.asJsonObject(addonStore["rtspEnabled"]);
|
|
10110
10110
|
if (enabledData) {
|
|
10111
10111
|
const states = /* @__PURE__ */ new Map();
|
|
10112
10112
|
for (const [k, v] of Object.entries(enabledData)) {
|
|
@@ -10123,7 +10123,7 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10123
10123
|
obj[k] = v;
|
|
10124
10124
|
}
|
|
10125
10125
|
this.ctx.settings?.writeAddonStore({ rtspTokens: obj }).catch((err) => {
|
|
10126
|
-
this.ctx.logger.warn("Failed to persist RTSP tokens", { meta: { error:
|
|
10126
|
+
this.ctx.logger.warn("Failed to persist RTSP tokens", { meta: { error: index.errMsg(err) } });
|
|
10127
10127
|
});
|
|
10128
10128
|
});
|
|
10129
10129
|
rtspProvider.setEnabledPersister((states) => {
|
|
@@ -10132,18 +10132,18 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10132
10132
|
obj[k] = v;
|
|
10133
10133
|
}
|
|
10134
10134
|
this.ctx.settings?.writeAddonStore({ rtspEnabled: obj }).catch((err) => {
|
|
10135
|
-
this.ctx.logger.warn("Failed to persist RTSP enabled states", { meta: { error:
|
|
10135
|
+
this.ctx.logger.warn("Failed to persist RTSP enabled states", { meta: { error: index.errMsg(err) } });
|
|
10136
10136
|
});
|
|
10137
10137
|
});
|
|
10138
10138
|
try {
|
|
10139
10139
|
const addonStore = await this.ctx.settings?.readAddonStore() ?? {};
|
|
10140
|
-
const overrideData =
|
|
10140
|
+
const overrideData = index.asJsonObject(addonStore["deviceOverrides"]);
|
|
10141
10141
|
if (overrideData) {
|
|
10142
10142
|
const overrides = /* @__PURE__ */ new Map();
|
|
10143
10143
|
for (const [rawKey, raw] of Object.entries(overrideData)) {
|
|
10144
10144
|
const numericKey = Number(rawKey);
|
|
10145
10145
|
if (!Number.isFinite(numericKey) || !Number.isInteger(numericKey)) continue;
|
|
10146
|
-
const o =
|
|
10146
|
+
const o = index.asJsonObject(raw);
|
|
10147
10147
|
if (!o) continue;
|
|
10148
10148
|
const entry = {};
|
|
10149
10149
|
if (typeof o["preBufferSecOverride"] === "number") {
|
|
@@ -10152,11 +10152,11 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10152
10152
|
if (typeof o["streamingDebug"] === "boolean") {
|
|
10153
10153
|
entry["streamingDebug"] = o["streamingDebug"];
|
|
10154
10154
|
}
|
|
10155
|
-
const pbRaw =
|
|
10155
|
+
const pbRaw = index.asJsonObject(o["preBuffer"]);
|
|
10156
10156
|
if (pbRaw) {
|
|
10157
10157
|
const preBuffer = {};
|
|
10158
10158
|
for (const [profile, v] of Object.entries(pbRaw)) {
|
|
10159
|
-
const sv =
|
|
10159
|
+
const sv = index.asJsonObject(v);
|
|
10160
10160
|
if (sv && typeof sv["seconds"] === "number") {
|
|
10161
10161
|
preBuffer[profile] = { enabled: sv["enabled"] !== false, seconds: sv["seconds"] };
|
|
10162
10162
|
}
|
|
@@ -10180,20 +10180,20 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10180
10180
|
obj[`${deviceId}`] = entry;
|
|
10181
10181
|
}
|
|
10182
10182
|
this.ctx.settings?.writeAddonStore({ deviceOverrides: obj }).catch((err) => {
|
|
10183
|
-
this.ctx.logger.warn("Failed to persist device overrides", { meta: { error:
|
|
10183
|
+
this.ctx.logger.warn("Failed to persist device overrides", { meta: { error: index.errMsg(err) } });
|
|
10184
10184
|
});
|
|
10185
10185
|
});
|
|
10186
10186
|
try {
|
|
10187
10187
|
const addonStore = await this.ctx.settings?.readAddonStore() ?? {};
|
|
10188
|
-
const raw =
|
|
10188
|
+
const raw = index.asJsonObject(addonStore["profileMap"]);
|
|
10189
10189
|
if (raw) {
|
|
10190
10190
|
const loaded = /* @__PURE__ */ new Map();
|
|
10191
10191
|
for (const [rawKey, rawVal] of Object.entries(raw)) {
|
|
10192
10192
|
const deviceId = Number(rawKey);
|
|
10193
10193
|
if (!Number.isFinite(deviceId) || !Number.isInteger(deviceId)) continue;
|
|
10194
|
-
const val =
|
|
10194
|
+
const val = index.asJsonObject(rawVal);
|
|
10195
10195
|
if (!val) continue;
|
|
10196
|
-
const mapObj =
|
|
10196
|
+
const mapObj = index.asJsonObject(val["map"]) ?? {};
|
|
10197
10197
|
const map = {};
|
|
10198
10198
|
for (const profile of PROFILE_KEYS) {
|
|
10199
10199
|
const v = mapObj[profile];
|
|
@@ -10213,13 +10213,13 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10213
10213
|
obj[`${deviceId}`] = { map: { ...assignment.map }, auto: assignment.auto };
|
|
10214
10214
|
}
|
|
10215
10215
|
this.ctx.settings?.writeAddonStore({ profileMap: obj }).catch((err) => {
|
|
10216
|
-
this.ctx.logger.warn("Failed to persist profile map", { meta: { error:
|
|
10216
|
+
this.ctx.logger.warn("Failed to persist profile map", { meta: { error: index.errMsg(err) } });
|
|
10217
10217
|
});
|
|
10218
10218
|
};
|
|
10219
10219
|
this.brokerManager.setProfileMapPersister(profileMapPersister);
|
|
10220
10220
|
await this.brokerManager.startRtspServer(this.config.rtspPort);
|
|
10221
10221
|
this.subscribe(
|
|
10222
|
-
{ category:
|
|
10222
|
+
{ category: index.EventCategory.PipelineAgentHwaccelChanged },
|
|
10223
10223
|
(event) => {
|
|
10224
10224
|
const { agentNodeId, reason } = event.data;
|
|
10225
10225
|
if (typeof agentNodeId !== "string" || agentNodeId.length === 0) return;
|
|
@@ -10236,7 +10236,7 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10236
10236
|
}).catch((err) => {
|
|
10237
10237
|
this.ctx.logger.warn("hwaccel-driven decoder rotation failed", {
|
|
10238
10238
|
tags: { nodeId: agentNodeId },
|
|
10239
|
-
meta: { error:
|
|
10239
|
+
meta: { error: index.errMsg(err) }
|
|
10240
10240
|
});
|
|
10241
10241
|
});
|
|
10242
10242
|
}
|
|
@@ -10257,7 +10257,7 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10257
10257
|
}).catch((err) => {
|
|
10258
10258
|
this.ctx.logger.warn("decoder-down rotation failed", {
|
|
10259
10259
|
tags: { nodeId },
|
|
10260
|
-
meta: { error:
|
|
10260
|
+
meta: { error: index.errMsg(err) }
|
|
10261
10261
|
});
|
|
10262
10262
|
});
|
|
10263
10263
|
}
|
|
@@ -10314,20 +10314,20 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10314
10314
|
};
|
|
10315
10315
|
this.ctx.logger.info("Stream broker manager initialized");
|
|
10316
10316
|
const registrations = [
|
|
10317
|
-
{ capability:
|
|
10317
|
+
{ capability: index.streamBrokerCapability, provider: this.brokerManager },
|
|
10318
10318
|
{
|
|
10319
|
-
capability:
|
|
10319
|
+
capability: index.cameraStreamsCapability,
|
|
10320
10320
|
provider: cameraStreamsProvider,
|
|
10321
10321
|
kind: "wrapper",
|
|
10322
10322
|
defaultActive: true
|
|
10323
10323
|
},
|
|
10324
10324
|
{
|
|
10325
|
-
capability:
|
|
10325
|
+
capability: index.webrtcSessionCapability,
|
|
10326
10326
|
provider: webrtcSessionProvider,
|
|
10327
10327
|
kind: "wrapper",
|
|
10328
10328
|
defaultActive: true
|
|
10329
10329
|
},
|
|
10330
|
-
{ capability:
|
|
10330
|
+
{ capability: index.addonWidgetsSourceCapability, provider: widgetsProvider }
|
|
10331
10331
|
];
|
|
10332
10332
|
return registrations;
|
|
10333
10333
|
}
|
|
@@ -10368,8 +10368,8 @@ class StreamBrokerAddon extends types.BaseAddon {
|
|
|
10368
10368
|
const heartbeatDue = !prev || timestamp - prev.emittedAt >= BROKER_METRICS_HEARTBEAT_MS;
|
|
10369
10369
|
if (prev && prev.json === json && !heartbeatDue) continue;
|
|
10370
10370
|
this.lastEmittedBrokerSnapshot.set(brokerId, { json, emittedAt: timestamp });
|
|
10371
|
-
eventBus.emit(
|
|
10372
|
-
|
|
10371
|
+
eventBus.emit(index.createEvent(
|
|
10372
|
+
index.EventCategory.StreamBrokerMetricsSnapshot,
|
|
10373
10373
|
{ type: "device", id: deviceId, nodeId },
|
|
10374
10374
|
{ brokerId, deviceId, profile, nodeId, stats, timestamp }
|
|
10375
10375
|
));
|
|
@@ -11345,7 +11345,7 @@ class FrameServerImpl {
|
|
|
11345
11345
|
for (const h of this.connectHandlers) h(connectionId);
|
|
11346
11346
|
},
|
|
11347
11347
|
(err) => {
|
|
11348
|
-
const msg =
|
|
11348
|
+
const msg = index.errMsg(err);
|
|
11349
11349
|
this.rejectPending(connectionId, `auth-failed:${msg}`);
|
|
11350
11350
|
}
|
|
11351
11351
|
);
|