@camstack/system 1.2.272 → 1.2.273
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/camera-grid/addon.d.ts +13 -0
- package/dist/builtins/camera-grid/grid-canvas-seed.d.ts +62 -0
- package/dist/builtins/camera-grid/grid-canvas.d.ts +4 -2
- package/dist/builtins/camera-grid/grid-child.d.ts +10 -0
- package/dist/builtins/camera-grid/grid-compositor.d.ts +10 -0
- package/dist/builtins/camera-grid/index.js +321 -10
- package/dist/builtins/camera-grid/index.mjs +321 -10
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/cgroup-pids.d.ts +112 -0
- package/dist/builtins/native-metrics/native-metrics.addon.d.ts +1 -0
- package/dist/builtins/native-metrics/native-metrics.addon.js +209 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +209 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +1 -1
- package/dist/builtins/snapshot/index.mjs +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{dist-_YWIPtUH.js → dist-D5ONNqL6.js} +187 -11
- package/dist/{dist-Diz59Dhi.mjs → dist-DrLhdcwI.mjs} +187 -11
- package/dist/index.js +12 -5
- package/dist/index.mjs +12 -5
- package/dist/kernel/moleculer/process-service.d.ts +54 -0
- package/dist/{retired-settings-keys-C2ocoH_l.js → retired-settings-keys-1686ou3s.js} +1 -1
- package/dist/{retired-settings-keys-C_Hg5d37.mjs → retired-settings-keys-Du_0qedo.mjs} +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D5ONNqL6.js");
|
|
7
7
|
const require_hub_cap_forward = require("../../hub-cap-forward-DmHNjbB0.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as StorageLocationModeSchema, Bt as resolveLocationMode, Dt as mayWriteToLocation, Et as mayReadLocation, Kt as settingsStoreCapability, M as StorageMigrationJobSchema, On as parseJsonObject, Pn as EventCategory, W as collectSecretConfigKeys, Xt as storageMigrationCapability, Yt as storageCapability, _ as LegacyStorageLocationDefaultSchema, in as withLocationMode, j as StorageLocationTypeSchema, k as StorageCleanupJobSchema, kt as modeMayWrite, ot as evictionPolicyOfLocation, pt as isLocationEnabled, sn as BaseAddon, ut as gbToBytes, x as REDACTED_SECRET, yt as legacyModeOf } from "../../dist-
|
|
1
|
+
import { A as StorageLocationModeSchema, Bt as resolveLocationMode, Dt as mayWriteToLocation, Et as mayReadLocation, Kt as settingsStoreCapability, M as StorageMigrationJobSchema, On as parseJsonObject, Pn as EventCategory, W as collectSecretConfigKeys, Xt as storageMigrationCapability, Yt as storageCapability, _ as LegacyStorageLocationDefaultSchema, in as withLocationMode, j as StorageLocationTypeSchema, k as StorageCleanupJobSchema, kt as modeMayWrite, ot as evictionPolicyOfLocation, pt as isLocationEnabled, sn as BaseAddon, ut as gbToBytes, x as REDACTED_SECRET, yt as legacyModeOf } from "../../dist-DrLhdcwI.mjs";
|
|
2
2
|
import { t as HUB_CAP_FWD_ACTION } from "../../hub-cap-forward-BdT320dq.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D5ONNqL6.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { an as errMsg, sn as BaseAddon, wn as hydrateSchema } from "../../dist-
|
|
1
|
+
import { an as errMsg, sn as BaseAddon, wn as hydrateSchema } from "../../dist-DrLhdcwI.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D5ONNqL6.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ct as logDestinationCapability, sn as BaseAddon } from "../../dist-
|
|
1
|
+
import { Ct as logDestinationCapability, sn as BaseAddon } from "../../dist-DrLhdcwI.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|
|
@@ -691,7 +691,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
691
691
|
return EventCategory;
|
|
692
692
|
}({});
|
|
693
693
|
//#endregion
|
|
694
|
-
//#region ../types/dist/sleep-
|
|
694
|
+
//#region ../types/dist/sleep-CiR4z7r9.mjs
|
|
695
695
|
/**
|
|
696
696
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
697
697
|
* window to float samples (D455).
|
|
@@ -1857,6 +1857,17 @@ var CamProfileSchema = zod.z.enum([
|
|
|
1857
1857
|
"mid",
|
|
1858
1858
|
"low"
|
|
1859
1859
|
]);
|
|
1860
|
+
/**
|
|
1861
|
+
* Which rung a per-camera consumer listens on: an explicit profile, or `auto`.
|
|
1862
|
+
*
|
|
1863
|
+
* `auto` is a REAL value, not an absent one — it means "resolve it by the rule
|
|
1864
|
+
* that consumer owns". It lives beside `CamProfile` because a rung is the only
|
|
1865
|
+
* operator-facing way to name a stream: a cam-stream id is broker-internal and
|
|
1866
|
+
* moves when a slot is reassigned, so a stored id silently stops meaning what
|
|
1867
|
+
* the operator picked. Today's one user is the audio analyser, whose rule is
|
|
1868
|
+
* "the lowest AVAILABLE native rung" (D537).
|
|
1869
|
+
*/
|
|
1870
|
+
var AudioStreamPickSchema = zod.z.union([CamProfileSchema, zod.z.literal("auto")]);
|
|
1860
1871
|
var CamStreamKindSchema = zod.z.enum([
|
|
1861
1872
|
"pull-rtsp",
|
|
1862
1873
|
"pull-rtmp",
|
|
@@ -3404,7 +3415,7 @@ function sleep(ms) {
|
|
|
3404
3415
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
3405
3416
|
}
|
|
3406
3417
|
//#endregion
|
|
3407
|
-
//#region ../types/dist/canonical-hash-
|
|
3418
|
+
//#region ../types/dist/canonical-hash-CPK2Dy60.mjs
|
|
3408
3419
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
3409
3420
|
opus: "libopus",
|
|
3410
3421
|
aac: "aac",
|
|
@@ -3505,16 +3516,29 @@ function resolveStreamMaps(selection) {
|
|
|
3505
3516
|
};
|
|
3506
3517
|
}
|
|
3507
3518
|
/** The `-vf` filter args, or `[]` when a consumer `-vf` already claims the slot. */
|
|
3508
|
-
function buildVideoFilterArgs(scale, outputArgs, filterGraph) {
|
|
3519
|
+
function buildVideoFilterArgs(scale, outputArgs, filterGraph, hwUpload) {
|
|
3509
3520
|
if (filterGraph) {
|
|
3510
3521
|
if (scale) throw new Error("FfmpegInvocation: video.scale cannot be combined with a filter graph — scale inside the graph instead (the -vf would feed an output the graph already feeds)");
|
|
3511
3522
|
if (outputArgs.some((a) => a === "-vf")) throw new Error("FfmpegInvocation: outputArgs carries a -vf while a filter graph feeds the same output — fold the filter into the graph");
|
|
3512
3523
|
return [];
|
|
3513
3524
|
}
|
|
3514
|
-
if (!scale) return [];
|
|
3515
3525
|
if (outputArgs.some((a) => a === "-vf")) return [];
|
|
3516
|
-
if (scale.
|
|
3517
|
-
|
|
3526
|
+
if (!scale) return hwUpload.length > 0 ? ["-vf", hwUpload] : [];
|
|
3527
|
+
const suffix = hwUpload.length > 0 ? `,${hwUpload}` : "";
|
|
3528
|
+
if (scale.mode === "exact") return ["-vf", `scale=${scale.width}:${scale.height}${suffix}`];
|
|
3529
|
+
return ["-vf", `scale='min(${scale.width},iw)':'min(${scale.height},ih)':force_original_aspect_ratio=decrease:force_divisible_by=2${suffix}`];
|
|
3530
|
+
}
|
|
3531
|
+
/**
|
|
3532
|
+
* The upload filter a hardware encode needs, or `''`.
|
|
3533
|
+
*
|
|
3534
|
+
* Nothing is uploaded when the DECODE already left the frames on the GPU
|
|
3535
|
+
* (`-hwaccel vaapi`): they are surfaces already, and uploading a surface is an
|
|
3536
|
+
* error rather than a no-op.
|
|
3537
|
+
*/
|
|
3538
|
+
function resolveHwUpload(device, decodeHwAccel) {
|
|
3539
|
+
if (device === void 0) return "";
|
|
3540
|
+
if (!isSoftwareDecode(decodeHwAccel)) return "";
|
|
3541
|
+
return "format=nv12,hwupload";
|
|
3518
3542
|
}
|
|
3519
3543
|
/** Rate-control args for an encode plan. */
|
|
3520
3544
|
function buildRateControlArgs(video) {
|
|
@@ -3534,7 +3558,7 @@ function buildRateControlArgs(video) {
|
|
|
3534
3558
|
];
|
|
3535
3559
|
}
|
|
3536
3560
|
/** The whole video block (`-vf` … `-c:v` … knobs), after `-i`. */
|
|
3537
|
-
function buildVideoArgs(video, outputArgs, filterGraph) {
|
|
3561
|
+
function buildVideoArgs(video, outputArgs, filterGraph, hwEncode) {
|
|
3538
3562
|
if (video.kind === "raw") {
|
|
3539
3563
|
if (filterGraph && video.filter !== void 0) throw new Error("FfmpegInvocation: video.filter cannot be combined with a filter graph — fold the filter into the graph");
|
|
3540
3564
|
return [
|
|
@@ -3554,8 +3578,10 @@ function buildVideoArgs(video, outputArgs, filterGraph) {
|
|
|
3554
3578
|
...video.bitstreamFilter ? ["-bsf:v", video.bitstreamFilter] : []
|
|
3555
3579
|
];
|
|
3556
3580
|
}
|
|
3581
|
+
const hwUpload = hwEncode === void 0 ? "" : resolveHwUpload(hwEncode.device, hwEncode.decodeHwAccel);
|
|
3582
|
+
if (hwEncode !== void 0 && filterGraph) throw new Error("FfmpegInvocation: a hardware encode fed by a filter graph must upload INSIDE the graph — hwEncodeDevice cannot be combined with filterGraph");
|
|
3557
3583
|
const args = [
|
|
3558
|
-
...buildVideoFilterArgs(video.scale, outputArgs, filterGraph),
|
|
3584
|
+
...buildVideoFilterArgs(video.scale, outputArgs, filterGraph, hwUpload),
|
|
3559
3585
|
"-c:v",
|
|
3560
3586
|
video.encoder
|
|
3561
3587
|
];
|
|
@@ -3725,10 +3751,18 @@ function buildAudioSidecarArgs(sidecar) {
|
|
|
3725
3751
|
* (`0:a:0?`): the sidecar is defined as the SOURCE's microphone on its own RTP
|
|
3726
3752
|
* output, not as whatever the main output happens to carry.
|
|
3727
3753
|
*/
|
|
3754
|
+
/** The hardware-encode context for this invocation, or `undefined`. */
|
|
3755
|
+
function hwEncodeFor(inv) {
|
|
3756
|
+
return inv.hwEncodeDevice === void 0 ? void 0 : {
|
|
3757
|
+
device: inv.hwEncodeDevice,
|
|
3758
|
+
decodeHwAccel: inv.decodeHwAccel
|
|
3759
|
+
};
|
|
3760
|
+
}
|
|
3728
3761
|
function buildFfmpegArgs(inv) {
|
|
3729
3762
|
const graph = inv.filterGraph ?? null;
|
|
3730
3763
|
const head = [
|
|
3731
3764
|
...logBannerArgs(inv.logLevel),
|
|
3765
|
+
...inv.hwEncodeDevice !== void 0 ? ["-vaapi_device", inv.hwEncodeDevice.renderNode] : [],
|
|
3732
3766
|
...buildInputArgs(inv.input, inv.decodeHwAccel),
|
|
3733
3767
|
...(inv.extraInputs ?? []).flatMap((extra) => buildInputArgs(extra, inv.decodeHwAccel)),
|
|
3734
3768
|
...graph ? ["-filter_complex", graph.graph] : []
|
|
@@ -3742,7 +3776,7 @@ function buildFfmpegArgs(inv) {
|
|
|
3742
3776
|
"-an",
|
|
3743
3777
|
"-map",
|
|
3744
3778
|
maps.video ?? "0:v:0",
|
|
3745
|
-
...buildVideoArgs(inv.video, inv.outputArgs, graph),
|
|
3779
|
+
...buildVideoArgs(inv.video, inv.outputArgs, graph, hwEncodeFor(inv)),
|
|
3746
3780
|
...threadArgs,
|
|
3747
3781
|
...inv.outputArgs,
|
|
3748
3782
|
...buildRtpOutputArgs(inv.sink.video)
|
|
@@ -3765,7 +3799,7 @@ function buildFfmpegArgs(inv) {
|
|
|
3765
3799
|
return [
|
|
3766
3800
|
...head,
|
|
3767
3801
|
...videoMapArgs,
|
|
3768
|
-
...buildVideoArgs(inv.video, inv.outputArgs, graph),
|
|
3802
|
+
...buildVideoArgs(inv.video, inv.outputArgs, graph, hwEncodeFor(inv)),
|
|
3769
3803
|
...threadArgs,
|
|
3770
3804
|
...mutedAudio ? [] : audioMapArgs,
|
|
3771
3805
|
...audioArgs,
|
|
@@ -19996,6 +20030,7 @@ var MediaFileKindEnum = zod.z.enum([
|
|
|
19996
20030
|
"keyFrameSmall",
|
|
19997
20031
|
"thumbnailSmall",
|
|
19998
20032
|
"confirmationCrop",
|
|
20033
|
+
"debugCrop",
|
|
19999
20034
|
"sceneFrame"
|
|
20000
20035
|
]);
|
|
20001
20036
|
/**
|
|
@@ -22307,6 +22342,18 @@ var RunnerCameraConfigSchema = zod.z.object({
|
|
|
22307
22342
|
motionStreamId: zod.z.string(),
|
|
22308
22343
|
detectionStreamId: zod.z.string(),
|
|
22309
22344
|
/**
|
|
22345
|
+
* Which rung this camera's audio analysis listens on — `auto` (the lowest
|
|
22346
|
+
* AVAILABLE native rung) or an explicit one.
|
|
22347
|
+
*
|
|
22348
|
+
* Not consumed by the runner: carried here so it travels with the camera's
|
|
22349
|
+
* config the way `audioMotionWindowMs` does, and so the orchestrator's
|
|
22350
|
+
* watchdog resolves the same stream the audio subscription did. OPTIONAL
|
|
22351
|
+
* with no default — absent means `auto`, which is what every camera written
|
|
22352
|
+
* before this field had, and an absent optional adds nothing to the
|
|
22353
|
+
* generated cap-input defaults (D537).
|
|
22354
|
+
*/
|
|
22355
|
+
audioStreamPick: AudioStreamPickSchema.optional(),
|
|
22356
|
+
/**
|
|
22310
22357
|
* Motion sources that can activate the pipeline. At least one must
|
|
22311
22358
|
* be present. Multiple sources OR-ed: any one firing arms the
|
|
22312
22359
|
* cooldown timer and transitions watching → active. The same
|
|
@@ -25941,6 +25988,104 @@ var WebrtcStreamChoiceSchema = zod.z.object({
|
|
|
25941
25988
|
bitrateKbps: zod.z.number().nullable()
|
|
25942
25989
|
});
|
|
25943
25990
|
/**
|
|
25991
|
+
* The last move the adaptive ladder made on this session, and the numbers it
|
|
25992
|
+
* rested on. Mirrors `LadderDecision` in the stream-broker's
|
|
25993
|
+
* `adaptive-controller.ts` — the log line's evidence, made readable.
|
|
25994
|
+
*
|
|
25995
|
+
* Nullability is load-bearing: `lossRatio: null` means the loss tracker had
|
|
25996
|
+
* no window to report, which is NOT a link with zero loss.
|
|
25997
|
+
*/
|
|
25998
|
+
var WebrtcLadderDecisionSchema = zod.z.object({
|
|
25999
|
+
/** `loss` — RTCP / client-reported packet loss; `stall` — the picture
|
|
26000
|
+
* stopped moving; `healthy` — a promotion. */
|
|
26001
|
+
cause: zod.z.enum([
|
|
26002
|
+
"loss",
|
|
26003
|
+
"stall",
|
|
26004
|
+
"healthy"
|
|
26005
|
+
]),
|
|
26006
|
+
/** The rung the ladder moved TO. Null for a move that changed no rung
|
|
26007
|
+
* (an MTU reduction, a forced transcode-down at the bottom). */
|
|
26008
|
+
tier: CamProfileSchema.nullable(),
|
|
26009
|
+
/** Whether that move forced the egress transcode-down rung. */
|
|
26010
|
+
forcedTranscodeDown: zod.z.boolean(),
|
|
26011
|
+
/** Loss ratio over the tracker's window at the moment of the decision. */
|
|
26012
|
+
lossRatio: zod.z.number().nullable(),
|
|
26013
|
+
/** The client's reported downlink at that moment, in kbps. */
|
|
26014
|
+
clientKbps: zod.z.number().nullable(),
|
|
26015
|
+
/** How long the stall detector had been seeing nothing arrive. */
|
|
26016
|
+
stalledForMs: zod.z.number().nullable(),
|
|
26017
|
+
/** Whether the broker WAS sending while that was measured — the half that
|
|
26018
|
+
* separates "the camera stopped" from "the link stopped". */
|
|
26019
|
+
serverSending: zod.z.boolean().nullable(),
|
|
26020
|
+
/** Epoch ms. The overlay prints its age; a decision from 40 minutes ago
|
|
26021
|
+
* must not read like one from this second. */
|
|
26022
|
+
at: zod.z.number()
|
|
26023
|
+
});
|
|
26024
|
+
/** Per-tier count of MEASURED downgrades this viewer session has suffered. */
|
|
26025
|
+
var WebrtcTierFailureSchema = zod.z.object({
|
|
26026
|
+
tier: CamProfileSchema,
|
|
26027
|
+
failures: zod.z.number().int().nonnegative()
|
|
26028
|
+
});
|
|
26029
|
+
/**
|
|
26030
|
+
* What the SERVER decided for one WebRTC session — the half the client cannot
|
|
26031
|
+
* measure. See `getSessionDebug`.
|
|
26032
|
+
*/
|
|
26033
|
+
var WebrtcSessionDebugSchema = zod.z.object({
|
|
26034
|
+
sessionId: zod.z.string(),
|
|
26035
|
+
/** Whether the session still exists here. Everything below is null when
|
|
26036
|
+
* it does not — a dead session has no measurements, not zero ones. */
|
|
26037
|
+
alive: zod.z.boolean(),
|
|
26038
|
+
/** Epoch ms this snapshot was taken, so the overlay can show its age. */
|
|
26039
|
+
observedAt: zod.z.number(),
|
|
26040
|
+
/** The broker actually feeding this session (`<deviceId>/<camStreamId>`). */
|
|
26041
|
+
brokerId: zod.z.string().nullable(),
|
|
26042
|
+
camStreamId: zod.z.string().nullable(),
|
|
26043
|
+
/** `derived` = this hub BUILT the rung being served (a transcode/scale of
|
|
26044
|
+
* another stream); `native` = the camera's own encode. */
|
|
26045
|
+
sourceKind: zod.z.enum([
|
|
26046
|
+
"native",
|
|
26047
|
+
"derived",
|
|
26048
|
+
"unknown"
|
|
26049
|
+
]),
|
|
26050
|
+
/** Whether the ladder is running at all (an `adaptive` target). */
|
|
26051
|
+
adaptive: zod.z.boolean(),
|
|
26052
|
+
/** The rung `auto` ACTUALLY resolved to right now. Null when the broker
|
|
26053
|
+
* is bound to no profile slot (a manually-activated stream). */
|
|
26054
|
+
servedTier: CamProfileSchema.nullable(),
|
|
26055
|
+
/** Which node ingests the source. Null when unresolved. */
|
|
26056
|
+
ingestNodeId: zod.z.string().nullable(),
|
|
26057
|
+
/** Whether that node is a remote one (the media crosses a node boundary
|
|
26058
|
+
* before it reaches this session). Null when unresolved. */
|
|
26059
|
+
ingestIsRemote: zod.z.boolean().nullable(),
|
|
26060
|
+
/** Codec off the source, and the one negotiated with this client. */
|
|
26061
|
+
sourceCodec: zod.z.string().nullable(),
|
|
26062
|
+
negotiatedCodec: zod.z.string().nullable(),
|
|
26063
|
+
/** Whether the EGRESS leg re-encodes for this client or forwards the
|
|
26064
|
+
* source bytes untouched. */
|
|
26065
|
+
egressLeg: zod.z.enum([
|
|
26066
|
+
"copy",
|
|
26067
|
+
"transcode",
|
|
26068
|
+
"unknown"
|
|
26069
|
+
]),
|
|
26070
|
+
/** What the broker itself reports about the rung it is serving. */
|
|
26071
|
+
brokerStatus: zod.z.string().nullable(),
|
|
26072
|
+
brokerCodec: zod.z.string().nullable(),
|
|
26073
|
+
brokerBitrateKbps: zod.z.number().nullable(),
|
|
26074
|
+
brokerInputFps: zod.z.number().nullable(),
|
|
26075
|
+
brokerUptimeMs: zod.z.number().nullable(),
|
|
26076
|
+
/** RTP packets this session has sent — the server's own "am I sending?". */
|
|
26077
|
+
rtpPacketsSent: zod.z.number().nullable(),
|
|
26078
|
+
/** D42: the track may be carrying the recorded feeder, not live. The ladder
|
|
26079
|
+
* is suspended there, so a frozen picture in `recorded` mode means
|
|
26080
|
+
* something entirely different. */
|
|
26081
|
+
trackMode: zod.z.enum(["live", "recorded"]).nullable(),
|
|
26082
|
+
lastDecision: WebrtcLadderDecisionSchema.nullable(),
|
|
26083
|
+
tierFailures: zod.z.array(WebrtcTierFailureSchema),
|
|
26084
|
+
/** Successful promotions in this viewer session (drives the progressive
|
|
26085
|
+
* healthy timer). Null when no ladder is running. */
|
|
26086
|
+
upgradeCount: zod.z.number().nullable()
|
|
26087
|
+
});
|
|
26088
|
+
/**
|
|
25944
26089
|
* WebRTC session — device-scoped facade over the system `webrtc` cap.
|
|
25945
26090
|
*
|
|
25946
26091
|
* Exposes per-device signaling (`createSession`, `handleAnswer`,
|
|
@@ -26180,7 +26325,27 @@ var webrtcSessionCapability = {
|
|
|
26180
26325
|
* the same answer as "it ended": either way nothing is holding it up.
|
|
26181
26326
|
*/
|
|
26182
26327
|
alive: zod.z.boolean()
|
|
26183
|
-
}))
|
|
26328
|
+
})),
|
|
26329
|
+
/**
|
|
26330
|
+
* The SERVER's half of the stream-debug overlay, for one live session.
|
|
26331
|
+
*
|
|
26332
|
+
* The client can measure its own transport (`getStats()`); it cannot see
|
|
26333
|
+
* which rung `auto` actually resolved to, why the ladder last moved, or
|
|
26334
|
+
* whether the rung it is being served is the camera's own encode or
|
|
26335
|
+
* something this hub built. That asymmetry is why "quality is stuck on
|
|
26336
|
+
* low" reports have historically been unanswerable from the viewer alone.
|
|
26337
|
+
*
|
|
26338
|
+
* EVERY measurement here is nullable and `null` means UNKNOWN, never zero
|
|
26339
|
+
* (D393): a session whose ladder has never moved reports
|
|
26340
|
+
* `lastDecision: null`, which is a different fact from a ladder that moved
|
|
26341
|
+
* for `healthy` with a 0 loss ratio.
|
|
26342
|
+
*
|
|
26343
|
+
* Read-only, ~1 Hz, polled by the overlay only while it is visible.
|
|
26344
|
+
*/
|
|
26345
|
+
getSessionDebug: method(zod.z.object({
|
|
26346
|
+
deviceId: zod.z.number().int().nonnegative(),
|
|
26347
|
+
sessionId: zod.z.string()
|
|
26348
|
+
}), WebrtcSessionDebugSchema, { kind: "query" })
|
|
26184
26349
|
},
|
|
26185
26350
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
26186
26351
|
mount: { kind: "server-provided" }
|
|
@@ -45782,6 +45947,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
45782
45947
|
addonId: null,
|
|
45783
45948
|
access: "view"
|
|
45784
45949
|
},
|
|
45950
|
+
"webrtcSession.getSessionDebug": {
|
|
45951
|
+
capName: "webrtc-session",
|
|
45952
|
+
capScope: "device",
|
|
45953
|
+
addonId: null,
|
|
45954
|
+
access: "view"
|
|
45955
|
+
},
|
|
45785
45956
|
"webrtcSession.getSessionState": {
|
|
45786
45957
|
capName: "webrtc-session",
|
|
45787
45958
|
capScope: "device",
|
|
@@ -47765,6 +47936,11 @@ Object.freeze({
|
|
|
47765
47936
|
form: "single",
|
|
47766
47937
|
optional: false
|
|
47767
47938
|
}],
|
|
47939
|
+
"webrtcSession.getSessionDebug": [{
|
|
47940
|
+
name: "deviceId",
|
|
47941
|
+
form: "single",
|
|
47942
|
+
optional: false
|
|
47943
|
+
}],
|
|
47768
47944
|
"webrtcSession.getSessionState": [{
|
|
47769
47945
|
name: "deviceId",
|
|
47770
47946
|
form: "single",
|
|
@@ -691,7 +691,7 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
691
691
|
return EventCategory;
|
|
692
692
|
}({});
|
|
693
693
|
//#endregion
|
|
694
|
-
//#region ../types/dist/sleep-
|
|
694
|
+
//#region ../types/dist/sleep-CiR4z7r9.mjs
|
|
695
695
|
/**
|
|
696
696
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
697
697
|
* window to float samples (D455).
|
|
@@ -1857,6 +1857,17 @@ var CamProfileSchema = z.enum([
|
|
|
1857
1857
|
"mid",
|
|
1858
1858
|
"low"
|
|
1859
1859
|
]);
|
|
1860
|
+
/**
|
|
1861
|
+
* Which rung a per-camera consumer listens on: an explicit profile, or `auto`.
|
|
1862
|
+
*
|
|
1863
|
+
* `auto` is a REAL value, not an absent one — it means "resolve it by the rule
|
|
1864
|
+
* that consumer owns". It lives beside `CamProfile` because a rung is the only
|
|
1865
|
+
* operator-facing way to name a stream: a cam-stream id is broker-internal and
|
|
1866
|
+
* moves when a slot is reassigned, so a stored id silently stops meaning what
|
|
1867
|
+
* the operator picked. Today's one user is the audio analyser, whose rule is
|
|
1868
|
+
* "the lowest AVAILABLE native rung" (D537).
|
|
1869
|
+
*/
|
|
1870
|
+
var AudioStreamPickSchema = z.union([CamProfileSchema, z.literal("auto")]);
|
|
1860
1871
|
var CamStreamKindSchema = z.enum([
|
|
1861
1872
|
"pull-rtsp",
|
|
1862
1873
|
"pull-rtmp",
|
|
@@ -3404,7 +3415,7 @@ function sleep(ms) {
|
|
|
3404
3415
|
return new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
|
|
3405
3416
|
}
|
|
3406
3417
|
//#endregion
|
|
3407
|
-
//#region ../types/dist/canonical-hash-
|
|
3418
|
+
//#region ../types/dist/canonical-hash-CPK2Dy60.mjs
|
|
3408
3419
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
3409
3420
|
opus: "libopus",
|
|
3410
3421
|
aac: "aac",
|
|
@@ -3505,16 +3516,29 @@ function resolveStreamMaps(selection) {
|
|
|
3505
3516
|
};
|
|
3506
3517
|
}
|
|
3507
3518
|
/** The `-vf` filter args, or `[]` when a consumer `-vf` already claims the slot. */
|
|
3508
|
-
function buildVideoFilterArgs(scale, outputArgs, filterGraph) {
|
|
3519
|
+
function buildVideoFilterArgs(scale, outputArgs, filterGraph, hwUpload) {
|
|
3509
3520
|
if (filterGraph) {
|
|
3510
3521
|
if (scale) throw new Error("FfmpegInvocation: video.scale cannot be combined with a filter graph — scale inside the graph instead (the -vf would feed an output the graph already feeds)");
|
|
3511
3522
|
if (outputArgs.some((a) => a === "-vf")) throw new Error("FfmpegInvocation: outputArgs carries a -vf while a filter graph feeds the same output — fold the filter into the graph");
|
|
3512
3523
|
return [];
|
|
3513
3524
|
}
|
|
3514
|
-
if (!scale) return [];
|
|
3515
3525
|
if (outputArgs.some((a) => a === "-vf")) return [];
|
|
3516
|
-
if (scale.
|
|
3517
|
-
|
|
3526
|
+
if (!scale) return hwUpload.length > 0 ? ["-vf", hwUpload] : [];
|
|
3527
|
+
const suffix = hwUpload.length > 0 ? `,${hwUpload}` : "";
|
|
3528
|
+
if (scale.mode === "exact") return ["-vf", `scale=${scale.width}:${scale.height}${suffix}`];
|
|
3529
|
+
return ["-vf", `scale='min(${scale.width},iw)':'min(${scale.height},ih)':force_original_aspect_ratio=decrease:force_divisible_by=2${suffix}`];
|
|
3530
|
+
}
|
|
3531
|
+
/**
|
|
3532
|
+
* The upload filter a hardware encode needs, or `''`.
|
|
3533
|
+
*
|
|
3534
|
+
* Nothing is uploaded when the DECODE already left the frames on the GPU
|
|
3535
|
+
* (`-hwaccel vaapi`): they are surfaces already, and uploading a surface is an
|
|
3536
|
+
* error rather than a no-op.
|
|
3537
|
+
*/
|
|
3538
|
+
function resolveHwUpload(device, decodeHwAccel) {
|
|
3539
|
+
if (device === void 0) return "";
|
|
3540
|
+
if (!isSoftwareDecode(decodeHwAccel)) return "";
|
|
3541
|
+
return "format=nv12,hwupload";
|
|
3518
3542
|
}
|
|
3519
3543
|
/** Rate-control args for an encode plan. */
|
|
3520
3544
|
function buildRateControlArgs(video) {
|
|
@@ -3534,7 +3558,7 @@ function buildRateControlArgs(video) {
|
|
|
3534
3558
|
];
|
|
3535
3559
|
}
|
|
3536
3560
|
/** The whole video block (`-vf` … `-c:v` … knobs), after `-i`. */
|
|
3537
|
-
function buildVideoArgs(video, outputArgs, filterGraph) {
|
|
3561
|
+
function buildVideoArgs(video, outputArgs, filterGraph, hwEncode) {
|
|
3538
3562
|
if (video.kind === "raw") {
|
|
3539
3563
|
if (filterGraph && video.filter !== void 0) throw new Error("FfmpegInvocation: video.filter cannot be combined with a filter graph — fold the filter into the graph");
|
|
3540
3564
|
return [
|
|
@@ -3554,8 +3578,10 @@ function buildVideoArgs(video, outputArgs, filterGraph) {
|
|
|
3554
3578
|
...video.bitstreamFilter ? ["-bsf:v", video.bitstreamFilter] : []
|
|
3555
3579
|
];
|
|
3556
3580
|
}
|
|
3581
|
+
const hwUpload = hwEncode === void 0 ? "" : resolveHwUpload(hwEncode.device, hwEncode.decodeHwAccel);
|
|
3582
|
+
if (hwEncode !== void 0 && filterGraph) throw new Error("FfmpegInvocation: a hardware encode fed by a filter graph must upload INSIDE the graph — hwEncodeDevice cannot be combined with filterGraph");
|
|
3557
3583
|
const args = [
|
|
3558
|
-
...buildVideoFilterArgs(video.scale, outputArgs, filterGraph),
|
|
3584
|
+
...buildVideoFilterArgs(video.scale, outputArgs, filterGraph, hwUpload),
|
|
3559
3585
|
"-c:v",
|
|
3560
3586
|
video.encoder
|
|
3561
3587
|
];
|
|
@@ -3725,10 +3751,18 @@ function buildAudioSidecarArgs(sidecar) {
|
|
|
3725
3751
|
* (`0:a:0?`): the sidecar is defined as the SOURCE's microphone on its own RTP
|
|
3726
3752
|
* output, not as whatever the main output happens to carry.
|
|
3727
3753
|
*/
|
|
3754
|
+
/** The hardware-encode context for this invocation, or `undefined`. */
|
|
3755
|
+
function hwEncodeFor(inv) {
|
|
3756
|
+
return inv.hwEncodeDevice === void 0 ? void 0 : {
|
|
3757
|
+
device: inv.hwEncodeDevice,
|
|
3758
|
+
decodeHwAccel: inv.decodeHwAccel
|
|
3759
|
+
};
|
|
3760
|
+
}
|
|
3728
3761
|
function buildFfmpegArgs(inv) {
|
|
3729
3762
|
const graph = inv.filterGraph ?? null;
|
|
3730
3763
|
const head = [
|
|
3731
3764
|
...logBannerArgs(inv.logLevel),
|
|
3765
|
+
...inv.hwEncodeDevice !== void 0 ? ["-vaapi_device", inv.hwEncodeDevice.renderNode] : [],
|
|
3732
3766
|
...buildInputArgs(inv.input, inv.decodeHwAccel),
|
|
3733
3767
|
...(inv.extraInputs ?? []).flatMap((extra) => buildInputArgs(extra, inv.decodeHwAccel)),
|
|
3734
3768
|
...graph ? ["-filter_complex", graph.graph] : []
|
|
@@ -3742,7 +3776,7 @@ function buildFfmpegArgs(inv) {
|
|
|
3742
3776
|
"-an",
|
|
3743
3777
|
"-map",
|
|
3744
3778
|
maps.video ?? "0:v:0",
|
|
3745
|
-
...buildVideoArgs(inv.video, inv.outputArgs, graph),
|
|
3779
|
+
...buildVideoArgs(inv.video, inv.outputArgs, graph, hwEncodeFor(inv)),
|
|
3746
3780
|
...threadArgs,
|
|
3747
3781
|
...inv.outputArgs,
|
|
3748
3782
|
...buildRtpOutputArgs(inv.sink.video)
|
|
@@ -3765,7 +3799,7 @@ function buildFfmpegArgs(inv) {
|
|
|
3765
3799
|
return [
|
|
3766
3800
|
...head,
|
|
3767
3801
|
...videoMapArgs,
|
|
3768
|
-
...buildVideoArgs(inv.video, inv.outputArgs, graph),
|
|
3802
|
+
...buildVideoArgs(inv.video, inv.outputArgs, graph, hwEncodeFor(inv)),
|
|
3769
3803
|
...threadArgs,
|
|
3770
3804
|
...mutedAudio ? [] : audioMapArgs,
|
|
3771
3805
|
...audioArgs,
|
|
@@ -19996,6 +20030,7 @@ var MediaFileKindEnum = z.enum([
|
|
|
19996
20030
|
"keyFrameSmall",
|
|
19997
20031
|
"thumbnailSmall",
|
|
19998
20032
|
"confirmationCrop",
|
|
20033
|
+
"debugCrop",
|
|
19999
20034
|
"sceneFrame"
|
|
20000
20035
|
]);
|
|
20001
20036
|
/**
|
|
@@ -22307,6 +22342,18 @@ var RunnerCameraConfigSchema = z.object({
|
|
|
22307
22342
|
motionStreamId: z.string(),
|
|
22308
22343
|
detectionStreamId: z.string(),
|
|
22309
22344
|
/**
|
|
22345
|
+
* Which rung this camera's audio analysis listens on — `auto` (the lowest
|
|
22346
|
+
* AVAILABLE native rung) or an explicit one.
|
|
22347
|
+
*
|
|
22348
|
+
* Not consumed by the runner: carried here so it travels with the camera's
|
|
22349
|
+
* config the way `audioMotionWindowMs` does, and so the orchestrator's
|
|
22350
|
+
* watchdog resolves the same stream the audio subscription did. OPTIONAL
|
|
22351
|
+
* with no default — absent means `auto`, which is what every camera written
|
|
22352
|
+
* before this field had, and an absent optional adds nothing to the
|
|
22353
|
+
* generated cap-input defaults (D537).
|
|
22354
|
+
*/
|
|
22355
|
+
audioStreamPick: AudioStreamPickSchema.optional(),
|
|
22356
|
+
/**
|
|
22310
22357
|
* Motion sources that can activate the pipeline. At least one must
|
|
22311
22358
|
* be present. Multiple sources OR-ed: any one firing arms the
|
|
22312
22359
|
* cooldown timer and transitions watching → active. The same
|
|
@@ -25941,6 +25988,104 @@ var WebrtcStreamChoiceSchema = z.object({
|
|
|
25941
25988
|
bitrateKbps: z.number().nullable()
|
|
25942
25989
|
});
|
|
25943
25990
|
/**
|
|
25991
|
+
* The last move the adaptive ladder made on this session, and the numbers it
|
|
25992
|
+
* rested on. Mirrors `LadderDecision` in the stream-broker's
|
|
25993
|
+
* `adaptive-controller.ts` — the log line's evidence, made readable.
|
|
25994
|
+
*
|
|
25995
|
+
* Nullability is load-bearing: `lossRatio: null` means the loss tracker had
|
|
25996
|
+
* no window to report, which is NOT a link with zero loss.
|
|
25997
|
+
*/
|
|
25998
|
+
var WebrtcLadderDecisionSchema = z.object({
|
|
25999
|
+
/** `loss` — RTCP / client-reported packet loss; `stall` — the picture
|
|
26000
|
+
* stopped moving; `healthy` — a promotion. */
|
|
26001
|
+
cause: z.enum([
|
|
26002
|
+
"loss",
|
|
26003
|
+
"stall",
|
|
26004
|
+
"healthy"
|
|
26005
|
+
]),
|
|
26006
|
+
/** The rung the ladder moved TO. Null for a move that changed no rung
|
|
26007
|
+
* (an MTU reduction, a forced transcode-down at the bottom). */
|
|
26008
|
+
tier: CamProfileSchema.nullable(),
|
|
26009
|
+
/** Whether that move forced the egress transcode-down rung. */
|
|
26010
|
+
forcedTranscodeDown: z.boolean(),
|
|
26011
|
+
/** Loss ratio over the tracker's window at the moment of the decision. */
|
|
26012
|
+
lossRatio: z.number().nullable(),
|
|
26013
|
+
/** The client's reported downlink at that moment, in kbps. */
|
|
26014
|
+
clientKbps: z.number().nullable(),
|
|
26015
|
+
/** How long the stall detector had been seeing nothing arrive. */
|
|
26016
|
+
stalledForMs: z.number().nullable(),
|
|
26017
|
+
/** Whether the broker WAS sending while that was measured — the half that
|
|
26018
|
+
* separates "the camera stopped" from "the link stopped". */
|
|
26019
|
+
serverSending: z.boolean().nullable(),
|
|
26020
|
+
/** Epoch ms. The overlay prints its age; a decision from 40 minutes ago
|
|
26021
|
+
* must not read like one from this second. */
|
|
26022
|
+
at: z.number()
|
|
26023
|
+
});
|
|
26024
|
+
/** Per-tier count of MEASURED downgrades this viewer session has suffered. */
|
|
26025
|
+
var WebrtcTierFailureSchema = z.object({
|
|
26026
|
+
tier: CamProfileSchema,
|
|
26027
|
+
failures: z.number().int().nonnegative()
|
|
26028
|
+
});
|
|
26029
|
+
/**
|
|
26030
|
+
* What the SERVER decided for one WebRTC session — the half the client cannot
|
|
26031
|
+
* measure. See `getSessionDebug`.
|
|
26032
|
+
*/
|
|
26033
|
+
var WebrtcSessionDebugSchema = z.object({
|
|
26034
|
+
sessionId: z.string(),
|
|
26035
|
+
/** Whether the session still exists here. Everything below is null when
|
|
26036
|
+
* it does not — a dead session has no measurements, not zero ones. */
|
|
26037
|
+
alive: z.boolean(),
|
|
26038
|
+
/** Epoch ms this snapshot was taken, so the overlay can show its age. */
|
|
26039
|
+
observedAt: z.number(),
|
|
26040
|
+
/** The broker actually feeding this session (`<deviceId>/<camStreamId>`). */
|
|
26041
|
+
brokerId: z.string().nullable(),
|
|
26042
|
+
camStreamId: z.string().nullable(),
|
|
26043
|
+
/** `derived` = this hub BUILT the rung being served (a transcode/scale of
|
|
26044
|
+
* another stream); `native` = the camera's own encode. */
|
|
26045
|
+
sourceKind: z.enum([
|
|
26046
|
+
"native",
|
|
26047
|
+
"derived",
|
|
26048
|
+
"unknown"
|
|
26049
|
+
]),
|
|
26050
|
+
/** Whether the ladder is running at all (an `adaptive` target). */
|
|
26051
|
+
adaptive: z.boolean(),
|
|
26052
|
+
/** The rung `auto` ACTUALLY resolved to right now. Null when the broker
|
|
26053
|
+
* is bound to no profile slot (a manually-activated stream). */
|
|
26054
|
+
servedTier: CamProfileSchema.nullable(),
|
|
26055
|
+
/** Which node ingests the source. Null when unresolved. */
|
|
26056
|
+
ingestNodeId: z.string().nullable(),
|
|
26057
|
+
/** Whether that node is a remote one (the media crosses a node boundary
|
|
26058
|
+
* before it reaches this session). Null when unresolved. */
|
|
26059
|
+
ingestIsRemote: z.boolean().nullable(),
|
|
26060
|
+
/** Codec off the source, and the one negotiated with this client. */
|
|
26061
|
+
sourceCodec: z.string().nullable(),
|
|
26062
|
+
negotiatedCodec: z.string().nullable(),
|
|
26063
|
+
/** Whether the EGRESS leg re-encodes for this client or forwards the
|
|
26064
|
+
* source bytes untouched. */
|
|
26065
|
+
egressLeg: z.enum([
|
|
26066
|
+
"copy",
|
|
26067
|
+
"transcode",
|
|
26068
|
+
"unknown"
|
|
26069
|
+
]),
|
|
26070
|
+
/** What the broker itself reports about the rung it is serving. */
|
|
26071
|
+
brokerStatus: z.string().nullable(),
|
|
26072
|
+
brokerCodec: z.string().nullable(),
|
|
26073
|
+
brokerBitrateKbps: z.number().nullable(),
|
|
26074
|
+
brokerInputFps: z.number().nullable(),
|
|
26075
|
+
brokerUptimeMs: z.number().nullable(),
|
|
26076
|
+
/** RTP packets this session has sent — the server's own "am I sending?". */
|
|
26077
|
+
rtpPacketsSent: z.number().nullable(),
|
|
26078
|
+
/** D42: the track may be carrying the recorded feeder, not live. The ladder
|
|
26079
|
+
* is suspended there, so a frozen picture in `recorded` mode means
|
|
26080
|
+
* something entirely different. */
|
|
26081
|
+
trackMode: z.enum(["live", "recorded"]).nullable(),
|
|
26082
|
+
lastDecision: WebrtcLadderDecisionSchema.nullable(),
|
|
26083
|
+
tierFailures: z.array(WebrtcTierFailureSchema),
|
|
26084
|
+
/** Successful promotions in this viewer session (drives the progressive
|
|
26085
|
+
* healthy timer). Null when no ladder is running. */
|
|
26086
|
+
upgradeCount: z.number().nullable()
|
|
26087
|
+
});
|
|
26088
|
+
/**
|
|
25944
26089
|
* WebRTC session — device-scoped facade over the system `webrtc` cap.
|
|
25945
26090
|
*
|
|
25946
26091
|
* Exposes per-device signaling (`createSession`, `handleAnswer`,
|
|
@@ -26180,7 +26325,27 @@ var webrtcSessionCapability = {
|
|
|
26180
26325
|
* the same answer as "it ended": either way nothing is holding it up.
|
|
26181
26326
|
*/
|
|
26182
26327
|
alive: z.boolean()
|
|
26183
|
-
}))
|
|
26328
|
+
})),
|
|
26329
|
+
/**
|
|
26330
|
+
* The SERVER's half of the stream-debug overlay, for one live session.
|
|
26331
|
+
*
|
|
26332
|
+
* The client can measure its own transport (`getStats()`); it cannot see
|
|
26333
|
+
* which rung `auto` actually resolved to, why the ladder last moved, or
|
|
26334
|
+
* whether the rung it is being served is the camera's own encode or
|
|
26335
|
+
* something this hub built. That asymmetry is why "quality is stuck on
|
|
26336
|
+
* low" reports have historically been unanswerable from the viewer alone.
|
|
26337
|
+
*
|
|
26338
|
+
* EVERY measurement here is nullable and `null` means UNKNOWN, never zero
|
|
26339
|
+
* (D393): a session whose ladder has never moved reports
|
|
26340
|
+
* `lastDecision: null`, which is a different fact from a ladder that moved
|
|
26341
|
+
* for `healthy` with a 0 loss ratio.
|
|
26342
|
+
*
|
|
26343
|
+
* Read-only, ~1 Hz, polled by the overlay only while it is visible.
|
|
26344
|
+
*/
|
|
26345
|
+
getSessionDebug: method(z.object({
|
|
26346
|
+
deviceId: z.number().int().nonnegative(),
|
|
26347
|
+
sessionId: z.string()
|
|
26348
|
+
}), WebrtcSessionDebugSchema, { kind: "query" })
|
|
26184
26349
|
},
|
|
26185
26350
|
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
26186
26351
|
mount: { kind: "server-provided" }
|
|
@@ -45782,6 +45947,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
|
|
|
45782
45947
|
addonId: null,
|
|
45783
45948
|
access: "view"
|
|
45784
45949
|
},
|
|
45950
|
+
"webrtcSession.getSessionDebug": {
|
|
45951
|
+
capName: "webrtc-session",
|
|
45952
|
+
capScope: "device",
|
|
45953
|
+
addonId: null,
|
|
45954
|
+
access: "view"
|
|
45955
|
+
},
|
|
45785
45956
|
"webrtcSession.getSessionState": {
|
|
45786
45957
|
capName: "webrtc-session",
|
|
45787
45958
|
capScope: "device",
|
|
@@ -47765,6 +47936,11 @@ Object.freeze({
|
|
|
47765
47936
|
form: "single",
|
|
47766
47937
|
optional: false
|
|
47767
47938
|
}],
|
|
47939
|
+
"webrtcSession.getSessionDebug": [{
|
|
47940
|
+
name: "deviceId",
|
|
47941
|
+
form: "single",
|
|
47942
|
+
optional: false
|
|
47943
|
+
}],
|
|
47768
47944
|
"webrtcSession.getSessionState": [{
|
|
47769
47945
|
name: "deviceId",
|
|
47770
47946
|
form: "single",
|