@camstack/addon-pipeline 0.1.0 → 0.1.2
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/{addon-CwDFZWAb.d.cts → addon-DK7eQ0PN.d.cts} +3 -4
- package/dist/{addon-CwDFZWAb.d.ts → addon-DK7eQ0PN.d.ts} +3 -4
- package/dist/addon.cjs +27 -72
- package/dist/addon.cjs.map +1 -1
- package/dist/addon.d.cts +1 -1
- package/dist/addon.d.ts +1 -1
- package/dist/addon.js +27 -72
- package/dist/addon.js.map +1 -1
- package/dist/index.cjs +29 -3304
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -921
- package/dist/index.d.ts +4 -921
- package/dist/index.js +28 -3271
- package/dist/index.js.map +1 -1
- package/package.json +34 -17
package/dist/addon.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { P as PipelineAddon, d as RecordingEngineDependencies, e as RecordingEngineV2Dependencies, P as default } from './addon-
|
|
1
|
+
export { P as PipelineAddon, d as RecordingEngineDependencies, e as RecordingEngineV2Dependencies, P as default } from './addon-DK7eQ0PN.cjs';
|
|
2
2
|
import '@camstack/types';
|
|
3
3
|
import 'better-sqlite3';
|
package/dist/addon.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { P as PipelineAddon, d as RecordingEngineDependencies, e as RecordingEngineV2Dependencies, P as default } from './addon-
|
|
1
|
+
export { P as PipelineAddon, d as RecordingEngineDependencies, e as RecordingEngineV2Dependencies, P as default } from './addon-DK7eQ0PN.js';
|
|
2
2
|
import '@camstack/types';
|
|
3
3
|
import 'better-sqlite3';
|
package/dist/addon.js
CHANGED
|
@@ -14,6 +14,7 @@ __export(ffmpeg_config_exports, {
|
|
|
14
14
|
buildFfmpegInputArgs: () => buildFfmpegInputArgs,
|
|
15
15
|
buildFfmpegOutputArgs: () => buildFfmpegOutputArgs,
|
|
16
16
|
detectPlatformDefaults: () => detectPlatformDefaults,
|
|
17
|
+
resolveFfmpegBinary: () => resolveFfmpegBinary,
|
|
17
18
|
resolveFfmpegConfig: () => resolveFfmpegConfig
|
|
18
19
|
});
|
|
19
20
|
import { execFileSync } from "child_process";
|
|
@@ -58,6 +59,12 @@ function buildFfmpegOutputArgs(config) {
|
|
|
58
59
|
if (config.outputArgs?.length) args.push(...config.outputArgs);
|
|
59
60
|
return args;
|
|
60
61
|
}
|
|
62
|
+
async function resolveFfmpegBinary(configPath, deps) {
|
|
63
|
+
if (configPath && configPath !== "ffmpeg") {
|
|
64
|
+
return configPath;
|
|
65
|
+
}
|
|
66
|
+
return deps.ensureFfmpeg();
|
|
67
|
+
}
|
|
61
68
|
var init_ffmpeg_config = __esm({
|
|
62
69
|
"src/recording/ffmpeg-config.ts"() {
|
|
63
70
|
"use strict";
|
|
@@ -1166,7 +1173,7 @@ var recording_coordinator_exports = {};
|
|
|
1166
1173
|
__export(recording_coordinator_exports, {
|
|
1167
1174
|
RecordingCoordinator: () => RecordingCoordinator
|
|
1168
1175
|
});
|
|
1169
|
-
var POLICY_EVAL_INTERVAL_MS, MOTION_FALLBACK_TIMEOUT_MS, RecordingCoordinator;
|
|
1176
|
+
var DEFAULT_SEGMENT_DURATION_SEC, POLICY_EVAL_INTERVAL_MS, MOTION_FALLBACK_TIMEOUT_MS, RecordingCoordinator;
|
|
1170
1177
|
var init_recording_coordinator = __esm({
|
|
1171
1178
|
"src/recording/recording-coordinator.ts"() {
|
|
1172
1179
|
"use strict";
|
|
@@ -1176,6 +1183,7 @@ var init_recording_coordinator = __esm({
|
|
|
1176
1183
|
init_retention_manager();
|
|
1177
1184
|
init_playlist_generator();
|
|
1178
1185
|
init_storage_estimator();
|
|
1186
|
+
DEFAULT_SEGMENT_DURATION_SEC = 4;
|
|
1179
1187
|
POLICY_EVAL_INTERVAL_MS = 1e3;
|
|
1180
1188
|
MOTION_FALLBACK_TIMEOUT_MS = 6e4;
|
|
1181
1189
|
RecordingCoordinator = class _RecordingCoordinator {
|
|
@@ -1189,6 +1197,7 @@ var init_recording_coordinator = __esm({
|
|
|
1189
1197
|
storagePath;
|
|
1190
1198
|
globalFfmpegConfig;
|
|
1191
1199
|
detectedFfmpegConfig;
|
|
1200
|
+
segmentDurationSec;
|
|
1192
1201
|
recordings = /* @__PURE__ */ new Map();
|
|
1193
1202
|
policyTimer = null;
|
|
1194
1203
|
retentionManager;
|
|
@@ -1205,6 +1214,7 @@ var init_recording_coordinator = __esm({
|
|
|
1205
1214
|
this.storagePath = config.storagePath;
|
|
1206
1215
|
this.globalFfmpegConfig = config.globalFfmpegConfig;
|
|
1207
1216
|
this.detectedFfmpegConfig = config.detectedFfmpegConfig;
|
|
1217
|
+
this.segmentDurationSec = config.segmentDurationSec ?? DEFAULT_SEGMENT_DURATION_SEC;
|
|
1208
1218
|
this.retentionManager = new RetentionManager(
|
|
1209
1219
|
this.db,
|
|
1210
1220
|
this.logger.child("retention"),
|
|
@@ -1290,7 +1300,7 @@ var init_recording_coordinator = __esm({
|
|
|
1290
1300
|
const writerConfig = {
|
|
1291
1301
|
deviceId,
|
|
1292
1302
|
streamId: sp.streamId,
|
|
1293
|
-
segmentDurationSec:
|
|
1303
|
+
segmentDurationSec: this.segmentDurationSec,
|
|
1294
1304
|
storagePath: this.storagePath,
|
|
1295
1305
|
storageName,
|
|
1296
1306
|
subDirectory,
|
|
@@ -3135,9 +3145,7 @@ var PipelineAddon = class {
|
|
|
3135
3145
|
capabilities: [
|
|
3136
3146
|
{ name: "stream-broker", mode: "singleton" },
|
|
3137
3147
|
{ name: "recording-engine", mode: "singleton" },
|
|
3138
|
-
{ name: "analysis-
|
|
3139
|
-
{ name: "analysis-data-persistence", mode: "singleton" },
|
|
3140
|
-
{ name: "webrtc", mode: "collection" }
|
|
3148
|
+
{ name: "analysis-data-persistence", mode: "singleton" }
|
|
3141
3149
|
]
|
|
3142
3150
|
};
|
|
3143
3151
|
// Stream broker
|
|
@@ -3150,11 +3158,10 @@ var PipelineAddon = class {
|
|
|
3150
3158
|
currentRecordingConfig = {
|
|
3151
3159
|
ffmpegPath: "ffmpeg",
|
|
3152
3160
|
hwaccel: void 0,
|
|
3153
|
-
threads: void 0
|
|
3161
|
+
threads: void 0,
|
|
3162
|
+
segmentDurationSeconds: 4,
|
|
3163
|
+
defaultRetentionDays: 30
|
|
3154
3164
|
};
|
|
3155
|
-
// Analysis pipeline
|
|
3156
|
-
analysisPipeline = null;
|
|
3157
|
-
analysisLogger = null;
|
|
3158
3165
|
// Analysis persistence
|
|
3159
3166
|
persistenceFacade = null;
|
|
3160
3167
|
setRecordingDependencies(deps) {
|
|
@@ -3184,10 +3191,14 @@ var PipelineAddon = class {
|
|
|
3184
3191
|
hwaccel: context.addonConfig.hwaccel ?? this.currentRecordingConfig.hwaccel,
|
|
3185
3192
|
threads: context.addonConfig.threads ?? this.currentRecordingConfig.threads
|
|
3186
3193
|
};
|
|
3194
|
+
const segmentDurationSeconds = context.addonConfig.segmentDurationSeconds ?? this.currentRecordingConfig.segmentDurationSeconds;
|
|
3195
|
+
const defaultRetentionDays = context.addonConfig.defaultRetentionDays ?? this.currentRecordingConfig.defaultRetentionDays;
|
|
3187
3196
|
this.currentRecordingConfig = {
|
|
3188
3197
|
ffmpegPath,
|
|
3189
3198
|
hwaccel: globalFfmpegConfig.hwaccel,
|
|
3190
|
-
threads: globalFfmpegConfig.threads
|
|
3199
|
+
threads: globalFfmpegConfig.threads,
|
|
3200
|
+
segmentDurationSeconds,
|
|
3201
|
+
defaultRetentionDays
|
|
3191
3202
|
};
|
|
3192
3203
|
const fileStorage = context.storage.files;
|
|
3193
3204
|
if (!fileStorage) {
|
|
@@ -3203,7 +3214,8 @@ var PipelineAddon = class {
|
|
|
3203
3214
|
fileStorage,
|
|
3204
3215
|
storagePath,
|
|
3205
3216
|
globalFfmpegConfig,
|
|
3206
|
-
detectedFfmpegConfig
|
|
3217
|
+
detectedFfmpegConfig,
|
|
3218
|
+
segmentDurationSec: segmentDurationSeconds
|
|
3207
3219
|
});
|
|
3208
3220
|
await this.coordinator.start();
|
|
3209
3221
|
context.logger.info("Recording Engine initialized");
|
|
@@ -3212,16 +3224,6 @@ var PipelineAddon = class {
|
|
|
3212
3224
|
context.logger.warn(`Recording Engine failed to initialize: ${msg}`);
|
|
3213
3225
|
}
|
|
3214
3226
|
}
|
|
3215
|
-
this.analysisLogger = context.logger;
|
|
3216
|
-
try {
|
|
3217
|
-
const mod = await import("@camstack/lib-pipeline-analysis");
|
|
3218
|
-
const instance = new mod.AnalysisPipeline();
|
|
3219
|
-
this.analysisPipeline = instance;
|
|
3220
|
-
this.analysisLogger.info("Analysis pipeline loaded successfully");
|
|
3221
|
-
} catch (error) {
|
|
3222
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
3223
|
-
this.analysisLogger.warn(`Analysis pipeline not available: ${msg} -- analysis features disabled`);
|
|
3224
|
-
}
|
|
3225
3227
|
const eventPersistence = new EventPersistenceService({
|
|
3226
3228
|
getStorageLocation: () => context.storage,
|
|
3227
3229
|
subscribe: (filter, handler) => context.eventBus.subscribe(filter, handler),
|
|
@@ -3273,7 +3275,6 @@ var PipelineAddon = class {
|
|
|
3273
3275
|
this.sqliteDb = null;
|
|
3274
3276
|
}
|
|
3275
3277
|
this.recordingDb = null;
|
|
3276
|
-
this.analysisPipeline = null;
|
|
3277
3278
|
if (this.persistenceFacade) {
|
|
3278
3279
|
this.persistenceFacade.eventPersistence.stop();
|
|
3279
3280
|
this.persistenceFacade.retention.stop();
|
|
@@ -3286,13 +3287,8 @@ var PipelineAddon = class {
|
|
|
3286
3287
|
return this.brokerManager;
|
|
3287
3288
|
case "recording-engine":
|
|
3288
3289
|
return this.coordinator;
|
|
3289
|
-
case "analysis-pipeline":
|
|
3290
|
-
return this.analysisPipeline;
|
|
3291
3290
|
case "analysis-data-persistence":
|
|
3292
3291
|
return this.persistenceFacade;
|
|
3293
|
-
case "webrtc":
|
|
3294
|
-
return null;
|
|
3295
|
-
// WebRTC is provided externally or via collection
|
|
3296
3292
|
default:
|
|
3297
3293
|
return null;
|
|
3298
3294
|
}
|
|
@@ -3306,52 +3302,9 @@ var PipelineAddon = class {
|
|
|
3306
3302
|
if (!this.recordingDb) throw new Error("PipelineAddon recording not initialized");
|
|
3307
3303
|
return this.recordingDb;
|
|
3308
3304
|
}
|
|
3309
|
-
/** Whether the analysis pipeline package loaded successfully */
|
|
3310
|
-
isAnalysisAvailable() {
|
|
3311
|
-
return this.analysisPipeline !== null;
|
|
3312
|
-
}
|
|
3313
3305
|
// --- IConfigurable ---
|
|
3314
3306
|
getConfigSchema() {
|
|
3315
|
-
return {
|
|
3316
|
-
sections: [
|
|
3317
|
-
{
|
|
3318
|
-
id: "ffmpeg",
|
|
3319
|
-
title: "FFmpeg Settings",
|
|
3320
|
-
columns: 2,
|
|
3321
|
-
fields: [
|
|
3322
|
-
{
|
|
3323
|
-
type: "text",
|
|
3324
|
-
key: "ffmpegPath",
|
|
3325
|
-
label: "FFmpeg Binary Path",
|
|
3326
|
-
description: 'Path to the ffmpeg executable, or just "ffmpeg" if it is in your PATH',
|
|
3327
|
-
placeholder: "ffmpeg"
|
|
3328
|
-
},
|
|
3329
|
-
{
|
|
3330
|
-
type: "select",
|
|
3331
|
-
key: "hwaccel",
|
|
3332
|
-
label: "Hardware Acceleration",
|
|
3333
|
-
description: "Enable GPU-accelerated video encoding if supported by your hardware",
|
|
3334
|
-
options: [
|
|
3335
|
-
{ value: "", label: "None (software)", description: "CPU-only encoding" },
|
|
3336
|
-
{ value: "nvenc", label: "NVIDIA NVENC", description: "NVIDIA GPU encoding" },
|
|
3337
|
-
{ value: "vaapi", label: "Intel VAAPI", description: "Intel GPU encoding (Linux)" },
|
|
3338
|
-
{ value: "videotoolbox", label: "Apple VideoToolbox", description: "macOS hardware encoding" }
|
|
3339
|
-
]
|
|
3340
|
-
},
|
|
3341
|
-
{
|
|
3342
|
-
type: "number",
|
|
3343
|
-
key: "threads",
|
|
3344
|
-
label: "FFmpeg Threads",
|
|
3345
|
-
description: "Number of CPU threads for software encoding (0 = auto)",
|
|
3346
|
-
min: 0,
|
|
3347
|
-
max: 64,
|
|
3348
|
-
step: 1,
|
|
3349
|
-
unit: "threads"
|
|
3350
|
-
}
|
|
3351
|
-
]
|
|
3352
|
-
}
|
|
3353
|
-
]
|
|
3354
|
-
};
|
|
3307
|
+
return { sections: [] };
|
|
3355
3308
|
}
|
|
3356
3309
|
getConfig() {
|
|
3357
3310
|
return { ...this.currentRecordingConfig };
|
|
@@ -3360,7 +3313,9 @@ var PipelineAddon = class {
|
|
|
3360
3313
|
this.currentRecordingConfig = {
|
|
3361
3314
|
ffmpegPath: config.ffmpegPath ?? this.currentRecordingConfig.ffmpegPath,
|
|
3362
3315
|
hwaccel: config.hwaccel ?? this.currentRecordingConfig.hwaccel,
|
|
3363
|
-
threads: config.threads ?? this.currentRecordingConfig.threads
|
|
3316
|
+
threads: config.threads ?? this.currentRecordingConfig.threads,
|
|
3317
|
+
segmentDurationSeconds: config.segmentDurationSeconds ?? this.currentRecordingConfig.segmentDurationSeconds,
|
|
3318
|
+
defaultRetentionDays: config.defaultRetentionDays ?? this.currentRecordingConfig.defaultRetentionDays
|
|
3364
3319
|
};
|
|
3365
3320
|
}
|
|
3366
3321
|
};
|