@camstack/types 1.2.227 → 1.2.229
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/capabilities/device-manager.cap.d.ts +5 -0
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +6 -0
- package/dist/deps/binary-downloader.d.ts +12 -0
- package/dist/deps/ffmpeg-artifacts.d.ts +66 -0
- package/dist/deps/ffmpeg-binary-source.d.ts +43 -45
- package/dist/deps/ffmpeg-downloader.d.ts +12 -41
- package/dist/deps/index.d.ts +2 -1
- package/dist/index.js +21 -1
- package/dist/index.mjs +21 -2
- package/dist/interfaces/camera-switches.d.ts +10 -0
- package/dist/node.d.ts +2 -1
- package/dist/node.js +216 -119
- package/dist/node.mjs +216 -120
- package/package.json +1 -1
|
@@ -252,6 +252,7 @@ export declare const MigrateSwitchReportSchema: z.ZodObject<{
|
|
|
252
252
|
"object-detection": "object-detection";
|
|
253
253
|
"device-audio": "device-audio";
|
|
254
254
|
"broker-audio": "broker-audio";
|
|
255
|
+
"event-saving": "event-saving";
|
|
255
256
|
}>;
|
|
256
257
|
outcome: z.ZodEnum<{
|
|
257
258
|
off: "off";
|
|
@@ -275,6 +276,7 @@ export declare const MigrateDeviceResultSchema: z.ZodObject<{
|
|
|
275
276
|
"object-detection": "object-detection";
|
|
276
277
|
"device-audio": "device-audio";
|
|
277
278
|
"broker-audio": "broker-audio";
|
|
279
|
+
"event-saving": "event-saving";
|
|
278
280
|
}>;
|
|
279
281
|
outcome: z.ZodEnum<{
|
|
280
282
|
off: "off";
|
|
@@ -293,6 +295,7 @@ export declare const MigrateDeviceResultSchema: z.ZodObject<{
|
|
|
293
295
|
"object-detection": "object-detection";
|
|
294
296
|
"device-audio": "device-audio";
|
|
295
297
|
"broker-audio": "broker-audio";
|
|
298
|
+
"event-saving": "event-saving";
|
|
296
299
|
}>>>;
|
|
297
300
|
swapped: z.ZodBoolean;
|
|
298
301
|
}, z.core.$strip>;
|
|
@@ -362,6 +365,7 @@ export declare const deviceManagerCapability: {
|
|
|
362
365
|
"object-detection": "object-detection";
|
|
363
366
|
"device-audio": "device-audio";
|
|
364
367
|
"broker-audio": "broker-audio";
|
|
368
|
+
"event-saving": "event-saving";
|
|
365
369
|
}>;
|
|
366
370
|
outcome: z.ZodEnum<{
|
|
367
371
|
off: "off";
|
|
@@ -380,6 +384,7 @@ export declare const deviceManagerCapability: {
|
|
|
380
384
|
"object-detection": "object-detection";
|
|
381
385
|
"device-audio": "device-audio";
|
|
382
386
|
"broker-audio": "broker-audio";
|
|
387
|
+
"event-saving": "event-saving";
|
|
383
388
|
}>>>;
|
|
384
389
|
swapped: z.ZodBoolean;
|
|
385
390
|
}, z.core.$strip>, "mutation">;
|
|
@@ -519,6 +519,7 @@ declare const CameraStatusSchema: z.ZodObject<{
|
|
|
519
519
|
"object-detection": "object-detection";
|
|
520
520
|
"device-audio": "device-audio";
|
|
521
521
|
"broker-audio": "broker-audio";
|
|
522
|
+
"event-saving": "event-saving";
|
|
522
523
|
}>>>;
|
|
523
524
|
degraded: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
524
525
|
stage: z.ZodEnum<{
|
|
@@ -1264,6 +1265,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1264
1265
|
"object-detection": "object-detection";
|
|
1265
1266
|
"device-audio": "device-audio";
|
|
1266
1267
|
"broker-audio": "broker-audio";
|
|
1268
|
+
"event-saving": "event-saving";
|
|
1267
1269
|
}>;
|
|
1268
1270
|
label: z.ZodString;
|
|
1269
1271
|
costWhenOff: z.ZodString;
|
|
@@ -1324,6 +1326,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1324
1326
|
"object-detection": "object-detection";
|
|
1325
1327
|
"device-audio": "device-audio";
|
|
1326
1328
|
"broker-audio": "broker-audio";
|
|
1329
|
+
"event-saving": "event-saving";
|
|
1327
1330
|
}>;
|
|
1328
1331
|
enabled: z.ZodBoolean;
|
|
1329
1332
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -1338,6 +1341,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1338
1341
|
"object-detection": "object-detection";
|
|
1339
1342
|
"device-audio": "device-audio";
|
|
1340
1343
|
"broker-audio": "broker-audio";
|
|
1344
|
+
"event-saving": "event-saving";
|
|
1341
1345
|
}>;
|
|
1342
1346
|
label: z.ZodString;
|
|
1343
1347
|
costWhenOff: z.ZodString;
|
|
@@ -1489,6 +1493,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1489
1493
|
"object-detection": "object-detection";
|
|
1490
1494
|
"device-audio": "device-audio";
|
|
1491
1495
|
"broker-audio": "broker-audio";
|
|
1496
|
+
"event-saving": "event-saving";
|
|
1492
1497
|
}>>>;
|
|
1493
1498
|
degraded: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
1494
1499
|
stage: z.ZodEnum<{
|
|
@@ -1625,6 +1630,7 @@ export declare const pipelineOrchestratorCapability: {
|
|
|
1625
1630
|
"object-detection": "object-detection";
|
|
1626
1631
|
"device-audio": "device-audio";
|
|
1627
1632
|
"broker-audio": "broker-audio";
|
|
1633
|
+
"event-saving": "event-saving";
|
|
1628
1634
|
}>>>;
|
|
1629
1635
|
degraded: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
1630
1636
|
stage: z.ZodEnum<{
|
|
@@ -24,6 +24,18 @@ export interface DownloadOptions {
|
|
|
24
24
|
readonly archiveFormat?: 'zip' | 'tar.gz' | 'tar.xz';
|
|
25
25
|
/** Relative path within archive to the binary (e.g., 'ffmpeg-6.1/bin/ffmpeg') */
|
|
26
26
|
readonly archiveInnerPath?: string;
|
|
27
|
+
/**
|
|
28
|
+
* SHA-256 the downloaded ARCHIVE must have, verified before a byte of it is
|
|
29
|
+
* extracted.
|
|
30
|
+
*
|
|
31
|
+
* Optional only because the python downloader predates it. For ffmpeg it is
|
|
32
|
+
* not optional in practice: the download is the ONLY source of the binary
|
|
33
|
+
* every transcode runs through, it arrives over a redirect to a third-party
|
|
34
|
+
* host, and the publisher ships no checksums of its own — so ours is the only
|
|
35
|
+
* thing standing between a changed artifact and a silent swap of the most
|
|
36
|
+
* privileged subprocess this system spawns.
|
|
37
|
+
*/
|
|
38
|
+
readonly sha256?: string;
|
|
27
39
|
}
|
|
28
40
|
/**
|
|
29
41
|
* Download a binary to the target directory.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
3
|
+
*
|
|
4
|
+
* ## Why a download, on every node, including the container
|
|
5
|
+
*
|
|
6
|
+
* The version of ffmpeg used to be CODE: baked into the image, changeable only
|
|
7
|
+
* by rebuilding and rolling it. Now it is DATA — this file states the release,
|
|
8
|
+
* and a node that boots with a different one downloads it. Changing ffmpeg is a
|
|
9
|
+
* framework bump, not an image rebuild.
|
|
10
|
+
*
|
|
11
|
+
* It also settles the licence question by removing it. FFmpeg's licence is
|
|
12
|
+
* chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
|
|
13
|
+
* (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
|
|
14
|
+
* makes the result undistributable. These are GPL v3 builds, and we do not
|
|
15
|
+
* distribute them: the user's own node fetches the archive from the project
|
|
16
|
+
* that publishes it, so we convey no GPL work and inherit none of the
|
|
17
|
+
* obligations that come with conveying one. That is the whole reason the image
|
|
18
|
+
* no longer installs ffmpeg at all — not a technical preference.
|
|
19
|
+
*
|
|
20
|
+
* ## Why jellyfin-ffmpeg
|
|
21
|
+
*
|
|
22
|
+
* One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
|
|
23
|
+
* from one release, with the widest hardware surface of anything maintained:
|
|
24
|
+
* VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
|
|
25
|
+
* MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
|
|
26
|
+
* so the binary is not linked against a driver stack it may not find.
|
|
27
|
+
*
|
|
28
|
+
* **What it still needs from the host, measured 2026-09-19.** On the Unraid
|
|
29
|
+
* HOST, which has no libva, `-vaapi_device` aborts the process outright —
|
|
30
|
+
* `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
|
|
31
|
+
* "Assertion in generated code"' failed`. Inside our container, which installs
|
|
32
|
+
* libva plus the iHD driver, the same command encodes: verified end to end with
|
|
33
|
+
* `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
|
|
34
|
+
* KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
|
|
35
|
+
*
|
|
36
|
+
* ## Why each artifact carries a checksum and a claim
|
|
37
|
+
*
|
|
38
|
+
* The download is now the only source, so `sha256` is verified before anything
|
|
39
|
+
* is extracted — jellyfin publishes no checksums on its release assets, so
|
|
40
|
+
* these are ours, taken at the version bump. And `expectedHwaccels` is what the
|
|
41
|
+
* build is supposed to be able to do: a binary that probes short of its own
|
|
42
|
+
* claim is a source that changed under us, which is precisely what went
|
|
43
|
+
* unnoticed for months when a static build turned out to carry no VAAPI at all
|
|
44
|
+
* (D536).
|
|
45
|
+
*/
|
|
46
|
+
/** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
|
|
47
|
+
export declare const FFMPEG_RELEASE: "8.1.2-5";
|
|
48
|
+
/** ffmpeg 8.1.2 is what this release builds — for the log line, not resolution. */
|
|
49
|
+
export declare const FFMPEG_VERSION: "8.1.2";
|
|
50
|
+
export interface FfmpegArtifact {
|
|
51
|
+
readonly url: string;
|
|
52
|
+
readonly archiveFormat: 'zip' | 'tar.gz' | 'tar.xz';
|
|
53
|
+
/** SHA-256 of the ARCHIVE, verified before extraction. */
|
|
54
|
+
readonly sha256: string;
|
|
55
|
+
/** Bytes, as published — for the "downloading 60 MB" line. */
|
|
56
|
+
readonly sizeBytes: number;
|
|
57
|
+
/**
|
|
58
|
+
* `-hwaccels` names this build must report. Asserted after download: short of
|
|
59
|
+
* this is a changed source, not a quiet degradation.
|
|
60
|
+
*/
|
|
61
|
+
readonly expectedHwaccels: readonly string[];
|
|
62
|
+
}
|
|
63
|
+
/** The artifact for this node, or a refusal naming what was asked for. */
|
|
64
|
+
export declare function getFfmpegArtifact(platform: string, arch: string): FfmpegArtifact;
|
|
65
|
+
/** The URL alone, for a caller that wants nothing else. */
|
|
66
|
+
export declare function getFfmpegDownloadUrl(platform: string, arch: string): string;
|
|
@@ -1,74 +1,72 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* WHICH ffmpeg a node runs
|
|
2
|
+
* WHICH ffmpeg a node runs — one rule, on every node.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* WebRTC transcode leg, the recorder, snapshots and the camera grid. What that
|
|
6
|
-
* binary is compiled with decides whether any of them can use the machine's
|
|
7
|
-
* hardware, so it is not a detail to leave to whatever the host happens to have
|
|
8
|
-
* on its PATH:
|
|
4
|
+
* ## The rule
|
|
9
5
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
6
|
+
* 1. `CAMSTACK_FFMPEG_PATH`, when the operator set it and it exists. Pointing
|
|
7
|
+
* at your own build is a deliberate act and it wins over everything.
|
|
8
|
+
* 2. The pinned build this node has already downloaded, named by release
|
|
9
|
+
* (`ffmpeg-<release>`), in `<dataDir>/deps`.
|
|
10
|
+
* 3. Nothing — the caller downloads it. See `ffmpeg-artifacts.ts`.
|
|
13
11
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* The system PATH is not on that list and must never be. A host binary is an
|
|
13
|
+
* unknown version with unknown vendor libraries, and it changes under us on any
|
|
14
|
+
* host update; a self-hosted NVR cannot assume the host has ffmpeg at all
|
|
15
|
+
* (D536).
|
|
16
16
|
*
|
|
17
|
-
*
|
|
18
|
-
* | --- | --- |
|
|
19
|
-
* | our container image | {@link BUNDLED_FFMPEG_PATH}, installed by the image |
|
|
20
|
-
* | anything else (a native macOS agent) | the static build we download into `<dataDir>/deps` |
|
|
17
|
+
* ## Why the container image is not special any more
|
|
21
18
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* write can.
|
|
19
|
+
* It was, for one day: the image installed ffmpeg, CamStack preferred it, and
|
|
20
|
+
* that made the answer depend on where a node ran — an image node got VAAPI, a
|
|
21
|
+
* native one got a portable build with none. Now every node downloads the same
|
|
22
|
+
* pinned build, so:
|
|
27
23
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
24
|
+
* - the ffmpeg version is DATA, not code: changing it is a framework bump, not
|
|
25
|
+
* an image rebuild and a container swap on every machine;
|
|
26
|
+
* - we ship no ffmpeg binary, so we convey no GPL work — the node fetches it
|
|
27
|
+
* from the project that publishes it;
|
|
28
|
+
* - one binary, one set of capabilities, everywhere. A bug that depends on
|
|
29
|
+
* which ffmpeg answered stops being possible.
|
|
32
30
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
31
|
+
* What the image still owes is the DRIVERS, which no binary can bring: libva
|
|
32
|
+
* plus the iHD media driver for Intel. Measured 2026-09-19 — the portable build
|
|
33
|
+
* encodes VAAPI inside our container and ABORTS on the bare Unraid host, where
|
|
34
|
+
* `libva-drm.so.2` does not exist.
|
|
37
35
|
*
|
|
38
|
-
*
|
|
39
|
-
* `Device creation failed: -12` — the name parses, the device cannot exist —
|
|
40
|
-
* then transcodes in software with nothing naming the cause.
|
|
36
|
+
* ## Absent is absent
|
|
41
37
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* sets it.
|
|
38
|
+
* The naming carries the release, so two versions coexist during a change and a
|
|
39
|
+
* rollback is a file that is already on disk rather than a download.
|
|
45
40
|
*/
|
|
46
|
-
/** Where our container image puts the ffmpeg it installs. Only the image writes this. */
|
|
47
|
-
export declare const BUNDLED_FFMPEG_PATH = "/opt/camstack/bin/ffmpeg";
|
|
48
41
|
/** Operator override. Unset on every node unless a human deliberately set it. */
|
|
49
42
|
export declare const FFMPEG_PATH_ENV = "CAMSTACK_FFMPEG_PATH";
|
|
50
|
-
export type FfmpegBinaryOrigin = 'override' | '
|
|
43
|
+
export type FfmpegBinaryOrigin = 'override' | 'downloaded';
|
|
51
44
|
export interface FfmpegBinaryChoice {
|
|
52
45
|
readonly origin: FfmpegBinaryOrigin;
|
|
53
46
|
readonly path: string;
|
|
54
47
|
}
|
|
55
48
|
export interface FfmpegBinarySourceInput {
|
|
56
49
|
readonly platform: string;
|
|
57
|
-
/** `<dataDir>/deps/ffmpeg
|
|
58
|
-
readonly
|
|
50
|
+
/** `<dataDir>/deps/ffmpeg-<release>` — where the pinned build lands. */
|
|
51
|
+
readonly pinnedPath: string;
|
|
59
52
|
/** The raw value of {@link FFMPEG_PATH_ENV}, or null/empty when unset. */
|
|
60
53
|
readonly override: string | null | undefined;
|
|
61
54
|
readonly exists: (path: string) => boolean;
|
|
62
55
|
}
|
|
63
56
|
/**
|
|
64
|
-
* The
|
|
65
|
-
*
|
|
57
|
+
* The file name the pinned build is stored under.
|
|
58
|
+
*
|
|
59
|
+
* Versioned on purpose: a download is then idempotent, two releases can sit
|
|
60
|
+
* side by side while a change rolls through a cluster, and going back is a path
|
|
61
|
+
* that already exists instead of a fetch that has to succeed.
|
|
62
|
+
*/
|
|
63
|
+
export declare function ffmpegBinaryName(platform: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* The binary to use, or `null` when it has to be downloaded first.
|
|
66
66
|
*
|
|
67
67
|
* An override that does not exist is NOT silently skipped — it is an operator
|
|
68
68
|
* mistake, and falling through to a different binary than the one they named
|
|
69
|
-
* would hide it. The caller reports it and carries on with the
|
|
70
|
-
* is the only safe direction: a typo must not stop a node
|
|
69
|
+
* would hide it. The caller reports it and carries on with the pinned build,
|
|
70
|
+
* which is the only safe direction: a typo must not stop a node serving video.
|
|
71
71
|
*/
|
|
72
72
|
export declare function chooseFfmpegBinary(input: FfmpegBinarySourceInput): FfmpegBinaryChoice | null;
|
|
73
|
-
/** The image-provided path for a platform, or `null` where we ship no image. */
|
|
74
|
-
export declare function bundledFfmpegPath(platform: string): string | null;
|
|
@@ -1,47 +1,18 @@
|
|
|
1
1
|
import type { IScopedLogger } from '../interfaces/logging.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* The ffmpeg this node runs, downloading the pinned build if it is not here
|
|
4
|
+
* yet, and reporting what it got.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Order: the operator's `CAMSTACK_FFMPEG_PATH` → the pinned build already on
|
|
7
|
+
* disk → download it. No PATH, no image copy, no per-platform special case —
|
|
8
|
+
* see `ffmpeg-binary-source.ts` for why the image stopped being special after
|
|
9
|
+
* exactly one day.
|
|
8
10
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* -
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* is how a build with no VAAPI at all served every transcode on this fleet
|
|
16
|
-
* for months (D536).
|
|
17
|
-
*
|
|
18
|
-
* `expectedHwaccels` is that missing claim. It is deliberately EMPTY for the
|
|
19
|
-
* linux static builds: they carry no hardware support and pretending otherwise
|
|
20
|
-
* would make the assertion a lie. That emptiness is the honest description of
|
|
21
|
-
* a portable build, and the reason a node that has an image prefers the image's
|
|
22
|
-
* ffmpeg over this one.
|
|
23
|
-
*/
|
|
24
|
-
export interface FfmpegArtifact {
|
|
25
|
-
readonly url: string;
|
|
26
|
-
readonly archiveFormat: 'zip' | 'tar.gz' | 'tar.xz';
|
|
27
|
-
/** `-hwaccels` names this artifact is built with. Empty = none, honestly. */
|
|
28
|
-
readonly expectedHwaccels: readonly string[];
|
|
29
|
-
}
|
|
30
|
-
/** The artifact for this node, or a refusal naming what was asked for. */
|
|
31
|
-
export declare function getFfmpegArtifact(platform: string, arch: string): FfmpegArtifact;
|
|
32
|
-
/** The URL alone, for a caller that wants nothing else. */
|
|
33
|
-
export declare function getFfmpegDownloadUrl(platform: string, arch: string): string;
|
|
34
|
-
/**
|
|
35
|
-
* Ensure an ffmpeg binary WE provide is available on this node, and report
|
|
36
|
-
* which one and what it can do.
|
|
37
|
-
*
|
|
38
|
-
* Order: the operator's voluntary override → the one our image installed → a
|
|
39
|
-
* copy we already downloaded → download it. The system PATH is not in that
|
|
40
|
-
* list and must never be: see `ffmpeg-binary-source.ts`.
|
|
41
|
-
*
|
|
42
|
-
* The line it logs is the point as much as the path is. "Which ffmpeg am I
|
|
43
|
-
* running, and does it have vaapi" had no answer anywhere in the product, and
|
|
44
|
-
* that is what let a hardware-incapable binary serve every transcode on a hub
|
|
45
|
-
* with a working iGPU for months, silently in software.
|
|
11
|
+
* The line it logs is half the point. "Which ffmpeg am I running, and does it
|
|
12
|
+
* have vaapi" had no answer anywhere in the product, and that is what let a
|
|
13
|
+
* hardware-incapable binary serve every transcode on a hub with a working iGPU
|
|
14
|
+
* for months. The other half is the assertion beneath it: a build that probes
|
|
15
|
+
* short of what its artifact claims is a source that changed under us, and it
|
|
16
|
+
* says so with both lists.
|
|
46
17
|
*/
|
|
47
18
|
export declare function ensureFfmpeg(dataDir: string, logger: IScopedLogger): Promise<string>;
|
package/dist/deps/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { ensureBinary, downloadBinary, findInPath, getPlatformInfo, buildBinaryPath, } from './binary-downloader.js';
|
|
2
|
-
export { ensureFfmpeg
|
|
2
|
+
export { ensureFfmpeg } from './ffmpeg-downloader.js';
|
|
3
|
+
export { FFMPEG_RELEASE, getFfmpegArtifact, getFfmpegDownloadUrl } from './ffmpeg-artifacts.js';
|
|
3
4
|
export { ensurePython, installPythonPackages, installPythonRequirements, getPythonDownloadUrl, PYTHON_VERSION, } from './python-downloader.js';
|
package/dist/index.js
CHANGED
|
@@ -1072,6 +1072,7 @@ var CameraSwitchIdSchema = zod.z.enum([
|
|
|
1072
1072
|
"device-audio",
|
|
1073
1073
|
"broker-audio",
|
|
1074
1074
|
"audio-analysis",
|
|
1075
|
+
"event-saving",
|
|
1075
1076
|
"recording",
|
|
1076
1077
|
"notifications"
|
|
1077
1078
|
]);
|
|
@@ -1098,6 +1099,7 @@ var CAMERA_SWITCH_ORDER = [
|
|
|
1098
1099
|
"device-audio",
|
|
1099
1100
|
"broker-audio",
|
|
1100
1101
|
"audio-analysis",
|
|
1102
|
+
"event-saving",
|
|
1101
1103
|
"recording",
|
|
1102
1104
|
"notifications"
|
|
1103
1105
|
];
|
|
@@ -1182,6 +1184,13 @@ var AUDIO_ANALYSIS_CAP_NAME = "audio-analysis";
|
|
|
1182
1184
|
*/
|
|
1183
1185
|
var PRIVACY_MASK_CAP_NAME = "privacy-mask";
|
|
1184
1186
|
/**
|
|
1187
|
+
* The wrapper that TURNS DETECTIONS INTO STORED HISTORY — tracks, events and
|
|
1188
|
+
* their media. Named here for the same reason as the others, and with one
|
|
1189
|
+
* extra: it has no gate of its own except this binding, so it is the only
|
|
1190
|
+
* thing standing between a camera's detections and the database.
|
|
1191
|
+
*/
|
|
1192
|
+
var PIPELINE_ANALYTICS_CAP_NAME = "pipeline-analytics";
|
|
1193
|
+
/**
|
|
1185
1194
|
* Every analyser a camera CamStack BUILDS is created with switched off.
|
|
1186
1195
|
*
|
|
1187
1196
|
* A grid and a Terminal camera are `DeviceType.Camera`, so every wrapper that
|
|
@@ -1210,7 +1219,7 @@ var DERIVED_CAMERA_SILENCED_CAP_NAMES = [
|
|
|
1210
1219
|
"motion-detection",
|
|
1211
1220
|
DETECTION_PIPELINE_CAP_NAME,
|
|
1212
1221
|
AUDIO_ANALYSIS_CAP_NAME,
|
|
1213
|
-
|
|
1222
|
+
PIPELINE_ANALYTICS_CAP_NAME,
|
|
1214
1223
|
"scene-monitor"
|
|
1215
1224
|
];
|
|
1216
1225
|
/**
|
|
@@ -1272,6 +1281,16 @@ var CAMERA_SWITCH_CATALOG = {
|
|
|
1272
1281
|
},
|
|
1273
1282
|
countsAsSwitchedOff: true
|
|
1274
1283
|
},
|
|
1284
|
+
"event-saving": {
|
|
1285
|
+
id: "event-saving",
|
|
1286
|
+
label: "Event saving",
|
|
1287
|
+
costWhenOff: "Off: nothing about this camera is written to its history — no tracks, no events and no event snapshots or clips. Detection keeps running and live boxes still appear, so the camera looks busy while its timeline stays empty, and anything that fires ON an event (notification rules, event-triggered recording) has nothing to fire on. Continuous recording is unaffected, and history already written is kept.",
|
|
1288
|
+
authority: {
|
|
1289
|
+
kind: "wrapper-binding",
|
|
1290
|
+
capName: PIPELINE_ANALYTICS_CAP_NAME
|
|
1291
|
+
},
|
|
1292
|
+
countsAsSwitchedOff: true
|
|
1293
|
+
},
|
|
1275
1294
|
recording: {
|
|
1276
1295
|
id: "recording",
|
|
1277
1296
|
label: "Recording",
|
|
@@ -59037,6 +59056,7 @@ exports.OsdSourceValueTypeEnum = OsdSourceValueTypeEnum;
|
|
|
59037
59056
|
exports.OsdStatusSchema = OsdStatusSchema;
|
|
59038
59057
|
exports.PET_FEEDER_MANUAL_FEED_MAX = PET_FEEDER_MANUAL_FEED_MAX;
|
|
59039
59058
|
exports.PET_FEEDER_MANUAL_FEED_MIN = PET_FEEDER_MANUAL_FEED_MIN;
|
|
59059
|
+
exports.PIPELINE_ANALYTICS_CAP_NAME = PIPELINE_ANALYTICS_CAP_NAME;
|
|
59040
59060
|
exports.PIPELINE_FLOW_CAPABILITY_NAMES = PIPELINE_FLOW_CAPABILITY_NAMES;
|
|
59041
59061
|
exports.PIPELINE_OWNER_CAPABILITY_NAMES = PIPELINE_OWNER_CAPABILITY_NAMES;
|
|
59042
59062
|
exports.PRIVACY_MASK_CAP_NAME = PRIVACY_MASK_CAP_NAME;
|