@camstack/addon-post-analysis 0.1.18 → 0.1.20

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.
Files changed (68) hide show
  1. package/dist/embedding-encoder/index.js +1 -1
  2. package/dist/embedding-encoder/index.mjs +1 -1
  3. package/dist/enrichment-engine/index.js +1 -1
  4. package/dist/enrichment-engine/index.mjs +1 -1
  5. package/dist/{index-DafwGlkQ.js → index-B0RhVv1c.js} +3940 -807
  6. package/dist/index-B0RhVv1c.js.map +1 -0
  7. package/dist/{index-CIJfmsWX.mjs → index-ot5PeFg_.mjs} +3943 -810
  8. package/dist/index-ot5PeFg_.mjs.map +1 -0
  9. package/dist/pipeline-analytics/@mf-types.zip +0 -0
  10. package/dist/pipeline-analytics/{__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-h5aXOPSA.mjs → __mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_sdk__loadShare__.mjs-lantnv8e.mjs} +1 -1
  11. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-BD3oMNGB.mjs +29 -0
  12. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BgOHCakr.mjs +18 -0
  13. package/dist/pipeline-analytics/{__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.mjs-D-USVuHq.mjs → __mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.mjs-D1qPKjvR.mjs} +3 -1
  14. package/dist/pipeline-analytics/{__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-qQCPW8pT.mjs → __mfe_internal__addon_pipeline_analytics_widgets__loadShare__react__loadShare__.mjs_commonjs-proxy-B5X50Xa4.mjs} +1 -1
  15. package/dist/pipeline-analytics/{__mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-Bv9bYz9E.mjs → __mfe_internal__addon_pipeline_analytics_widgets__loadShare__react_mf_2_dom__loadShare__.mjs_commonjs-proxy-B10b5k5J.mjs} +1 -1
  16. package/dist/pipeline-analytics/_stub.js +2 -3
  17. package/dist/pipeline-analytics/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-B3kCe2qM.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_analytics_widgets-DWB3apaJ.mjs} +6 -6
  18. package/dist/pipeline-analytics/{client-DHmQcIWy.mjs → client-C6xdgLZU.mjs} +2 -2
  19. package/dist/pipeline-analytics/{hostInit-CuWzic_f.mjs → hostInit-3cyL9eyG.mjs} +12 -12
  20. package/dist/pipeline-analytics/{index-BA65ZJOW.mjs → index-BCTHeI2m.mjs} +254 -268
  21. package/dist/pipeline-analytics/{index-Crs1D0Uu.mjs → index-BuWLz0GG.mjs} +1 -1
  22. package/dist/pipeline-analytics/{index-gpelkpEE.mjs → index-CIwq-tQL.mjs} +1 -1
  23. package/dist/pipeline-analytics/{index-CHnXxMRA.mjs → index-CWBMDbou.mjs} +1 -1
  24. package/dist/pipeline-analytics/index-CZhagnlH.mjs +67784 -0
  25. package/dist/pipeline-analytics/{index-DicaGC31.mjs → index-D883Q5B8.mjs} +1 -1
  26. package/dist/pipeline-analytics/index-DtOI1aTU.mjs +18504 -0
  27. package/dist/pipeline-analytics/index.js +605 -42
  28. package/dist/pipeline-analytics/index.js.map +1 -1
  29. package/dist/pipeline-analytics/index.mjs +604 -42
  30. package/dist/pipeline-analytics/index.mjs.map +1 -1
  31. package/dist/pipeline-analytics/{jsx-runtime-Wcfyyyt4.mjs → jsx-runtime-DdLhuHmJ.mjs} +1 -1
  32. package/dist/pipeline-analytics/remoteEntry.js +1 -1
  33. package/dist/pipeline-analytics/{schemas-ChN4Ih0h.mjs → schemas-B7L0qZtq.mjs} +530 -515
  34. package/package.json +12 -27
  35. package/dist/ffmpeg-config-DRONlBsj.mjs +0 -56
  36. package/dist/ffmpeg-config-DRONlBsj.mjs.map +0 -1
  37. package/dist/ffmpeg-config-uANz3sV5.js +0 -73
  38. package/dist/ffmpeg-config-uANz3sV5.js.map +0 -1
  39. package/dist/index-CIJfmsWX.mjs.map +0 -1
  40. package/dist/index-DafwGlkQ.js.map +0 -1
  41. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-d8PmLbO2.mjs +0 -19
  42. package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.mjs-BcWYbuKp.mjs +0 -18
  43. package/dist/pipeline-analytics/index-CUXiTSWS.mjs +0 -13883
  44. package/dist/pipeline-analytics/index-gbflFMEY.mjs +0 -36403
  45. package/dist/playlist-generator-EhPaB7Hn.js +0 -48
  46. package/dist/playlist-generator-EhPaB7Hn.js.map +0 -1
  47. package/dist/playlist-generator-VTkgn53O.mjs +0 -48
  48. package/dist/playlist-generator-VTkgn53O.mjs.map +0 -1
  49. package/dist/recording/index.js +0 -257
  50. package/dist/recording/index.js.map +0 -1
  51. package/dist/recording/index.mjs +0 -235
  52. package/dist/recording/index.mjs.map +0 -1
  53. package/dist/recording-coordinator-BKsM_JGg.js +0 -1052
  54. package/dist/recording-coordinator-BKsM_JGg.js.map +0 -1
  55. package/dist/recording-coordinator-Bw3N1gYu.mjs +0 -1012
  56. package/dist/recording-coordinator-Bw3N1gYu.mjs.map +0 -1
  57. package/dist/recording-db-gOgaoQh0.js +0 -348
  58. package/dist/recording-db-gOgaoQh0.js.map +0 -1
  59. package/dist/recording-db-lIkSMTLq.mjs +0 -348
  60. package/dist/recording-db-lIkSMTLq.mjs.map +0 -1
  61. package/dist/recording-service-facade-B9lG6OFn.mjs +0 -123
  62. package/dist/recording-service-facade-B9lG6OFn.mjs.map +0 -1
  63. package/dist/recording-service-facade-Do1PKlAL.js +0 -123
  64. package/dist/recording-service-facade-Do1PKlAL.js.map +0 -1
  65. package/dist/storage-estimator-CRpoQc9j.js +0 -72
  66. package/dist/storage-estimator-CRpoQc9j.js.map +0 -1
  67. package/dist/storage-estimator-DzD8gWJH.mjs +0 -72
  68. package/dist/storage-estimator-DzD8gWJH.mjs.map +0 -1
