@camstack/addon-pipeline 1.2.625 → 1.2.627
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/THIRD_PARTY_MODELS.md +1 -1
- package/dist/audio-analyzer/index.js +3 -3
- package/dist/audio-analyzer/index.mjs +3 -3
- package/dist/{custom-model-catalog-CJ5aXIOD.mjs → custom-model-catalog-DtxDgB4p.mjs} +6 -6
- package/dist/{custom-model-catalog-DvR-whP_.js → custom-model-catalog-rWY1H5Ei.js} +6 -6
- package/dist/detection-pipeline/index.js +16 -16
- package/dist/detection-pipeline/index.mjs +16 -16
- package/dist/{dist-_rq_UVv6.mjs → dist-CQe330cU.mjs} +6823 -14340
- package/dist/{dist-Cpis101z.js → dist-CcZsLU96.js} +6823 -14340
- package/dist/{model-catalogs-DfoDNm1t.mjs → model-catalogs-B43s5kgs.mjs} +3 -3
- package/dist/{model-catalogs-4g6cUT_r.js → model-catalogs-BJjn54AQ.js} +3 -3
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-CJXGd0X8.js → node-Ba3e855X.js} +2 -2
- package/dist/{node-Dvv27Xny.mjs → node-XOjWaowO.mjs} +2 -2
- package/dist/pipeline-runner/index.js +20 -20
- package/dist/pipeline-runner/index.mjs +20 -20
- package/dist/{process-memory-BGbqzwKk.js → process-memory-Dw_mzdZ5.js} +1 -1
- package/dist/{process-memory-CnqFCrg1.mjs → process-memory-DyYlcpfM.mjs} +1 -1
- package/dist/recorder/index.js +26 -1816
- package/dist/recorder/index.mjs +26 -1816
- package/dist/{restream-intent-DyGmLAU9.mjs → restream-intent-DvzCnthK.mjs} +1 -1
- package/dist/{restream-intent-7uDNqMKs.js → restream-intent-DzrZ_EHP.js} +1 -1
- package/dist/{segment-demux-js-DCxqN1Pl.mjs → segment-demux-js-BVwtkI0F.mjs} +1 -1
- package/dist/{segment-demux-js-CL0PehIS.js → segment-demux-js-qzmsqDt7.js} +1 -1
- package/dist/session-decode/decode-worker-main.js +8 -8
- package/dist/session-decode/decode-worker-main.mjs +8 -8
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DJ_CX5Lw.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CJJ0Dj8s.mjs} +3 -3
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D-GlPMcf.mjs +26 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CEiM-boT.mjs +26 -0
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-tMlXFYkK.mjs → hostInit-BIx670St.mjs} +3 -3
- package/dist/stream-broker/index.js +34 -34
- package/dist/stream-broker/index.mjs +34 -34
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +7 -2
- package/python/inference_pool.py +3 -3
- package/python/postprocessors/ctc.py +1 -1
- package/python/postprocessors/plate_slots.py +2 -2
- package/python/postprocessors/test_ctc.py +1 -1
- package/python/postprocessors/test_plate_slots.py +1 -1
- package/python/postprocessors/test_ssd.py +1 -1
- package/python/postprocessors/test_yolo_split_dfl.py +3 -3
- package/python/postprocessors/test_yolo_split_dfl_numpy.py +5 -5
- package/python/postprocessors/test_yolonas.py +5 -5
- package/python/postprocessors/test_yolov9_edgetpu_concat.py +3 -3
- package/python/postprocessors/testdata/yunet_int8_outputs.json +2 -2
- package/python/postprocessors/yolo_split_dfl.py +5 -5
- package/python/postprocessors/yolonas.py +3 -3
- package/python/test_dequant_edgetpu.py +2 -2
- package/python/test_inference_pool_preprocess.py +2 -2
- package/python/webgpu_isolated.py +1 -1
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-D02gyL5r.mjs +0 -26
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-CPQe09h1.mjs +0 -26
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.2.
|
|
39
|
+
version: "1.2.416",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -45,7 +45,7 @@ async function r() {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"@camstack/sdk": {
|
|
48
|
-
version: "1.2.
|
|
48
|
+
version: "1.2.153",
|
|
49
49
|
scope: "default",
|
|
50
50
|
shareConfig: {
|
|
51
51
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.2.
|
|
84
|
+
version: "1.2.325",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
|
@@ -3,11 +3,11 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-emK7D4bc.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
7
|
-
const require_node = require("../node-
|
|
8
|
-
const require_restream_intent = require("../restream-intent-
|
|
6
|
+
const require_dist = require("../dist-CcZsLU96.js");
|
|
7
|
+
const require_node = require("../node-Ba3e855X.js");
|
|
8
|
+
const require_restream_intent = require("../restream-intent-DzrZ_EHP.js");
|
|
9
9
|
const require_remote_restream = require("../remote-restream-CO36Sr30.js");
|
|
10
|
-
const require_segment_demux_js = require("../segment-demux-js-
|
|
10
|
+
const require_segment_demux_js = require("../segment-demux-js-qzmsqDt7.js");
|
|
11
11
|
let node_os = require("node:os");
|
|
12
12
|
node_os = require_chunk.__toESM(node_os);
|
|
13
13
|
let node_crypto = require("node:crypto");
|
|
@@ -222,7 +222,7 @@ function wireBrokerFfmpeg(deps) {
|
|
|
222
222
|
* `perDevice: true` holds end to end: the session logger is built with
|
|
223
223
|
* `withTags(deviceTags)` in `broker-webrtc-server.ts`, and `ScopedLogger`
|
|
224
224
|
* merges bound tags into every line, so every one of those lines carries
|
|
225
|
-
* `tags.deviceId` as the numeric id. `| json | deviceId="
|
|
225
|
+
* `tags.deviceId` as the numeric id. `| json | deviceId="102"` works.
|
|
226
226
|
*
|
|
227
227
|
* Read at session CREATION, so it takes effect on the next session rather than
|
|
228
228
|
* mid-call — the same property the per-camera `webrtcDebug` switch has always
|
|
@@ -242,7 +242,7 @@ var CH_WEBRTC = require_dist.declareLogChannel({
|
|
|
242
242
|
*
|
|
243
243
|
* `perDevice: FALSE`, and this is not an oversight — it is the corollary the
|
|
244
244
|
* plan insists be made explicit. These lines put the device in `meta`, not in
|
|
245
|
-
* `tags`, so `| json | deviceId="
|
|
245
|
+
* `tags`, so `| json | deviceId="102"` does not select them. Declaring this
|
|
246
246
|
* channel per-camera would be a lie the UI repeats: an operator would narrow
|
|
247
247
|
* to one camera, see nothing, and conclude the code path was never taken.
|
|
248
248
|
*
|
|
@@ -682,7 +682,7 @@ function mergeViewerCounts(parts) {
|
|
|
682
682
|
*
|
|
683
683
|
* Every log line about a device carries `tags: { deviceId }`, always the same
|
|
684
684
|
* key and always the numeric id: a miss rate, a media gap or a routing fault is
|
|
685
|
-
* always asked per-camera ("why is
|
|
685
|
+
* always asked per-camera ("why is 102 worse than 101?"), and a line that omits
|
|
686
686
|
* the tag cannot answer it.
|
|
687
687
|
*/
|
|
688
688
|
function deviceIdFromBrokerId$1(brokerId) {
|
|
@@ -835,7 +835,7 @@ async function waitForSourceMedia(input) {
|
|
|
835
835
|
*
|
|
836
836
|
* Measured on this hub 2026-09-13: every Alexa session on the baby monitor
|
|
837
837
|
* produced a `stream.online` and a `stream.offline` pair against
|
|
838
|
-
* `
|
|
838
|
+
* `106/egress:8e96e97a…`, and the operator read them as the battery camera
|
|
839
839
|
* flapping during its wake. Nothing was flapping — that is just what an egress
|
|
840
840
|
* pipe does, once per session, by design.
|
|
841
841
|
*
|
|
@@ -1016,7 +1016,7 @@ function nextEnabledSignals(input) {
|
|
|
1016
1016
|
* The HOLD a camera's own signal buys, and what it may not buy.
|
|
1017
1017
|
*
|
|
1018
1018
|
* A stream a consumer merely watches is not a reason to wake a battery camera —
|
|
1019
|
-
* a
|
|
1019
|
+
* a continuous-pull client holds a session open for ever, and treating that as
|
|
1020
1020
|
* demand keeps the camera awake for ever, which is the whole point of the
|
|
1021
1021
|
* battery (D173). So a sentry consumer is FED without being INTENT, and the
|
|
1022
1022
|
* only thing that dials is a signal the camera reported about itself.
|
|
@@ -2068,7 +2068,7 @@ var DerivedStreamFeeder = class extends FfmpegPushReader {
|
|
|
2068
2068
|
*
|
|
2069
2069
|
* Every camera in this fleet speaks G.711 (PCMU/PCMA), so the copy could never
|
|
2070
2070
|
* work for any of them: no `derived:*` stream has EVER carried audio, and
|
|
2071
|
-
* camera
|
|
2071
|
+
* camera 108 — whose `low` (motion, and therefore audio) profile is mapped to
|
|
2072
2072
|
* a derived stream — went silent the day it was remapped.
|
|
2073
2073
|
*
|
|
2074
2074
|
* So the carrier decides, explicitly and loudly, not the profile: source audio
|
|
@@ -2224,7 +2224,7 @@ function derivedBitrateCeilingKbps(video) {
|
|
|
2224
2224
|
* whose default rate control is `cap`), because a derived tier is RECORDED
|
|
2225
2225
|
* and the scrub reads a `low` segment whole only while it is under 1.5 MB
|
|
2226
2226
|
* (D163). Uncapped CRF has no relationship to that ceiling: 1438/low
|
|
2227
|
-
* measured 537–941 kbps at 640x360@25 against 142 kbps for camera
|
|
2227
|
+
* measured 537–941 kbps at 640x360@25 against 142 kbps for camera 101's
|
|
2228
2228
|
* NATIVE low at the identical geometry, peaking at 1.19 MB in a 10 s
|
|
2229
2229
|
* segment. Quiet scenes still spend less than the cap.
|
|
2230
2230
|
*/
|
|
@@ -2363,7 +2363,7 @@ function rankInitialAssignment(streams) {
|
|
|
2363
2363
|
*
|
|
2364
2364
|
* So the key is retired EXPLICITLY: read once, converted into the
|
|
2365
2365
|
* configuration that now carries its meaning, and cleared. An operator who had
|
|
2366
|
-
* typed "3 s of history on
|
|
2366
|
+
* typed "3 s of history on 102's substream" keeps 3 s of history on 102's
|
|
2367
2367
|
* substream; they do not silently get the cluster default, and they do not
|
|
2368
2368
|
* silently get nothing.
|
|
2369
2369
|
*/
|
|
@@ -4508,7 +4508,7 @@ var RtspRestreamer = class {
|
|
|
4508
4508
|
/**
|
|
4509
4509
|
* Sessions that count as LIVE INTENT — everything except a sentry dial.
|
|
4510
4510
|
*
|
|
4511
|
-
* The split exists so a
|
|
4511
|
+
* The split exists so a continuous-pull client can hold a session open for ever
|
|
4512
4512
|
* against a battery camera without keeping it awake (D173). For a broker with
|
|
4513
4513
|
* no sentry session this equals {@link getSessionCount} exactly, which is
|
|
4514
4514
|
* why nothing else changed behaviour.
|
|
@@ -4643,7 +4643,7 @@ var RtspRestreamer = class {
|
|
|
4643
4643
|
* {@link PRIME_MAX_PACKETS}) and PACED (see {@link PacedRtpReplay}). Both
|
|
4644
4644
|
* were absent: this replayed the entire retained ring in one synchronous
|
|
4645
4645
|
* nested loop, measured at 9.9 Mbps instantaneous against a 485 kbps steady
|
|
4646
|
-
* stream (20×) on
|
|
4646
|
+
* stream (20×) on 101/mid and 40.7 Mbps on 101/high, with a population p99 of
|
|
4647
4647
|
* 28.3 s of history and a same-day max of 61.5 s / 17065 packets.
|
|
4648
4648
|
*/
|
|
4649
4649
|
servePendingSessionsRtp() {
|
|
@@ -6332,7 +6332,7 @@ function buildAudioCodecCapApi(api) {
|
|
|
6332
6332
|
*
|
|
6333
6333
|
* ## What this exists to stop
|
|
6334
6334
|
*
|
|
6335
|
-
* 2026-08-25, device 3629 ("
|
|
6335
|
+
* 2026-08-25, device 3629 ("Camera porta retro", Reolink). Its Baichuan
|
|
6336
6336
|
* session expired under a socket that stayed open, so every
|
|
6337
6337
|
* `stream-catalog.getCatalog` answered `buildVideoStreamOptions failed …
|
|
6338
6338
|
* responseCode 400`. The reconcile poll asked again 30 s later. And again. For
|
|
@@ -6519,7 +6519,7 @@ function decideAudioPlaneAction(observation, state, nowMs) {
|
|
|
6519
6519
|
* for the verdict: it exists to avoid a per-session cross-process
|
|
6520
6520
|
* `decoder.getInfo`, so it expires on a **read** cadence, and one minute later
|
|
6521
6521
|
* the decoder answers `vaapi` again and the next cold child re-pays the death.
|
|
6522
|
-
* Measured on camera
|
|
6522
|
+
* Measured on camera 101 on 2026-08-07: the hardware failure recurs at 22:17:07,
|
|
6523
6523
|
* 22:18:42, 22:28:48, 22:30:52, 22:32:39, 22:34:07, 22:52:07 — once per memo
|
|
6524
6524
|
* window, forever, on a hub where it has never once succeeded.
|
|
6525
6525
|
*
|
|
@@ -9077,7 +9077,7 @@ var RENDER_TIMEOUT_MS = 2e4;
|
|
|
9077
9077
|
* real time, or an H.265 source). At real time the width must stay the source's
|
|
9078
9078
|
* own, because an identity scale is precisely what `clipCanCopy` looks for.
|
|
9079
9079
|
*
|
|
9080
|
-
* Measured on a real
|
|
9080
|
+
* Measured on a real 101 720p window, `-preset veryfast`: crf 23 at 1280 is
|
|
9081
9081
|
* 254 KB and 0.23 s of encode, against the 922 KB the copy of the same window
|
|
9082
9082
|
* carried. Capping wider renditions here costs nothing an operator can see on a
|
|
9083
9083
|
* phone and keeps the burst bounded on a hub that is already busy.
|
|
@@ -9116,7 +9116,7 @@ function eventClipEncodeWidth(sourceWidth, speed) {
|
|
|
9116
9116
|
* - **A GIF is a re-encode by definition.**
|
|
9117
9117
|
*
|
|
9118
9118
|
* Copying is what makes a notification clip the camera's own 1280×720 picture
|
|
9119
|
-
* rather than `libx264 -crf 28` at 480 px — measured on
|
|
9119
|
+
* rather than `libx264 -crf 28` at 480 px — measured on 101, the same eleven
|
|
9120
9120
|
* seconds are 224 KB copied against a visibly softer re-encode, and the gif
|
|
9121
9121
|
* derived from it stops looking pixellated for the same reason.
|
|
9122
9122
|
*/
|
|
@@ -13317,7 +13317,7 @@ var SentryPump = class {
|
|
|
13317
13317
|
* A lightweight TCP server that broadcasts raw encoded video bytes
|
|
13318
13318
|
* (H.264/H.265 Annex-B) to all connected clients.
|
|
13319
13319
|
*
|
|
13320
|
-
* Each StreamBroker owns one StreamPipeServer. Restreamers (e.g.
|
|
13320
|
+
* Each StreamBroker owns one StreamPipeServer. Restreamers (e.g. restreamer)
|
|
13321
13321
|
* connect via `tcp://127.0.0.1:{port}` and receive the same byte stream
|
|
13322
13322
|
* that the broker reads from the camera, eliminating duplicate RTSP
|
|
13323
13323
|
* connections.
|
|
@@ -13457,9 +13457,9 @@ var DROP_REPORT_INTERVAL_MS = 3e4;
|
|
|
13457
13457
|
var StreamBroker = class StreamBroker {
|
|
13458
13458
|
deviceId;
|
|
13459
13459
|
/**
|
|
13460
|
-
* Numeric device id parsed once from `deviceId` (`
|
|
13461
|
-
* `tags.deviceId`. Every log line about a device carries it: "why is
|
|
13462
|
-
* worse than
|
|
13460
|
+
* Numeric device id parsed once from `deviceId` (`101/native` → 101), for
|
|
13461
|
+
* `tags.deviceId`. Every log line about a device carries it: "why is 102
|
|
13462
|
+
* worse than 101?" is the question every media-gap investigation starts from,
|
|
13463
13463
|
* and a line without the tag cannot be grouped to answer it.
|
|
13464
13464
|
*/
|
|
13465
13465
|
numericDeviceId;
|
|
@@ -13608,7 +13608,7 @@ var StreamBroker = class StreamBroker {
|
|
|
13608
13608
|
* which ANY caller may dial the source again. Armed on every dial ATTEMPT
|
|
13609
13609
|
* with the current backoff window. The 30s reconnect timer was honored on
|
|
13610
13610
|
* ITS path, but parallel dial channels (demand resume, broker recreation)
|
|
13611
|
-
* re-dialed instantly — an unreachable camera (
|
|
13611
|
+
* re-dialed instantly — an unreachable camera (105 EHOSTUNREACH) looped
|
|
13612
13612
|
* hundreds of dials/sec, the relayed log flood ballooned hub-main to
|
|
13613
13613
|
* 1.9 GB in 4 h and starved the HTTPS API. This gate makes the backoff a
|
|
13614
13614
|
* BROKER-level invariant instead of a per-path courtesy.
|
|
@@ -13837,7 +13837,7 @@ var StreamBroker = class StreamBroker {
|
|
|
13837
13837
|
* The open prebuffer hold, or `null` when the prebuffer is off.
|
|
13838
13838
|
*
|
|
13839
13839
|
* A real object rather than a flag plus a synthetic row, so "who is keeping
|
|
13840
|
-
* camera
|
|
13840
|
+
* camera 102 warm?" is answered by something that EXISTS: it has an id, it
|
|
13841
13841
|
* has a start time, and `hasDemand()` consults it the way it consults every
|
|
13842
13842
|
* other holder.
|
|
13843
13843
|
*/
|
|
@@ -13870,7 +13870,7 @@ var StreamBroker = class StreamBroker {
|
|
|
13870
13870
|
* that socket down. In that window `resolveCurrentSource()` truthfully
|
|
13871
13871
|
* answers with a socket nobody can dial.
|
|
13872
13872
|
*
|
|
13873
|
-
* That cost device
|
|
13873
|
+
* That cost device 106 its sentry on 2026-09-16: the window re-opened
|
|
13874
13874
|
* (which `suspend()` does deliberately, for a consumer that never left) with
|
|
13875
13875
|
* the real url, `planPrestream` refused it `not-lazy`, and the refusal is
|
|
13876
13876
|
* terminal — the operator's client sat dark for ten seconds and gave up six
|
|
@@ -14240,7 +14240,7 @@ var StreamBroker = class StreamBroker {
|
|
|
14240
14240
|
* streaming (`if (!this.reconnectTimer) return`). This is for the opposite
|
|
14241
14241
|
* situation: the connection is fine and its CONTENT is wrong.
|
|
14242
14242
|
*
|
|
14243
|
-
* That is not hypothetical. Measured live on Hikvision
|
|
14243
|
+
* That is not hypothetical. Measured live on Hikvision 104 (2026-08-07):
|
|
14244
14244
|
* muting the camera's microphone restarts its encoder, the RTSP connection
|
|
14245
14245
|
* drops, and the broker reconnects — *while the mute is still being applied
|
|
14246
14246
|
* channel by channel*. It negotiates a video-only SDP, the camera comes back
|
|
@@ -15346,7 +15346,7 @@ var StreamBroker = class StreamBroker {
|
|
|
15346
15346
|
* How far back the ring is kept — the prebuffer, and nothing else.
|
|
15347
15347
|
*
|
|
15348
15348
|
* It used to be `max(detectionPreRollMs, recordingPreRollMs)`: a maximum over
|
|
15349
|
-
* CONFIGURATIONS, which is what made "how much history does camera
|
|
15349
|
+
* CONFIGURATIONS, which is what made "how much history does camera 102 hold"
|
|
15350
15350
|
* a question with two answers and no owner. There is one configuration now,
|
|
15351
15351
|
* so the retention is it.
|
|
15352
15352
|
*/
|
|
@@ -18033,7 +18033,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
18033
18033
|
* memo above on purpose: the memo answers "what should decode this" on a read
|
|
18034
18034
|
* cadence and expires in a minute, so folding the failure into it meant the
|
|
18035
18035
|
* next cold child one minute later re-paid the same ~3 s death — measured
|
|
18036
|
-
* seven times on
|
|
18036
|
+
* seven times on 101 between 22:17 and 22:52 on 2026-08-07. See
|
|
18037
18037
|
* `dead-decode-backends.ts`.
|
|
18038
18038
|
*/
|
|
18039
18039
|
deadDecodeBackends = createDeadDecodeBackends();
|
|
@@ -18606,7 +18606,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
18606
18606
|
* refreshing it: a battery camera refuses a capture while it believes
|
|
18607
18607
|
* itself asleep, and that belief lags the wake by seconds — so the only
|
|
18608
18608
|
* attempts ever made were the sentry's own, while composing, which is
|
|
18609
|
-
* BEFORE any media exists. Measured on device
|
|
18609
|
+
* BEFORE any media exists. Measured on device 106 (2026-09-16): four
|
|
18610
18610
|
* wakes in forty minutes, the encoded picture `bytes=23912` every time,
|
|
18611
18611
|
* and between first packet and suspend not one capture was even
|
|
18612
18612
|
* attempted. The operator read the result as a placeholder rather than
|
|
@@ -19421,7 +19421,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
19421
19421
|
* A restart drops the RTSP connection and the broker reconnects on its own —
|
|
19422
19422
|
* but the reconnect lands INSIDE the restart window, so it negotiates
|
|
19423
19423
|
* whatever transient SDP the camera is offering mid-change. Measured on
|
|
19424
|
-
* Hikvision
|
|
19424
|
+
* Hikvision 104 (2026-08-07): a microphone mute/unmute left all three
|
|
19425
19425
|
* brokers holding video-only sessions against a camera that had its audio
|
|
19426
19426
|
* mux back, and because those sessions were healthy nothing ever re-dialed.
|
|
19427
19427
|
* The hub was deaf on that camera until the device was disabled long enough
|
|
@@ -22224,7 +22224,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
22224
22224
|
* assignment). When the device's assignment is operator-locked
|
|
22225
22225
|
* (`auto === false`) occupied slots stay put (a derived on `low` must
|
|
22226
22226
|
* not be kicked off). Empty slots refill from unused natives when the
|
|
22227
|
-
* device has a derived stream (
|
|
22227
|
+
* device has a derived stream (108 / 1438) or the whole map is empty —
|
|
22228
22228
|
* a camera without deriveds still honours an operator unassign.
|
|
22229
22229
|
*/
|
|
22230
22230
|
async reconcileAutoAssignment(deviceId, reason, streamAdded = false) {
|
|
@@ -22987,7 +22987,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
22987
22987
|
* Only ever an input to "can this track be COPIED into the derived MPEG-TS".
|
|
22988
22988
|
* `null` resolves to the AAC re-encode, so every failure of this read lands
|
|
22989
22989
|
* on the branch that still produces audible audio — the read can never mute
|
|
22990
|
-
* a camera, which is the direction that cost
|
|
22990
|
+
* a camera, which is the direction that cost 108 four silent days.
|
|
22991
22991
|
*/
|
|
22992
22992
|
observedSourceAudioCodec(deviceId, source) {
|
|
22993
22993
|
const camStreamId = source.kind === "camStream" ? source.camStreamId : this.assignments.get(deviceId)?.map[source.profile] ?? null;
|
|
@@ -26784,7 +26784,7 @@ var AdaptiveSession = class AdaptiveSession {
|
|
|
26784
26784
|
* `needsTranscode` is final the moment the answer's codec is known — the
|
|
26785
26785
|
* "Codec negotiated" line already prints it — but the acquire used to happen
|
|
26786
26786
|
* inside `startFeedingFrames`, which runs only after the DTLS wait. On camera
|
|
26787
|
-
*
|
|
26787
|
+
* 101 that put the leg ~2 s after session creation and the first packet ~5 s
|
|
26788
26788
|
* after that, against a browser watchdog that re-offers every ~5 s: the viewer
|
|
26789
26789
|
* was always gone before the media existed, and the next session paid for a
|
|
26790
26790
|
* cold child again. Three minutes of that on 2026-08-07 22:17–22:20.
|
|
@@ -32046,7 +32046,7 @@ var RecordedFeeder = class {
|
|
|
32046
32046
|
* the loop slept, the cursor never moved off the seek target, and the only
|
|
32047
32047
|
* evidence was a `recorded:play-census` line with `pacedAus=150 segments=1`.
|
|
32048
32048
|
* A branch that silently drops work logs (repo rule) — and the log carries
|
|
32049
|
-
* `deviceId` through `onLog`'s tags, because "why is 4374 worse than
|
|
32049
|
+
* `deviceId` through `onLog`'s tags, because "why is 4374 worse than 101" is
|
|
32050
32050
|
* the only way this question is ever asked.
|
|
32051
32051
|
*
|
|
32052
32052
|
* Logged once per segment start per feeder: a broken camera should name every
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as __toESM } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { Bn as isSoftwareDecode, Cr as record, D as G711_SCALE_CORRECTION_DB, Er as EventCategory, Et as egressTransportFromRequest, Gn as BaseAddon, Hn as DeviceType, Jt as memoizePinnedFfmpeg, K as RingBuffer, Kn as CAM_PROFILE_ORDER, L as RATE_CONTROL_RELAXED, Ln as buildFfmpegArgs, Lt as gifDeriveSpeed, Nn as webrtcSessionCapability, Pn as AUDIO_PRESETS, Pt as ffmpegRate, R as RATE_CONTROL_TIGHT, Rt as gifFromMp4Args, St as deviceRemovalHookCapability, Tr as union, Tt as egressTranscodeSharingKey, Un as errMsg, Ut as loadContributionCapability, Vn as DeviceFeature, Wn as BOOT_RECOVERY_BACKOFF_MS, Wt as logChannelsCapability, X as addonWidgetsSourceCapability, Zn as createEvent, _r as discriminatedUnion, _t as deriveBatteryPresence, ar as isSecretMarker, br as number, c as CLIP_STILL_REASON_CODE_HEADER, cr as maskUrlCredentials, et as armRemovalReconcile, gn as resolveEgressDecodeHwAccel, gr as boolean, hr as array, ht as declareLogChannel, ir as isEvent, it as batteryCapability, kn as streamBrokerCapability, lr as nodePin, lt as clipExportFailureOf, mr as _enum, mt as createLogChannelsProvider, o as BatteryStatusSchema, or as makeProfileBrokerId, pt as createHwAccelCache, qn as CamProfileSchema, s as CLIP_BROKER_PACED_RATES, sn as rankStreams, sr as makeSourceBrokerId, st as cameraStreamsCapability, tr as expandAudioChunkToF32le, ur as parseProfileBrokerId, w as EncodeProfileSchema, wr as string, xr as object, yr as literal, zn as invocationFromEncodeProfile } from "../dist-
|
|
3
|
-
import { a as defaultFfmpegSpawn, i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, s as probeFfmpegBinary, t as ChildCostRegistry } from "../node-
|
|
4
|
-
import { a as parseRestreamPath, d as PREBUFFER_MAX_MS, f as capPreRollRequestMs, i as isLiveEdgeOnlyDial, m as resolvePrebuffer, n as NO_DECLARATION, p as prebufferRetentionMs, s as sdpVariantFor, u as withSentryIntent } from "../restream-intent-
|
|
2
|
+
import { Bn as isSoftwareDecode, Cr as record, D as G711_SCALE_CORRECTION_DB, Er as EventCategory, Et as egressTransportFromRequest, Gn as BaseAddon, Hn as DeviceType, Jt as memoizePinnedFfmpeg, K as RingBuffer, Kn as CAM_PROFILE_ORDER, L as RATE_CONTROL_RELAXED, Ln as buildFfmpegArgs, Lt as gifDeriveSpeed, Nn as webrtcSessionCapability, Pn as AUDIO_PRESETS, Pt as ffmpegRate, R as RATE_CONTROL_TIGHT, Rt as gifFromMp4Args, St as deviceRemovalHookCapability, Tr as union, Tt as egressTranscodeSharingKey, Un as errMsg, Ut as loadContributionCapability, Vn as DeviceFeature, Wn as BOOT_RECOVERY_BACKOFF_MS, Wt as logChannelsCapability, X as addonWidgetsSourceCapability, Zn as createEvent, _r as discriminatedUnion, _t as deriveBatteryPresence, ar as isSecretMarker, br as number, c as CLIP_STILL_REASON_CODE_HEADER, cr as maskUrlCredentials, et as armRemovalReconcile, gn as resolveEgressDecodeHwAccel, gr as boolean, hr as array, ht as declareLogChannel, ir as isEvent, it as batteryCapability, kn as streamBrokerCapability, lr as nodePin, lt as clipExportFailureOf, mr as _enum, mt as createLogChannelsProvider, o as BatteryStatusSchema, or as makeProfileBrokerId, pt as createHwAccelCache, qn as CamProfileSchema, s as CLIP_BROKER_PACED_RATES, sn as rankStreams, sr as makeSourceBrokerId, st as cameraStreamsCapability, tr as expandAudioChunkToF32le, ur as parseProfileBrokerId, w as EncodeProfileSchema, wr as string, xr as object, yr as literal, zn as invocationFromEncodeProfile } from "../dist-CQe330cU.mjs";
|
|
3
|
+
import { a as defaultFfmpegSpawn, i as NO_COST_CLAIM, n as Fmp4FragmentChild, r as Fmp4FragmentPlane, s as probeFfmpegBinary, t as ChildCostRegistry } from "../node-XOjWaowO.mjs";
|
|
4
|
+
import { a as parseRestreamPath, d as PREBUFFER_MAX_MS, f as capPreRollRequestMs, i as isLiveEdgeOnlyDial, m as resolvePrebuffer, n as NO_DECLARATION, p as prebufferRetentionMs, s as sdpVariantFor, u as withSentryIntent } from "../restream-intent-DvzCnthK.mjs";
|
|
5
5
|
import { n as profileForStreamId } from "../remote-restream-BeHi78PZ.mjs";
|
|
6
|
-
import { a as require_mp4box_all, c as parseNalLengthSize, i as runFfmpegOnce, n as demuxSegmentPreferJs, o as avccSampleToAnnexB, r as FfmpegFallbackRefusedError, s as buildKeyframeAnnexB, t as demuxSegmentFullJs } from "../segment-demux-js-
|
|
6
|
+
import { a as require_mp4box_all, c as parseNalLengthSize, i as runFfmpegOnce, n as demuxSegmentPreferJs, o as avccSampleToAnnexB, r as FfmpegFallbackRefusedError, s as buildKeyframeAnnexB, t as demuxSegmentFullJs } from "../segment-demux-js-BVwtkI0F.mjs";
|
|
7
7
|
import { createRequire } from "node:module";
|
|
8
8
|
import * as os$1 from "node:os";
|
|
9
9
|
import { networkInterfaces, tmpdir } from "node:os";
|
|
@@ -218,7 +218,7 @@ function wireBrokerFfmpeg(deps) {
|
|
|
218
218
|
* `perDevice: true` holds end to end: the session logger is built with
|
|
219
219
|
* `withTags(deviceTags)` in `broker-webrtc-server.ts`, and `ScopedLogger`
|
|
220
220
|
* merges bound tags into every line, so every one of those lines carries
|
|
221
|
-
* `tags.deviceId` as the numeric id. `| json | deviceId="
|
|
221
|
+
* `tags.deviceId` as the numeric id. `| json | deviceId="102"` works.
|
|
222
222
|
*
|
|
223
223
|
* Read at session CREATION, so it takes effect on the next session rather than
|
|
224
224
|
* mid-call — the same property the per-camera `webrtcDebug` switch has always
|
|
@@ -238,7 +238,7 @@ var CH_WEBRTC = declareLogChannel({
|
|
|
238
238
|
*
|
|
239
239
|
* `perDevice: FALSE`, and this is not an oversight — it is the corollary the
|
|
240
240
|
* plan insists be made explicit. These lines put the device in `meta`, not in
|
|
241
|
-
* `tags`, so `| json | deviceId="
|
|
241
|
+
* `tags`, so `| json | deviceId="102"` does not select them. Declaring this
|
|
242
242
|
* channel per-camera would be a lie the UI repeats: an operator would narrow
|
|
243
243
|
* to one camera, see nothing, and conclude the code path was never taken.
|
|
244
244
|
*
|
|
@@ -678,7 +678,7 @@ function mergeViewerCounts(parts) {
|
|
|
678
678
|
*
|
|
679
679
|
* Every log line about a device carries `tags: { deviceId }`, always the same
|
|
680
680
|
* key and always the numeric id: a miss rate, a media gap or a routing fault is
|
|
681
|
-
* always asked per-camera ("why is
|
|
681
|
+
* always asked per-camera ("why is 102 worse than 101?"), and a line that omits
|
|
682
682
|
* the tag cannot answer it.
|
|
683
683
|
*/
|
|
684
684
|
function deviceIdFromBrokerId$1(brokerId) {
|
|
@@ -831,7 +831,7 @@ async function waitForSourceMedia(input) {
|
|
|
831
831
|
*
|
|
832
832
|
* Measured on this hub 2026-09-13: every Alexa session on the baby monitor
|
|
833
833
|
* produced a `stream.online` and a `stream.offline` pair against
|
|
834
|
-
* `
|
|
834
|
+
* `106/egress:8e96e97a…`, and the operator read them as the battery camera
|
|
835
835
|
* flapping during its wake. Nothing was flapping — that is just what an egress
|
|
836
836
|
* pipe does, once per session, by design.
|
|
837
837
|
*
|
|
@@ -1012,7 +1012,7 @@ function nextEnabledSignals(input) {
|
|
|
1012
1012
|
* The HOLD a camera's own signal buys, and what it may not buy.
|
|
1013
1013
|
*
|
|
1014
1014
|
* A stream a consumer merely watches is not a reason to wake a battery camera —
|
|
1015
|
-
* a
|
|
1015
|
+
* a continuous-pull client holds a session open for ever, and treating that as
|
|
1016
1016
|
* demand keeps the camera awake for ever, which is the whole point of the
|
|
1017
1017
|
* battery (D173). So a sentry consumer is FED without being INTENT, and the
|
|
1018
1018
|
* only thing that dials is a signal the camera reported about itself.
|
|
@@ -2064,7 +2064,7 @@ var DerivedStreamFeeder = class extends FfmpegPushReader {
|
|
|
2064
2064
|
*
|
|
2065
2065
|
* Every camera in this fleet speaks G.711 (PCMU/PCMA), so the copy could never
|
|
2066
2066
|
* work for any of them: no `derived:*` stream has EVER carried audio, and
|
|
2067
|
-
* camera
|
|
2067
|
+
* camera 108 — whose `low` (motion, and therefore audio) profile is mapped to
|
|
2068
2068
|
* a derived stream — went silent the day it was remapped.
|
|
2069
2069
|
*
|
|
2070
2070
|
* So the carrier decides, explicitly and loudly, not the profile: source audio
|
|
@@ -2220,7 +2220,7 @@ function derivedBitrateCeilingKbps(video) {
|
|
|
2220
2220
|
* whose default rate control is `cap`), because a derived tier is RECORDED
|
|
2221
2221
|
* and the scrub reads a `low` segment whole only while it is under 1.5 MB
|
|
2222
2222
|
* (D163). Uncapped CRF has no relationship to that ceiling: 1438/low
|
|
2223
|
-
* measured 537–941 kbps at 640x360@25 against 142 kbps for camera
|
|
2223
|
+
* measured 537–941 kbps at 640x360@25 against 142 kbps for camera 101's
|
|
2224
2224
|
* NATIVE low at the identical geometry, peaking at 1.19 MB in a 10 s
|
|
2225
2225
|
* segment. Quiet scenes still spend less than the cap.
|
|
2226
2226
|
*/
|
|
@@ -2359,7 +2359,7 @@ function rankInitialAssignment(streams) {
|
|
|
2359
2359
|
*
|
|
2360
2360
|
* So the key is retired EXPLICITLY: read once, converted into the
|
|
2361
2361
|
* configuration that now carries its meaning, and cleared. An operator who had
|
|
2362
|
-
* typed "3 s of history on
|
|
2362
|
+
* typed "3 s of history on 102's substream" keeps 3 s of history on 102's
|
|
2363
2363
|
* substream; they do not silently get the cluster default, and they do not
|
|
2364
2364
|
* silently get nothing.
|
|
2365
2365
|
*/
|
|
@@ -4504,7 +4504,7 @@ var RtspRestreamer = class {
|
|
|
4504
4504
|
/**
|
|
4505
4505
|
* Sessions that count as LIVE INTENT — everything except a sentry dial.
|
|
4506
4506
|
*
|
|
4507
|
-
* The split exists so a
|
|
4507
|
+
* The split exists so a continuous-pull client can hold a session open for ever
|
|
4508
4508
|
* against a battery camera without keeping it awake (D173). For a broker with
|
|
4509
4509
|
* no sentry session this equals {@link getSessionCount} exactly, which is
|
|
4510
4510
|
* why nothing else changed behaviour.
|
|
@@ -4639,7 +4639,7 @@ var RtspRestreamer = class {
|
|
|
4639
4639
|
* {@link PRIME_MAX_PACKETS}) and PACED (see {@link PacedRtpReplay}). Both
|
|
4640
4640
|
* were absent: this replayed the entire retained ring in one synchronous
|
|
4641
4641
|
* nested loop, measured at 9.9 Mbps instantaneous against a 485 kbps steady
|
|
4642
|
-
* stream (20×) on
|
|
4642
|
+
* stream (20×) on 101/mid and 40.7 Mbps on 101/high, with a population p99 of
|
|
4643
4643
|
* 28.3 s of history and a same-day max of 61.5 s / 17065 packets.
|
|
4644
4644
|
*/
|
|
4645
4645
|
servePendingSessionsRtp() {
|
|
@@ -6328,7 +6328,7 @@ function buildAudioCodecCapApi(api) {
|
|
|
6328
6328
|
*
|
|
6329
6329
|
* ## What this exists to stop
|
|
6330
6330
|
*
|
|
6331
|
-
* 2026-08-25, device 3629 ("
|
|
6331
|
+
* 2026-08-25, device 3629 ("Camera porta retro", Reolink). Its Baichuan
|
|
6332
6332
|
* session expired under a socket that stayed open, so every
|
|
6333
6333
|
* `stream-catalog.getCatalog` answered `buildVideoStreamOptions failed …
|
|
6334
6334
|
* responseCode 400`. The reconcile poll asked again 30 s later. And again. For
|
|
@@ -6515,7 +6515,7 @@ function decideAudioPlaneAction(observation, state, nowMs) {
|
|
|
6515
6515
|
* for the verdict: it exists to avoid a per-session cross-process
|
|
6516
6516
|
* `decoder.getInfo`, so it expires on a **read** cadence, and one minute later
|
|
6517
6517
|
* the decoder answers `vaapi` again and the next cold child re-pays the death.
|
|
6518
|
-
* Measured on camera
|
|
6518
|
+
* Measured on camera 101 on 2026-08-07: the hardware failure recurs at 22:17:07,
|
|
6519
6519
|
* 22:18:42, 22:28:48, 22:30:52, 22:32:39, 22:34:07, 22:52:07 — once per memo
|
|
6520
6520
|
* window, forever, on a hub where it has never once succeeded.
|
|
6521
6521
|
*
|
|
@@ -9073,7 +9073,7 @@ var RENDER_TIMEOUT_MS = 2e4;
|
|
|
9073
9073
|
* real time, or an H.265 source). At real time the width must stay the source's
|
|
9074
9074
|
* own, because an identity scale is precisely what `clipCanCopy` looks for.
|
|
9075
9075
|
*
|
|
9076
|
-
* Measured on a real
|
|
9076
|
+
* Measured on a real 101 720p window, `-preset veryfast`: crf 23 at 1280 is
|
|
9077
9077
|
* 254 KB and 0.23 s of encode, against the 922 KB the copy of the same window
|
|
9078
9078
|
* carried. Capping wider renditions here costs nothing an operator can see on a
|
|
9079
9079
|
* phone and keeps the burst bounded on a hub that is already busy.
|
|
@@ -9112,7 +9112,7 @@ function eventClipEncodeWidth(sourceWidth, speed) {
|
|
|
9112
9112
|
* - **A GIF is a re-encode by definition.**
|
|
9113
9113
|
*
|
|
9114
9114
|
* Copying is what makes a notification clip the camera's own 1280×720 picture
|
|
9115
|
-
* rather than `libx264 -crf 28` at 480 px — measured on
|
|
9115
|
+
* rather than `libx264 -crf 28` at 480 px — measured on 101, the same eleven
|
|
9116
9116
|
* seconds are 224 KB copied against a visibly softer re-encode, and the gif
|
|
9117
9117
|
* derived from it stops looking pixellated for the same reason.
|
|
9118
9118
|
*/
|
|
@@ -13313,7 +13313,7 @@ var SentryPump = class {
|
|
|
13313
13313
|
* A lightweight TCP server that broadcasts raw encoded video bytes
|
|
13314
13314
|
* (H.264/H.265 Annex-B) to all connected clients.
|
|
13315
13315
|
*
|
|
13316
|
-
* Each StreamBroker owns one StreamPipeServer. Restreamers (e.g.
|
|
13316
|
+
* Each StreamBroker owns one StreamPipeServer. Restreamers (e.g. restreamer)
|
|
13317
13317
|
* connect via `tcp://127.0.0.1:{port}` and receive the same byte stream
|
|
13318
13318
|
* that the broker reads from the camera, eliminating duplicate RTSP
|
|
13319
13319
|
* connections.
|
|
@@ -13453,9 +13453,9 @@ var DROP_REPORT_INTERVAL_MS = 3e4;
|
|
|
13453
13453
|
var StreamBroker = class StreamBroker {
|
|
13454
13454
|
deviceId;
|
|
13455
13455
|
/**
|
|
13456
|
-
* Numeric device id parsed once from `deviceId` (`
|
|
13457
|
-
* `tags.deviceId`. Every log line about a device carries it: "why is
|
|
13458
|
-
* worse than
|
|
13456
|
+
* Numeric device id parsed once from `deviceId` (`101/native` → 101), for
|
|
13457
|
+
* `tags.deviceId`. Every log line about a device carries it: "why is 102
|
|
13458
|
+
* worse than 101?" is the question every media-gap investigation starts from,
|
|
13459
13459
|
* and a line without the tag cannot be grouped to answer it.
|
|
13460
13460
|
*/
|
|
13461
13461
|
numericDeviceId;
|
|
@@ -13604,7 +13604,7 @@ var StreamBroker = class StreamBroker {
|
|
|
13604
13604
|
* which ANY caller may dial the source again. Armed on every dial ATTEMPT
|
|
13605
13605
|
* with the current backoff window. The 30s reconnect timer was honored on
|
|
13606
13606
|
* ITS path, but parallel dial channels (demand resume, broker recreation)
|
|
13607
|
-
* re-dialed instantly — an unreachable camera (
|
|
13607
|
+
* re-dialed instantly — an unreachable camera (105 EHOSTUNREACH) looped
|
|
13608
13608
|
* hundreds of dials/sec, the relayed log flood ballooned hub-main to
|
|
13609
13609
|
* 1.9 GB in 4 h and starved the HTTPS API. This gate makes the backoff a
|
|
13610
13610
|
* BROKER-level invariant instead of a per-path courtesy.
|
|
@@ -13833,7 +13833,7 @@ var StreamBroker = class StreamBroker {
|
|
|
13833
13833
|
* The open prebuffer hold, or `null` when the prebuffer is off.
|
|
13834
13834
|
*
|
|
13835
13835
|
* A real object rather than a flag plus a synthetic row, so "who is keeping
|
|
13836
|
-
* camera
|
|
13836
|
+
* camera 102 warm?" is answered by something that EXISTS: it has an id, it
|
|
13837
13837
|
* has a start time, and `hasDemand()` consults it the way it consults every
|
|
13838
13838
|
* other holder.
|
|
13839
13839
|
*/
|
|
@@ -13866,7 +13866,7 @@ var StreamBroker = class StreamBroker {
|
|
|
13866
13866
|
* that socket down. In that window `resolveCurrentSource()` truthfully
|
|
13867
13867
|
* answers with a socket nobody can dial.
|
|
13868
13868
|
*
|
|
13869
|
-
* That cost device
|
|
13869
|
+
* That cost device 106 its sentry on 2026-09-16: the window re-opened
|
|
13870
13870
|
* (which `suspend()` does deliberately, for a consumer that never left) with
|
|
13871
13871
|
* the real url, `planPrestream` refused it `not-lazy`, and the refusal is
|
|
13872
13872
|
* terminal — the operator's client sat dark for ten seconds and gave up six
|
|
@@ -14236,7 +14236,7 @@ var StreamBroker = class StreamBroker {
|
|
|
14236
14236
|
* streaming (`if (!this.reconnectTimer) return`). This is for the opposite
|
|
14237
14237
|
* situation: the connection is fine and its CONTENT is wrong.
|
|
14238
14238
|
*
|
|
14239
|
-
* That is not hypothetical. Measured live on Hikvision
|
|
14239
|
+
* That is not hypothetical. Measured live on Hikvision 104 (2026-08-07):
|
|
14240
14240
|
* muting the camera's microphone restarts its encoder, the RTSP connection
|
|
14241
14241
|
* drops, and the broker reconnects — *while the mute is still being applied
|
|
14242
14242
|
* channel by channel*. It negotiates a video-only SDP, the camera comes back
|
|
@@ -15342,7 +15342,7 @@ var StreamBroker = class StreamBroker {
|
|
|
15342
15342
|
* How far back the ring is kept — the prebuffer, and nothing else.
|
|
15343
15343
|
*
|
|
15344
15344
|
* It used to be `max(detectionPreRollMs, recordingPreRollMs)`: a maximum over
|
|
15345
|
-
* CONFIGURATIONS, which is what made "how much history does camera
|
|
15345
|
+
* CONFIGURATIONS, which is what made "how much history does camera 102 hold"
|
|
15346
15346
|
* a question with two answers and no owner. There is one configuration now,
|
|
15347
15347
|
* so the retention is it.
|
|
15348
15348
|
*/
|
|
@@ -18029,7 +18029,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
18029
18029
|
* memo above on purpose: the memo answers "what should decode this" on a read
|
|
18030
18030
|
* cadence and expires in a minute, so folding the failure into it meant the
|
|
18031
18031
|
* next cold child one minute later re-paid the same ~3 s death — measured
|
|
18032
|
-
* seven times on
|
|
18032
|
+
* seven times on 101 between 22:17 and 22:52 on 2026-08-07. See
|
|
18033
18033
|
* `dead-decode-backends.ts`.
|
|
18034
18034
|
*/
|
|
18035
18035
|
deadDecodeBackends = createDeadDecodeBackends();
|
|
@@ -18602,7 +18602,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
18602
18602
|
* refreshing it: a battery camera refuses a capture while it believes
|
|
18603
18603
|
* itself asleep, and that belief lags the wake by seconds — so the only
|
|
18604
18604
|
* attempts ever made were the sentry's own, while composing, which is
|
|
18605
|
-
* BEFORE any media exists. Measured on device
|
|
18605
|
+
* BEFORE any media exists. Measured on device 106 (2026-09-16): four
|
|
18606
18606
|
* wakes in forty minutes, the encoded picture `bytes=23912` every time,
|
|
18607
18607
|
* and between first packet and suspend not one capture was even
|
|
18608
18608
|
* attempted. The operator read the result as a placeholder rather than
|
|
@@ -19417,7 +19417,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
19417
19417
|
* A restart drops the RTSP connection and the broker reconnects on its own —
|
|
19418
19418
|
* but the reconnect lands INSIDE the restart window, so it negotiates
|
|
19419
19419
|
* whatever transient SDP the camera is offering mid-change. Measured on
|
|
19420
|
-
* Hikvision
|
|
19420
|
+
* Hikvision 104 (2026-08-07): a microphone mute/unmute left all three
|
|
19421
19421
|
* brokers holding video-only sessions against a camera that had its audio
|
|
19422
19422
|
* mux back, and because those sessions were healthy nothing ever re-dialed.
|
|
19423
19423
|
* The hub was deaf on that camera until the device was disabled long enough
|
|
@@ -22220,7 +22220,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
22220
22220
|
* assignment). When the device's assignment is operator-locked
|
|
22221
22221
|
* (`auto === false`) occupied slots stay put (a derived on `low` must
|
|
22222
22222
|
* not be kicked off). Empty slots refill from unused natives when the
|
|
22223
|
-
* device has a derived stream (
|
|
22223
|
+
* device has a derived stream (108 / 1438) or the whole map is empty —
|
|
22224
22224
|
* a camera without deriveds still honours an operator unassign.
|
|
22225
22225
|
*/
|
|
22226
22226
|
async reconcileAutoAssignment(deviceId, reason, streamAdded = false) {
|
|
@@ -22983,7 +22983,7 @@ var StreamBrokerManager = class StreamBrokerManager {
|
|
|
22983
22983
|
* Only ever an input to "can this track be COPIED into the derived MPEG-TS".
|
|
22984
22984
|
* `null` resolves to the AAC re-encode, so every failure of this read lands
|
|
22985
22985
|
* on the branch that still produces audible audio — the read can never mute
|
|
22986
|
-
* a camera, which is the direction that cost
|
|
22986
|
+
* a camera, which is the direction that cost 108 four silent days.
|
|
22987
22987
|
*/
|
|
22988
22988
|
observedSourceAudioCodec(deviceId, source) {
|
|
22989
22989
|
const camStreamId = source.kind === "camStream" ? source.camStreamId : this.assignments.get(deviceId)?.map[source.profile] ?? null;
|
|
@@ -26780,7 +26780,7 @@ var AdaptiveSession = class AdaptiveSession {
|
|
|
26780
26780
|
* `needsTranscode` is final the moment the answer's codec is known — the
|
|
26781
26781
|
* "Codec negotiated" line already prints it — but the acquire used to happen
|
|
26782
26782
|
* inside `startFeedingFrames`, which runs only after the DTLS wait. On camera
|
|
26783
|
-
*
|
|
26783
|
+
* 101 that put the leg ~2 s after session creation and the first packet ~5 s
|
|
26784
26784
|
* after that, against a browser watchdog that re-offers every ~5 s: the viewer
|
|
26785
26785
|
* was always gone before the media existed, and the next session paid for a
|
|
26786
26786
|
* cold child again. Three minutes of that on 2026-08-07 22:17–22:20.
|
|
@@ -32042,7 +32042,7 @@ var RecordedFeeder = class {
|
|
|
32042
32042
|
* the loop slept, the cursor never moved off the seek target, and the only
|
|
32043
32043
|
* evidence was a `recorded:play-census` line with `pacedAus=150 segments=1`.
|
|
32044
32044
|
* A branch that silently drops work logs (repo rule) — and the log carries
|
|
32045
|
-
* `deviceId` through `onLog`'s tags, because "why is 4374 worse than
|
|
32045
|
+
* `deviceId` through `onLog`'s tags, because "why is 4374 worse than 101" is
|
|
32046
32046
|
* the only way this question is ever asked.
|
|
32047
32047
|
*
|
|
32048
32048
|
* Logged once per segment start per feeder: a broken camera should name every
|
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-CJJ0Dj8s.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.627",
|
|
4
4
|
"description": "Pipeline bundle — runner, detection, motion, audio + stream broker. Multi-entry npm package shipping pipeline addons under a single bundle.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -15,7 +15,12 @@
|
|
|
15
15
|
"license": "MIT",
|
|
16
16
|
"repository": {
|
|
17
17
|
"type": "git",
|
|
18
|
-
"url": "https://github.com/camstack/server"
|
|
18
|
+
"url": "https://github.com/camstack/server.git",
|
|
19
|
+
"directory": "packages/addon-pipeline"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://camstack-docs.zentik.app",
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/camstack/server/issues"
|
|
19
24
|
},
|
|
20
25
|
"main": "./dist/pipeline-runner/index.js",
|
|
21
26
|
"exports": {
|
package/python/inference_pool.py
CHANGED
|
@@ -501,7 +501,7 @@ def _resolve_onnx_providers(
|
|
|
501
501
|
|
|
502
502
|
|
|
503
503
|
# WebGPU: one ORT session per OS process (Dawn/Vulkan SIGSEGVs on a second
|
|
504
|
-
# session in-process —
|
|
504
|
+
# session in-process — agent-b 2026-10-10). Implementation lives in
|
|
505
505
|
# webgpu_isolated.py; the pool parent never holds a WebGPU session itself.
|
|
506
506
|
from webgpu_isolated import WebGpuIsolatedSession # noqa: E402
|
|
507
507
|
|
|
@@ -1439,7 +1439,7 @@ def _load_model(slot: ModelSlot, config: dict) -> None:
|
|
|
1439
1439
|
slot.config["_input_shape"] = session.get_inputs()[0].shape
|
|
1440
1440
|
except Exception:
|
|
1441
1441
|
pass
|
|
1442
|
-
# Declared input DTYPE. super-gradients /
|
|
1442
|
+
# Declared input DTYPE. super-gradients / plus catalog YOLO-NAS exports bake
|
|
1443
1443
|
# their preprocessing into the graph and take `tensor(uint8)` — the
|
|
1444
1444
|
# preprocess must feed raw uint8 pixels, not the float32 [0,1] tensor
|
|
1445
1445
|
# (a hard onnxruntime type error otherwise).
|
|
@@ -1943,7 +1943,7 @@ def _preprocess(img: Image.Image, config: dict) -> tuple[dict, float, tuple[int,
|
|
|
1943
1943
|
if bench_fid is not None:
|
|
1944
1944
|
_bench_preprocess_cache[(bench_fid, input_size)] = result
|
|
1945
1945
|
return result
|
|
1946
|
-
# uint8-input ONNX models: super-gradients /
|
|
1946
|
+
# uint8-input ONNX models: super-gradients / plus catalog YOLO-NAS exports
|
|
1947
1947
|
# bake the /255 preprocessing INTO the graph and declare a uint8 input
|
|
1948
1948
|
# tensor. Feeding the historical float32 [0,1] tensor is a hard
|
|
1949
1949
|
# onnxruntime type error, so feed raw uint8 pixels in the declared
|
|
@@ -355,7 +355,7 @@ def postprocess_ctc(
|
|
|
355
355
|
# quad warp (2026-08-20) started delivering legible strips, the correct
|
|
356
356
|
# decodes arrived as "DN.D7578" / "DN-P 1091" / "DN:HF 974" and this gate
|
|
357
357
|
# threw away every one of them — the warp scored 1/21 instead of 4/21 on the
|
|
358
|
-
# cam-
|
|
358
|
+
# cam-102 ground-truth set purely because of this line.
|
|
359
359
|
#
|
|
360
360
|
# The exemption is deliberately narrow: EXACTLY ONE seal-like glyph, strictly
|
|
361
361
|
# INTERIOR, and the remainder must CONFORM to the region grammar. Noise
|