@ceralive/cerastream 2026.7.5 → 2026.8.0
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/client.d.ts +3 -3
- package/dist/client.js +39 -42
- package/dist/config.d.ts +1 -1
- package/dist/config.js +8 -10
- package/dist/constants.d.ts +14 -14
- package/dist/constants.js +18 -18
- package/dist/envelope.d.ts +1 -1
- package/dist/envelope.js +4 -4
- package/dist/errors.d.ts +13 -13
- package/dist/errors.js +43 -43
- package/dist/events.d.ts +183 -94
- package/dist/events.js +56 -31
- package/dist/index.d.ts +9 -9
- package/dist/index.js +9 -9
- package/dist/messages.d.ts +117 -99
- package/dist/messages.js +55 -40
- package/dist/paths.d.ts +2 -2
- package/dist/paths.js +9 -11
- package/dist/transport.js +7 -7
- package/dist/types.d.ts +48 -36
- package/dist/types.js +42 -36
- package/package.json +44 -39
package/dist/messages.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import { AUDIO_DELAY_MAX_MS } from
|
|
3
|
-
import { helloParamsSchema, helloResultSchema
|
|
4
|
-
import { balancerAlgorithmSchema, bitrateControlSchema, captureDeviceKindSchema, captureDeviceSchema, cerastreamConfigSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, previewTierSchema, streamStateSchema, videoCodecSchema, } from
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { AUDIO_DELAY_MAX_MS } from './constants.js';
|
|
3
|
+
import { helloParamsSchema, helloResultSchema } from './envelope.js';
|
|
4
|
+
import { balancerAlgorithmSchema, bitrateControlSchema, captureDeviceKindSchema, captureDeviceSchema, cerastreamConfigSchema, configChangePhaseSchema, inputModeSchema, mediaClassSchema, previewEncodeModeSchema, previewTierSchema, streamStateSchema, videoCodecSchema, } from './types.js';
|
|
5
5
|
// The eight v1 control methods (schema.md "v1 messages"). Each is matched
|
|
6
6
|
// byte-for-byte to schema.md: the JSON shape on the wire is the contract.
|
|
7
7
|
// ---- 1. start ----
|
|
@@ -45,6 +45,12 @@ export const reloadConfigParamsSchema = z.object({
|
|
|
45
45
|
meter_device: z.string().nullable().optional(),
|
|
46
46
|
})
|
|
47
47
|
.optional(),
|
|
48
|
+
// Absent leaves the engine's current preview-encoder selection unchanged. This
|
|
49
|
+
// belongs on `reload-config` rather than `change-config`: the preview encoder is
|
|
50
|
+
// fixed when a session graph is built, so it takes effect on the NEXT stream
|
|
51
|
+
// session, and routing it through the transactional method would restart a live
|
|
52
|
+
// stream to change a preview setting.
|
|
53
|
+
preview_encode: previewEncodeModeSchema.optional(),
|
|
48
54
|
});
|
|
49
55
|
export const reloadConfigResultSchema = z.object({
|
|
50
56
|
applied: reloadConfigParamsSchema, // post-clamp values actually applied
|
|
@@ -67,7 +73,7 @@ export const setBitrateResultSchema = z.object({
|
|
|
67
73
|
// ---- 5. switch-input ----
|
|
68
74
|
export const switchInputParamsSchema = z.object({
|
|
69
75
|
input_id: z.string(), // device/input identifier from list-devices
|
|
70
|
-
mode: inputModeSchema.default(
|
|
76
|
+
mode: inputModeSchema.default('manual'),
|
|
71
77
|
});
|
|
72
78
|
export const switchInputResultSchema = z.object({
|
|
73
79
|
active_input: z.string(),
|
|
@@ -96,15 +102,15 @@ export const listDevicesResultSchema = z.object({
|
|
|
96
102
|
});
|
|
97
103
|
// ---- 7. subscribe-events ----
|
|
98
104
|
export const eventTopicSchema = z.enum([
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
105
|
+
'status',
|
|
106
|
+
'switch',
|
|
107
|
+
'device',
|
|
108
|
+
'bitrate',
|
|
109
|
+
'srt-stats',
|
|
110
|
+
'error',
|
|
111
|
+
'preview',
|
|
112
|
+
'audio-level',
|
|
113
|
+
'config-change',
|
|
108
114
|
]);
|
|
109
115
|
export const subscribeEventsParamsSchema = z.object({
|
|
110
116
|
topics: z.array(eventTopicSchema).optional(), // default: all topics
|
|
@@ -113,14 +119,14 @@ export const subscribeEventsResultSchema = z.object({
|
|
|
113
119
|
subscribed: z.array(eventTopicSchema),
|
|
114
120
|
});
|
|
115
121
|
// ---- 8. preview-session ----
|
|
116
|
-
export const previewSessionParamsSchema = z.discriminatedUnion(
|
|
122
|
+
export const previewSessionParamsSchema = z.discriminatedUnion('action', [
|
|
117
123
|
z.object({
|
|
118
|
-
action: z.literal(
|
|
124
|
+
action: z.literal('start'),
|
|
119
125
|
tier: previewTierSchema,
|
|
120
126
|
}),
|
|
121
|
-
z.object({ action: z.literal(
|
|
127
|
+
z.object({ action: z.literal('stop'), session_id: z.string() }),
|
|
122
128
|
z.object({
|
|
123
|
-
action: z.literal(
|
|
129
|
+
action: z.literal('signal'), // webrtc only
|
|
124
130
|
session_id: z.string(),
|
|
125
131
|
sdp: z.string().optional(),
|
|
126
132
|
ice: z.unknown().optional(),
|
|
@@ -129,12 +135,12 @@ export const previewSessionParamsSchema = z.discriminatedUnion("action", [
|
|
|
129
135
|
export const previewSessionResultSchema = z.object({
|
|
130
136
|
session_id: z.string(),
|
|
131
137
|
tier: previewTierSchema,
|
|
132
|
-
transport: z.discriminatedUnion(
|
|
138
|
+
transport: z.discriminatedUnion('kind', [
|
|
133
139
|
z.object({
|
|
134
|
-
kind: z.literal(
|
|
135
|
-
socket: z.literal(
|
|
140
|
+
kind: z.literal('uds-binary'),
|
|
141
|
+
socket: z.literal('/run/cerastream/preview.sock'),
|
|
136
142
|
}),
|
|
137
|
-
z.object({ kind: z.literal(
|
|
143
|
+
z.object({ kind: z.literal('webrtc'), sdp: z.string().optional() }),
|
|
138
144
|
]),
|
|
139
145
|
});
|
|
140
146
|
// ---- 9. get-capabilities ----
|
|
@@ -170,8 +176,8 @@ export const platformCapsSchema = z.object({
|
|
|
170
176
|
max_resolution: z.string(),
|
|
171
177
|
// additive: the engine's resolved hardware kind and how it was resolved.
|
|
172
178
|
// Optional so a pre-field engine (which omits both) still parses.
|
|
173
|
-
hardware_kind: z.enum([
|
|
174
|
-
source: z.enum([
|
|
179
|
+
hardware_kind: z.enum(['rk3588', 'jetson', 'n100', 'generic']).optional(),
|
|
180
|
+
source: z.enum(['detected', 'override']).optional(),
|
|
175
181
|
});
|
|
176
182
|
// Preview-server availability (0.4.0, additive). Lets the UI tell an unbound /
|
|
177
183
|
// port-conflicted preview (enabled:true, bound:false) from a down engine.
|
|
@@ -179,6 +185,15 @@ export const previewAvailabilitySchema = z.object({
|
|
|
179
185
|
enabled: z.boolean(),
|
|
180
186
|
port: z.number().int().min(1).max(65535).optional(), // present when a listener is (or would be) bound
|
|
181
187
|
bound: z.boolean(),
|
|
188
|
+
// Whether this PLATFORM publishes a hardware preview encoder at all — the fact
|
|
189
|
+
// that decides whether a hardware-preview toggle may be offered. It rides the
|
|
190
|
+
// capability fetch rather than stream status because a consumer reads
|
|
191
|
+
// capabilities while IDLE, which is exactly when the operator picks the setting.
|
|
192
|
+
// Three readings, none interchangeable: absent ⇒ legacy engine, capability
|
|
193
|
+
// UNKNOWN (never assume false); false ⇒ this board publishes none, hide the
|
|
194
|
+
// toggle; true ⇒ it does. Independent of whether any session is realizing it
|
|
195
|
+
// (`status.preview_encoder_realized`).
|
|
196
|
+
preview_hw_capability: z.boolean().optional(),
|
|
182
197
|
});
|
|
183
198
|
export const getCapabilitiesResultSchema = z.object({
|
|
184
199
|
platform: platformCapsSchema,
|
|
@@ -216,7 +231,7 @@ export const changeConfigParamsSchema = z
|
|
|
216
231
|
input_mode: captureDeviceKindSchema.optional(),
|
|
217
232
|
})
|
|
218
233
|
.refine((delta) => Object.keys(delta).length > 0, {
|
|
219
|
-
message:
|
|
234
|
+
message: 'change-config delta must carry at least one field',
|
|
220
235
|
});
|
|
221
236
|
// `Ok` for every phase the transaction actually reached — INCLUDING
|
|
222
237
|
// `rollback_failed`, an honest terminal outcome rather than an RPC fault. A
|
|
@@ -235,18 +250,18 @@ export const changeConfigResultSchema = z.object({
|
|
|
235
250
|
* refuses to build a second session that would race it. Mirrors the Rust
|
|
236
251
|
* `REASON_TEARDOWN_TIMEOUT`; consumers render it distinctly.
|
|
237
252
|
*/
|
|
238
|
-
export const REASON_TEARDOWN_TIMEOUT =
|
|
253
|
+
export const REASON_TEARDOWN_TIMEOUT = 'teardown_timeout';
|
|
239
254
|
// ---- method registry (count-assertion source of truth) ----
|
|
240
255
|
/** The eight v1 control methods (the literal JSON-RPC `method` strings). */
|
|
241
256
|
export const V1_METHODS = [
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
257
|
+
'start',
|
|
258
|
+
'stop',
|
|
259
|
+
'reload-config',
|
|
260
|
+
'set-bitrate',
|
|
261
|
+
'switch-input',
|
|
262
|
+
'list-devices',
|
|
263
|
+
'subscribe-events',
|
|
264
|
+
'preview-session',
|
|
250
265
|
];
|
|
251
266
|
/**
|
|
252
267
|
* method → { params, result } Zod schema pair. `hello` is the handshake; the
|
|
@@ -257,27 +272,27 @@ export const requestSchemas = {
|
|
|
257
272
|
hello: { params: helloParamsSchema, result: helloResultSchema },
|
|
258
273
|
start: { params: startParamsSchema, result: startResultSchema },
|
|
259
274
|
stop: { params: stopParamsSchema, result: stopResultSchema },
|
|
260
|
-
|
|
275
|
+
'reload-config': {
|
|
261
276
|
params: reloadConfigParamsSchema,
|
|
262
277
|
result: reloadConfigResultSchema,
|
|
263
278
|
},
|
|
264
|
-
|
|
279
|
+
'set-bitrate': {
|
|
265
280
|
params: setBitrateParamsSchema,
|
|
266
281
|
result: setBitrateResultSchema,
|
|
267
282
|
},
|
|
268
|
-
|
|
283
|
+
'switch-input': {
|
|
269
284
|
params: switchInputParamsSchema,
|
|
270
285
|
result: switchInputResultSchema,
|
|
271
286
|
},
|
|
272
|
-
|
|
287
|
+
'list-devices': {
|
|
273
288
|
params: listDevicesParamsSchema,
|
|
274
289
|
result: listDevicesResultSchema,
|
|
275
290
|
},
|
|
276
|
-
|
|
291
|
+
'subscribe-events': {
|
|
277
292
|
params: subscribeEventsParamsSchema,
|
|
278
293
|
result: subscribeEventsResultSchema,
|
|
279
294
|
},
|
|
280
|
-
|
|
295
|
+
'preview-session': {
|
|
281
296
|
params: previewSessionParamsSchema,
|
|
282
297
|
result: previewSessionResultSchema,
|
|
283
298
|
},
|
package/dist/paths.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, PREVIEW_SOCKET_NAME } from
|
|
1
|
+
import { CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, PREVIEW_SOCKET_NAME } from './constants.js';
|
|
2
2
|
/** Resolve the IPC runtime dir: explicit override → {@link IPC_DIR_ENV} → default. */
|
|
3
3
|
export declare function resolveIpcDir(override?: string): string;
|
|
4
4
|
/** Resolve the control-plane socket path within the (possibly overridden) IPC dir. */
|
|
@@ -11,4 +11,4 @@ export declare function previewSocketPath(dir?: string): string;
|
|
|
11
11
|
* `/usr/bin/cerastream` → the bare name (let PATH decide).
|
|
12
12
|
*/
|
|
13
13
|
export declare function getCerastreamExec(execPath?: string): string;
|
|
14
|
-
export {
|
|
14
|
+
export { CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, PREVIEW_SOCKET_NAME };
|
package/dist/paths.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { execSync } from
|
|
2
|
-
import { existsSync, statSync } from
|
|
3
|
-
import { join } from
|
|
4
|
-
import { CERASTREAM_BIN, CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, IPC_DIR_ENV, PREVIEW_SOCKET_NAME, } from
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, statSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { CERASTREAM_BIN, CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, IPC_DIR_ENV, PREVIEW_SOCKET_NAME, } from './constants.js';
|
|
5
5
|
// Socket-path + engine-exec helpers (ADR-0002 §3). They resolve the runtime IPC
|
|
6
6
|
// dir from the CERASTREAM_IPC_DIR override (then the explicit arg), defaulting to
|
|
7
7
|
// /run/cerastream. cerastream is a systemd-owned service (ADR-0005) — CeraUI
|
|
@@ -34,9 +34,7 @@ export function getCerastreamExec(execPath) {
|
|
|
34
34
|
const inDir = join(execPath, CERASTREAM_BIN);
|
|
35
35
|
if (isFile(inDir))
|
|
36
36
|
return inDir;
|
|
37
|
-
return execPath.endsWith(CERASTREAM_BIN)
|
|
38
|
-
? execPath
|
|
39
|
-
: join(execPath, CERASTREAM_BIN);
|
|
37
|
+
return execPath.endsWith(CERASTREAM_BIN) ? execPath : join(execPath, CERASTREAM_BIN);
|
|
40
38
|
}
|
|
41
39
|
const onPath = findInPath(CERASTREAM_BIN);
|
|
42
40
|
if (onPath)
|
|
@@ -57,10 +55,10 @@ function isFile(p) {
|
|
|
57
55
|
function findInPath(name) {
|
|
58
56
|
try {
|
|
59
57
|
const out = execSync(`command -v ${name}`, {
|
|
60
|
-
encoding:
|
|
61
|
-
stdio: [
|
|
58
|
+
encoding: 'utf-8',
|
|
59
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
62
60
|
}).trim();
|
|
63
|
-
const first = out.split(
|
|
61
|
+
const first = out.split('\n')[0]?.trim();
|
|
64
62
|
if (first && existsSync(first))
|
|
65
63
|
return first;
|
|
66
64
|
}
|
|
@@ -69,4 +67,4 @@ function findInPath(name) {
|
|
|
69
67
|
}
|
|
70
68
|
return undefined;
|
|
71
69
|
}
|
|
72
|
-
export {
|
|
70
|
+
export { CONTROL_SOCKET_NAME, DEFAULT_IPC_DIR, PREVIEW_SOCKET_NAME };
|
package/dist/transport.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MAX_LINE_BYTES } from
|
|
1
|
+
import { MAX_LINE_BYTES } from './constants.js';
|
|
2
2
|
/**
|
|
3
3
|
* A single Unix-socket connection that frames bytes into NDJSON lines. Construct,
|
|
4
4
|
* `open()` (rejects if the socket can't be reached), `send()` lines, `close()`
|
|
@@ -7,7 +7,7 @@ import { MAX_LINE_BYTES } from "./constants.js";
|
|
|
7
7
|
export class LineSocket {
|
|
8
8
|
socketPath;
|
|
9
9
|
socket;
|
|
10
|
-
buffer =
|
|
10
|
+
buffer = '';
|
|
11
11
|
bufferedBytes = 0;
|
|
12
12
|
handlers;
|
|
13
13
|
closed = false;
|
|
@@ -39,7 +39,7 @@ export class LineSocket {
|
|
|
39
39
|
*/
|
|
40
40
|
send(line) {
|
|
41
41
|
if (this.closed || !this.socket) {
|
|
42
|
-
throw new Error(
|
|
42
|
+
throw new Error('LineSocket.send: socket is not open');
|
|
43
43
|
}
|
|
44
44
|
this.socket.write(`${line}\n`);
|
|
45
45
|
this.socket.flush();
|
|
@@ -61,9 +61,9 @@ export class LineSocket {
|
|
|
61
61
|
onData(chunk) {
|
|
62
62
|
if (this.closed)
|
|
63
63
|
return;
|
|
64
|
-
this.buffer += chunk.toString(
|
|
64
|
+
this.buffer += chunk.toString('utf8');
|
|
65
65
|
this.bufferedBytes += chunk.byteLength;
|
|
66
|
-
let nl = this.buffer.indexOf(
|
|
66
|
+
let nl = this.buffer.indexOf('\n');
|
|
67
67
|
if (nl === -1) {
|
|
68
68
|
// No complete line yet — guard the unbounded-line case (fatal framing error).
|
|
69
69
|
if (this.bufferedBytes > MAX_LINE_BYTES) {
|
|
@@ -80,9 +80,9 @@ export class LineSocket {
|
|
|
80
80
|
}
|
|
81
81
|
if (line.length > 0)
|
|
82
82
|
this.handlers?.onLine(line);
|
|
83
|
-
nl = this.buffer.indexOf(
|
|
83
|
+
nl = this.buffer.indexOf('\n');
|
|
84
84
|
}
|
|
85
|
-
this.bufferedBytes = Buffer.byteLength(this.buffer,
|
|
85
|
+
this.bufferedBytes = Buffer.byteLength(this.buffer, 'utf8');
|
|
86
86
|
}
|
|
87
87
|
fail(err) {
|
|
88
88
|
this.fireClose(err);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import { z } from
|
|
1
|
+
import { z } from 'zod';
|
|
2
2
|
export declare const streamStateSchema: z.ZodEnum<{
|
|
3
3
|
idle: "idle";
|
|
4
4
|
starting: "starting";
|
|
5
|
-
streaming: "streaming";
|
|
6
5
|
stopping: "stopping";
|
|
6
|
+
streaming: "streaming";
|
|
7
7
|
}>;
|
|
8
8
|
export type StreamState = z.infer<typeof streamStateSchema>;
|
|
9
9
|
export declare const inputModeSchema: z.ZodEnum<{
|
|
10
|
-
manual: "manual";
|
|
11
10
|
auto: "auto";
|
|
11
|
+
manual: "manual";
|
|
12
12
|
}>;
|
|
13
13
|
export type InputMode = z.infer<typeof inputModeSchema>;
|
|
14
14
|
export declare const balancerAlgorithmSchema: z.ZodEnum<{
|
|
15
15
|
adaptive: "adaptive";
|
|
16
|
-
fixed: "fixed";
|
|
17
16
|
aimd: "aimd";
|
|
17
|
+
fixed: "fixed";
|
|
18
18
|
}>;
|
|
19
19
|
export type BalancerAlgorithm = z.infer<typeof balancerAlgorithmSchema>;
|
|
20
20
|
export declare const mediaClassSchema: z.ZodEnum<{
|
|
21
|
-
video: "video";
|
|
22
21
|
audio: "audio";
|
|
22
|
+
video: "video";
|
|
23
23
|
}>;
|
|
24
24
|
export type MediaClass = z.infer<typeof mediaClassSchema>;
|
|
25
25
|
export declare const previewTierSchema: z.ZodEnum<{
|
|
@@ -27,6 +27,18 @@ export declare const previewTierSchema: z.ZodEnum<{
|
|
|
27
27
|
webrtc: "webrtc";
|
|
28
28
|
}>;
|
|
29
29
|
export type PreviewTier = z.infer<typeof previewTierSchema>;
|
|
30
|
+
export declare const previewEncodeModeSchema: z.ZodEnum<{
|
|
31
|
+
hardware: "hardware";
|
|
32
|
+
software: "software";
|
|
33
|
+
}>;
|
|
34
|
+
export type PreviewEncodeMode = z.infer<typeof previewEncodeModeSchema>;
|
|
35
|
+
export declare const previewEncodeFallbackSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
36
|
+
code: z.ZodLiteral<"factory-missing">;
|
|
37
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
38
|
+
code: z.ZodLiteral<"property-failure">;
|
|
39
|
+
property: z.ZodString;
|
|
40
|
+
}, z.core.$strip>], "code">;
|
|
41
|
+
export type PreviewEncodeFallback = z.infer<typeof previewEncodeFallbackSchema>;
|
|
30
42
|
export declare const videoCodecSchema: z.ZodEnum<{
|
|
31
43
|
h264: "h264";
|
|
32
44
|
h265: "h265";
|
|
@@ -45,25 +57,25 @@ export declare const bitrateControlSchema: z.ZodEnum<{
|
|
|
45
57
|
export type BitrateControl = z.infer<typeof bitrateControlSchema>;
|
|
46
58
|
export declare const captureDeviceKindSchema: z.ZodEnum<{
|
|
47
59
|
audio: "audio";
|
|
60
|
+
camlink: "camlink";
|
|
48
61
|
hdmi: "hdmi";
|
|
49
|
-
uvc_h264: "uvc_h264";
|
|
50
|
-
uvc_h265: "uvc_h265";
|
|
51
62
|
mjpeg: "mjpeg";
|
|
52
|
-
camlink: "camlink";
|
|
53
|
-
test: "test";
|
|
54
63
|
network: "network";
|
|
64
|
+
test: "test";
|
|
65
|
+
uvc_h264: "uvc_h264";
|
|
66
|
+
uvc_h265: "uvc_h265";
|
|
55
67
|
}>;
|
|
56
68
|
export type CaptureDeviceKind = z.infer<typeof captureDeviceKindSchema>;
|
|
57
69
|
export declare const deviceTransportSchema: z.ZodEnum<{
|
|
58
|
-
hdmi: "hdmi";
|
|
59
|
-
usb: "usb";
|
|
60
70
|
bluetooth: "bluetooth";
|
|
71
|
+
hdmi: "hdmi";
|
|
61
72
|
onboard: "onboard";
|
|
73
|
+
usb: "usb";
|
|
62
74
|
}>;
|
|
63
75
|
export type DeviceTransport = z.infer<typeof deviceTransportSchema>;
|
|
64
76
|
export declare const configChangePhaseSchema: z.ZodEnum<{
|
|
65
|
-
applying: "applying";
|
|
66
77
|
applied: "applied";
|
|
78
|
+
applying: "applying";
|
|
67
79
|
reverted: "reverted";
|
|
68
80
|
rollback_failed: "rollback_failed";
|
|
69
81
|
}>;
|
|
@@ -86,8 +98,8 @@ export declare const bitrateConfigSchema: z.ZodObject<{
|
|
|
86
98
|
max_bitrate: z.ZodNumber;
|
|
87
99
|
balancer: z.ZodDefault<z.ZodEnum<{
|
|
88
100
|
adaptive: "adaptive";
|
|
89
|
-
fixed: "fixed";
|
|
90
101
|
aimd: "aimd";
|
|
102
|
+
fixed: "fixed";
|
|
91
103
|
}>>;
|
|
92
104
|
}, z.core.$strip>;
|
|
93
105
|
export type BitrateConfig = z.infer<typeof bitrateConfigSchema>;
|
|
@@ -100,15 +112,15 @@ export type BitrateConfig = z.infer<typeof bitrateConfigSchema>;
|
|
|
100
112
|
*/
|
|
101
113
|
export declare const audioModeSchema: z.ZodEnum<{
|
|
102
114
|
default: "default";
|
|
103
|
-
none: "none";
|
|
104
115
|
device: "device";
|
|
116
|
+
none: "none";
|
|
105
117
|
}>;
|
|
106
118
|
export type AudioMode = z.infer<typeof audioModeSchema>;
|
|
107
119
|
export declare const audioConfigSchema: z.ZodObject<{
|
|
108
120
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
109
121
|
default: "default";
|
|
110
|
-
none: "none";
|
|
111
122
|
device: "device";
|
|
123
|
+
none: "none";
|
|
112
124
|
}>>;
|
|
113
125
|
device: z.ZodOptional<z.ZodString>;
|
|
114
126
|
codec: z.ZodOptional<z.ZodString>;
|
|
@@ -138,8 +150,8 @@ export declare const cerastreamConfigSchema: z.ZodObject<{
|
|
|
138
150
|
max_bitrate: z.ZodNumber;
|
|
139
151
|
balancer: z.ZodDefault<z.ZodEnum<{
|
|
140
152
|
adaptive: "adaptive";
|
|
141
|
-
fixed: "fixed";
|
|
142
153
|
aimd: "aimd";
|
|
154
|
+
fixed: "fixed";
|
|
143
155
|
}>>;
|
|
144
156
|
}, z.core.$strip>;
|
|
145
157
|
input_id: z.ZodOptional<z.ZodString>;
|
|
@@ -152,8 +164,8 @@ export declare const cerastreamConfigSchema: z.ZodObject<{
|
|
|
152
164
|
audio: z.ZodOptional<z.ZodObject<{
|
|
153
165
|
mode: z.ZodOptional<z.ZodEnum<{
|
|
154
166
|
default: "default";
|
|
155
|
-
none: "none";
|
|
156
167
|
device: "device";
|
|
168
|
+
none: "none";
|
|
157
169
|
}>>;
|
|
158
170
|
device: z.ZodOptional<z.ZodString>;
|
|
159
171
|
codec: z.ZodOptional<z.ZodString>;
|
|
@@ -166,13 +178,13 @@ export declare const cerastreamConfigSchema: z.ZodObject<{
|
|
|
166
178
|
}>>;
|
|
167
179
|
input_mode: z.ZodOptional<z.ZodEnum<{
|
|
168
180
|
audio: "audio";
|
|
181
|
+
camlink: "camlink";
|
|
169
182
|
hdmi: "hdmi";
|
|
170
|
-
uvc_h264: "uvc_h264";
|
|
171
|
-
uvc_h265: "uvc_h265";
|
|
172
183
|
mjpeg: "mjpeg";
|
|
173
|
-
camlink: "camlink";
|
|
174
|
-
test: "test";
|
|
175
184
|
network: "network";
|
|
185
|
+
test: "test";
|
|
186
|
+
uvc_h264: "uvc_h264";
|
|
187
|
+
uvc_h265: "uvc_h265";
|
|
176
188
|
}>>;
|
|
177
189
|
}, z.core.$strip>;
|
|
178
190
|
export type CerastreamConfig = z.infer<typeof cerastreamConfigSchema>;
|
|
@@ -194,13 +206,13 @@ export declare const captureModeSchema: z.ZodObject<{
|
|
|
194
206
|
media_type: z.ZodString;
|
|
195
207
|
pipeline_kind: z.ZodEnum<{
|
|
196
208
|
audio: "audio";
|
|
209
|
+
camlink: "camlink";
|
|
197
210
|
hdmi: "hdmi";
|
|
198
|
-
uvc_h264: "uvc_h264";
|
|
199
|
-
uvc_h265: "uvc_h265";
|
|
200
211
|
mjpeg: "mjpeg";
|
|
201
|
-
camlink: "camlink";
|
|
202
|
-
test: "test";
|
|
203
212
|
network: "network";
|
|
213
|
+
test: "test";
|
|
214
|
+
uvc_h264: "uvc_h264";
|
|
215
|
+
uvc_h265: "uvc_h265";
|
|
204
216
|
}>;
|
|
205
217
|
caps: z.ZodArray<z.ZodObject<{
|
|
206
218
|
width: z.ZodOptional<z.ZodNumber>;
|
|
@@ -215,8 +227,8 @@ export declare const captureDeviceSchema: z.ZodObject<{
|
|
|
215
227
|
device_path: z.ZodString;
|
|
216
228
|
display_name: z.ZodString;
|
|
217
229
|
media_class: z.ZodEnum<{
|
|
218
|
-
video: "video";
|
|
219
230
|
audio: "audio";
|
|
231
|
+
video: "video";
|
|
220
232
|
}>;
|
|
221
233
|
caps: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
222
234
|
width: z.ZodOptional<z.ZodNumber>;
|
|
@@ -226,25 +238,25 @@ export declare const captureDeviceSchema: z.ZodObject<{
|
|
|
226
238
|
}, z.core.$strip>>>;
|
|
227
239
|
kind: z.ZodOptional<z.ZodEnum<{
|
|
228
240
|
audio: "audio";
|
|
241
|
+
camlink: "camlink";
|
|
229
242
|
hdmi: "hdmi";
|
|
230
|
-
uvc_h264: "uvc_h264";
|
|
231
|
-
uvc_h265: "uvc_h265";
|
|
232
243
|
mjpeg: "mjpeg";
|
|
233
|
-
camlink: "camlink";
|
|
234
|
-
test: "test";
|
|
235
244
|
network: "network";
|
|
245
|
+
test: "test";
|
|
246
|
+
uvc_h264: "uvc_h264";
|
|
247
|
+
uvc_h265: "uvc_h265";
|
|
236
248
|
}>>;
|
|
237
249
|
modes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
238
250
|
media_type: z.ZodString;
|
|
239
251
|
pipeline_kind: z.ZodEnum<{
|
|
240
252
|
audio: "audio";
|
|
253
|
+
camlink: "camlink";
|
|
241
254
|
hdmi: "hdmi";
|
|
242
|
-
uvc_h264: "uvc_h264";
|
|
243
|
-
uvc_h265: "uvc_h265";
|
|
244
255
|
mjpeg: "mjpeg";
|
|
245
|
-
camlink: "camlink";
|
|
246
|
-
test: "test";
|
|
247
256
|
network: "network";
|
|
257
|
+
test: "test";
|
|
258
|
+
uvc_h264: "uvc_h264";
|
|
259
|
+
uvc_h265: "uvc_h265";
|
|
248
260
|
}>;
|
|
249
261
|
caps: z.ZodArray<z.ZodObject<{
|
|
250
262
|
width: z.ZodOptional<z.ZodNumber>;
|
|
@@ -256,10 +268,10 @@ export declare const captureDeviceSchema: z.ZodObject<{
|
|
|
256
268
|
alsa_card_id: z.ZodOptional<z.ZodString>;
|
|
257
269
|
product_name: z.ZodOptional<z.ZodString>;
|
|
258
270
|
transport: z.ZodOptional<z.ZodEnum<{
|
|
259
|
-
hdmi: "hdmi";
|
|
260
|
-
usb: "usb";
|
|
261
271
|
bluetooth: "bluetooth";
|
|
272
|
+
hdmi: "hdmi";
|
|
262
273
|
onboard: "onboard";
|
|
274
|
+
usb: "usb";
|
|
263
275
|
}>>;
|
|
264
276
|
stable_id: z.ZodOptional<z.ZodString>;
|
|
265
277
|
physical_group_id: z.ZodOptional<z.ZodString>;
|
package/dist/types.js
CHANGED
|
@@ -1,57 +1,63 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import { DEFAULT_BALANCER, DEFAULT_MAX_BITRATE, DEFAULT_MIN_BITRATE, DEFAULT_SRT_LATENCY, } from
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { DEFAULT_BALANCER, DEFAULT_MAX_BITRATE, DEFAULT_MIN_BITRATE, DEFAULT_SRT_LATENCY, } from './constants.js';
|
|
3
3
|
// Shared domain enums + the unified engine config. Field names are domain-level
|
|
4
4
|
// (snake_case, matching the ceracoder config convention) — never engine
|
|
5
5
|
// internals (schema.md "Conventions").
|
|
6
|
-
export const streamStateSchema = z.enum([
|
|
7
|
-
|
|
8
|
-
"starting",
|
|
9
|
-
"streaming",
|
|
10
|
-
"stopping",
|
|
11
|
-
]);
|
|
12
|
-
export const inputModeSchema = z.enum(["manual", "auto"]);
|
|
6
|
+
export const streamStateSchema = z.enum(['idle', 'starting', 'streaming', 'stopping']);
|
|
7
|
+
export const inputModeSchema = z.enum(['manual', 'auto']);
|
|
13
8
|
// re-used from ceracoder (schema.md §"v1 messages" shared fragments)
|
|
14
|
-
export const balancerAlgorithmSchema = z.enum([
|
|
15
|
-
export const mediaClassSchema = z.enum([
|
|
16
|
-
export const previewTierSchema = z.enum([
|
|
9
|
+
export const balancerAlgorithmSchema = z.enum(['adaptive', 'fixed', 'aimd']);
|
|
10
|
+
export const mediaClassSchema = z.enum(['video', 'audio']);
|
|
11
|
+
export const previewTierSchema = z.enum(['webcodecs', 'webrtc']);
|
|
12
|
+
// Which encoder the LIVE preview branch uses. Set through `reload-config`
|
|
13
|
+
// (additive) and reported back as the ACTIVE mode on stream status. Applies to
|
|
14
|
+
// the NEXT stream session: the preview encoder is fixed when a session graph is
|
|
15
|
+
// built, so this never swaps an encoder mid-stream.
|
|
16
|
+
export const previewEncodeModeSchema = z.enum(['software', 'hardware']);
|
|
17
|
+
// Why a `hardware` preview request is encoding in software anyway — a tagged
|
|
18
|
+
// union so a consumer branches on `code` and still receives the detail a code
|
|
19
|
+
// carries. `property-failure` names the property the element refused, which is
|
|
20
|
+
// the difference between "hardware preview is broken" and "this image's encoder
|
|
21
|
+
// plugin does not take `rc-mode`". ABSENT is the normal case (software was
|
|
22
|
+
// chosen, hardware was delivered, or the board never offered the toggle) — there
|
|
23
|
+
// is deliberately no `{code:"none"}` sentinel.
|
|
24
|
+
export const previewEncodeFallbackSchema = z.discriminatedUnion('code', [
|
|
25
|
+
z.object({ code: z.literal('factory-missing') }),
|
|
26
|
+
z.object({ code: z.literal('property-failure'), property: z.string() }),
|
|
27
|
+
]);
|
|
17
28
|
// Requested egress video codec (0.4.0, additive). Absent ⇒ the engine picks its
|
|
18
29
|
// platform default. Wire values are the codec id strings the encoder caps also
|
|
19
30
|
// advertise ("h264"/"h265") — never an encoder element name.
|
|
20
|
-
export const videoCodecSchema = z.enum([
|
|
31
|
+
export const videoCodecSchema = z.enum(['h264', 'h265']);
|
|
21
32
|
// Same-codec passthrough policy (0.5.0, additive). Absent ⇒ "auto". "auto" =
|
|
22
33
|
// passthrough only when adaptive bitrate is inactive and eligibility holds;
|
|
23
34
|
// "force" = passthrough whenever eligible (typed start failure otherwise);
|
|
24
35
|
// "off" = always transcode. See schema.md and the engine's layer-C matrix.
|
|
25
|
-
export const videoPassthroughSchema = z.enum([
|
|
36
|
+
export const videoPassthroughSchema = z.enum(['auto', 'force', 'off']);
|
|
26
37
|
// Which surface owns the running bitrate, reported additively on a set-bitrate /
|
|
27
38
|
// reload-config response (0.5.0). "encoder" = applied; "source-fixed" = a
|
|
28
39
|
// passthrough graph fixes the bitrate at the source, so the request was NOT
|
|
29
40
|
// applied (paired with reason "passthrough").
|
|
30
|
-
export const bitrateControlSchema = z.enum([
|
|
41
|
+
export const bitrateControlSchema = z.enum(['encoder', 'source-fixed']);
|
|
31
42
|
// Engine-typed capture-device family (0.4.0, additive). CeraUI groups a device
|
|
32
43
|
// by the engine's resolved kind (a UVC/USB dongle is uvc_h264/mjpeg, never
|
|
33
44
|
// mislabeled HDMI). Absent ⇒ CeraUI falls back to a bus/name heuristic.
|
|
34
45
|
export const captureDeviceKindSchema = z.enum([
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
'hdmi',
|
|
47
|
+
'uvc_h264',
|
|
48
|
+
'uvc_h265',
|
|
49
|
+
'mjpeg',
|
|
50
|
+
'camlink',
|
|
51
|
+
'audio',
|
|
52
|
+
'test',
|
|
53
|
+
'network',
|
|
43
54
|
]);
|
|
44
55
|
// How a capture device is physically attached (Todo 20, additive). The transport
|
|
45
56
|
// tag CeraUI renders beside the product name (e.g. "RØDE NT-USB · USB"). Distinct
|
|
46
57
|
// from captureDeviceKind: an HDMI-to-USB dongle is kind:uvc_h264 but transport:usb,
|
|
47
58
|
// while the SoC's dedicated HDMI-RX port is transport:hdmi. Absent on a legacy
|
|
48
59
|
// producer or when no hint identifies a transport.
|
|
49
|
-
export const deviceTransportSchema = z.enum([
|
|
50
|
-
"usb",
|
|
51
|
-
"hdmi",
|
|
52
|
-
"bluetooth",
|
|
53
|
-
"onboard",
|
|
54
|
-
]);
|
|
60
|
+
export const deviceTransportSchema = z.enum(['usb', 'hdmi', 'bluetooth', 'onboard']);
|
|
55
61
|
// Phase of one `change-config` transaction (0.10.0, additive). `applying` is
|
|
56
62
|
// published once at entry, then exactly ONE terminal phase for the same
|
|
57
63
|
// attempt_id: `applied` (the new config satisfied the outcome gate),
|
|
@@ -59,10 +65,10 @@ export const deviceTransportSchema = z.enum([
|
|
|
59
65
|
// `rollback_failed` (no rollback was possible, or the one attempt also failed —
|
|
60
66
|
// the engine is idle, which is the truthful terminal state).
|
|
61
67
|
export const configChangePhaseSchema = z.enum([
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
68
|
+
'applying',
|
|
69
|
+
'applied',
|
|
70
|
+
'reverted',
|
|
71
|
+
'rollback_failed',
|
|
66
72
|
]);
|
|
67
73
|
// ---- config sub-schemas (canonical; reused by `start` + the unified config) ----
|
|
68
74
|
/** SRT transport config. Mirrors schema.md `start.srt` exactly. */
|
|
@@ -90,8 +96,8 @@ export const bitrateConfigSchema = z
|
|
|
90
96
|
})
|
|
91
97
|
// Mirrors the Rust dispatch guard: an inverted range can't drive the balancer.
|
|
92
98
|
.refine((b) => b.min_bitrate <= b.max_bitrate, {
|
|
93
|
-
message:
|
|
94
|
-
path: [
|
|
99
|
+
message: 'min_bitrate must not exceed max_bitrate',
|
|
100
|
+
path: ['min_bitrate'],
|
|
95
101
|
});
|
|
96
102
|
/**
|
|
97
103
|
* Audio config section of the unified engine config (0.4.0, additive). Every
|
|
@@ -106,7 +112,7 @@ export const bitrateConfigSchema = z
|
|
|
106
112
|
// leg (requires `device`). Absent ⇒ legacy inference from `device`/source kind,
|
|
107
113
|
// so a pre-0.6.0 caller keeps working. Replaces leaking pseudo-source strings
|
|
108
114
|
// (e.g. "No audio") into `device`.
|
|
109
|
-
export const audioModeSchema = z.enum([
|
|
115
|
+
export const audioModeSchema = z.enum(['none', 'default', 'device']);
|
|
110
116
|
export const audioConfigSchema = z.object({
|
|
111
117
|
mode: audioModeSchema.optional(),
|
|
112
118
|
device: z.string().optional(), // ALSA capture device id; absent ⇒ test-tone fallback
|