@camstack/addon-pipeline 1.1.19 → 1.1.21
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/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/audio-codec-ffmpeg/index.js +1125 -0
- package/dist/audio-codec-ffmpeg/index.mjs +1107 -0
- package/dist/decoder-ffmpeg/index.js +543 -288
- package/dist/decoder-ffmpeg/index.mjs +542 -287
- package/dist/detection-pipeline/index.js +1 -1
- package/dist/detection-pipeline/index.mjs +1 -1
- package/dist/{dist-BgoBMCez.js → dist-BiP1gPeY.js} +20 -1
- package/dist/{dist-7Yx2dmuV.mjs → dist-tzhTTRq4.mjs} +20 -1
- package/dist/{ffmpeg-args-common-c3p-nWtU.mjs → frame-dropper-CwkBTPGV.mjs} +22 -22
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +1 -1
- package/dist/pipeline-runner/index.mjs +1 -1
- package/dist/recorder/index.js +24 -4
- package/dist/recorder/index.mjs +24 -4
- package/dist/stream-broker/_stub.js +35 -35
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-w2pP0MYO.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-D08qJTw_.mjs} +3 -3
- package/dist/stream-broker/{hostInit-BUEbBinp.mjs → hostInit-CGnMNtPl.mjs} +3 -3
- package/dist/stream-broker/index.js +487 -458
- package/dist/stream-broker/index.mjs +477 -448
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-CYmHXacX.js → MaskShapeCanvas-DI4BY7W2-CW4Qu4V6.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-B-BkPQvX.js → MotionZonesSettings-NcxxQN8r-CHJ39tfi.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-DC3Jw85p.js → PrivacyMaskSettings-APgPLF7p-dInJ7kcz.js} +1 -1
- package/embed-dist/assets/{index-B0IQgci0.js → index-CKpVWKSG.js} +4 -4
- package/embed-dist/index.html +1 -1
- package/package.json +10 -10
- package/dist/audio-codec-nodeav/index.js +0 -310
- package/dist/audio-codec-nodeav/index.mjs +0 -305
- package/dist/codec-runtime-BOk-13PN.js +0 -202
- package/dist/codec-runtime-BsqlEjPi.mjs +0 -197
- package/dist/{ffmpeg-args-common-CASoNt42.js → frame-dropper-7RTo_YyG.js} +21 -21
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BnQ_awK4.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-BiP1gPeY.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_model_download_service_C_IHWnXx.__toESM(node_fs);
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __require } from "../chunk-BdkLduGY.mjs";
|
|
2
|
-
import { A as nodePin, B as BaseAddon, C as detectionPipelineCapability, J as hydrateSchema, L as supportedRuntimes$1, P as runtimeDevices$1, T as hfModelUrl, W as EventCategory, Z as parseJsonUnknown, a as COCO_TO_MACRO, et as sleep, i as COCO_80_LABELS, j as pipelineExecutorCapability, p as YAMNET_TO_MACRO, q as createEvent, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, w as evaluateZoneRules, x as defaultDeviceFor$1, z as errMsg } from "../dist-
|
|
2
|
+
import { A as nodePin, B as BaseAddon, C as detectionPipelineCapability, J as hydrateSchema, L as supportedRuntimes$1, P as runtimeDevices$1, T as hfModelUrl, W as EventCategory, Z as parseJsonUnknown, a as COCO_TO_MACRO, et as sleep, i as COCO_80_LABELS, j as pipelineExecutorCapability, p as YAMNET_TO_MACRO, q as createEvent, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, w as evaluateZoneRules, x as defaultDeviceFor$1, z as errMsg } from "../dist-tzhTTRq4.mjs";
|
|
3
3
|
import { a as isModelDownloaded, i as ensureModel, n as deleteModelFromDisk } from "../model-download-service-C-IHWnXx-3Mmeob3l.mjs";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import * as path$1 from "node:path";
|
|
@@ -7214,7 +7214,21 @@ var StorageLocationDeclarationSchema = object({
|
|
|
7214
7214
|
* slots (e.g. `recordingsLow` → `recordings`) so operators only need to
|
|
7215
7215
|
* configure the primary location.
|
|
7216
7216
|
*/
|
|
7217
|
-
defaultsTo: string().optional()
|
|
7217
|
+
defaultsTo: string().optional(),
|
|
7218
|
+
/**
|
|
7219
|
+
* Which node root the seeded `<id>:default` instance is placed under on a
|
|
7220
|
+
* FRESH install:
|
|
7221
|
+
* - `'data'` (default) — the node's data dir (`CAMSTACK_DATA` / boot dir),
|
|
7222
|
+
* the appData volume. Right for small/durable data (backups, logs, models).
|
|
7223
|
+
* - `'media'` — the dedicated media volume (`CAMSTACK_MEDIA_ROOT`) when that
|
|
7224
|
+
* env is set, else falls back to the data root. Right for bulky, hot media
|
|
7225
|
+
* (recordings, event media) that should stay off the appData disk.
|
|
7226
|
+
*
|
|
7227
|
+
* Only affects the seeded default's `basePath`; operators can repoint any
|
|
7228
|
+
* location afterwards, and a `defaultsTo` slot inherits its parent's root
|
|
7229
|
+
* regardless of this field. Absent (the common case) is treated as `'data'`.
|
|
7230
|
+
*/
|
|
7231
|
+
defaultRoot: _enum(["data", "media"]).optional()
|
|
7218
7232
|
});
|
|
7219
7233
|
var DecoderStatsSchema = object({
|
|
7220
7234
|
inputFps: number(),
|
|
@@ -8572,6 +8586,10 @@ var RtspRestreamEntrySchema = object({
|
|
|
8572
8586
|
var BrokerRtspClientSchema = object({
|
|
8573
8587
|
sessionId: string(),
|
|
8574
8588
|
remoteAddr: string(),
|
|
8589
|
+
/** Client `User-Agent` (e.g. `recorder` for the recorder's RTSP pull), or
|
|
8590
|
+
* null/absent when the client sent none. Lets the UI label a consumer by
|
|
8591
|
+
* purpose. Optional so a client built against an older schema stays valid. */
|
|
8592
|
+
userAgent: string().nullish(),
|
|
8575
8593
|
playing: boolean(),
|
|
8576
8594
|
muted: boolean(),
|
|
8577
8595
|
connectedAt: number(),
|
|
@@ -12844,6 +12862,7 @@ var audioCodecCapability = {
|
|
|
12844
12862
|
name: "audio-codec",
|
|
12845
12863
|
scope: "system",
|
|
12846
12864
|
mode: "singleton",
|
|
12865
|
+
preferredProvider: "audio-codec-ffmpeg",
|
|
12847
12866
|
methods: {
|
|
12848
12867
|
/** Probe the local runtime and return the supported codec matrix. */
|
|
12849
12868
|
listSupportedCodecs: method(_void(), array(AudioCodecInfoSchema).readonly()),
|
|
@@ -7214,7 +7214,21 @@ var StorageLocationDeclarationSchema = object({
|
|
|
7214
7214
|
* slots (e.g. `recordingsLow` → `recordings`) so operators only need to
|
|
7215
7215
|
* configure the primary location.
|
|
7216
7216
|
*/
|
|
7217
|
-
defaultsTo: string().optional()
|
|
7217
|
+
defaultsTo: string().optional(),
|
|
7218
|
+
/**
|
|
7219
|
+
* Which node root the seeded `<id>:default` instance is placed under on a
|
|
7220
|
+
* FRESH install:
|
|
7221
|
+
* - `'data'` (default) — the node's data dir (`CAMSTACK_DATA` / boot dir),
|
|
7222
|
+
* the appData volume. Right for small/durable data (backups, logs, models).
|
|
7223
|
+
* - `'media'` — the dedicated media volume (`CAMSTACK_MEDIA_ROOT`) when that
|
|
7224
|
+
* env is set, else falls back to the data root. Right for bulky, hot media
|
|
7225
|
+
* (recordings, event media) that should stay off the appData disk.
|
|
7226
|
+
*
|
|
7227
|
+
* Only affects the seeded default's `basePath`; operators can repoint any
|
|
7228
|
+
* location afterwards, and a `defaultsTo` slot inherits its parent's root
|
|
7229
|
+
* regardless of this field. Absent (the common case) is treated as `'data'`.
|
|
7230
|
+
*/
|
|
7231
|
+
defaultRoot: _enum(["data", "media"]).optional()
|
|
7218
7232
|
});
|
|
7219
7233
|
var DecoderStatsSchema = object({
|
|
7220
7234
|
inputFps: number(),
|
|
@@ -8572,6 +8586,10 @@ var RtspRestreamEntrySchema = object({
|
|
|
8572
8586
|
var BrokerRtspClientSchema = object({
|
|
8573
8587
|
sessionId: string(),
|
|
8574
8588
|
remoteAddr: string(),
|
|
8589
|
+
/** Client `User-Agent` (e.g. `recorder` for the recorder's RTSP pull), or
|
|
8590
|
+
* null/absent when the client sent none. Lets the UI label a consumer by
|
|
8591
|
+
* purpose. Optional so a client built against an older schema stays valid. */
|
|
8592
|
+
userAgent: string().nullish(),
|
|
8575
8593
|
playing: boolean(),
|
|
8576
8594
|
muted: boolean(),
|
|
8577
8595
|
connectedAt: number(),
|
|
@@ -12844,6 +12862,7 @@ var audioCodecCapability = {
|
|
|
12844
12862
|
name: "audio-codec",
|
|
12845
12863
|
scope: "system",
|
|
12846
12864
|
mode: "singleton",
|
|
12865
|
+
preferredProvider: "audio-codec-ffmpeg",
|
|
12847
12866
|
methods: {
|
|
12848
12867
|
/** Probe the local runtime and return the supported codec matrix. */
|
|
12849
12868
|
listSupportedCodecs: method(_void(), array(AudioCodecInfoSchema).readonly()),
|
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
//#region src/stream-broker/stream-broker/frame-dropper.ts
|
|
2
|
-
var FrameDropper = class {
|
|
3
|
-
intervalMs;
|
|
4
|
-
lastPassedAt = -Infinity;
|
|
5
|
-
constructor(maxFps) {
|
|
6
|
-
this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
|
|
7
|
-
}
|
|
8
|
-
shouldKeep() {
|
|
9
|
-
if (this.intervalMs === 0) return true;
|
|
10
|
-
const now = Date.now();
|
|
11
|
-
if (now - this.lastPassedAt >= this.intervalMs) {
|
|
12
|
-
this.lastPassedAt = now;
|
|
13
|
-
return true;
|
|
14
|
-
}
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
setMaxFps(maxFps) {
|
|
18
|
-
this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
//#endregion
|
|
22
1
|
//#region src/stream-broker/stream-broker/ffmpeg-args-common.ts
|
|
23
2
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
24
3
|
opus: "libopus",
|
|
@@ -48,4 +27,25 @@ function logBannerArgs(level) {
|
|
|
48
27
|
];
|
|
49
28
|
}
|
|
50
29
|
//#endregion
|
|
51
|
-
|
|
30
|
+
//#region src/stream-broker/stream-broker/frame-dropper.ts
|
|
31
|
+
var FrameDropper = class {
|
|
32
|
+
intervalMs;
|
|
33
|
+
lastPassedAt = -Infinity;
|
|
34
|
+
constructor(maxFps) {
|
|
35
|
+
this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
|
|
36
|
+
}
|
|
37
|
+
shouldKeep() {
|
|
38
|
+
if (this.intervalMs === 0) return true;
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
if (now - this.lastPassedAt >= this.intervalMs) {
|
|
41
|
+
this.lastPassedAt = now;
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
setMaxFps(maxFps) {
|
|
47
|
+
this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
//#endregion
|
|
51
|
+
export { audioEncoderArgs as n, logBannerArgs as r, FrameDropper as t };
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-BiP1gPeY.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BaseAddon, J as hydrateSchema, U as DeviceType, k as motionDetectionCapability, w as evaluateZoneRules } from "../dist-
|
|
1
|
+
import { B as BaseAddon, J as hydrateSchema, U as DeviceType, k as motionDetectionCapability, w as evaluateZoneRules } from "../dist-tzhTTRq4.mjs";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-BiP1gPeY.js");
|
|
6
6
|
let _camstack_shm_ring = require("@camstack/shm-ring");
|
|
7
7
|
//#region src/pipeline-runner/frame-queue.ts
|
|
8
8
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as nodePin, B as BaseAddon, M as pipelineRunnerCapability, S as defineCustomActions, W as EventCategory, X as makeSourceBrokerId, at as lazy, ct as object, nt as array, q as createEvent, rt as boolean, st as number, tt as _enum, ut as string, y as customAction, z as errMsg } from "../dist-
|
|
1
|
+
import { A as nodePin, B as BaseAddon, M as pipelineRunnerCapability, S as defineCustomActions, W as EventCategory, X as makeSourceBrokerId, at as lazy, ct as object, nt as array, q as createEvent, rt as boolean, st as number, tt as _enum, ut as string, y as customAction, z as errMsg } from "../dist-tzhTTRq4.mjs";
|
|
2
2
|
import { FrameRingReaderCache } from "@camstack/shm-ring";
|
|
3
3
|
//#region src/pipeline-runner/frame-queue.ts
|
|
4
4
|
/**
|
package/dist/recorder/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BnQ_awK4.js");
|
|
2
|
-
const require_dist = require("../dist-
|
|
2
|
+
const require_dist = require("../dist-BiP1gPeY.js");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_model_download_service_C_IHWnXx.__toESM(node_path);
|
|
@@ -965,6 +965,8 @@ function buildPassthroughArgs(a) {
|
|
|
965
965
|
return [
|
|
966
966
|
"-rtsp_transport",
|
|
967
967
|
"tcp",
|
|
968
|
+
"-user_agent",
|
|
969
|
+
"recorder",
|
|
968
970
|
"-i",
|
|
969
971
|
a.rtspUrl,
|
|
970
972
|
"-map",
|
|
@@ -1004,6 +1006,8 @@ var RESTART_MAX_MS = 1e4;
|
|
|
1004
1006
|
/** A process that ran at least this long is "stable" → reset the restart count,
|
|
1005
1007
|
* so sporadic blips over a long lifetime never accumulate into a give-up. */
|
|
1006
1008
|
var STABLE_RUN_MS = 3e4;
|
|
1009
|
+
/** Grace between the SIGTERM in stop() and the escalated SIGKILL. */
|
|
1010
|
+
var KILL_GRACE_MS = 500;
|
|
1007
1011
|
/** Supervises one passthrough ffmpeg for a single (camera, profile). */
|
|
1008
1012
|
var SegmentWriter = class {
|
|
1009
1013
|
cfg;
|
|
@@ -1068,8 +1072,17 @@ var SegmentWriter = class {
|
|
|
1068
1072
|
clearTimeout(this.restartTimer);
|
|
1069
1073
|
this.restartTimer = null;
|
|
1070
1074
|
}
|
|
1071
|
-
this.proc
|
|
1075
|
+
const proc = this.proc;
|
|
1072
1076
|
this.proc = null;
|
|
1077
|
+
if (!proc) return;
|
|
1078
|
+
try {
|
|
1079
|
+
proc.kill("SIGTERM");
|
|
1080
|
+
} catch {}
|
|
1081
|
+
setTimeout(() => {
|
|
1082
|
+
if (proc.exitCode === null && proc.signalCode === null) try {
|
|
1083
|
+
proc.kill("SIGKILL");
|
|
1084
|
+
} catch {}
|
|
1085
|
+
}, KILL_GRACE_MS).unref?.();
|
|
1073
1086
|
}
|
|
1074
1087
|
};
|
|
1075
1088
|
//#endregion
|
|
@@ -1893,12 +1906,19 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
1893
1906
|
statBytes: async (absPath) => (await node_fs.promises.stat(absPath)).size,
|
|
1894
1907
|
moveFile: async (fromAbs, toAbs) => {
|
|
1895
1908
|
await node_fs.promises.mkdir(node_path.default.dirname(toAbs), { recursive: true });
|
|
1896
|
-
|
|
1909
|
+
try {
|
|
1910
|
+
await node_fs.promises.rename(fromAbs, toAbs);
|
|
1911
|
+
} catch (err) {
|
|
1912
|
+
if (err.code !== "EXDEV") throw err;
|
|
1913
|
+
await node_fs.promises.copyFile(fromAbs, toAbs);
|
|
1914
|
+
await node_fs.promises.unlink(fromAbs);
|
|
1915
|
+
}
|
|
1897
1916
|
},
|
|
1898
1917
|
logger: { warn: (message, extras) => this.ctx.logger.warn(message, { meta: { extras } }) }
|
|
1899
1918
|
};
|
|
1900
1919
|
this.segmentStore = new SegmentStore(segmentStoreDeps);
|
|
1901
|
-
const
|
|
1920
|
+
const mediaRoot = process.env.CAMSTACK_MEDIA_ROOT?.trim();
|
|
1921
|
+
const tmpRoot = node_path.default.join(mediaRoot ?? this.ctx.dataDir, "rec-tmp");
|
|
1902
1922
|
const brokerHandle = this.ctx.useCapability("stream-broker", brokerScope(BROKER_HOST_NODE_ID));
|
|
1903
1923
|
this.controller = new RecordingController({
|
|
1904
1924
|
api: this.ctx.api,
|
package/dist/recorder/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as selectAssignedProfileSlots, B as BaseAddon, F as storageEvictableCapability, J as hydrateSchema, K as createDurableState, N as recordingCapability, O as migrateConfigToBands, U as DeviceType, W as EventCategory, d as RecordingConfigSchema, lt as record, ut as string, z as errMsg } from "../dist-
|
|
1
|
+
import { $ as selectAssignedProfileSlots, B as BaseAddon, F as storageEvictableCapability, J as hydrateSchema, K as createDurableState, N as recordingCapability, O as migrateConfigToBands, U as DeviceType, W as EventCategory, d as RecordingConfigSchema, lt as record, ut as string, z as errMsg } from "../dist-tzhTTRq4.mjs";
|
|
2
2
|
import { t as createFileDataPlaneHandler } from "../model-download-service-C-IHWnXx-3Mmeob3l.mjs";
|
|
3
3
|
import { promises } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -964,6 +964,8 @@ function buildPassthroughArgs(a) {
|
|
|
964
964
|
return [
|
|
965
965
|
"-rtsp_transport",
|
|
966
966
|
"tcp",
|
|
967
|
+
"-user_agent",
|
|
968
|
+
"recorder",
|
|
967
969
|
"-i",
|
|
968
970
|
a.rtspUrl,
|
|
969
971
|
"-map",
|
|
@@ -1003,6 +1005,8 @@ var RESTART_MAX_MS = 1e4;
|
|
|
1003
1005
|
/** A process that ran at least this long is "stable" → reset the restart count,
|
|
1004
1006
|
* so sporadic blips over a long lifetime never accumulate into a give-up. */
|
|
1005
1007
|
var STABLE_RUN_MS = 3e4;
|
|
1008
|
+
/** Grace between the SIGTERM in stop() and the escalated SIGKILL. */
|
|
1009
|
+
var KILL_GRACE_MS = 500;
|
|
1006
1010
|
/** Supervises one passthrough ffmpeg for a single (camera, profile). */
|
|
1007
1011
|
var SegmentWriter = class {
|
|
1008
1012
|
cfg;
|
|
@@ -1067,8 +1071,17 @@ var SegmentWriter = class {
|
|
|
1067
1071
|
clearTimeout(this.restartTimer);
|
|
1068
1072
|
this.restartTimer = null;
|
|
1069
1073
|
}
|
|
1070
|
-
this.proc
|
|
1074
|
+
const proc = this.proc;
|
|
1071
1075
|
this.proc = null;
|
|
1076
|
+
if (!proc) return;
|
|
1077
|
+
try {
|
|
1078
|
+
proc.kill("SIGTERM");
|
|
1079
|
+
} catch {}
|
|
1080
|
+
setTimeout(() => {
|
|
1081
|
+
if (proc.exitCode === null && proc.signalCode === null) try {
|
|
1082
|
+
proc.kill("SIGKILL");
|
|
1083
|
+
} catch {}
|
|
1084
|
+
}, KILL_GRACE_MS).unref?.();
|
|
1072
1085
|
}
|
|
1073
1086
|
};
|
|
1074
1087
|
//#endregion
|
|
@@ -1892,12 +1905,19 @@ var RecorderV2Addon = class extends BaseAddon {
|
|
|
1892
1905
|
statBytes: async (absPath) => (await promises.stat(absPath)).size,
|
|
1893
1906
|
moveFile: async (fromAbs, toAbs) => {
|
|
1894
1907
|
await promises.mkdir(path.dirname(toAbs), { recursive: true });
|
|
1895
|
-
|
|
1908
|
+
try {
|
|
1909
|
+
await promises.rename(fromAbs, toAbs);
|
|
1910
|
+
} catch (err) {
|
|
1911
|
+
if (err.code !== "EXDEV") throw err;
|
|
1912
|
+
await promises.copyFile(fromAbs, toAbs);
|
|
1913
|
+
await promises.unlink(fromAbs);
|
|
1914
|
+
}
|
|
1896
1915
|
},
|
|
1897
1916
|
logger: { warn: (message, extras) => this.ctx.logger.warn(message, { meta: { extras } }) }
|
|
1898
1917
|
};
|
|
1899
1918
|
this.segmentStore = new SegmentStore(segmentStoreDeps);
|
|
1900
|
-
const
|
|
1919
|
+
const mediaRoot = process.env.CAMSTACK_MEDIA_ROOT?.trim();
|
|
1920
|
+
const tmpRoot = path.join(mediaRoot ?? this.ctx.dataDir, "rec-tmp");
|
|
1901
1921
|
const brokerHandle = this.ctx.useCapability("stream-broker", brokerScope(BROKER_HOST_NODE_ID));
|
|
1902
1922
|
this.controller = new RecordingController({
|
|
1903
1923
|
api: this.ctx.api,
|
|
@@ -307,7 +307,7 @@ function ae({ outputArgs: e, onChange: t }) {
|
|
|
307
307
|
}
|
|
308
308
|
//#endregion
|
|
309
309
|
//#region src/stream-broker/widgets/FfmpegParamsField.tsx
|
|
310
|
-
var
|
|
310
|
+
var oe = [
|
|
311
311
|
{
|
|
312
312
|
group: "Demuxer",
|
|
313
313
|
label: "-thread_queue_size 1024",
|
|
@@ -350,7 +350,7 @@ var N = [
|
|
|
350
350
|
args: ["-stimeout", "5000000"],
|
|
351
351
|
description: "Socket I/O timeout (microseconds, 5s)"
|
|
352
352
|
}
|
|
353
|
-
],
|
|
353
|
+
], N = [
|
|
354
354
|
{
|
|
355
355
|
group: "Muxer",
|
|
356
356
|
label: "-flush_packets 1",
|
|
@@ -733,7 +733,7 @@ function ce({ config: t, value: n, onSave: i }) {
|
|
|
733
733
|
}), /* @__PURE__ */ g(B, {
|
|
734
734
|
id: `${t.fieldKey}-input-picker`,
|
|
735
735
|
disabled: !1,
|
|
736
|
-
catalogue:
|
|
736
|
+
catalogue: oe,
|
|
737
737
|
onPick: (e) => D("input", e)
|
|
738
738
|
})]
|
|
739
739
|
}), /* @__PURE__ */ g("textarea", {
|
|
@@ -765,7 +765,7 @@ function ce({ config: t, value: n, onSave: i }) {
|
|
|
765
765
|
}), /* @__PURE__ */ g(B, {
|
|
766
766
|
id: `${t.fieldKey}-output-picker`,
|
|
767
767
|
disabled: !1,
|
|
768
|
-
catalogue:
|
|
768
|
+
catalogue: N,
|
|
769
769
|
onPick: (e) => D("output", e)
|
|
770
770
|
})]
|
|
771
771
|
}), /* @__PURE__ */ g("textarea", {
|
|
@@ -954,16 +954,16 @@ function B({ id: e, disabled: n, catalogue: i, onPick: a }) {
|
|
|
954
954
|
//#endregion
|
|
955
955
|
//#region src/stream-broker/widgets/format-ua.ts
|
|
956
956
|
var V = 24;
|
|
957
|
-
function
|
|
957
|
+
function de(e) {
|
|
958
958
|
return /\bEdg\b|\bEdgA\b|\bEdgiOS\b|Edge\//.test(e) ? "Edge" : /\bOPR\b|Opera/.test(e) ? "Opera" : /Firefox\/|\bFxiOS\b/.test(e) ? "Firefox" : /Chrome\/|\bCriOS\b/.test(e) ? "Chrome" : /Safari\//.test(e) ? "Safari" : null;
|
|
959
959
|
}
|
|
960
|
-
function
|
|
960
|
+
function fe(e) {
|
|
961
961
|
return /iPhone|iPad|iPod|\biOS\b|CriOS|FxiOS/.test(e) ? "iOS" : /Mac OS X|Macintosh/.test(e) ? "macOS" : /Windows/.test(e) ? "Windows" : /Android/.test(e) ? "Android" : /Linux/.test(e) ? "Linux" : null;
|
|
962
962
|
}
|
|
963
|
-
function
|
|
963
|
+
function H(e) {
|
|
964
964
|
let t = e.trim();
|
|
965
965
|
if (t.length === 0) return "";
|
|
966
|
-
let n =
|
|
966
|
+
let n = de(t), r = fe(t);
|
|
967
967
|
return n && r ? `${n}/${r}` : n || r || (t.length > V ? `${t.slice(0, V)}…` : t);
|
|
968
968
|
}
|
|
969
969
|
//#endregion
|
|
@@ -982,7 +982,7 @@ var U = {
|
|
|
982
982
|
"high",
|
|
983
983
|
"mid",
|
|
984
984
|
"low"
|
|
985
|
-
],
|
|
985
|
+
], G = {
|
|
986
986
|
alexa: "bg-blue-500/15 text-blue-400",
|
|
987
987
|
homekit: "bg-purple-500/15 text-purple-400",
|
|
988
988
|
"webrtc-browser": "bg-emerald-500/15 text-emerald-400",
|
|
@@ -995,7 +995,7 @@ var U = {
|
|
|
995
995
|
snapshot: "bg-cyan-500/15 text-cyan-400",
|
|
996
996
|
warmup: "bg-foreground-subtle/10 text-foreground-subtle",
|
|
997
997
|
unknown: "bg-foreground-subtle/10 text-foreground-subtle"
|
|
998
|
-
},
|
|
998
|
+
}, K = {
|
|
999
999
|
alexa: "ALEXA",
|
|
1000
1000
|
homekit: "HOMEKIT",
|
|
1001
1001
|
"webrtc-browser": "BROWSER",
|
|
@@ -1009,25 +1009,25 @@ var U = {
|
|
|
1009
1009
|
warmup: "WARMUP",
|
|
1010
1010
|
unknown: "—"
|
|
1011
1011
|
};
|
|
1012
|
+
function me(e) {
|
|
1013
|
+
return K[e] ?? e.toUpperCase().slice(0, 8);
|
|
1014
|
+
}
|
|
1012
1015
|
function he(e) {
|
|
1013
|
-
return
|
|
1016
|
+
return K[e] ?? e;
|
|
1014
1017
|
}
|
|
1015
1018
|
function ge(e) {
|
|
1016
|
-
return G[e] ?? e;
|
|
1017
|
-
}
|
|
1018
|
-
function _e(e) {
|
|
1019
1019
|
let t = e.config ?? {};
|
|
1020
1020
|
return e.deviceId === void 0 ? /* @__PURE__ */ g("div", {
|
|
1021
1021
|
className: "rounded-lg border border-warning/30 bg-warning/10 px-3 py-2 text-xs text-warning",
|
|
1022
1022
|
children: "StreamBrokerPanel requires a deviceId"
|
|
1023
|
-
}) : /* @__PURE__ */ g(
|
|
1023
|
+
}) : /* @__PURE__ */ g(_e, {
|
|
1024
1024
|
deviceId: e.deviceId,
|
|
1025
1025
|
title: t.title,
|
|
1026
1026
|
variant: t.variant,
|
|
1027
1027
|
hideEmpty: t.hideEmpty
|
|
1028
1028
|
});
|
|
1029
1029
|
}
|
|
1030
|
-
function
|
|
1030
|
+
function _e({ deviceId: e, title: t = "Stream Brokers", variant: n = "full", hideEmpty: r = !1 }) {
|
|
1031
1031
|
f(["streamBroker", "listAllProfileSlots"], [
|
|
1032
1032
|
"device.streams-registered",
|
|
1033
1033
|
"device.streams-unregistered",
|
|
@@ -1048,7 +1048,7 @@ function ve({ deviceId: e, title: t = "Stream Brokers", variant: n = "full", hid
|
|
|
1048
1048
|
let d = new Set(a.map((e) => e.sourceCamStreamId).filter((e) => e !== null)), p = (c ?? []).filter((e) => !d.has(e.camStreamId)), m = a.length > 0, v = p.length > 0;
|
|
1049
1049
|
return r && !m && !v ? null : n === "compact" ? m ? /* @__PURE__ */ g("div", {
|
|
1050
1050
|
className: "divide-y divide-border/30",
|
|
1051
|
-
children: a.map((e) => /* @__PURE__ */ g(
|
|
1051
|
+
children: a.map((e) => /* @__PURE__ */ g(J, {
|
|
1052
1052
|
slot: e,
|
|
1053
1053
|
camStreams: l,
|
|
1054
1054
|
compact: !0
|
|
@@ -1071,7 +1071,7 @@ function ve({ deviceId: e, title: t = "Stream Brokers", variant: n = "full", hid
|
|
|
1071
1071
|
}),
|
|
1072
1072
|
m ? /* @__PURE__ */ g("div", {
|
|
1073
1073
|
className: "divide-y divide-border/30",
|
|
1074
|
-
children: a.map((e) => /* @__PURE__ */ g(
|
|
1074
|
+
children: a.map((e) => /* @__PURE__ */ g(J, {
|
|
1075
1075
|
slot: e,
|
|
1076
1076
|
camStreams: l,
|
|
1077
1077
|
compact: !1
|
|
@@ -1083,7 +1083,7 @@ function ve({ deviceId: e, title: t = "Stream Brokers", variant: n = "full", hid
|
|
|
1083
1083
|
children: "No profile slots assigned for this device"
|
|
1084
1084
|
})]
|
|
1085
1085
|
}),
|
|
1086
|
-
v && /* @__PURE__ */ g(
|
|
1086
|
+
v && /* @__PURE__ */ g(ve, {
|
|
1087
1087
|
deviceId: e,
|
|
1088
1088
|
camStreamIds: p.map((e) => e.camStreamId),
|
|
1089
1089
|
camStreams: l
|
|
@@ -1091,7 +1091,7 @@ function ve({ deviceId: e, title: t = "Stream Brokers", variant: n = "full", hid
|
|
|
1091
1091
|
]
|
|
1092
1092
|
});
|
|
1093
1093
|
}
|
|
1094
|
-
function
|
|
1094
|
+
function ve({ deviceId: e, camStreamIds: t, camStreams: n }) {
|
|
1095
1095
|
let [i, a] = r(!1);
|
|
1096
1096
|
return /* @__PURE__ */ _("div", {
|
|
1097
1097
|
className: "border-t border-border/50",
|
|
@@ -1108,7 +1108,7 @@ function ye({ deviceId: e, camStreamIds: t, camStreams: n }) {
|
|
|
1108
1108
|
})]
|
|
1109
1109
|
}), i && /* @__PURE__ */ g("div", {
|
|
1110
1110
|
className: "divide-y divide-border/30",
|
|
1111
|
-
children: t.map((t) => /* @__PURE__ */ g(
|
|
1111
|
+
children: t.map((t) => /* @__PURE__ */ g(ye, {
|
|
1112
1112
|
deviceId: e,
|
|
1113
1113
|
camStreamId: t,
|
|
1114
1114
|
camStreams: n
|
|
@@ -1116,7 +1116,7 @@ function ye({ deviceId: e, camStreamIds: t, camStreams: n }) {
|
|
|
1116
1116
|
})]
|
|
1117
1117
|
});
|
|
1118
1118
|
}
|
|
1119
|
-
function
|
|
1119
|
+
function ye({ deviceId: e, camStreamId: t, camStreams: n }) {
|
|
1120
1120
|
let r = x(e, t), i = c("stream-broker.metrics-snapshot", (e) => e.brokerId === r)?.stats, a = n.get(t), o = i?.status === "streaming";
|
|
1121
1121
|
return /* @__PURE__ */ _("div", {
|
|
1122
1122
|
className: "px-4 py-2",
|
|
@@ -1191,7 +1191,7 @@ function be({ deviceId: e, camStreamId: t, camStreams: n }) {
|
|
|
1191
1191
|
})]
|
|
1192
1192
|
});
|
|
1193
1193
|
}
|
|
1194
|
-
function
|
|
1194
|
+
function q(e, t) {
|
|
1195
1195
|
let n = (e) => {
|
|
1196
1196
|
if (!e || typeof e != "object") return;
|
|
1197
1197
|
let r = e;
|
|
@@ -1212,13 +1212,13 @@ function K(e, t) {
|
|
|
1212
1212
|
if (t !== void 0) return t;
|
|
1213
1213
|
}
|
|
1214
1214
|
}
|
|
1215
|
-
function
|
|
1215
|
+
function J({ slot: e, camStreams: t, compact: n }) {
|
|
1216
1216
|
let r = y(), a = c("stream-broker.metrics-snapshot", (t) => t.brokerId === e.brokerId)?.stats;
|
|
1217
1217
|
f(["streamBroker", "listClients"], ["stream-broker.metrics-snapshot"]);
|
|
1218
1218
|
let { data: s } = l({ brokerId: e.brokerId }, {
|
|
1219
1219
|
enabled: a?.status === "streaming",
|
|
1220
1220
|
staleTime: 2e3
|
|
1221
|
-
}), { data: u } = d({ deviceId: e.deviceId }, { staleTime: 15e3 }), m = e.sourceCamStreamId ?? e.profile, h = !!(
|
|
1221
|
+
}), { data: u } = d({ deviceId: e.deviceId }, { staleTime: 15e3 }), m = e.sourceCamStreamId ?? e.profile, h = !!(q(u, `preBufferEnabled:${m}`) ?? !0), b = q(u, `preBufferSec:${m}`), x = o({ onSuccess: () => {
|
|
1222
1222
|
r.invalidateQueries({ queryKey: [["streamBroker", "getDeviceSettingsContribution"]] });
|
|
1223
1223
|
} }), S = (t) => {
|
|
1224
1224
|
x.mutate({
|
|
@@ -1506,12 +1506,12 @@ function q({ slot: e, camStreams: t, compact: n }) {
|
|
|
1506
1506
|
]
|
|
1507
1507
|
});
|
|
1508
1508
|
}
|
|
1509
|
-
var
|
|
1509
|
+
var be = 280, xe = 120;
|
|
1510
1510
|
function Y({ trigger: t, content: n, widthClass: a }) {
|
|
1511
1511
|
let o = e(null), s = e(null), [c, l] = r(!1), [u, d] = r(!1), f = i(() => {
|
|
1512
1512
|
s.current &&= (clearTimeout(s.current), null);
|
|
1513
1513
|
}, []), p = i(() => {
|
|
1514
|
-
f(), s.current = setTimeout(() => l(!1),
|
|
1514
|
+
f(), s.current = setTimeout(() => l(!1), xe);
|
|
1515
1515
|
}, [f]);
|
|
1516
1516
|
return /* @__PURE__ */ _("span", {
|
|
1517
1517
|
ref: o,
|
|
@@ -1521,7 +1521,7 @@ function Y({ trigger: t, content: n, widthClass: a }) {
|
|
|
1521
1521
|
let e = o.current;
|
|
1522
1522
|
if (e) {
|
|
1523
1523
|
let t = e.getBoundingClientRect(), n = window.innerHeight - t.bottom, r = t.top;
|
|
1524
|
-
d(n <
|
|
1524
|
+
d(n < be && r > n);
|
|
1525
1525
|
}
|
|
1526
1526
|
l(!0);
|
|
1527
1527
|
}, [f]),
|
|
@@ -1600,7 +1600,7 @@ function Se({ clients: e, encodedCount: t, onKill: n }) {
|
|
|
1600
1600
|
return /* @__PURE__ */ g(Q, {
|
|
1601
1601
|
kind: "RTSP",
|
|
1602
1602
|
kindClass: "bg-warning/10 text-warning",
|
|
1603
|
-
tag: e.remoteAddr,
|
|
1603
|
+
tag: e.userAgent ? H(e.userAgent) : e.remoteAddr,
|
|
1604
1604
|
state: {
|
|
1605
1605
|
text: i + (e.muted ? " · muted" : ""),
|
|
1606
1606
|
className: a
|
|
@@ -1614,11 +1614,11 @@ function Se({ clients: e, encodedCount: t, onKill: n }) {
|
|
|
1614
1614
|
}, `r-${e.sessionId}`);
|
|
1615
1615
|
}),
|
|
1616
1616
|
s.map((e) => {
|
|
1617
|
-
let t = e.attribution, n =
|
|
1618
|
-
t.label && i.push(t.label), r && i.push(`sess ${r}`), t.userId && i.push(`user ${t.userId.slice(0, 8)}`), t.remoteAddr && i.push(`@${t.remoteAddr}`), t.userAgent && i.push(
|
|
1619
|
-
let a = i.length > 0 ? i.join(" · ") :
|
|
1617
|
+
let t = e.attribution, n = G[t.kind] ?? "bg-foreground-subtle/10 text-foreground-subtle", r = t.sessionId ? t.sessionId.slice(0, 8) : null, i = [];
|
|
1618
|
+
t.label && i.push(t.label), r && i.push(`sess ${r}`), t.userId && i.push(`user ${t.userId.slice(0, 8)}`), t.remoteAddr && i.push(`@${t.remoteAddr}`), t.userAgent && i.push(H(t.userAgent));
|
|
1619
|
+
let a = i.length > 0 ? i.join(" · ") : he(t.kind), o = [];
|
|
1620
1620
|
return t.media && o.push({ text: t.media }), t.targetCodec && o.push(t.targetCodec), t.transport && o.push(t.transport), o.push(`${e.packetsDelivered} pkts`), /* @__PURE__ */ g(Q, {
|
|
1621
|
-
kind:
|
|
1621
|
+
kind: me(t.kind),
|
|
1622
1622
|
kindClass: n,
|
|
1623
1623
|
tag: a,
|
|
1624
1624
|
metrics: o,
|
|
@@ -1794,7 +1794,7 @@ function Te({ count: e, clients: t, onKill: n }) {
|
|
|
1794
1794
|
className: "flex items-center justify-between gap-2",
|
|
1795
1795
|
children: [/* @__PURE__ */ g("span", {
|
|
1796
1796
|
className: "text-foreground font-mono",
|
|
1797
|
-
children: e.remoteAddr
|
|
1797
|
+
children: e.userAgent ? H(e.userAgent) : e.remoteAddr
|
|
1798
1798
|
}), /* @__PURE__ */ _("span", {
|
|
1799
1799
|
className: "flex items-center gap-1 shrink-0",
|
|
1800
1800
|
children: [/* @__PURE__ */ _("span", {
|
|
@@ -1829,7 +1829,7 @@ function Te({ count: e, clients: t, onKill: n }) {
|
|
|
1829
1829
|
//#endregion
|
|
1830
1830
|
//#region src/stream-broker/widgets/index.tsx
|
|
1831
1831
|
var Ee = {
|
|
1832
|
-
"stream-broker-panel":
|
|
1832
|
+
"stream-broker-panel": ge,
|
|
1833
1833
|
"ffmpeg-params": ue
|
|
1834
1834
|
};
|
|
1835
1835
|
//#endregion
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.1.
|
|
6
|
+
version: "1.1.13",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_stream_broker_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.1.
|
|
21
|
+
version: "1.1.16",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_stream_broker_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.1.
|
|
36
|
+
version: "1.1.15",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_stream_broker_widgets",
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.1.
|
|
39
|
+
version: "1.1.16",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -45,7 +45,7 @@ async function r() {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"@camstack/sdk": {
|
|
48
|
-
version: "1.1.
|
|
48
|
+
version: "1.1.13",
|
|
49
49
|
scope: "default",
|
|
50
50
|
shareConfig: {
|
|
51
51
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.1.
|
|
84
|
+
version: "1.1.15",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|