@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.
- package/dist/embedding-encoder/index.js +1 -1
- package/dist/embedding-encoder/index.mjs +1 -1
- package/dist/enrichment-engine/index.js +1 -1
- package/dist/enrichment-engine/index.mjs +1 -1
- package/dist/{index-DafwGlkQ.js → index-B0RhVv1c.js} +3940 -807
- package/dist/index-B0RhVv1c.js.map +1 -0
- package/dist/{index-CIJfmsWX.mjs → index-ot5PeFg_.mjs} +3943 -810
- package/dist/index-ot5PeFg_.mjs.map +1 -0
- package/dist/pipeline-analytics/@mf-types.zip +0 -0
- 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
- package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-BD3oMNGB.mjs +29 -0
- 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
- 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
- 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
- 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
- package/dist/pipeline-analytics/_stub.js +2 -3
- 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
- package/dist/pipeline-analytics/{client-DHmQcIWy.mjs → client-C6xdgLZU.mjs} +2 -2
- package/dist/pipeline-analytics/{hostInit-CuWzic_f.mjs → hostInit-3cyL9eyG.mjs} +12 -12
- package/dist/pipeline-analytics/{index-BA65ZJOW.mjs → index-BCTHeI2m.mjs} +254 -268
- package/dist/pipeline-analytics/{index-Crs1D0Uu.mjs → index-BuWLz0GG.mjs} +1 -1
- package/dist/pipeline-analytics/{index-gpelkpEE.mjs → index-CIwq-tQL.mjs} +1 -1
- package/dist/pipeline-analytics/{index-CHnXxMRA.mjs → index-CWBMDbou.mjs} +1 -1
- package/dist/pipeline-analytics/index-CZhagnlH.mjs +67784 -0
- package/dist/pipeline-analytics/{index-DicaGC31.mjs → index-D883Q5B8.mjs} +1 -1
- package/dist/pipeline-analytics/index-DtOI1aTU.mjs +18504 -0
- package/dist/pipeline-analytics/index.js +605 -42
- package/dist/pipeline-analytics/index.js.map +1 -1
- package/dist/pipeline-analytics/index.mjs +604 -42
- package/dist/pipeline-analytics/index.mjs.map +1 -1
- package/dist/pipeline-analytics/{jsx-runtime-Wcfyyyt4.mjs → jsx-runtime-DdLhuHmJ.mjs} +1 -1
- package/dist/pipeline-analytics/remoteEntry.js +1 -1
- package/dist/pipeline-analytics/{schemas-ChN4Ih0h.mjs → schemas-B7L0qZtq.mjs} +530 -515
- package/package.json +12 -27
- package/dist/ffmpeg-config-DRONlBsj.mjs +0 -56
- package/dist/ffmpeg-config-DRONlBsj.mjs.map +0 -1
- package/dist/ffmpeg-config-uANz3sV5.js +0 -73
- package/dist/ffmpeg-config-uANz3sV5.js.map +0 -1
- package/dist/index-CIJfmsWX.mjs.map +0 -1
- package/dist/index-DafwGlkQ.js.map +0 -1
- package/dist/pipeline-analytics/__mfe_internal__addon_pipeline_analytics_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.mjs-d8PmLbO2.mjs +0 -19
- 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
- package/dist/pipeline-analytics/index-CUXiTSWS.mjs +0 -13883
- package/dist/pipeline-analytics/index-gbflFMEY.mjs +0 -36403
- package/dist/playlist-generator-EhPaB7Hn.js +0 -48
- package/dist/playlist-generator-EhPaB7Hn.js.map +0 -1
- package/dist/playlist-generator-VTkgn53O.mjs +0 -48
- package/dist/playlist-generator-VTkgn53O.mjs.map +0 -1
- package/dist/recording/index.js +0 -257
- package/dist/recording/index.js.map +0 -1
- package/dist/recording/index.mjs +0 -235
- package/dist/recording/index.mjs.map +0 -1
- package/dist/recording-coordinator-BKsM_JGg.js +0 -1052
- package/dist/recording-coordinator-BKsM_JGg.js.map +0 -1
- package/dist/recording-coordinator-Bw3N1gYu.mjs +0 -1012
- package/dist/recording-coordinator-Bw3N1gYu.mjs.map +0 -1
- package/dist/recording-db-gOgaoQh0.js +0 -348
- package/dist/recording-db-gOgaoQh0.js.map +0 -1
- package/dist/recording-db-lIkSMTLq.mjs +0 -348
- package/dist/recording-db-lIkSMTLq.mjs.map +0 -1
- package/dist/recording-service-facade-B9lG6OFn.mjs +0 -123
- package/dist/recording-service-facade-B9lG6OFn.mjs.map +0 -1
- package/dist/recording-service-facade-Do1PKlAL.js +0 -123
- package/dist/recording-service-facade-Do1PKlAL.js.map +0 -1
- package/dist/storage-estimator-CRpoQc9j.js +0 -72
- package/dist/storage-estimator-CRpoQc9j.js.map +0 -1
- package/dist/storage-estimator-DzD8gWJH.mjs +0 -72
- 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.
|
|
4
|
-
"description": "CamStack Post-Analysis bundle —
|
|
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/
|
|
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": "
|
|
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;;;;;;"}
|