@camstack/system 1.2.262 → 1.2.263
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/camera-grid/addon.d.ts +18 -13
- package/dist/builtins/camera-grid/grid-profiles.d.ts +28 -33
- package/dist/builtins/camera-grid/grid-snapshot.d.ts +4 -4
- package/dist/builtins/camera-grid/grid-stream-descriptor.d.ts +4 -6
- package/dist/builtins/camera-grid/grid-stream-relay.d.ts +7 -11
- package/dist/builtins/camera-grid/index.d.ts +2 -2
- package/dist/builtins/camera-grid/index.js +177 -216
- package/dist/builtins/camera-grid/index.mjs +175 -213
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ interface CameraGridAddonConfig {
|
|
|
8
8
|
export declare class CameraGridAddon extends BaseAddon<CameraGridAddonConfig> {
|
|
9
9
|
private relay;
|
|
10
10
|
private reconcileTimer;
|
|
11
|
-
/** Keyed by
|
|
11
|
+
/** Keyed by instance id — ONE composition per grid. */
|
|
12
12
|
private readonly sessions;
|
|
13
13
|
private readonly deviceIdByInstanceId;
|
|
14
14
|
private readonly tombstones;
|
|
@@ -22,7 +22,7 @@ export declare class CameraGridAddon extends BaseAddon<CameraGridAddonConfig> {
|
|
|
22
22
|
* (D224), and 60 s is the window for a fact — "does 615 have a low assigned"
|
|
23
23
|
* — that only changes when an operator changes it.
|
|
24
24
|
*/
|
|
25
|
-
private readonly
|
|
25
|
+
private readonly planByInstanceId;
|
|
26
26
|
private snapshots;
|
|
27
27
|
private frameSampler;
|
|
28
28
|
private ffmpegBinaryPath;
|
|
@@ -44,30 +44,35 @@ export declare class CameraGridAddon extends BaseAddon<CameraGridAddonConfig> {
|
|
|
44
44
|
private reconcile;
|
|
45
45
|
private silenceAnalysis;
|
|
46
46
|
/**
|
|
47
|
-
* Which
|
|
47
|
+
* Which stream each grid reads each of its sources at, asked of the BROKER.
|
|
48
48
|
*
|
|
49
49
|
* `listAllProfileSlots` is the one authority on "does 615 have a low
|
|
50
50
|
* assigned", and `sourceCamStreamId === null` is its way of saying no. A read
|
|
51
|
-
* that FAILS leaves the previous answer in place and says so
|
|
51
|
+
* that FAILS leaves the previous answer in place and says so — it is not an
|
|
52
52
|
* empty catalog, and turning it into one would retract the streams of every
|
|
53
53
|
* grid on the hub.
|
|
54
54
|
*/
|
|
55
|
-
private
|
|
55
|
+
private refreshSourcePlans;
|
|
56
56
|
/**
|
|
57
|
-
* Say
|
|
57
|
+
* Say WHICH stream each cell is read at, and who could not be read - once per
|
|
58
|
+
* change.
|
|
58
59
|
*
|
|
59
|
-
* A
|
|
60
|
-
* broker that swept it
|
|
61
|
-
*
|
|
62
|
-
*
|
|
60
|
+
* Both halves earn their line. A grid silently missing from a catalog is
|
|
61
|
+
* indistinguishable from a broker that swept it, so the refusal names the
|
|
62
|
+
* sources. And the chosen profiles are the answer to "why is this tile
|
|
63
|
+
* soft?" — a camera whose only assigned slot is `high` is read at `high`, and
|
|
64
|
+
* nothing else in the system would ever say so.
|
|
65
|
+
*
|
|
66
|
+
* Logged on the EDGE: a grid that cannot be composed would otherwise write a
|
|
67
|
+
* line a minute for ever.
|
|
63
68
|
*/
|
|
64
|
-
private
|
|
65
|
-
private
|
|
69
|
+
private logSourcePlan;
|
|
70
|
+
private planFor;
|
|
66
71
|
private ensureSessions;
|
|
67
72
|
private makeSession;
|
|
68
73
|
/** The session a dial is asking for, or `null` - which the relay answers 404 to. */
|
|
69
74
|
private sessionFor;
|
|
70
|
-
/** This grid's
|
|
75
|
+
/** This grid's composition, as the list the snapshot source expects. */
|
|
71
76
|
private sessionsForDevice;
|
|
72
77
|
/** A grid that is gone stops immediately - it must not keep N sources dialled. */
|
|
73
78
|
private retireWithdrawnSessions;
|
|
@@ -1,47 +1,42 @@
|
|
|
1
1
|
import { CamProfile } from '@camstack/types';
|
|
2
2
|
/**
|
|
3
|
-
* One id, for every grid, forever
|
|
3
|
+
* One id, for every grid, forever.
|
|
4
4
|
*
|
|
5
|
-
* D519's reason
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* D519's reason is what keeps this id bare: a per-instance or newly-spelled id
|
|
6
|
+
* mints a second cam-stream and orphans whatever profile assignment the
|
|
7
|
+
* operator had made. It was `high` on the live hub before the per-profile
|
|
8
|
+
* detour and it is `high` again, so nothing an operator assigned is disturbed.
|
|
9
9
|
*/
|
|
10
10
|
export declare const GRID_CAM_STREAM_ID = "grid";
|
|
11
|
-
/**
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export declare
|
|
21
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The slot the single composition claims.
|
|
13
|
+
*
|
|
14
|
+
* NOT decoration. A device publishing one stream with no hint is ranked by
|
|
15
|
+
* pixel count and lands in `mid` — the slot `recordings` does not select on its
|
|
16
|
+
* own, that `recordingsLow` ignores, and that scrub never reads. The Dreame
|
|
17
|
+
* robot's single 720p relay landed exactly there and its footage was written
|
|
18
|
+
* where nothing looked.
|
|
19
|
+
*/
|
|
20
|
+
export declare const GRID_OUTPUT_PROFILE: CamProfile;
|
|
21
|
+
/** The cheapest stream this source serves, or `null` when it serves none. */
|
|
22
|
+
export declare function lowestServedProfile(served: readonly CamProfile[]): CamProfile | null;
|
|
23
|
+
export interface GridSourceProfilesInput {
|
|
22
24
|
/** Every camera the composition takes a cell from, deduplicated. */
|
|
23
25
|
readonly sourceDeviceIds: readonly number[];
|
|
24
26
|
/**
|
|
25
27
|
* Which profiles this source can serve, or `null` when nobody could say.
|
|
26
28
|
* `null` is not an empty list: an unanswerable question is a refusal, and
|
|
27
|
-
* saying so separately
|
|
29
|
+
* saying so separately keeps "we did not ask" out of the catalog.
|
|
28
30
|
*/
|
|
29
31
|
readonly profilesServedBy: (deviceId: number) => readonly CamProfile[] | null;
|
|
30
32
|
}
|
|
31
|
-
export
|
|
32
|
-
|
|
33
|
-
readonly offered:
|
|
34
|
-
|
|
35
|
-
readonly
|
|
36
|
-
|
|
37
|
-
/** The sources that could not serve it. Empty only when there are none at all. */
|
|
33
|
+
export interface GridSourcePlan {
|
|
34
|
+
/** True when every source can be read — the only case a grid is on offer. */
|
|
35
|
+
readonly offered: boolean;
|
|
36
|
+
/** Which stream each source is read at. Only contains readable sources. */
|
|
37
|
+
readonly profileBySource: ReadonlyMap<number, CamProfile>;
|
|
38
|
+
/** The sources that serve nothing, or that nobody could answer for. */
|
|
38
39
|
readonly missingSources: readonly number[];
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
*
|
|
43
|
-
* Every profile gets a row whether it is offered or not: an absent row says
|
|
44
|
-
* nothing, and the caller logging a refusal needs the reason more than the
|
|
45
|
-
* caller publishing an offer needs the offer.
|
|
46
|
-
*/
|
|
47
|
-
export declare function offeredGridProfiles(input: OfferedGridProfilesInput): readonly GridProfileOffer[];
|
|
40
|
+
}
|
|
41
|
+
/** Which stream to read each source at, and who cannot be read at all. */
|
|
42
|
+
export declare function gridSourceProfiles(input: GridSourceProfilesInput): GridSourcePlan;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { CamProfile } from '@camstack/types';
|
|
2
1
|
import { GridStreamLogger } from './grid-stream-session.js';
|
|
3
2
|
/** Where a grid's last composed frame is kept between compositions. */
|
|
4
3
|
export interface GridLastFrameStore {
|
|
@@ -8,7 +7,6 @@ export interface GridLastFrameStore {
|
|
|
8
7
|
}
|
|
9
8
|
/** Just enough of a session for the snapshot to choose one and read its state. */
|
|
10
9
|
export interface GridSnapshotSession {
|
|
11
|
-
readonly profile: CamProfile;
|
|
12
10
|
isRunning(): boolean;
|
|
13
11
|
}
|
|
14
12
|
export interface GridSnapshotAnswerInput {
|
|
@@ -40,8 +38,10 @@ export interface GridSnapshotImage {
|
|
|
40
38
|
export interface GridSnapshotDeps<S extends GridSnapshotSession = GridSnapshotSession> {
|
|
41
39
|
readonly logger: GridStreamLogger;
|
|
42
40
|
/**
|
|
43
|
-
* This grid's
|
|
44
|
-
*
|
|
41
|
+
* This grid's compositions — one, since the collapse to a single output.
|
|
42
|
+
* Kept as a LIST because the choosing logic below is the same either way and
|
|
43
|
+
* a list of one costs nothing. EMPTY means this addon does not own the
|
|
44
|
+
* device — never "no picture".
|
|
45
45
|
*/
|
|
46
46
|
readonly sessionsFor: (deviceId: number) => readonly S[];
|
|
47
47
|
/**
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CamStreamDescriptor } from '@camstack/types';
|
|
2
2
|
export interface GridStreamDescriptorInput {
|
|
3
|
-
/** Which composition this is. Also the `profileHint` — see below. */
|
|
4
|
-
readonly profile: CamProfile;
|
|
5
3
|
readonly width: number;
|
|
6
4
|
readonly height: number;
|
|
7
5
|
readonly fps: number;
|
|
@@ -17,8 +15,8 @@ export interface GridStreamDescriptorInput {
|
|
|
17
15
|
* scrub never reads. The Dreame robot's one 720p relay landed exactly there and
|
|
18
16
|
* its footage was written nowhere anything looked.
|
|
19
17
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
18
|
+
* So the single composition claims `high` EXPLICITLY (`GRID_OUTPUT_PROFILE`).
|
|
19
|
+
* It is also the slot this stream held before the per-profile detour, which is
|
|
20
|
+
* what keeps an operator's existing assignment intact.
|
|
23
21
|
*/
|
|
24
22
|
export declare function gridStreamDescriptor(input: GridStreamDescriptorInput): CamStreamDescriptor;
|
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
import { CamProfile } from '@camstack/types';
|
|
2
1
|
import { GridStreamLogger, GridStreamSession } from './grid-stream-session.js';
|
|
3
2
|
/**
|
|
4
|
-
* Which grid
|
|
3
|
+
* Which grid. There is one composition of it, so that is the whole address.
|
|
5
4
|
*
|
|
6
|
-
* The
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* would be the broker asking for "whichever", which is how a `low` slot ends
|
|
12
|
-
* up holding a `high` composition.
|
|
5
|
+
* The path used to carry a profile segment, because a grid published one
|
|
6
|
+
* composition per profile and a dial naming none would have been the broker
|
|
7
|
+
* asking for "whichever". With a single output "whichever" is well defined,
|
|
8
|
+
* and the segment would be a choice with one option — which is not a choice,
|
|
9
|
+
* it is a way to spell one stream two ways.
|
|
13
10
|
*/
|
|
14
11
|
export interface GridStreamRequest {
|
|
15
12
|
readonly instanceId: string;
|
|
16
|
-
readonly profile: CamProfile;
|
|
17
13
|
}
|
|
18
|
-
/** `/grid/<instanceId
|
|
14
|
+
/** `/grid/<instanceId>.flv`, or `null` when it is anything else. */
|
|
19
15
|
export declare function parseGridStreamPath(url: string | undefined): GridStreamRequest | null;
|
|
20
16
|
export interface GridStreamRelayDeps {
|
|
21
17
|
readonly logger: GridStreamLogger;
|
|
@@ -22,8 +22,8 @@ export type { GridPlanEncodeContext } from './grid-plan.js';
|
|
|
22
22
|
export { normalizeGridRows } from './grid-row-normalization.js';
|
|
23
23
|
export type { NormalizedGridRows } from './grid-row-normalization.js';
|
|
24
24
|
export { gridStreamDescriptor } from './grid-stream-descriptor.js';
|
|
25
|
-
export { GRID_CAM_STREAM_ID,
|
|
26
|
-
export type {
|
|
25
|
+
export { GRID_CAM_STREAM_ID, GRID_OUTPUT_PROFILE, gridSourceProfiles, lowestServedProfile, } from './grid-profiles.js';
|
|
26
|
+
export type { GridSourcePlan } from './grid-profiles.js';
|
|
27
27
|
export { gridSourceDial } from './grid-sentry-sources.js';
|
|
28
28
|
export type { GridSourceAcquisition, GridSourceDial } from './grid-sentry-sources.js';
|
|
29
29
|
export { GridSnapshotSource, gridSnapshotAnswerFor } from './grid-snapshot.js';
|