package/package.json CHANGED
@@ -1,13 +1,12 @@
1
1
  {
2
2
  "name": "@camstack/addon-post-analysis",
3
- "version": "0.1.18",
4
- "description": "CamStack Post-Analysis bundle — recording, enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping 4 addons that consume pipeline output.",
3
+ "version": "0.1.20",
4
+ "description": "CamStack Post-Analysis bundle — enrichment, embedding-encoder, pipeline-analytics. Multi-entry npm package shipping addons that consume pipeline output.",
5
5
  "keywords": [
6
6
  "camstack",
7
7
  "addon",
8
8
  "camstack-addon",
9
9
  "post-analysis",
10
- "recording",
11
10
  "enrichment",
12
11
  "embedding",
13
12
  "analytics"
@@ -17,12 +16,8 @@
17
16
  "type": "git",
18
17
  "url": "https://github.com/camstack/server"
19
18
  },
20
- "main": "./dist/recording/index.js",
19
+ "main": "./dist/pipeline-analytics/index.js",
21
20
  "exports": {
22
- "./recording": {
23
- "import": "./dist/recording/index.mjs",
24
- "require": "./dist/recording/index.js"
25
- },
26
21
  "./enrichment-engine": {
27
22
  "import": "./dist/enrichment-engine/index.mjs",
28
23
  "require": "./dist/enrichment-engine/index.js"
@@ -45,7 +40,7 @@
45
40
  "displayName": "Post-Analysis",
46
41
  "bundle": {
47
42
  "displayName": "Post-Analysis",
48
- "description": "Recording, enrichment, embedding encoder, and pipeline analytics — consumers of pipeline output."
43
+ "description": "Enrichment, embedding encoder, and pipeline analytics — consumers of pipeline output."
49
44
  },
50
45
  "nativeDependencies": {
51
46
  "better-sqlite3": "^12.8.0",
@@ -53,24 +48,6 @@
53
48
  "sharp": "^0.34.0"
54
49
  },
55
50
  "addons": [
56
- {
57
- "id": "recording",
58
- "category": "analytics",
59
- "name": "Recording",
60
- "description": "Per-camera detection-triggered recording with per-stream profile + retention. Subscribes to detection events on the post-analysis bus and writes timestamped clips to the recordings StorageLocation.",
61
- "entry": "./dist/recording/index.js",
62
- "execution": {
63
- "placement": "any-node"
64
- },
65
- "protected": true,
66
- "capabilities": [
67
- {
68
- "name": "recording-engine"
69
- }
70
- ],
71
- "icon": "assets/icon.svg",
72
- "color": "#9333ea"
73
- },
74
51
  {
75
52
  "id": "enrichment-engine",
76
53
  "category": "analytics",
@@ -127,6 +104,14 @@
127
104
  "name": "addon-widgets-source"
128
105
  }
129
106
  ],
107
+ "storageLocations": [
108
+ {
109
+ "id": "eventMedia",
110
+ "displayName": "Event Media",
111
+ "cardinality": "single",
112
+ "description": "Detection snapshots, thumbnails and crops."
113
+ }
114
+ ],
130
115
  "icon": "assets/icon.svg",
131
116
  "color": "#9333ea"
132
117
  }
@@ -1,56 +0,0 @@
1
- import { execFileSync } from "node:child_process";
2
- import * as os from "node:os";
3
- function detectPlatformDefaults(ffmpegPath = "ffmpeg") {
4
- let hwaccels = [];
5
- try {
6
- const output = execFileSync(ffmpegPath, ["-hwaccels", "-hide_banner"], { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
7
- hwaccels = output.split("\n").map((l) => l.trim()).filter((l) => l && l !== "Hardware acceleration methods:");
8
- } catch {
9
- }
10
- const platform = os.platform();
11
- if (platform === "darwin" && hwaccels.includes("videotoolbox")) return { hwaccel: "videotoolbox", threads: 0 };
12
- if (platform === "linux") {
13
- for (const hw of ["vaapi", "qsv", "cuda", "v4l2m2m"]) {
14
- if (hwaccels.includes(hw)) return { hwaccel: hw, threads: 0 };
15
- }
16
- }
17
- return { hwaccel: "none", threads: Math.max(1, Math.floor(os.cpus().length / 2)) };
18
- }
19
- function resolveFfmpegConfig(deviceConfig, globalConfig, detected) {
20
- return {
21
- path: deviceConfig?.path ?? globalConfig.path ?? detected.path ?? "ffmpeg",
22
- hwaccel: deviceConfig?.hwaccel ?? globalConfig.hwaccel ?? detected.hwaccel ?? "none",
23
- inputArgs: deviceConfig?.inputArgs ?? globalConfig.inputArgs,
24
- outputArgs: deviceConfig?.outputArgs ?? globalConfig.outputArgs,
25
- videoCodec: deviceConfig?.videoCodec ?? globalConfig.videoCodec ?? "copy",
26
- audioCodec: deviceConfig?.audioCodec ?? globalConfig.audioCodec ?? "copy",
27
- threads: deviceConfig?.threads ?? globalConfig.threads ?? detected.threads
28
- };
29
- }
30
- function buildFfmpegInputArgs(config, inputUrl) {
31
- const args = ["-hide_banner", "-loglevel", "warning"];
32
- if (config.hwaccel && config.hwaccel !== "none") args.push("-hwaccel", config.hwaccel);
33
- if (config.threads !== void 0) args.push("-threads", String(config.threads));
34
- if (config.inputArgs?.length) args.push(...config.inputArgs);
35
- args.push("-rtsp_transport", "tcp", "-i", inputUrl);
36
- return args;
37
- }
38
- function buildFfmpegOutputArgs(config) {
39
- const args = ["-c:v", config.videoCodec ?? "copy", "-c:a", config.audioCodec ?? "copy"];
40
- if (config.outputArgs?.length) args.push(...config.outputArgs);
41
- return args;
42
- }
43
- async function resolveFfmpegBinary(configPath, deps) {
44
- if (configPath && configPath !== "ffmpeg") {
45
- return configPath;
46
- }
47
- return deps.ensureFfmpeg();
48
- }
49
- export {
50
- buildFfmpegInputArgs,
51
- buildFfmpegOutputArgs,
52
- detectPlatformDefaults,
53
- resolveFfmpegBinary,
54
- resolveFfmpegConfig
55
- };
56
- //# sourceMappingURL=ffmpeg-config-DRONlBsj.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ffmpeg-config-DRONlBsj.mjs","sources":["../src/recording/recording/ffmpeg-config.ts"],"sourcesContent":["import { execFileSync } from 'node:child_process'\nimport * as os from 'node:os'\nimport type { FfmpegConfig, IAddonDepsManager } from '@camstack/types'\n\n/**\n * Probe ffmpeg binary and detect optimal hwaccel for the host platform.\n * Called once at server startup, result cached.\n */\nexport function detectPlatformDefaults(ffmpegPath: string = 'ffmpeg'): Partial<FfmpegConfig> {\n let hwaccels: string[] = []\n try {\n const output = execFileSync(ffmpegPath, ['-hwaccels', '-hide_banner'], { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] })\n hwaccels = output.split('\\n').map(l => l.trim()).filter(l => l && l !== 'Hardware acceleration methods:')\n } catch {\n // ffmpeg not found or hwaccel probe failed — fall through to defaults\n }\n\n const platform = os.platform()\n if (platform === 'darwin' && hwaccels.includes('videotoolbox')) return { hwaccel: 'videotoolbox', threads: 0 }\n if (platform === 'linux') {\n for (const hw of ['vaapi', 'qsv', 'cuda', 'v4l2m2m'] as const) {\n if (hwaccels.includes(hw)) return { hwaccel: hw, threads: 0 }\n }\n }\n return { hwaccel: 'none', threads: Math.max(1, Math.floor(os.cpus().length / 2)) }\n}\n\n/**\n * Resolve ffmpeg config for a device.\n * Merge order: detected <- global <- per-device (most specific wins).\n */\nexport function resolveFfmpegConfig(\n deviceConfig: Partial<FfmpegConfig> | undefined,\n globalConfig: Partial<FfmpegConfig>,\n detected: Partial<FfmpegConfig>,\n): FfmpegConfig {\n return {\n path: deviceConfig?.path ?? globalConfig.path ?? detected.path ?? 'ffmpeg',\n hwaccel: deviceConfig?.hwaccel ?? globalConfig.hwaccel ?? detected.hwaccel ?? 'none',\n inputArgs: deviceConfig?.inputArgs ?? globalConfig.inputArgs,\n outputArgs: deviceConfig?.outputArgs ?? globalConfig.outputArgs,\n videoCodec: deviceConfig?.videoCodec ?? globalConfig.videoCodec ?? 'copy',\n audioCodec: deviceConfig?.audioCodec ?? globalConfig.audioCodec ?? 'copy',\n threads: deviceConfig?.threads ?? globalConfig.threads ?? detected.threads,\n }\n}\n\n/**\n * Build common ffmpeg args from a resolved config.\n */\nexport function buildFfmpegInputArgs(config: FfmpegConfig, inputUrl: string): string[] {\n const args: string[] = ['-hide_banner', '-loglevel', 'warning']\n if (config.hwaccel && config.hwaccel !== 'none') args.push('-hwaccel', config.hwaccel)\n if (config.threads !== undefined) args.push('-threads', String(config.threads))\n if (config.inputArgs?.length) args.push(...config.inputArgs)\n args.push('-rtsp_transport', 'tcp', '-i', inputUrl)\n return args\n}\n\nexport function buildFfmpegOutputArgs(config: FfmpegConfig): string[] {\n const args: string[] = ['-c:v', config.videoCodec ?? 'copy', '-c:a', config.audioCodec ?? 'copy']\n if (config.outputArgs?.length) args.push(...config.outputArgs)\n return args\n}\n\n/**\n * Resolve ffmpeg binary path. Priority:\n * 1. Explicit config path\n * 2. Embedded (data/deps/ffmpeg)\n * 3. System PATH\n * 4. Download static build\n */\nexport async function resolveFfmpegBinary(\n configPath: string | undefined,\n deps: IAddonDepsManager,\n): Promise<string> {\n // Explicit config\n if (configPath && configPath !== 'ffmpeg') {\n return configPath\n }\n\n // Try embedded or download via deps manager\n return deps.ensureFfmpeg()\n}\n"],"names":[],"mappings":";;AAQO,SAAS,uBAAuB,aAAqB,UAAiC;AAC3F,MAAI,WAAqB,CAAA;AACzB,MAAI;AACF,UAAM,SAAS,aAAa,YAAY,CAAC,aAAa,cAAc,GAAG,EAAE,UAAU,QAAQ,SAAS,KAAM,OAAO,CAAC,QAAQ,QAAQ,MAAM,GAAG;AAC3I,eAAW,OAAO,MAAM,IAAI,EAAE,IAAI,CAAA,MAAK,EAAE,KAAA,CAAM,EAAE,OAAO,CAAA,MAAK,KAAK,MAAM,gCAAgC;AAAA,EAC1G,QAAQ;AAAA,EAER;AAEA,QAAM,WAAW,GAAG,SAAA;AACpB,MAAI,aAAa,YAAY,SAAS,SAAS,cAAc,EAAG,QAAO,EAAE,SAAS,gBAAgB,SAAS,EAAA;AAC3G,MAAI,aAAa,SAAS;AACxB,eAAW,MAAM,CAAC,SAAS,OAAO,QAAQ,SAAS,GAAY;AAC7D,UAAI,SAAS,SAAS,EAAE,UAAU,EAAE,SAAS,IAAI,SAAS,EAAA;AAAA,IAC5D;AAAA,EACF;AACA,SAAO,EAAE,SAAS,QAAQ,SAAS,KAAK,IAAI,GAAG,KAAK,MAAM,GAAG,KAAA,EAAO,SAAS,CAAC,CAAC,EAAA;AACjF;AAMO,SAAS,oBACd,cACA,cACA,UACc;AACd,SAAO;AAAA,IACL,MAAM,cAAc,QAAQ,aAAa,QAAQ,SAAS,QAAQ;AAAA,IAClE,SAAS,cAAc,WAAW,aAAa,WAAW,SAAS,WAAW;AAAA,IAC9E,WAAW,cAAc,aAAa,aAAa;AAAA,IACnD,YAAY,cAAc,cAAc,aAAa;AAAA,IACrD,YAAY,cAAc,cAAc,aAAa,cAAc;AAAA,IACnE,YAAY,cAAc,cAAc,aAAa,cAAc;AAAA,IACnE,SAAS,cAAc,WAAW,aAAa,WAAW,SAAS;AAAA,EAAA;AAEvE;AAKO,SAAS,qBAAqB,QAAsB,UAA4B;AACrF,QAAM,OAAiB,CAAC,gBAAgB,aAAa,SAAS;AAC9D,MAAI,OAAO,WAAW,OAAO,YAAY,OAAQ,MAAK,KAAK,YAAY,OAAO,OAAO;AACrF,MAAI,OAAO,YAAY,OAAW,MAAK,KAAK,YAAY,OAAO,OAAO,OAAO,CAAC;AAC9E,MAAI,OAAO,WAAW,aAAa,KAAK,GAAG,OAAO,SAAS;AAC3D,OAAK,KAAK,mBAAmB,OAAO,MAAM,QAAQ;AAClD,SAAO;AACT;AAEO,SAAS,sBAAsB,QAAgC;AACpE,QAAM,OAAiB,CAAC,QAAQ,OAAO,cAAc,QAAQ,QAAQ,OAAO,cAAc,MAAM;AAChG,MAAI,OAAO,YAAY,aAAa,KAAK,GAAG,OAAO,UAAU;AAC7D,SAAO;AACT;AASA,eAAsB,oBACpB,YACA,MACiB;AAEjB,MAAI,cAAc,eAAe,UAAU;AACzC,WAAO;AAAA,EACT;AAGA,SAAO,KAAK,aAAA;AACd;"}
@@ -1,73 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const node_child_process = require("node:child_process");
4
- const os = require("node:os");
5
- function _interopNamespaceDefault(e) {
6
- const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
7
- if (e) {
8
- for (const k in e) {
9
- if (k !== "default") {
10
- const d = Object.getOwnPropertyDescriptor(e, k);
11
- Object.defineProperty(n, k, d.get ? d : {
12
- enumerable: true,
13
- get: () => e[k]
14
- });
15
- }
16
- }
17
- }
18
- n.default = e;
19
- return Object.freeze(n);
20
- }
21
- const os__namespace = /* @__PURE__ */ _interopNamespaceDefault(os);
22
- function detectPlatformDefaults(ffmpegPath = "ffmpeg") {
23
- let hwaccels = [];
24
- try {
25
- const output = node_child_process.execFileSync(ffmpegPath, ["-hwaccels", "-hide_banner"], { encoding: "utf8", timeout: 5e3, stdio: ["pipe", "pipe", "pipe"] });
26
- hwaccels = output.split("\n").map((l) => l.trim()).filter((l) => l && l !== "Hardware acceleration methods:");
27
- } catch {
28
- }
29
- const platform = os__namespace.platform();
30
- if (platform === "darwin" && hwaccels.includes("videotoolbox")) return { hwaccel: "videotoolbox", threads: 0 };
31
- if (platform === "linux") {
32
- for (const hw of ["vaapi", "qsv", "cuda", "v4l2m2m"]) {
33
- if (hwaccels.includes(hw)) return { hwaccel: hw, threads: 0 };
34
- }
35
- }
36
- return { hwaccel: "none", threads: Math.max(1, Math.floor(os__namespace.cpus().length / 2)) };
37
- }
38
- function resolveFfmpegConfig(deviceConfig, globalConfig, detected) {
39
- return {
40
- path: deviceConfig?.path ?? globalConfig.path ?? detected.path ?? "ffmpeg",
41
- hwaccel: deviceConfig?.hwaccel ?? globalConfig.hwaccel ?? detected.hwaccel ?? "none",
42
- inputArgs: deviceConfig?.inputArgs ?? globalConfig.inputArgs,
43
- outputArgs: deviceConfig?.outputArgs ?? globalConfig.outputArgs,
44
- videoCodec: deviceConfig?.videoCodec ?? globalConfig.videoCodec ?? "copy",
45
- audioCodec: deviceConfig?.audioCodec ?? globalConfig.audioCodec ?? "copy",
46
- threads: deviceConfig?.threads ?? globalConfig.threads ?? detected.threads
47
- };
48
- }
49
- function buildFfmpegInputArgs(config, inputUrl) {
50
- const args = ["-hide_banner", "-loglevel", "warning"];
51
- if (config.hwaccel && config.hwaccel !== "none") args.push("-hwaccel", config.hwaccel);
52
- if (config.threads !== void 0) args.push("-threads", String(config.threads));
53
- if (config.inputArgs?.length) args.push(...config.inputArgs);
54
- args.push("-rtsp_transport", "tcp", "-i", inputUrl);
55
- return args;
56
- }
57
- function buildFfmpegOutputArgs(config) {
58
- const args = ["-c:v", config.videoCodec ?? "copy", "-c:a", config.audioCodec ?? "copy"];
59
- if (config.outputArgs?.length) args.push(...config.outputArgs);
60
- return args;
61
- }
62
- async function resolveFfmpegBinary(configPath, deps) {
63
- if (configPath && configPath !== "ffmpeg") {
64
- return configPath;
65
- }
66
- return deps.ensureFfmpeg();
67
- }
68
- exports.buildFfmpegInputArgs = buildFfmpegInputArgs;
69
- exports.buildFfmpegOutputArgs = buildFfmpegOutputArgs;
70
- exports.detectPlatformDefaults = detectPlatformDefaults;
71
- exports.resolveFfmpegBinary = resolveFfmpegBinary;
72
- exports.resolveFfmpegConfig = resolveFfmpegConfig;
73
- //# sourceMappingURL=ffmpeg-config-uANz3sV5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ffmpeg-config-uANz3sV5.js","sources":["../src/recording/recording/ffmpeg-config.ts"],"sourcesContent":["import { execFileSync } from 'node:child_process'\nimport * as os from 'node:os'\nimport type { FfmpegConfig, IAddonDepsManager } from '@camstack/types'\n\n/**\n * Probe ffmpeg binary and detect optimal hwaccel for the host platform.\n * Called once at server startup, result cached.\n */\nexport function detectPlatformDefaults(ffmpegPath: string = 'ffmpeg'): Partial<FfmpegConfig> {\n let hwaccels: string[] = []\n try {\n const output = execFileSync(ffmpegPath, ['-hwaccels', '-hide_banner'], { encoding: 'utf8', timeout: 5000, stdio: ['pipe', 'pipe', 'pipe'] })\n hwaccels = output.split('\\n').map(l => l.trim()).filter(l => l && l !== 'Hardware acceleration methods:')\n } catch {\n // ffmpeg not found or hwaccel probe failed — fall through to defaults\n }\n\n const platform = os.platform()\n if (platform === 'darwin' && hwaccels.includes('videotoolbox')) return { hwaccel: 'videotoolbox', threads: 0 }\n if (platform === 'linux') {\n for (const hw of ['vaapi', 'qsv', 'cuda', 'v4l2m2m'] as const) {\n if (hwaccels.includes(hw)) return { hwaccel: hw, threads: 0 }\n }\n }\n return { hwaccel: 'none', threads: Math.max(1, Math.floor(os.cpus().length / 2)) }\n}\n\n/**\n * Resolve ffmpeg config for a device.\n * Merge order: detected <- global <- per-device (most specific wins).\n */\nexport function resolveFfmpegConfig(\n deviceConfig: Partial<FfmpegConfig> | undefined,\n globalConfig: Partial<FfmpegConfig>,\n detected: Partial<FfmpegConfig>,\n): FfmpegConfig {\n return {\n path: deviceConfig?.path ?? globalConfig.path ?? detected.path ?? 'ffmpeg',\n hwaccel: deviceConfig?.hwaccel ?? globalConfig.hwaccel ?? detected.hwaccel ?? 'none',\n inputArgs: deviceConfig?.inputArgs ?? globalConfig.inputArgs,\n outputArgs: deviceConfig?.outputArgs ?? globalConfig.outputArgs,\n videoCodec: deviceConfig?.videoCodec ?? globalConfig.videoCodec ?? 'copy',\n audioCodec: deviceConfig?.audioCodec ?? globalConfig.audioCodec ?? 'copy',\n threads: deviceConfig?.threads ?? globalConfig.threads ?? detected.threads,\n }\n}\n\n/**\n * Build common ffmpeg args from a resolved config.\n */\nexport function buildFfmpegInputArgs(config: FfmpegConfig, inputUrl: string): string[] {\n const args: string[] = ['-hide_banner', '-loglevel', 'warning']\n if (config.hwaccel && config.hwaccel !== 'none') args.push('-hwaccel', config.hwaccel)\n if (config.threads !== undefined) args.push('-threads', String(config.threads))\n if (config.inputArgs?.length) args.push(...config.inputArgs)\n args.push('-rtsp_transport', 'tcp', '-i', inputUrl)\n return args\n}\n\nexport function buildFfmpegOutputArgs(config: FfmpegConfig): string[] {\n const args: string[] = ['-c:v', config.videoCodec ?? 'copy', '-c:a', config.audioCodec ?? 'copy']\n if (config.outputArgs?.length) args.push(...config.outputArgs)\n return args\n}\n\n/**\n * Resolve ffmpeg binary path. Priority:\n * 1. Explicit config path\n * 2. Embedded (data/deps/ffmpeg)\n * 3. System PATH\n * 4. Download static build\n */\nexport async function resolveFfmpegBinary(\n configPath: string | undefined,\n deps: IAddonDepsManager,\n): Promise<string> {\n // Explicit config\n if (configPath && configPath !== 'ffmpeg') {\n return configPath\n }\n\n // Try embedded or download via deps manager\n return deps.ensureFfmpeg()\n}\n"],"names":["execFileSync","os"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAQO,SAAS,uBAAuB,aAAqB,UAAiC;AAC3F,MAAI,WAAqB,CAAA;AACzB,MAAI;AACF,UAAM,SAASA,mBAAAA,aAAa,YAAY,CAAC,aAAa,cAAc,GAAG,EAAE,UAAU,QAAQ,SAAS,KAAM,OAAO,CAAC,QAAQ,QAAQ,MAAM,GAAG;AAC3I,eAAW,OAAO,MAAM,IAAI,EAAE,IAAI,CAAA,MAAK,EAAE,KAAA,CAAM,EAAE,OAAO,CAAA,MAAK,KAAK,MAAM,gCAAgC;AAAA,EAC1G,QAAQ;AAAA,EAER;AAEA,QAAM,WAAWC,cAAG,SAAA;AACpB,MAAI,aAAa,YAAY,SAAS,SAAS,cAAc,EAAG,QAAO,EAAE,SAAS,gBAAgB,SAAS,EAAA;AAC3G,MAAI,aAAa,SAAS;AACxB,eAAW,MAAM,CAAC,SAAS,OAAO,QAAQ,SAAS,GAAY;AAC7D,UAAI,SAAS,SAAS,EAAE,UAAU,EAAE,SAAS,IAAI,SAAS,EAAA;AAAA,IAC5D;AAAA,EACF;AACA,SAAO,EAAE,SAAS,QAAQ,SAAS,KAAK,IAAI,GAAG,KAAK,MAAMA,cAAG,KAAA,EAAO,SAAS,CAAC,CAAC,EAAA;AACjF;AAMO,SAAS,oBACd,cACA,cACA,UACc;AACd,SAAO;AAAA,IACL,MAAM,cAAc,QAAQ,aAAa,QAAQ,SAAS,QAAQ;AAAA,IAClE,SAAS,cAAc,WAAW,aAAa,WAAW,SAAS,WAAW;AAAA,IAC9E,WAAW,cAAc,aAAa,aAAa;AAAA,IACnD,YAAY,cAAc,cAAc,aAAa;AAAA,IACrD,YAAY,cAAc,cAAc,aAAa,cAAc;AAAA,IACnE,YAAY,cAAc,cAAc,aAAa,cAAc;AAAA,IACnE,SAAS,cAAc,WAAW,aAAa,WAAW,SAAS;AAAA,EAAA;AAEvE;AAKO,SAAS,qBAAqB,QAAsB,UAA4B;AACrF,QAAM,OAAiB,CAAC,gBAAgB,aAAa,SAAS;AAC9D,MAAI,OAAO,WAAW,OAAO,YAAY,OAAQ,MAAK,KAAK,YAAY,OAAO,OAAO;AACrF,MAAI,OAAO,YAAY,OAAW,MAAK,KAAK,YAAY,OAAO,OAAO,OAAO,CAAC;AAC9E,MAAI,OAAO,WAAW,aAAa,KAAK,GAAG,OAAO,SAAS;AAC3D,OAAK,KAAK,mBAAmB,OAAO,MAAM,QAAQ;AAClD,SAAO;AACT;AAEO,SAAS,sBAAsB,QAAgC;AACpE,QAAM,OAAiB,CAAC,QAAQ,OAAO,cAAc,QAAQ,QAAQ,OAAO,cAAc,MAAM;AAChG,MAAI,OAAO,YAAY,aAAa,KAAK,GAAG,OAAO,UAAU;AAC7D,SAAO;AACT;AASA,eAAsB,oBACpB,YACA,MACiB;AAEjB,MAAI,cAAc,eAAe,UAAU;AACzC,WAAO;AAAA,EACT;AAGA,SAAO,KAAK,aAAA;AACd;;;;;;"}