@camstack/system 1.2.320 → 1.2.322
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
- package/dist/builtins/alerts/alerts.addon.js +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +1 -1
- package/dist/builtins/autotrack/index.js +1 -1
- package/dist/builtins/autotrack/index.mjs +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
- package/dist/builtins/camera-grid/addon.d.ts +13 -1
- package/dist/builtins/camera-grid/index.js +46 -12
- package/dist/builtins/camera-grid/index.mjs +46 -12
- package/dist/builtins/composer/composer.addon.js +2 -2
- package/dist/builtins/composer/composer.addon.mjs +2 -2
- package/dist/builtins/console-logging/index.js +1 -1
- package/dist/builtins/console-logging/index.mjs +1 -1
- package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
- package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
- package/dist/builtins/device-manager/device-manager.addon.js +2 -2
- package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
- package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
- package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
- package/dist/builtins/hub-forwarder/index.js +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
- package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
- package/dist/builtins/local-auth/local-auth.addon.js +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
- package/dist/builtins/local-network/local-network.addon.js +1 -1
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/builtins/loki-logging/index.js +1 -1
- package/dist/builtins/loki-logging/index.mjs +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
- package/dist/builtins/platform-probe/index.js +1 -1
- package/dist/builtins/platform-probe/index.mjs +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
- package/dist/builtins/snapshot/index.js +18 -5
- package/dist/builtins/snapshot/index.mjs +18 -5
- package/dist/builtins/snapshot/snapshot.addon.d.ts +3 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +0 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +0 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
- package/dist/builtins/system-config/system-config.addon.js +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +1 -1
- package/dist/builtins/winston-logging/index.js +1 -1
- package/dist/builtins/winston-logging/index.mjs +1 -1
- package/dist/{composition-sources-D4UkcIhl.js → composition-sources-CB_xQieM.js} +1 -1
- package/dist/{composition-sources-Due6vto8.mjs → composition-sources-RzhpNlEu.mjs} +1 -1
- package/dist/{dist-B0AvBZxe.js → dist-D25eq33W.js} +94 -2
- package/dist/{dist-XfFiGX64.mjs → dist-DENeGKrn.mjs} +89 -3
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{retired-settings-keys-AmO1MZks.js → retired-settings-keys-BH9LRNsg.js} +1 -1
- package/dist/{retired-settings-keys-DXI77cc8.mjs → retired-settings-keys-iFdgpbfM.mjs} +1 -1
- package/package.json +1 -1
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as
|
|
1
|
+
import { Gn as errMsg, Kn as BaseAddon, R as addonPagesCapability, gr as EventCategory } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_settle_sources = require("../../settle-sources-Bhsy57y-.js");
|
|
8
8
|
let node_crypto = require("node:crypto");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as addonWidgetsCapability, Gn as
|
|
1
|
+
import { B as addonWidgetsCapability, Gn as errMsg, Kn as BaseAddon, gr as EventCategory } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { t as settleSourcesWithTimeout } from "../../settle-sources-CDtNC8ub.mjs";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
//#region src/builtins/alerts/prune-policy.ts
|
|
8
8
|
/**
|
|
9
9
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as
|
|
1
|
+
import { Gn as errMsg, Kn as BaseAddon, V as alertsCapability, gr as EventCategory, n as AlertSchema, nr as createEvent } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
//#region src/builtins/alerts/prune-policy.ts
|
|
3
3
|
/**
|
|
4
4
|
* Ids older than `cutoffMs`, oldest first.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
8
8
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
9
9
|
deadZoneFraction: .5,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gn as errMsg, Kn as BaseAddon, W as bareAddonId, _ as FIRST_LEVEL_MACRO_CLASSES, cr as isEvent, en as ptzAutotrackCapability, gr as EventCategory } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
//#region src/builtins/autotrack/autotrack-config.ts
|
|
3
3
|
var DEFAULT_AUTOTRACK_LOOP_CONFIG = {
|
|
4
4
|
deadZoneFraction: .5,
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let buffer = require("buffer");
|
|
9
9
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Ht as mayWriteToLocation, Kn as BaseAddon, U as backupCapability, gr as EventCategory, hn as storageOccupancyCapability } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
3
3
|
import { Buffer as Buffer$1 } from "buffer";
|
|
4
4
|
import * as fsp from "node:fs/promises";
|
|
@@ -26,7 +26,13 @@ export declare class CameraGridAddon extends BaseAddon<CameraGridAddonConfig> {
|
|
|
26
26
|
private activity;
|
|
27
27
|
private snapshots;
|
|
28
28
|
private frameSampler;
|
|
29
|
+
/** The node's pinned ffmpeg (D540). `null` until init resolved it — a
|
|
30
|
+
* composition then refuses by name; there is no PATH default. */
|
|
29
31
|
private ffmpegBinaryPath;
|
|
32
|
+
/** The node's pinned build, remembered only on success (D540). */
|
|
33
|
+
private readonly pinnedFfmpeg;
|
|
34
|
+
/** A resolution in flight, so a reconcile pass never starts a second. */
|
|
35
|
+
private ffmpegResolving;
|
|
30
36
|
private integrationId;
|
|
31
37
|
constructor();
|
|
32
38
|
protected onInitialize(): Promise<AddonInitResult>;
|
|
@@ -147,7 +153,13 @@ export declare class CameraGridAddon extends BaseAddon<CameraGridAddonConfig> {
|
|
|
147
153
|
private instanceForDevice;
|
|
148
154
|
private gridViewFor;
|
|
149
155
|
private saveGridLayout;
|
|
150
|
-
|
|
156
|
+
/**
|
|
157
|
+
* Resolve the pinned build, single-flighted, and hand it to the frame sampler.
|
|
158
|
+
* Never throws: a failure is an ERROR and leaves the binary unknown, so the
|
|
159
|
+
* next pass that wants a composition asks again. Never PATH: the host's
|
|
160
|
+
* ffmpeg is not ours (`packages/types/src/deps/ffmpeg-binary-source.ts`).
|
|
161
|
+
*/
|
|
162
|
+
private resolveFfmpeg;
|
|
151
163
|
/**
|
|
152
164
|
* The integration page: a list of grids, with a NAME.
|
|
153
165
|
*
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
let zod = require("zod");
|
|
8
8
|
let _camstack_types_node = require("@camstack/types/node");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -2982,7 +2982,13 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
2982
2982
|
activity = null;
|
|
2983
2983
|
snapshots = null;
|
|
2984
2984
|
frameSampler = null;
|
|
2985
|
-
|
|
2985
|
+
/** The node's pinned ffmpeg (D540). `null` until init resolved it — a
|
|
2986
|
+
* composition then refuses by name; there is no PATH default. */
|
|
2987
|
+
ffmpegBinaryPath = null;
|
|
2988
|
+
/** The node's pinned build, remembered only on success (D540). */
|
|
2989
|
+
pinnedFfmpeg = require_dist.memoizePinnedFfmpeg(() => this.ctx.deps.ensureFfmpeg());
|
|
2990
|
+
/** A resolution in flight, so a reconcile pass never starts a second. */
|
|
2991
|
+
ffmpegResolving = null;
|
|
2986
2992
|
integrationId;
|
|
2987
2993
|
constructor() {
|
|
2988
2994
|
super({ ...DEFAULTS });
|
|
@@ -2991,17 +2997,13 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
2991
2997
|
this.replaceTombstones(this.config.cameraGridTombstones);
|
|
2992
2998
|
await this.normalizeRows();
|
|
2993
2999
|
if (require_dist.declarationOwnerNodeId(this.ctx.kernel.localNodeId) === "hub") {
|
|
2994
|
-
|
|
3000
|
+
await this.resolveFfmpeg();
|
|
2995
3001
|
const relay = new GridStreamRelay({
|
|
2996
3002
|
logger: this.ctx.logger.child("relay"),
|
|
2997
3003
|
sessionFor: (request) => this.sessionFor(request)
|
|
2998
3004
|
});
|
|
2999
3005
|
await relay.start();
|
|
3000
3006
|
this.relay = relay;
|
|
3001
|
-
this.frameSampler = new GridFrameSampler({
|
|
3002
|
-
binaryPath: this.ffmpegBinaryPath,
|
|
3003
|
-
logger: this.ctx.logger.child("snapshot")
|
|
3004
|
-
});
|
|
3005
3007
|
this.snapshots = new GridSnapshotSource({
|
|
3006
3008
|
logger: this.ctx.logger.child("snapshot"),
|
|
3007
3009
|
sessionsFor: (deviceId) => this.sessionsForDevice(deviceId),
|
|
@@ -3341,7 +3343,19 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
3341
3343
|
continue;
|
|
3342
3344
|
}
|
|
3343
3345
|
if (this.sessions.has(key)) continue;
|
|
3344
|
-
|
|
3346
|
+
const binaryPath = this.ffmpegBinaryPath;
|
|
3347
|
+
if (binaryPath === null) {
|
|
3348
|
+
this.ctx.logger.error("camera-grid: composition refused — no pinned ffmpeg on this node (D540)", {
|
|
3349
|
+
tags: { deviceId },
|
|
3350
|
+
meta: {
|
|
3351
|
+
instanceId,
|
|
3352
|
+
profile
|
|
3353
|
+
}
|
|
3354
|
+
});
|
|
3355
|
+
this.resolveFfmpeg();
|
|
3356
|
+
continue;
|
|
3357
|
+
}
|
|
3358
|
+
this.sessions.set(key, new GridSessionEntry(instanceId, profile, this.makeSession(instanceId, deviceId, profile, binaryPath)));
|
|
3345
3359
|
}
|
|
3346
3360
|
}
|
|
3347
3361
|
/**
|
|
@@ -3371,9 +3385,9 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
3371
3385
|
}
|
|
3372
3386
|
return names;
|
|
3373
3387
|
}
|
|
3374
|
-
makeSession(instanceId, deviceId, profile) {
|
|
3388
|
+
makeSession(instanceId, deviceId, profile, binaryPath) {
|
|
3375
3389
|
const childContext = {
|
|
3376
|
-
binaryPath
|
|
3390
|
+
binaryPath,
|
|
3377
3391
|
logger: this.ctx.logger,
|
|
3378
3392
|
deviceId,
|
|
3379
3393
|
resolveSourceNames: (deviceIds) => this.sourceNames(deviceIds)
|
|
@@ -3590,8 +3604,28 @@ var CameraGridAddon = class extends require_dist.BaseAddon {
|
|
|
3590
3604
|
if (!view) throw new Error("camera-grid: the grid vanished while it was being saved");
|
|
3591
3605
|
return view;
|
|
3592
3606
|
}
|
|
3593
|
-
|
|
3594
|
-
|
|
3607
|
+
/**
|
|
3608
|
+
* Resolve the pinned build, single-flighted, and hand it to the frame sampler.
|
|
3609
|
+
* Never throws: a failure is an ERROR and leaves the binary unknown, so the
|
|
3610
|
+
* next pass that wants a composition asks again. Never PATH: the host's
|
|
3611
|
+
* ffmpeg is not ours (`packages/types/src/deps/ffmpeg-binary-source.ts`).
|
|
3612
|
+
*/
|
|
3613
|
+
resolveFfmpeg() {
|
|
3614
|
+
if (this.ffmpegBinaryPath !== null) return Promise.resolve();
|
|
3615
|
+
if (this.ffmpegResolving !== null) return this.ffmpegResolving;
|
|
3616
|
+
const attempt = this.pinnedFfmpeg().then((binaryPath) => {
|
|
3617
|
+
this.ffmpegBinaryPath = binaryPath;
|
|
3618
|
+
this.frameSampler = new GridFrameSampler({
|
|
3619
|
+
binaryPath,
|
|
3620
|
+
logger: this.ctx.logger.child("snapshot")
|
|
3621
|
+
});
|
|
3622
|
+
}).catch((err) => {
|
|
3623
|
+
this.ctx.logger.error("camera-grid: the pinned ffmpeg could not be resolved — compositions refuse until it is (D540)", { meta: { error: require_dist.errMsg(err) } });
|
|
3624
|
+
}).finally(() => {
|
|
3625
|
+
this.ffmpegResolving = null;
|
|
3626
|
+
});
|
|
3627
|
+
this.ffmpegResolving = attempt;
|
|
3628
|
+
return attempt;
|
|
3595
3629
|
}
|
|
3596
3630
|
/**
|
|
3597
3631
|
* The integration page: a list of grids, with a NAME.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as
|
|
1
|
+
import { An as buildFfmpegArgs, Gn as errMsg, Hn as DeviceFeature, J as cameraGridLayoutCapability, Kn as BaseAddon, Kt as motionCapability, T as MOTION_CLOSE_AFTER_MS, Ut as memoizePinnedFfmpeg, Wn as DeviceType, _n as streamCatalogCapability, fn as snapshotCapability, gr as EventCategory, h as DeclaredDevices, i as BaseDevice, m as DERIVED_CAMERA_SILENCED_CAP_NAMES, nr as createEvent, or as hydrateSchema, ot as declarationOwnerNodeId } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { FfmpegProcess } from "@camstack/types/node";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -2977,7 +2977,13 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
2977
2977
|
activity = null;
|
|
2978
2978
|
snapshots = null;
|
|
2979
2979
|
frameSampler = null;
|
|
2980
|
-
|
|
2980
|
+
/** The node's pinned ffmpeg (D540). `null` until init resolved it — a
|
|
2981
|
+
* composition then refuses by name; there is no PATH default. */
|
|
2982
|
+
ffmpegBinaryPath = null;
|
|
2983
|
+
/** The node's pinned build, remembered only on success (D540). */
|
|
2984
|
+
pinnedFfmpeg = memoizePinnedFfmpeg(() => this.ctx.deps.ensureFfmpeg());
|
|
2985
|
+
/** A resolution in flight, so a reconcile pass never starts a second. */
|
|
2986
|
+
ffmpegResolving = null;
|
|
2981
2987
|
integrationId;
|
|
2982
2988
|
constructor() {
|
|
2983
2989
|
super({ ...DEFAULTS });
|
|
@@ -2986,17 +2992,13 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
2986
2992
|
this.replaceTombstones(this.config.cameraGridTombstones);
|
|
2987
2993
|
await this.normalizeRows();
|
|
2988
2994
|
if (declarationOwnerNodeId(this.ctx.kernel.localNodeId) === "hub") {
|
|
2989
|
-
|
|
2995
|
+
await this.resolveFfmpeg();
|
|
2990
2996
|
const relay = new GridStreamRelay({
|
|
2991
2997
|
logger: this.ctx.logger.child("relay"),
|
|
2992
2998
|
sessionFor: (request) => this.sessionFor(request)
|
|
2993
2999
|
});
|
|
2994
3000
|
await relay.start();
|
|
2995
3001
|
this.relay = relay;
|
|
2996
|
-
this.frameSampler = new GridFrameSampler({
|
|
2997
|
-
binaryPath: this.ffmpegBinaryPath,
|
|
2998
|
-
logger: this.ctx.logger.child("snapshot")
|
|
2999
|
-
});
|
|
3000
3002
|
this.snapshots = new GridSnapshotSource({
|
|
3001
3003
|
logger: this.ctx.logger.child("snapshot"),
|
|
3002
3004
|
sessionsFor: (deviceId) => this.sessionsForDevice(deviceId),
|
|
@@ -3336,7 +3338,19 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
3336
3338
|
continue;
|
|
3337
3339
|
}
|
|
3338
3340
|
if (this.sessions.has(key)) continue;
|
|
3339
|
-
|
|
3341
|
+
const binaryPath = this.ffmpegBinaryPath;
|
|
3342
|
+
if (binaryPath === null) {
|
|
3343
|
+
this.ctx.logger.error("camera-grid: composition refused — no pinned ffmpeg on this node (D540)", {
|
|
3344
|
+
tags: { deviceId },
|
|
3345
|
+
meta: {
|
|
3346
|
+
instanceId,
|
|
3347
|
+
profile
|
|
3348
|
+
}
|
|
3349
|
+
});
|
|
3350
|
+
this.resolveFfmpeg();
|
|
3351
|
+
continue;
|
|
3352
|
+
}
|
|
3353
|
+
this.sessions.set(key, new GridSessionEntry(instanceId, profile, this.makeSession(instanceId, deviceId, profile, binaryPath)));
|
|
3340
3354
|
}
|
|
3341
3355
|
}
|
|
3342
3356
|
/**
|
|
@@ -3366,9 +3380,9 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
3366
3380
|
}
|
|
3367
3381
|
return names;
|
|
3368
3382
|
}
|
|
3369
|
-
makeSession(instanceId, deviceId, profile) {
|
|
3383
|
+
makeSession(instanceId, deviceId, profile, binaryPath) {
|
|
3370
3384
|
const childContext = {
|
|
3371
|
-
binaryPath
|
|
3385
|
+
binaryPath,
|
|
3372
3386
|
logger: this.ctx.logger,
|
|
3373
3387
|
deviceId,
|
|
3374
3388
|
resolveSourceNames: (deviceIds) => this.sourceNames(deviceIds)
|
|
@@ -3585,8 +3599,28 @@ var CameraGridAddon = class extends BaseAddon {
|
|
|
3585
3599
|
if (!view) throw new Error("camera-grid: the grid vanished while it was being saved");
|
|
3586
3600
|
return view;
|
|
3587
3601
|
}
|
|
3588
|
-
|
|
3589
|
-
|
|
3602
|
+
/**
|
|
3603
|
+
* Resolve the pinned build, single-flighted, and hand it to the frame sampler.
|
|
3604
|
+
* Never throws: a failure is an ERROR and leaves the binary unknown, so the
|
|
3605
|
+
* next pass that wants a composition asks again. Never PATH: the host's
|
|
3606
|
+
* ffmpeg is not ours (`packages/types/src/deps/ffmpeg-binary-source.ts`).
|
|
3607
|
+
*/
|
|
3608
|
+
resolveFfmpeg() {
|
|
3609
|
+
if (this.ffmpegBinaryPath !== null) return Promise.resolve();
|
|
3610
|
+
if (this.ffmpegResolving !== null) return this.ffmpegResolving;
|
|
3611
|
+
const attempt = this.pinnedFfmpeg().then((binaryPath) => {
|
|
3612
|
+
this.ffmpegBinaryPath = binaryPath;
|
|
3613
|
+
this.frameSampler = new GridFrameSampler({
|
|
3614
|
+
binaryPath,
|
|
3615
|
+
logger: this.ctx.logger.child("snapshot")
|
|
3616
|
+
});
|
|
3617
|
+
}).catch((err) => {
|
|
3618
|
+
this.ctx.logger.error("camera-grid: the pinned ffmpeg could not be resolved — compositions refuse until it is (D540)", { meta: { error: errMsg(err) } });
|
|
3619
|
+
}).finally(() => {
|
|
3620
|
+
this.ffmpegResolving = null;
|
|
3621
|
+
});
|
|
3622
|
+
this.ffmpegResolving = attempt;
|
|
3623
|
+
return attempt;
|
|
3590
3624
|
}
|
|
3591
3625
|
/**
|
|
3592
3626
|
* The integration page: a list of grids, with a NAME.
|
|
@@ -3,9 +3,9 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_device_state_changed = require("../../device-state-changed-Bk7cvTnz.js");
|
|
8
|
-
const require_composition_sources = require("../../composition-sources-
|
|
8
|
+
const require_composition_sources = require("../../composition-sources-CB_xQieM.js");
|
|
9
9
|
//#region src/builtins/composer/composed-device.ts
|
|
10
10
|
/**
|
|
11
11
|
* A composed device: an ordinary `BaseDevice` whose caps are served by the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Fn as compositionItemFieldPath, Gn as errMsg, In as compositionSliceKey, K as buildCapabilityLookup, Kn as BaseAddon, Ln as compositionSourceKey, Mn as composedDeviceRef, Nn as composedDeviceStableId, Pn as compositionFeatureEnabled, Rn as createStatefulExpressionMemory, Tn as COMPOSER_ADDON_ID, Vn as toExpressionValue, Wn as DeviceType, X as composerCapability, Z as compositionFieldKey, Zt as planComposition, c as COMPOSED_ITEM_FIXED_FIELDS, gr as EventCategory, h as DeclaredDevices, i as BaseDevice, jn as cloneStatefulExpressionMemory, nr as createEvent, t as ALL_CAPABILITY_DEFINITIONS, vt as evaluateCompositionField } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { n as parseDeviceStateChanged, t as isRecord$2 } from "../../device-state-changed-DoBbkyEI.mjs";
|
|
3
|
-
import { n as normalizedNativeOwner } from "../../composition-sources-
|
|
3
|
+
import { n as normalizedNativeOwner } from "../../composition-sources-RzhpNlEu.mjs";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
//#region src/builtins/composer/composed-device.ts
|
|
6
6
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/console-logging/console-destination.ts
|
|
9
9
|
var LEVEL_RANK = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kn as BaseAddon, Rt as logDestinationCapability } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/console-logging/console-destination.ts
|
|
4
4
|
var LEVEL_RANK = {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
4
|
-
const require_composition_sources = require("../../composition-sources-
|
|
3
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
4
|
+
const require_composition_sources = require("../../composition-sources-CB_xQieM.js");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
6
|
let _camstack_types_node = require("@camstack/types/node");
|
|
7
7
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as coreBlockAddonId, Gn as BaseAddon,
|
|
2
|
-
import { t as describeCompositionSources } from "../../composition-sources-
|
|
1
|
+
import { $ as coreBlockAddonId, Gn as errMsg, K as buildCapabilityLookup, Kn as BaseAddon, Ln as compositionSourceKey, Mn as composedDeviceRef, Q as compositionSourceRefs, Zt as planComposition, bn as validateComposition, d as CORE_BLOCK_ADDON_PREFIX, et as coreBlockComposition, f as CoreBlockSchema, h as DeclaredDevices, l as COMPOSER_RUNNER_ID, nn as replacedFieldKeys, nt as coreBlockSourceKind, rt as coreBlocksCapability, t as ALL_CAPABILITY_DEFINITIONS, tt as coreBlockIdFromAddonId, u as CORE_BLOCKS_ADDON_ID } from "../../dist-DENeGKrn.mjs";
|
|
2
|
+
import { t as describeCompositionSources } from "../../composition-sources-RzhpNlEu.mjs";
|
|
3
3
|
import { randomUUID } from "node:crypto";
|
|
4
4
|
import { customizationBlockName } from "@camstack/types/node";
|
|
5
5
|
import * as fs from "node:fs/promises";
|
|
@@ -3,8 +3,8 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
7
|
-
const require_retired_settings_keys = require("../../retired-settings-keys-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
|
+
const require_retired_settings_keys = require("../../retired-settings-keys-BH9LRNsg.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
10
10
|
let _camstack_types_node = require("@camstack/types/node");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Gn as
|
|
2
|
-
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-
|
|
1
|
+
import { Gn as errMsg, Hn as DeviceFeature, Kn as BaseAddon, Lt as locationIconKey, Nt as legacyAutoLinkIds, Qn as WELL_KNOWN_TAB_MAP, S as LocationIconIdSchema, Un as DeviceRole, Wn as DeviceType, Xt as parseStreamParamsFormPatch, _t as enumerateSchemaFields, bt as expandContainer, ct as defineExtensionSlotProvider, dn as siteZoneKey, dt as deviceManagerCapability, ft as deviceStateCapability, g as DeviceStatusSchema, gr as EventCategory, gt as enumerateItemArrayFields, hr as sleep$1, it as createDeviceExtensionProvider, j as STREAM_PROFILE_META, o as CAMERA_SWITCH_ORDER, on as runtimeStatePolicyFor, p as DAY_NAMES, pt as deviceStatusCapability, q as buildStreamParamsConfigSchema, qt as normalizeUnit, s as CAP_NAMES_WITH_STATUS, sr as isDeviceConfigCap, t as ALL_CAPABILITY_DEFINITIONS, ut as deviceExtensionCapability, v as FieldClaimModeSchema, w as MINUTES_PER_DAY, wt as formatMinutes, y as FieldClaimSchema } from "../../dist-DENeGKrn.mjs";
|
|
2
|
+
import { n as purgeRetiredSettingsRows } from "../../retired-settings-keys-iFdgpbfM.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { canonicalDeviceFingerprint } from "@camstack/types/node";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_device_state_changed = require("../../device-state-changed-Bk7cvTnz.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { At as isSameAddonId,
|
|
1
|
+
import { At as isSameAddonId, Bn as isSourceCap, Dn as SOURCE_CAPS, Gn as errMsg, Kn as BaseAddon, On as SOURCE_CAP_ACTIVE_FIELD, W as bareAddonId, Wn as DeviceType, ct as defineExtensionSlotProvider, gr as EventCategory, it as createDeviceExtensionProvider, kn as SOURCE_CAP_CHANGED_AT_FIELD, mt as doorbellCapability, nr as createEvent, ut as deviceExtensionCapability, zn as evaluateSensorEdge } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { n as parseDeviceStateChanged } from "../../device-state-changed-DoBbkyEI.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
//#region src/builtins/doorbell/trigger-engine.ts
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
9
9
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kn as BaseAddon, Rt as logDestinationCapability } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
//#region src/builtins/hub-forwarder/hub-forwarder-destination.ts
|
|
4
4
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
4
4
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
5
5
|
var NO_DEVICES = "liveness:no-devices";
|
|
6
6
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as RECORDING_SOURCE_CAMSTACK_ADDON, Gn as
|
|
1
|
+
import { E as RECORDING_SOURCE_CAMSTACK_ADDON, Gn as errMsg, Kn as BaseAddon, gr as EventCategory, k as RecordingStatusSchema, nr as createEvent } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
//#region src/builtins/liveness-monitor/liveness-checks.ts
|
|
3
3
|
var NO_DEVICES = "liveness:no-devices";
|
|
4
4
|
var ALL_OFFLINE = "liveness:all-devices-offline";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
9
9
|
let crypto$1 = require("crypto");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as __require, o as __toESM, t as __commonJSMin } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { H as authProviderCapability, Kn as BaseAddon, L as UserRecordSchema, M as ScopedTokenSchema, r as ApiKeyRecordSchema, yn as userManagementCapability } from "../../dist-DENeGKrn.mjs";
|
|
3
3
|
import * as crypto$2 from "node:crypto";
|
|
4
4
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
5
5
|
import nodeCrypto from "crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("../../dist-
|
|
3
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
4
4
|
const require_tls = require("../../tls-D_wUeOTD.js");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { It as localNetworkCapability, Kn as BaseAddon, gr as EventCategory } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, i as writeExtraSans, l as reissueTlsLeaf, n as readTlsAccessStatus, o as validateUploadedTls, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, y as applyLanHttp } from "../../tls-IM-v7JV4.mjs";
|
|
3
3
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
8
8
|
/**
|
|
9
9
|
* Loki rejects a label name that is not a valid Prometheus label
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kn as BaseAddon, Rt as logDestinationCapability } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
//#region src/builtins/loki-logging/loki-payload.ts
|
|
3
3
|
/**
|
|
4
4
|
* Loki rejects a label name that is not a valid Prometheus label
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_proc_stat = require("../../proc-stat-DL-WUOhl.js");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
let node_fs = require("node:fs");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Ct as foldSnapshotByFunction, Gn as
|
|
1
|
+
import { Ct as foldSnapshotByFunction, Gn as errMsg, Kn as BaseAddon, Wt as metricsProviderCapability, gr as EventCategory, nr as createEvent, rn as resolveBucketMs, tn as reducePoints } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { a as parseProcStat, i as nodeProcReader, n as elapsedSecSince, o as parseProcStatusRss, r as lifetimeCpuPercent, t as commandFromCmdline } from "../../proc-stat-CbC55Kqi.mjs";
|
|
3
3
|
import { access, readFile, readdir } from "node:fs/promises";
|
|
4
4
|
import * as fs from "node:fs";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_chunk.__toESM(node_fs);
|
|
9
9
|
let node_child_process = require("node:child_process");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { o as __toESM } from "../../chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { Gn as
|
|
2
|
+
import { Gn as errMsg, Kn as BaseAddon, Qt as platformProbeCapability, gr as EventCategory, ht as enumerateInferenceDevices, ir as emitReadiness, ln as scoreRuntimes } from "../../dist-DENeGKrn.mjs";
|
|
3
3
|
import * as fs from "node:fs";
|
|
4
4
|
import { execFile } from "node:child_process";
|
|
5
5
|
import * as os from "node:os";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
8
8
|
/**
|
|
9
9
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kn as BaseAddon, gr as EventCategory } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
//#region src/builtins/remote-access-orchestrator/enabled-providers-reconcile.ts
|
|
3
3
|
/**
|
|
4
4
|
* Reconcile the durable `enabledProviders` set against authoritative
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_snapshot_courtesy = require("../../snapshot-courtesy-Cqs7GkOV.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1135,6 +1135,9 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
|
|
|
1135
1135
|
captureFlight = new SingleFlight(COALESCE_MS, (outcome) => outcome.ok && outcome.image !== null);
|
|
1136
1136
|
/** Bounds simultaneous ffmpeg keyframe grabs (the wrapper path — common case). */
|
|
1137
1137
|
grabPool = new Semaphore(6);
|
|
1138
|
+
/** This node's PINNED ffmpeg (D540), asked once. The keyframe grab used to
|
|
1139
|
+
* spawn a bare `'ffmpeg'` — the HOST's binary — off PATH. */
|
|
1140
|
+
pinnedFfmpeg = require_dist.memoizePinnedFfmpeg(() => this.ctx.deps.ensureFfmpeg());
|
|
1138
1141
|
/** Bounds simultaneous native (vendor HTTP/ONVIF) snapshot fetches. */
|
|
1139
1142
|
nativePool = new Semaphore(6);
|
|
1140
1143
|
/**
|
|
@@ -2088,14 +2091,24 @@ var SnapshotAddon = class SnapshotAddon extends require_dist.BaseAddon {
|
|
|
2088
2091
|
* "first keyframe" when a suspended broker resumes.
|
|
2089
2092
|
*/
|
|
2090
2093
|
async runGrabWithResumeRetry(url, deviceId) {
|
|
2094
|
+
let ffmpegPath;
|
|
2095
|
+
try {
|
|
2096
|
+
ffmpegPath = await this.pinnedFfmpeg();
|
|
2097
|
+
} catch (err) {
|
|
2098
|
+
this.ctx.logger.error("grabFrame refused — no pinned ffmpeg on this node (D540)", {
|
|
2099
|
+
tags: { deviceId },
|
|
2100
|
+
meta: { error: require_dist.errMsg(err) }
|
|
2101
|
+
});
|
|
2102
|
+
throw new Error(`grabFrame: no pinned ffmpeg for device ${deviceId} — ${require_dist.errMsg(err)}`, { cause: err });
|
|
2103
|
+
}
|
|
2091
2104
|
let buf;
|
|
2092
2105
|
try {
|
|
2093
|
-
buf = await this.grabPool.run(() => runFfmpegFrameGrab(url, 15e3));
|
|
2106
|
+
buf = await this.grabPool.run(() => runFfmpegFrameGrab(ffmpegPath, url, 15e3));
|
|
2094
2107
|
} catch (err) {
|
|
2095
2108
|
if (isBrokerColdError(require_dist.errMsg(err))) {
|
|
2096
2109
|
this.ctx.logger.debug("grabFrame: broker-resume race — retrying in 1500ms", { tags: { deviceId } });
|
|
2097
2110
|
await new Promise((r) => setTimeout(r, 1500));
|
|
2098
|
-
buf = await this.grabPool.run(() => runFfmpegFrameGrab(url, 15e3));
|
|
2111
|
+
buf = await this.grabPool.run(() => runFfmpegFrameGrab(ffmpegPath, url, 15e3));
|
|
2099
2112
|
} else throw err;
|
|
2100
2113
|
}
|
|
2101
2114
|
if (buf.length === 0) return null;
|
|
@@ -2642,9 +2655,9 @@ function qualityRank(brokerId, prefix) {
|
|
|
2642
2655
|
function isBrokerColdError(msg) {
|
|
2643
2656
|
return msg.includes("Invalid data found when processing input") || msg.includes("Error opening input") || msg.includes("Connection refused") || msg.includes("No route to host");
|
|
2644
2657
|
}
|
|
2645
|
-
function runFfmpegFrameGrab(url, timeoutMs) {
|
|
2658
|
+
function runFfmpegFrameGrab(ffmpegPath, url, timeoutMs) {
|
|
2646
2659
|
return new Promise((resolve, reject) => {
|
|
2647
|
-
(0, node_child_process.execFile)(
|
|
2660
|
+
(0, node_child_process.execFile)(ffmpegPath, [
|
|
2648
2661
|
"-loglevel",
|
|
2649
2662
|
"error",
|
|
2650
2663
|
"-threads",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as batteryCapability, Gn as
|
|
1
|
+
import { G as batteryCapability, Gn as errMsg, Hn as DeviceFeature, Kn as BaseAddon, Ut as memoizePinnedFfmpeg, W as bareAddonId, Wn as DeviceType, a as BatteryStatusSchema, fn as snapshotCapability, gr as EventCategory, lr as nodePin, lt as deriveBatteryPresence, vn as streamQualityLabel } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { i as renderCourtesyOverlayJpeg, n as courtesyCacheKey, r as renderCourtesyJpeg } from "../../snapshot-courtesy-CZPvteq2.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -1129,6 +1129,9 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
|
|
|
1129
1129
|
captureFlight = new SingleFlight(COALESCE_MS, (outcome) => outcome.ok && outcome.image !== null);
|
|
1130
1130
|
/** Bounds simultaneous ffmpeg keyframe grabs (the wrapper path — common case). */
|
|
1131
1131
|
grabPool = new Semaphore(6);
|
|
1132
|
+
/** This node's PINNED ffmpeg (D540), asked once. The keyframe grab used to
|
|
1133
|
+
* spawn a bare `'ffmpeg'` — the HOST's binary — off PATH. */
|
|
1134
|
+
pinnedFfmpeg = memoizePinnedFfmpeg(() => this.ctx.deps.ensureFfmpeg());
|
|
1132
1135
|
/** Bounds simultaneous native (vendor HTTP/ONVIF) snapshot fetches. */
|
|
1133
1136
|
nativePool = new Semaphore(6);
|
|
1134
1137
|
/**
|
|
@@ -2082,14 +2085,24 @@ var SnapshotAddon = class SnapshotAddon extends BaseAddon {
|
|
|
2082
2085
|
* "first keyframe" when a suspended broker resumes.
|
|
2083
2086
|
*/
|
|
2084
2087
|
async runGrabWithResumeRetry(url, deviceId) {
|
|
2088
|
+
let ffmpegPath;
|
|
2089
|
+
try {
|
|
2090
|
+
ffmpegPath = await this.pinnedFfmpeg();
|
|
2091
|
+
} catch (err) {
|
|
2092
|
+
this.ctx.logger.error("grabFrame refused — no pinned ffmpeg on this node (D540)", {
|
|
2093
|
+
tags: { deviceId },
|
|
2094
|
+
meta: { error: errMsg(err) }
|
|
2095
|
+
});
|
|
2096
|
+
throw new Error(`grabFrame: no pinned ffmpeg for device ${deviceId} — ${errMsg(err)}`, { cause: err });
|
|
2097
|
+
}
|
|
2085
2098
|
let buf;
|
|
2086
2099
|
try {
|
|
2087
|
-
buf = await this.grabPool.run(() => runFfmpegFrameGrab(url, 15e3));
|
|
2100
|
+
buf = await this.grabPool.run(() => runFfmpegFrameGrab(ffmpegPath, url, 15e3));
|
|
2088
2101
|
} catch (err) {
|
|
2089
2102
|
if (isBrokerColdError(errMsg(err))) {
|
|
2090
2103
|
this.ctx.logger.debug("grabFrame: broker-resume race — retrying in 1500ms", { tags: { deviceId } });
|
|
2091
2104
|
await new Promise((r) => setTimeout(r, 1500));
|
|
2092
|
-
buf = await this.grabPool.run(() => runFfmpegFrameGrab(url, 15e3));
|
|
2105
|
+
buf = await this.grabPool.run(() => runFfmpegFrameGrab(ffmpegPath, url, 15e3));
|
|
2093
2106
|
} else throw err;
|
|
2094
2107
|
}
|
|
2095
2108
|
if (buf.length === 0) return null;
|
|
@@ -2636,9 +2649,9 @@ function qualityRank(brokerId, prefix) {
|
|
|
2636
2649
|
function isBrokerColdError(msg) {
|
|
2637
2650
|
return msg.includes("Invalid data found when processing input") || msg.includes("Error opening input") || msg.includes("Connection refused") || msg.includes("No route to host");
|
|
2638
2651
|
}
|
|
2639
|
-
function runFfmpegFrameGrab(url, timeoutMs) {
|
|
2652
|
+
function runFfmpegFrameGrab(ffmpegPath, url, timeoutMs) {
|
|
2640
2653
|
return new Promise((resolve, reject) => {
|
|
2641
|
-
execFile(
|
|
2654
|
+
execFile(ffmpegPath, [
|
|
2642
2655
|
"-loglevel",
|
|
2643
2656
|
"error",
|
|
2644
2657
|
"-threads",
|
|
@@ -93,6 +93,9 @@ export declare class SnapshotAddon extends BaseAddon<SnapshotAddonConfig> {
|
|
|
93
93
|
private readonly captureFlight;
|
|
94
94
|
/** Bounds simultaneous ffmpeg keyframe grabs (the wrapper path — common case). */
|
|
95
95
|
private readonly grabPool;
|
|
96
|
+
/** This node's PINNED ffmpeg (D540), asked once. The keyframe grab used to
|
|
97
|
+
* spawn a bare `'ffmpeg'` — the HOST's binary — off PATH. */
|
|
98
|
+
private readonly pinnedFfmpeg;
|
|
96
99
|
/** Bounds simultaneous native (vendor HTTP/ONVIF) snapshot fetches. */
|
|
97
100
|
private readonly nativePool;
|
|
98
101
|
/**
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
let node_crypto = require("node:crypto");
|
|
8
8
|
let node_fs_promises = require("node:fs/promises");
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kn as BaseAddon, St as filesystemBrowseCapability, gn as storageProviderCapability } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { mkdir, readdir, realpath, statfs } from "node:fs/promises";
|
|
4
4
|
import * as path$1 from "node:path";
|
|
Binary file
|
|
Binary file
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_hub_cap_forward = require("../../hub-cap-forward-DmHNjbB0.js");
|
|
8
8
|
let zod = require("zod");
|
|
9
9
|
let node_crypto = require("node:crypto");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { D as REDACTED_SECRET, F as StorageLocationTypeSchema, Gt as modeMayWrite, Ht as mayWriteToLocation, I as StorageMigrationJobSchema, Kn as BaseAddon, N as StorageCleanupJobSchema, Ot as isLocationEnabled, P as StorageLocationModeSchema, Pt as legacyModeOf, Tt as gbToBytes, Vt as mayReadLocation, Y as collectSecretConfigKeys, gr as EventCategory, in as resolveLocationMode, mn as storageMigrationCapability, pn as storageCapability, un as settingsStoreCapability, ur as parseJsonObject, wn as withLocationMode, x as LegacyStorageLocationDefaultSchema, yt as evictionPolicyOfLocation } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { t as HUB_CAP_FWD_ACTION } from "../../hub-cap-forward-BdT320dq.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
8
8
|
/**
|
|
9
9
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Gn as
|
|
1
|
+
import { Gn as errMsg, Kn as BaseAddon, or as hydrateSchema } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
//#region src/builtins/system-config/system-config.addon.ts
|
|
3
3
|
/**
|
|
4
4
|
* Built-in `system-config` addon — Phase 4 of the settings redesign.
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
-
const require_dist = require("../../dist-
|
|
6
|
+
const require_dist = require("../../dist-D25eq33W.js");
|
|
7
7
|
const require_formatter = require("../../formatter-DqAKDlvN.js");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
node_path = require_chunk.__toESM(node_path);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Kn as BaseAddon, Rt as logDestinationCapability } from "../../dist-DENeGKrn.mjs";
|
|
2
2
|
import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
|
|
3
3
|
import * as path$1 from "node:path";
|
|
4
4
|
import path from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Gn as errMsg, Ln as compositionSourceKey } from "./dist-DENeGKrn.mjs";
|
|
2
2
|
//#region src/builtins/core-blocks/composition-sources.ts
|
|
3
3
|
/**
|
|
4
4
|
* Describe what a composition reads and writes for SAVE-time validation
|
|
@@ -3512,7 +3512,7 @@ function errMsg(err) {
|
|
|
3512
3512
|
return String(err);
|
|
3513
3513
|
}
|
|
3514
3514
|
//#endregion
|
|
3515
|
-
//#region ../types/dist/composition-
|
|
3515
|
+
//#region ../types/dist/composition-Dq42XWp0.mjs
|
|
3516
3516
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
3517
3517
|
opus: "libopus",
|
|
3518
3518
|
aac: "aac",
|
|
@@ -3906,6 +3906,58 @@ function buildFfmpegArgs(inv) {
|
|
|
3906
3906
|
];
|
|
3907
3907
|
}
|
|
3908
3908
|
/**
|
|
3909
|
+
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
3910
|
+
*
|
|
3911
|
+
* ## Why a download, on every node, including the container
|
|
3912
|
+
*
|
|
3913
|
+
* The version of ffmpeg used to be CODE: baked into the image, changeable only
|
|
3914
|
+
* by rebuilding and rolling it. Now it is DATA — this file states the release,
|
|
3915
|
+
* and a node that boots with a different one downloads it. Changing ffmpeg is a
|
|
3916
|
+
* framework bump, not an image rebuild.
|
|
3917
|
+
*
|
|
3918
|
+
* It also settles the licence question by removing it. FFmpeg's licence is
|
|
3919
|
+
* chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
|
|
3920
|
+
* (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
|
|
3921
|
+
* makes the result undistributable. These are GPL v3 builds, and we do not
|
|
3922
|
+
* distribute them: the user's own node fetches the archive from the project
|
|
3923
|
+
* that publishes it, so we convey no GPL work and inherit none of the
|
|
3924
|
+
* obligations that come with conveying one. That is the whole reason the image
|
|
3925
|
+
* no longer installs ffmpeg at all — not a technical preference.
|
|
3926
|
+
*
|
|
3927
|
+
* ## Why jellyfin-ffmpeg
|
|
3928
|
+
*
|
|
3929
|
+
* One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
|
|
3930
|
+
* from one release, with the widest hardware surface of anything maintained:
|
|
3931
|
+
* VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
|
|
3932
|
+
* MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
|
|
3933
|
+
* so the binary is not linked against a driver stack it may not find.
|
|
3934
|
+
*
|
|
3935
|
+
* **What it still needs from the host, measured 2026-09-19.** On the Unraid
|
|
3936
|
+
* HOST, which has no libva, `-vaapi_device` aborts the process outright —
|
|
3937
|
+
* `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
|
|
3938
|
+
* "Assertion in generated code"' failed`. Inside our container, which installs
|
|
3939
|
+
* libva plus the iHD driver, the same command encodes: verified end to end with
|
|
3940
|
+
* `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
|
|
3941
|
+
* KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
|
|
3942
|
+
*
|
|
3943
|
+
* ## Why each artifact carries a checksum and a claim
|
|
3944
|
+
*
|
|
3945
|
+
* The download is now the only source, so `sha256` is verified before anything
|
|
3946
|
+
* is extracted — jellyfin publishes no checksums on its release assets, so
|
|
3947
|
+
* these are ours, taken at the version bump. And `expectedHwaccels` is what the
|
|
3948
|
+
* build is supposed to be able to do: a binary that probes short of its own
|
|
3949
|
+
* claim is a source that changed under us, which is precisely what went
|
|
3950
|
+
* unnoticed for months when a static build turned out to carry no VAAPI at all
|
|
3951
|
+
* (D536).
|
|
3952
|
+
*/
|
|
3953
|
+
/** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
|
|
3954
|
+
var FFMPEG_RELEASE = "8.1.2-5";
|
|
3955
|
+
var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
|
|
3956
|
+
function portable(target) {
|
|
3957
|
+
return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
|
|
3958
|
+
}
|
|
3959
|
+
portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
|
|
3960
|
+
/**
|
|
3909
3961
|
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
3910
3962
|
* valutatore puro del suo FRONTE.
|
|
3911
3963
|
*
|
|
@@ -5359,6 +5411,26 @@ var BASE_LIVE_EGRESS_PROFILE = {
|
|
|
5359
5411
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
5360
5412
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
5361
5413
|
/**
|
|
5414
|
+
* Memoize `ensure` on SUCCESS only.
|
|
5415
|
+
*
|
|
5416
|
+
* A failure is not remembered: the next caller asks again, so a node whose
|
|
5417
|
+
* first download failed (no network at boot) recovers on the next spawn that
|
|
5418
|
+
* needs it — with no timer and no retry loop, because the ask is driven by
|
|
5419
|
+
* work that actually wants the binary.
|
|
5420
|
+
*/
|
|
5421
|
+
function memoizePinnedFfmpeg(ensure) {
|
|
5422
|
+
let pending = null;
|
|
5423
|
+
return () => {
|
|
5424
|
+
if (pending !== null) return pending;
|
|
5425
|
+
const attempt = ensure();
|
|
5426
|
+
pending = attempt;
|
|
5427
|
+
attempt.catch(() => {
|
|
5428
|
+
if (pending === attempt) pending = null;
|
|
5429
|
+
});
|
|
5430
|
+
return attempt;
|
|
5431
|
+
};
|
|
5432
|
+
}
|
|
5433
|
+
/**
|
|
5362
5434
|
* Deep wiring healthcheck — snapshot of active reachability probes across
|
|
5363
5435
|
* every declared capability + widget of every installed plugin, on every
|
|
5364
5436
|
* node. Produced by the backend `WiringHealthService` and surfaced via
|
|
@@ -21918,6 +21990,21 @@ var ObjectEventSchema = zod.z.object({
|
|
|
21918
21990
|
keyFrameMediaId: zod.z.number().int().optional(),
|
|
21919
21991
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21920
21992
|
mediaUrl: zod.z.string().optional(),
|
|
21993
|
+
/**
|
|
21994
|
+
* When the change this row records HAPPENED, epoch ms, when that is earlier
|
|
21995
|
+
* than {@link timestamp} and the producer could date it (D684).
|
|
21996
|
+
*
|
|
21997
|
+
* Set on a package PICK-UP row only: its `timestamp` is when the departure
|
|
21998
|
+
* was CONCLUDED — five minutes of unseen observed time after the parcel went
|
|
21999
|
+
* — and a notification's footage has to be cut around the pick-up, not the
|
|
22000
|
+
* empty doormat after it (D682). Stored so every path that rebuilds a
|
|
22001
|
+
* notification subject from the row (the boot reconcile, a dry-run) anchors
|
|
22002
|
+
* on the same instant the live hook did.
|
|
22003
|
+
*
|
|
22004
|
+
* `timestamp` keeps its meaning. Absent on every other row and on every
|
|
22005
|
+
* pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
|
|
22006
|
+
*/
|
|
22007
|
+
observedAt: zod.z.number().optional(),
|
|
21921
22008
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
21922
22009
|
* event of the track (so an event row can be sorted by importance without a
|
|
21923
22010
|
* track join). Absent on legacy rows / before the track was scored. */
|
|
@@ -43959,7 +44046,6 @@ var RUNTIME_DEFAULTS = {
|
|
|
43959
44046
|
models: "camstack-data/models"
|
|
43960
44047
|
},
|
|
43961
44048
|
providers: [],
|
|
43962
|
-
"ffmpeg.binaryPath": "ffmpeg",
|
|
43963
44049
|
"ffmpeg.hwAccel": "auto",
|
|
43964
44050
|
"ffmpeg.threadCount": 0,
|
|
43965
44051
|
"auth.tokenExpiry": "30d"
|
|
@@ -58246,6 +58332,12 @@ Object.defineProperty(exports, "mayWriteToLocation", {
|
|
|
58246
58332
|
return mayWriteToLocation;
|
|
58247
58333
|
}
|
|
58248
58334
|
});
|
|
58335
|
+
Object.defineProperty(exports, "memoizePinnedFfmpeg", {
|
|
58336
|
+
enumerable: true,
|
|
58337
|
+
get: function() {
|
|
58338
|
+
return memoizePinnedFfmpeg;
|
|
58339
|
+
}
|
|
58340
|
+
});
|
|
58249
58341
|
Object.defineProperty(exports, "metricsProviderCapability", {
|
|
58250
58342
|
enumerable: true,
|
|
58251
58343
|
get: function() {
|
|
@@ -3512,7 +3512,7 @@ function errMsg(err) {
|
|
|
3512
3512
|
return String(err);
|
|
3513
3513
|
}
|
|
3514
3514
|
//#endregion
|
|
3515
|
-
//#region ../types/dist/composition-
|
|
3515
|
+
//#region ../types/dist/composition-Dq42XWp0.mjs
|
|
3516
3516
|
var AUDIO_ENCODER_BY_CODEC = {
|
|
3517
3517
|
opus: "libopus",
|
|
3518
3518
|
aac: "aac",
|
|
@@ -3906,6 +3906,58 @@ function buildFfmpegArgs(inv) {
|
|
|
3906
3906
|
];
|
|
3907
3907
|
}
|
|
3908
3908
|
/**
|
|
3909
|
+
* The ffmpeg build every CamStack node downloads, per platform and arch.
|
|
3910
|
+
*
|
|
3911
|
+
* ## Why a download, on every node, including the container
|
|
3912
|
+
*
|
|
3913
|
+
* The version of ffmpeg used to be CODE: baked into the image, changeable only
|
|
3914
|
+
* by rebuilding and rolling it. Now it is DATA — this file states the release,
|
|
3915
|
+
* and a node that boots with a different one downloads it. Changing ffmpeg is a
|
|
3916
|
+
* framework bump, not an image rebuild.
|
|
3917
|
+
*
|
|
3918
|
+
* It also settles the licence question by removing it. FFmpeg's licence is
|
|
3919
|
+
* chosen at compile time: the core is LGPL 2.1+, `--enable-gpl` makes it GPL
|
|
3920
|
+
* (for x264/x265), `--enable-version3` makes that v3, and `--enable-nonfree`
|
|
3921
|
+
* makes the result undistributable. These are GPL v3 builds, and we do not
|
|
3922
|
+
* distribute them: the user's own node fetches the archive from the project
|
|
3923
|
+
* that publishes it, so we convey no GPL work and inherit none of the
|
|
3924
|
+
* obligations that come with conveying one. That is the whole reason the image
|
|
3925
|
+
* no longer installs ffmpeg at all — not a technical preference.
|
|
3926
|
+
*
|
|
3927
|
+
* ## Why jellyfin-ffmpeg
|
|
3928
|
+
*
|
|
3929
|
+
* One vendor covering linux-amd64, linux-arm64, darwin-arm64 and darwin-x64
|
|
3930
|
+
* from one release, with the widest hardware surface of anything maintained:
|
|
3931
|
+
* VAAPI, QSV, NVENC/NVDEC, AMF, Vulkan, OpenCL and DRM on amd64, plus Rockchip
|
|
3932
|
+
* MPP on arm64. It reaches the vendor libraries through dlopen trampolines,
|
|
3933
|
+
* so the binary is not linked against a driver stack it may not find.
|
|
3934
|
+
*
|
|
3935
|
+
* **What it still needs from the host, measured 2026-09-19.** On the Unraid
|
|
3936
|
+
* HOST, which has no libva, `-vaapi_device` aborts the process outright —
|
|
3937
|
+
* `implib-gen: libva-drm.so.2: failed to load library ... Assertion '0 &&
|
|
3938
|
+
* "Assertion in generated code"' failed`. Inside our container, which installs
|
|
3939
|
+
* libva plus the iHD driver, the same command encodes: verified end to end with
|
|
3940
|
+
* `testsrc → format=nv12,hwupload → h264_vaapi`. So the image drops ffmpeg and
|
|
3941
|
+
* KEEPS the Intel media stack; the drivers are the part a binary cannot bring.
|
|
3942
|
+
*
|
|
3943
|
+
* ## Why each artifact carries a checksum and a claim
|
|
3944
|
+
*
|
|
3945
|
+
* The download is now the only source, so `sha256` is verified before anything
|
|
3946
|
+
* is extracted — jellyfin publishes no checksums on its release assets, so
|
|
3947
|
+
* these are ours, taken at the version bump. And `expectedHwaccels` is what the
|
|
3948
|
+
* build is supposed to be able to do: a binary that probes short of its own
|
|
3949
|
+
* claim is a source that changed under us, which is precisely what went
|
|
3950
|
+
* unnoticed for months when a static build turned out to carry no VAAPI at all
|
|
3951
|
+
* (D536).
|
|
3952
|
+
*/
|
|
3953
|
+
/** The pinned jellyfin-ffmpeg release. Changing this is the version change. */
|
|
3954
|
+
var FFMPEG_RELEASE = "8.1.2-5";
|
|
3955
|
+
var BASE = `https://github.com/jellyfin/jellyfin-ffmpeg/releases/download/v${FFMPEG_RELEASE}`;
|
|
3956
|
+
function portable(target) {
|
|
3957
|
+
return `${BASE}/jellyfin-ffmpeg_${FFMPEG_RELEASE}_portable_${target}-gpl.tar.xz`;
|
|
3958
|
+
}
|
|
3959
|
+
portable("linux64"), portable("linuxarm64"), portable("macarm64"), portable("mac64");
|
|
3960
|
+
/**
|
|
3909
3961
|
* LA tabella "quale booleano di questo tipo di device conta come ALTO", e il
|
|
3910
3962
|
* valutatore puro del suo FRONTE.
|
|
3911
3963
|
*
|
|
@@ -5359,6 +5411,26 @@ var BASE_LIVE_EGRESS_PROFILE = {
|
|
|
5359
5411
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
5360
5412
|
({ ...BASE_LIVE_EGRESS_PROFILE }), { ...BASE_LIVE_EGRESS_PROFILE.video };
|
|
5361
5413
|
/**
|
|
5414
|
+
* Memoize `ensure` on SUCCESS only.
|
|
5415
|
+
*
|
|
5416
|
+
* A failure is not remembered: the next caller asks again, so a node whose
|
|
5417
|
+
* first download failed (no network at boot) recovers on the next spawn that
|
|
5418
|
+
* needs it — with no timer and no retry loop, because the ask is driven by
|
|
5419
|
+
* work that actually wants the binary.
|
|
5420
|
+
*/
|
|
5421
|
+
function memoizePinnedFfmpeg(ensure) {
|
|
5422
|
+
let pending = null;
|
|
5423
|
+
return () => {
|
|
5424
|
+
if (pending !== null) return pending;
|
|
5425
|
+
const attempt = ensure();
|
|
5426
|
+
pending = attempt;
|
|
5427
|
+
attempt.catch(() => {
|
|
5428
|
+
if (pending === attempt) pending = null;
|
|
5429
|
+
});
|
|
5430
|
+
return attempt;
|
|
5431
|
+
};
|
|
5432
|
+
}
|
|
5433
|
+
/**
|
|
5362
5434
|
* Deep wiring healthcheck — snapshot of active reachability probes across
|
|
5363
5435
|
* every declared capability + widget of every installed plugin, on every
|
|
5364
5436
|
* node. Produced by the backend `WiringHealthService` and surfaced via
|
|
@@ -21918,6 +21990,21 @@ var ObjectEventSchema = z.object({
|
|
|
21918
21990
|
keyFrameMediaId: z.number().int().optional(),
|
|
21919
21991
|
/** Populated by B5 (recording playback URL for this event). */
|
|
21920
21992
|
mediaUrl: z.string().optional(),
|
|
21993
|
+
/**
|
|
21994
|
+
* When the change this row records HAPPENED, epoch ms, when that is earlier
|
|
21995
|
+
* than {@link timestamp} and the producer could date it (D684).
|
|
21996
|
+
*
|
|
21997
|
+
* Set on a package PICK-UP row only: its `timestamp` is when the departure
|
|
21998
|
+
* was CONCLUDED — five minutes of unseen observed time after the parcel went
|
|
21999
|
+
* — and a notification's footage has to be cut around the pick-up, not the
|
|
22000
|
+
* empty doormat after it (D682). Stored so every path that rebuilds a
|
|
22001
|
+
* notification subject from the row (the boot reconcile, a dry-run) anchors
|
|
22002
|
+
* on the same instant the live hook did.
|
|
22003
|
+
*
|
|
22004
|
+
* `timestamp` keeps its meaning. Absent on every other row and on every
|
|
22005
|
+
* pick-up written before D684 — UNKNOWN, never 0 and never `timestamp`.
|
|
22006
|
+
*/
|
|
22007
|
+
observedAt: z.number().optional(),
|
|
21921
22008
|
/** The parent track's key-event importance [0,1], propagated to every object
|
|
21922
22009
|
* event of the track (so an event row can be sorted by importance without a
|
|
21923
22010
|
* track join). Absent on legacy rows / before the track was scored. */
|
|
@@ -43959,7 +44046,6 @@ var RUNTIME_DEFAULTS = {
|
|
|
43959
44046
|
models: "camstack-data/models"
|
|
43960
44047
|
},
|
|
43961
44048
|
providers: [],
|
|
43962
|
-
"ffmpeg.binaryPath": "ffmpeg",
|
|
43963
44049
|
"ffmpeg.hwAccel": "auto",
|
|
43964
44050
|
"ffmpeg.threadCount": 0,
|
|
43965
44051
|
"auth.tokenExpiry": "30d"
|
|
@@ -57442,4 +57528,4 @@ function enumerateInferenceDevices(hw) {
|
|
|
57442
57528
|
return out;
|
|
57443
57529
|
}
|
|
57444
57530
|
//#endregion
|
|
57445
|
-
export { coreBlockAddonId as $,
|
|
57531
|
+
export { coreBlockAddonId as $, asJsonObject as $n, procedureAuthKey as $t, STORAGE_ACCESS_FALLBACK as A, buildFfmpegArgs as An, isSameAddonId as At, addonWidgetsCapability as B, isSourceCap as Bn, looseSchema as Bt, METHOD_ACCESS_MAP as C, vectorStoreCapability as Cn, foldSnapshotByFunction as Ct, REDACTED_SECRET as D, SOURCE_CAPS as Dn, isCollectionArrayMethod as Dt, RECORDING_SOURCE_CAMSTACK_ADDON as E, DEFAULT_FIRST_SIGHTING_FRESHNESS_MS as En, isArrayOutputSchema as Et, StorageLocationTypeSchema as F, compositionItemFieldPath as Fn, lifecycleJobSchema as Ft, batteryCapability as G, errMsg as Gn, modeMayWrite as Gt, authProviderCapability as H, DeviceFeature as Hn, mayWriteToLocation as Ht, StorageMigrationJobSchema as I, compositionSliceKey as In, localNetworkCapability as It, cameraGridLayoutCapability as J, DEVICE_SETTINGS_CONTRIBUTION_METHODS as Jn, objectInputDeclaresAddonId as Jt, buildCapabilityLookup as K, BaseAddon as Kn, motionCapability as Kt, UserRecordSchema as L, compositionSourceKey as Ln, locationIconKey as Lt, ScopedTokenSchema as M, composedDeviceRef as Mn, kebabToCamel as Mt, StorageCleanupJobSchema as N, composedDeviceStableId as Nn, legacyAutoLinkIds as Nt, RUNTIME_DEFAULTS as O, SOURCE_CAP_ACTIVE_FIELD as On, isLocationEnabled as Ot, StorageLocationModeSchema as P, compositionFeatureEnabled as Pn, legacyModeOf as Pt, compositionSourceRefs as Q, WELL_KNOWN_TAB_MAP as Qn, platformProbeCapability as Qt, addonPagesCapability as R, createStatefulExpressionMemory as Rn, logDestinationCapability as Rt, LocationIconIdSchema as S, vectorIndexDimConflictError as Sn, filesystemBrowseCapability as St, MOTION_CLOSE_AFTER_MS as T, COMPOSER_ADDON_ID as Tn, gbToBytes as Tt, backupCapability as U, DeviceRole as Un, memoizePinnedFfmpeg as Ut, alertsCapability as V, toExpressionValue as Vn, mayReadLocation as Vt, bareAddonId as W, DeviceType as Wn, metricsProviderCapability as Wt, composerCapability as X, ReadinessRegistry as Xn, parseStreamParamsFormPatch as Xt, collectSecretConfigKeys as Y, DEVICE_STATUS_METHOD as Yn, objectInputDeclaresRequiredDeviceId as Yt, compositionFieldKey as Z, ReadinessTimeoutError as Zn, planComposition as Zt, FIRST_LEVEL_MACRO_CLASSES as _, streamCatalogCapability as _n, enumerateSchemaFields as _t, BatteryStatusSchema as a, resolveMethodAuth as an, expandCapMethods as ar, dataStoreProviderCapability as at, LOG_LEVEL_RANK as b, validateComposition as bn, expandContainer as bt, COMPOSED_ITEM_FIXED_FIELDS as c, scopesAllowDeviceCap as cn, isEvent as cr, defineExtensionSlotProvider as ct, CORE_BLOCK_ADDON_PREFIX as d, siteZoneKey as dn, parseJsonUnknown as dr, deviceManagerCapability as dt, ptzAutotrackCapability as en, asNumber as er, coreBlockComposition as et, CoreBlockSchema as f, snapshotCapability as fn, readinessKey as fr, deviceStateCapability as ft, DeviceStatusSchema as g, storageProviderCapability as gn, EventCategory as gr, enumerateItemArrayFields as gt, DeclaredDevices as h, storageOccupancyCapability as hn, sleep as hr, enumerateInferenceDevices as ht, BaseDevice as i, resolveLocationMode as in, emitReadiness as ir, createDeviceExtensionProvider as it, STREAM_PROFILE_META as j, cloneStatefulExpressionMemory as jn, isVoidInput as jt, RecordingStatusSchema as k, SOURCE_CAP_CHANGED_AT_FIELD as kn, isObjectInput as kt, COMPOSER_RUNNER_ID as l, scoreRuntimes as ln, nodePin as lr, deriveBatteryPresence as lt, DERIVED_CAMERA_SILENCED_CAP_NAMES as m, storageMigrationCapability as mn, scopeKey as mr, doorbellCapability as mt, AlertSchema as n, replacedFieldKeys as nn, createEvent as nr, coreBlockSourceKind as nt, CAMERA_SWITCH_ORDER as o, runtimeStatePolicyFor as on, hydrateSchema as or, declarationOwnerNodeId as ot, DAY_NAMES as p, storageCapability as pn, resolveCapMount as pr, deviceStatusCapability as pt, buildStreamParamsConfigSchema as q, DATAPLANE_SECRET_HEADER as qn, normalizeUnit as qt, ApiKeyRecordSchema as r, resolveBucketMs as rn, emitDownForOwnedCaps as rr, coreBlocksCapability as rt, CAP_NAMES_WITH_STATUS as s, scopesAllowAddon as sn, isDeviceConfigCap as sr, decodeVectorBase64 as st, ALL_CAPABILITY_DEFINITIONS as t, reducePoints as tn, asString$1 as tr, coreBlockIdFromAddonId as tt, CORE_BLOCKS_ADDON_ID as u, settingsStoreCapability as un, parseJsonObject as ur, deviceExtensionCapability as ut, FieldClaimModeSchema as v, streamQualityLabel as vn, evaluateCompositionField as vt, MINUTES_PER_DAY as w, withLocationMode as wn, formatMinutes as wt, LegacyStorageLocationDefaultSchema as x, vectorDimFromBase64 as xn, extractNestedAddonId as xt, FieldClaimSchema as y, userManagementCapability as yn, evictionPolicyOfLocation as yt, addonSettingsCapability as z, evaluateSensorEdge as zn, logLevelAtMost as zt };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("./chunk-Cek0wNdY.js");
|
|
3
|
-
const require_dist = require("./dist-
|
|
3
|
+
const require_dist = require("./dist-D25eq33W.js");
|
|
4
4
|
const require_builtins_alerts_alerts_addon = require("./builtins/alerts/alerts.addon.js");
|
|
5
5
|
require("./builtins/alerts/index.js");
|
|
6
6
|
const require_builtins_composer_composer_addon = require("./builtins/composer/composer.addon.js");
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
|
|
2
|
-
import { $n as
|
|
2
|
+
import { $n as asJsonObject$1, $t as procedureAuthKey, Bt as looseSchema, C as METHOD_ACCESS_MAP, Dt as isCollectionArrayMethod, Et as isArrayOutputSchema, Ft as lifecycleJobSchema, Gn as errMsg$1, Jn as DEVICE_SETTINGS_CONTRIBUTION_METHODS, Jt as objectInputDeclaresAddonId, Mt as kebabToCamel, O as RUNTIME_DEFAULTS, Xn as ReadinessRegistry, Yn as DEVICE_STATUS_METHOD, Yt as objectInputDeclaresRequiredDeviceId, Zn as ReadinessTimeoutError, an as resolveMethodAuth, ar as expandCapMethods, b as LOG_LEVEL_RANK, cn as scopesAllowDeviceCap, dr as parseJsonUnknown, er as asNumber, fr as readinessKey, gr as EventCategory$1, jt as isVoidInput, kt as isObjectInput, mr as scopeKey, nr as createEvent, pr as resolveCapMount, qn as DATAPLANE_SECRET_HEADER$1, rr as emitDownForOwnedCaps, sn as scopesAllowAddon, t as ALL_CAPABILITY_DEFINITIONS, tr as asString$1, ur as parseJsonObject, xt as extractNestedAddonId, z as addonSettingsCapability, zt as logLevelAtMost } from "./dist-DENeGKrn.mjs";
|
|
3
3
|
import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
|
|
4
4
|
import "./builtins/alerts/index.mjs";
|
|
5
5
|
import { ComposerAddon } from "./builtins/composer/composer.addon.mjs";
|