@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.d.cts CHANGED
@@ -1,3 +1,3 @@
1
- export { P as PipelineAddon, d as RecordingEngineDependencies, e as RecordingEngineV2Dependencies, P as default } from './addon-CwDFZWAb.cjs';
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-CwDFZWAb.js';
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: 4,
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-pipeline", mode: "singleton" },
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
  };