@trillboards/edge-sdk 0.2.3 → 0.2.6
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/README.md +4 -3
- package/deploy/docker/Dockerfile.cloud-sense +117 -0
- package/deploy/docker/Dockerfile.cpu +30 -21
- package/deploy/docker/Dockerfile.cuda +30 -21
- package/deploy/docker/Dockerfile.openvino +30 -20
- package/deploy/docker/README.md +9 -4
- package/deploy/docker/connector-entrypoint.sh +122 -0
- package/deploy/helm/README.md +1 -1
- package/deploy/k8s/daemonset.yaml +1 -1
- package/deploy/macos/README.md +161 -0
- package/deploy/macos/TrillboardsSetupApp.m +603 -0
- package/deploy/macos/build-macos-pkg.sh +588 -0
- package/deploy/macos/com.trillboards.edge.plist +62 -0
- package/deploy/macos/com.trillboards.litertlm.plist +45 -0
- package/deploy/macos/pair.command +519 -0
- package/deploy/macos/scripts/ensure-litertlm.sh +62 -0
- package/deploy/macos/scripts/postinstall +153 -0
- package/deploy/macos/scripts/setup-litertlm.sh +272 -0
- package/deploy/macos/test-install-pair.sh +383 -0
- package/deploy/macos/test-setup-litertlm-reinstall.sh +109 -0
- package/deploy/systemd/install.sh +25 -15
- package/deploy/systemd/trillboards-edge.service +4 -1
- package/deploy/windows/README.md +70 -0
- package/deploy/windows/build-windows.ps1 +225 -0
- package/deploy/windows/bundle-windows-installer.ps1 +153 -0
- package/deploy/windows/check-feeds.js +26 -0
- package/deploy/windows/e2e/fixtures/person.jpg +0 -0
- package/deploy/windows/e2e/test-local-sense.ps1 +185 -0
- package/deploy/windows/install-update.ps1 +101 -0
- package/deploy/windows/installer.nsi +138 -0
- package/deploy/windows/register-litertlm-task.ps1 +42 -0
- package/deploy/windows/register-task.ps1 +44 -0
- package/deploy/windows/run-connector.ps1 +69 -0
- package/deploy/windows/setup-litertlm.ps1 +361 -0
- package/deploy/windows/stop-existing.ps1 +72 -0
- package/deploy/windows/trillboards-edge-task.vbs +25 -0
- package/deploy/windows/trillboards-edge.cmd +33 -0
- package/deploy/windows/trillboards-pair.cmd +276 -0
- package/deploy/windows/trillboards-setup.ps1 +456 -0
- package/deploy/windows/trillboards-setup.vbs +13 -0
- package/dist/AudienceAnalyzeClient.d.ts +136 -0
- package/dist/AudienceAnalyzeClient.d.ts.map +1 -0
- package/dist/AudienceAnalyzeClient.js +246 -0
- package/dist/AudienceAnalyzeClient.js.map +1 -0
- package/dist/ChannelProber.d.ts +150 -0
- package/dist/ChannelProber.d.ts.map +1 -0
- package/dist/ChannelProber.js +887 -0
- package/dist/ChannelProber.js.map +1 -0
- package/dist/CloudEscalationPolicy.d.ts +143 -0
- package/dist/CloudEscalationPolicy.d.ts.map +1 -0
- package/dist/CloudEscalationPolicy.js +137 -0
- package/dist/CloudEscalationPolicy.js.map +1 -0
- package/dist/CloudSensingManager.d.ts +533 -0
- package/dist/CloudSensingManager.d.ts.map +1 -0
- package/dist/CloudSensingManager.js +1254 -0
- package/dist/CloudSensingManager.js.map +1 -0
- package/dist/DiscoveryReportClient.d.ts +66 -0
- package/dist/DiscoveryReportClient.d.ts.map +1 -0
- package/dist/DiscoveryReportClient.js +85 -0
- package/dist/DiscoveryReportClient.js.map +1 -0
- package/dist/EdgeAgent.d.ts +12 -2
- package/dist/EdgeAgent.d.ts.map +1 -1
- package/dist/EdgeAgent.js +122 -65
- package/dist/EdgeAgent.js.map +1 -1
- package/dist/LiteRtVlmProvider.d.ts +193 -0
- package/dist/LiteRtVlmProvider.d.ts.map +1 -0
- package/dist/LiteRtVlmProvider.js +436 -0
- package/dist/LiteRtVlmProvider.js.map +1 -0
- package/dist/MosaicSource.d.ts +108 -0
- package/dist/MosaicSource.d.ts.map +1 -0
- package/dist/MosaicSource.js +274 -0
- package/dist/MosaicSource.js.map +1 -0
- package/dist/OnvifClient.d.ts +83 -0
- package/dist/OnvifClient.d.ts.map +1 -0
- package/dist/OnvifClient.js +209 -0
- package/dist/OnvifClient.js.map +1 -0
- package/dist/PairClient.d.ts +106 -0
- package/dist/PairClient.d.ts.map +1 -0
- package/dist/PairClient.js +186 -0
- package/dist/PairClient.js.map +1 -0
- package/dist/RecorderAddressRecovery.d.ts +53 -0
- package/dist/RecorderAddressRecovery.d.ts.map +1 -0
- package/dist/RecorderAddressRecovery.js +359 -0
- package/dist/RecorderAddressRecovery.js.map +1 -0
- package/dist/SceneChangeDetector.d.ts +291 -0
- package/dist/SceneChangeDetector.d.ts.map +1 -0
- package/dist/SceneChangeDetector.js +682 -0
- package/dist/SceneChangeDetector.js.map +1 -0
- package/dist/SensingProfileClient.d.ts +59 -0
- package/dist/SensingProfileClient.d.ts.map +1 -0
- package/dist/SensingProfileClient.js +78 -0
- package/dist/SensingProfileClient.js.map +1 -0
- package/dist/SetupSessionClient.d.ts +114 -0
- package/dist/SetupSessionClient.d.ts.map +1 -0
- package/dist/SetupSessionClient.js +95 -0
- package/dist/SetupSessionClient.js.map +1 -0
- package/dist/VlmAdmissionGate.d.ts +126 -0
- package/dist/VlmAdmissionGate.d.ts.map +1 -0
- package/dist/VlmAdmissionGate.js +166 -0
- package/dist/VlmAdmissionGate.js.map +1 -0
- package/dist/autoSense.d.ts +216 -0
- package/dist/autoSense.d.ts.map +1 -0
- package/dist/autoSense.js +521 -0
- package/dist/autoSense.js.map +1 -0
- package/dist/cli.d.ts +27 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +511 -21
- package/dist/cli.js.map +1 -1
- package/dist/combinedSense.d.ts +128 -0
- package/dist/combinedSense.d.ts.map +1 -0
- package/dist/combinedSense.js +261 -0
- package/dist/combinedSense.js.map +1 -0
- package/dist/config.d.ts +351 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +99 -2
- package/dist/config.js.map +1 -1
- package/dist/connectorCadence.d.ts +135 -0
- package/dist/connectorCadence.d.ts.map +1 -0
- package/dist/connectorCadence.js +151 -0
- package/dist/connectorCadence.js.map +1 -0
- package/dist/dataDir.d.ts +33 -0
- package/dist/dataDir.d.ts.map +1 -0
- package/dist/dataDir.js +76 -0
- package/dist/dataDir.js.map +1 -0
- package/dist/deployedCadence.d.ts +167 -0
- package/dist/deployedCadence.d.ts.map +1 -0
- package/dist/deployedCadence.js +209 -0
- package/dist/deployedCadence.js.map +1 -0
- package/dist/deployedCadenceSource.d.ts +48 -0
- package/dist/deployedCadenceSource.d.ts.map +1 -0
- package/dist/deployedCadenceSource.js +74 -0
- package/dist/deployedCadenceSource.js.map +1 -0
- package/dist/diagnose.d.ts +1 -1
- package/dist/diagnose.d.ts.map +1 -1
- package/dist/diagnose.js +13 -12
- package/dist/diagnose.js.map +1 -1
- package/dist/discovery.d.ts +131 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +499 -0
- package/dist/discovery.js.map +1 -0
- package/dist/gemmaModelOta.d.ts +118 -0
- package/dist/gemmaModelOta.d.ts.map +1 -0
- package/dist/gemmaModelOta.js +291 -0
- package/dist/gemmaModelOta.js.map +1 -0
- package/dist/index.d.ts +16 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -1
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +41 -18
- package/dist/init.js.map +1 -1
- package/dist/keepAwake.d.ts +33 -0
- package/dist/keepAwake.d.ts.map +1 -0
- package/dist/keepAwake.js +54 -0
- package/dist/keepAwake.js.map +1 -0
- package/dist/legacyRecorderProfile.d.ts +20 -0
- package/dist/legacyRecorderProfile.d.ts.map +1 -0
- package/dist/legacyRecorderProfile.js +27 -0
- package/dist/legacyRecorderProfile.js.map +1 -0
- package/dist/localInferenceSchema.d.ts +132 -0
- package/dist/localInferenceSchema.d.ts.map +1 -0
- package/dist/localInferenceSchema.js +274 -0
- package/dist/localInferenceSchema.js.map +1 -0
- package/dist/localSenseE2eHarness.d.ts +101 -0
- package/dist/localSenseE2eHarness.d.ts.map +1 -0
- package/dist/localSenseE2eHarness.js +279 -0
- package/dist/localSenseE2eHarness.js.map +1 -0
- package/dist/localSensing.d.ts +268 -0
- package/dist/localSensing.d.ts.map +1 -0
- package/dist/localSensing.js +492 -0
- package/dist/localSensing.js.map +1 -0
- package/dist/modelIntegrity.d.ts +59 -0
- package/dist/modelIntegrity.d.ts.map +1 -0
- package/dist/modelIntegrity.js +165 -0
- package/dist/modelIntegrity.js.map +1 -0
- package/dist/pairVerify.d.ts +100 -0
- package/dist/pairVerify.d.ts.map +1 -0
- package/dist/pairVerify.js +296 -0
- package/dist/pairVerify.js.map +1 -0
- package/dist/qrScanner.d.ts +33 -0
- package/dist/qrScanner.d.ts.map +1 -0
- package/dist/qrScanner.js +103 -0
- package/dist/qrScanner.js.map +1 -0
- package/dist/runtimePaths.d.ts +10 -0
- package/dist/runtimePaths.d.ts.map +1 -0
- package/dist/runtimePaths.js +79 -0
- package/dist/runtimePaths.js.map +1 -0
- package/dist/sensingRunMode.d.ts +68 -0
- package/dist/sensingRunMode.d.ts.map +1 -0
- package/dist/sensingRunMode.js +346 -0
- package/dist/sensingRunMode.js.map +1 -0
- package/dist/setupMode.d.ts +98 -0
- package/dist/setupMode.d.ts.map +1 -0
- package/dist/setupMode.js +828 -0
- package/dist/setupMode.js.map +1 -0
- package/dist/setupProgress.d.ts +31 -0
- package/dist/setupProgress.d.ts.map +1 -0
- package/dist/setupProgress.js +173 -0
- package/dist/setupProgress.js.map +1 -0
- package/package.json +13 -4
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.defaultHttpPoster = exports.AudienceAnalyzeClient = void 0;
|
|
37
|
+
const http = __importStar(require("http"));
|
|
38
|
+
const https = __importStar(require("https"));
|
|
39
|
+
const url_1 = require("url");
|
|
40
|
+
const crypto_1 = require("crypto");
|
|
41
|
+
class AudienceAnalyzeClient {
|
|
42
|
+
constructor(options, poster) {
|
|
43
|
+
if (!options.apiBaseUrl) {
|
|
44
|
+
throw new Error('apiBaseUrl is required for AudienceAnalyzeClient');
|
|
45
|
+
}
|
|
46
|
+
if (!options.deviceToken) {
|
|
47
|
+
throw new Error('deviceToken is required for AudienceAnalyzeClient');
|
|
48
|
+
}
|
|
49
|
+
const base = options.apiBaseUrl.replace(/\/+$/, '');
|
|
50
|
+
this.endpoint = `${base}/v2/earner/audience-analyze`;
|
|
51
|
+
this.deviceToken = options.deviceToken;
|
|
52
|
+
this.screenId = options.screenId;
|
|
53
|
+
this.fingerprint = options.fingerprint;
|
|
54
|
+
this.timeoutMs = options.timeoutMs ?? 30000;
|
|
55
|
+
this.imageWidth = options.imageWidth;
|
|
56
|
+
this.imageHeight = options.imageHeight;
|
|
57
|
+
this.poster = poster ?? exports.defaultHttpPoster;
|
|
58
|
+
}
|
|
59
|
+
/** The resolved POST URL (exposed for assertions / logging). */
|
|
60
|
+
getEndpoint() {
|
|
61
|
+
return this.endpoint;
|
|
62
|
+
}
|
|
63
|
+
authHeaders() {
|
|
64
|
+
return {
|
|
65
|
+
'Content-Type': 'application/json',
|
|
66
|
+
Accept: 'application/json',
|
|
67
|
+
// Device-request auth + replay guard (see middleware/deviceRequestAuth.js).
|
|
68
|
+
'X-Device-Token': this.deviceToken,
|
|
69
|
+
'X-Trillboard-Device-Token': this.deviceToken,
|
|
70
|
+
'X-Device-Timestamp': String(Date.now()),
|
|
71
|
+
'X-Device-Nonce': (0, crypto_1.randomUUID)(),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* POST a JPEG frame for cloud audience analysis. Returns the parsed response.
|
|
76
|
+
*/
|
|
77
|
+
async analyze(request) {
|
|
78
|
+
if (!request?.jpeg || request.jpeg.length === 0) {
|
|
79
|
+
throw new Error('analyze() requires a non-empty jpeg buffer');
|
|
80
|
+
}
|
|
81
|
+
const capturedAt = request.capturedAt ?? Date.now();
|
|
82
|
+
const imageBase64 = request.jpeg.toString('base64');
|
|
83
|
+
const payload = {
|
|
84
|
+
imageBase64,
|
|
85
|
+
capturedAt,
|
|
86
|
+
...(this.screenId ? { screenId: this.screenId } : {}),
|
|
87
|
+
...(this.fingerprint ? { fingerprint: this.fingerprint } : {}),
|
|
88
|
+
...(this.imageWidth ? { imageWidth: this.imageWidth } : {}),
|
|
89
|
+
...(this.imageHeight ? { imageHeight: this.imageHeight } : {}),
|
|
90
|
+
...(request.captureMode ? { captureMode: request.captureMode } : {}),
|
|
91
|
+
...(request.extra || {}),
|
|
92
|
+
};
|
|
93
|
+
const body = JSON.stringify(payload);
|
|
94
|
+
const result = await this.poster(this.endpoint, { method: 'POST', headers: this.authHeaders(), timeoutMs: this.timeoutMs }, body);
|
|
95
|
+
let parsed = null;
|
|
96
|
+
try {
|
|
97
|
+
parsed = result.body ? JSON.parse(result.body) : null;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
parsed = null;
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
statusCode: result.statusCode,
|
|
104
|
+
ok: result.statusCode >= 200 && result.statusCode < 300,
|
|
105
|
+
body: parsed,
|
|
106
|
+
rawBody: result.body,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* POST a PRE-ANALYZED structured result (computed ON-DEVICE by
|
|
111
|
+
* LiteRtVlmProvider) to the same audience-analyze endpoint. The server detects
|
|
112
|
+
* `preAnalyzed`, SKIPS the cloud VLM, and ingests the result directly —
|
|
113
|
+
* forcing provenance `local_connector` server-side so it drives the
|
|
114
|
+
* operator's Sense-Anything routes but is gated out of the sold bidstream.
|
|
115
|
+
* Same device-token auth + replay guard as analyze().
|
|
116
|
+
*
|
|
117
|
+
* EVIDENCE FRAME (optional): when `jpeg` (raw bytes) or `imageBase64` (already
|
|
118
|
+
* base64) is supplied, the SAME JPEG the on-device VLM analyzed is included as
|
|
119
|
+
* `imageBase64` ALONGSIDE `preAnalyzed`. The server uploads it and attaches it
|
|
120
|
+
* to any alert the result fires. The caller decides WHETHER to attach it — the
|
|
121
|
+
* connector only sends a frame for alert-worthy observations (see
|
|
122
|
+
* localSensing.ts), so this method just forwards what it's given. When neither
|
|
123
|
+
* is passed, NO `imageBase64` is sent (results-only, privacy-preserving
|
|
124
|
+
* default for empty/uninteresting scenes).
|
|
125
|
+
*/
|
|
126
|
+
async analyzePreAnalyzed(preAnalyzed, request = {}) {
|
|
127
|
+
if (!preAnalyzed || typeof preAnalyzed !== 'object') {
|
|
128
|
+
throw new Error('analyzePreAnalyzed() requires a structured result object');
|
|
129
|
+
}
|
|
130
|
+
const capturedAt = request.capturedAt ?? Date.now();
|
|
131
|
+
// Attach the evidence frame ONLY when one was supplied (an alert-worthy
|
|
132
|
+
// frame). Prefer raw bytes (encode here, mirroring analyze()); accept a
|
|
133
|
+
// pre-encoded string too. An empty buffer / empty string is treated as "no
|
|
134
|
+
// frame" so we never send a blank imageBase64.
|
|
135
|
+
let imageBase64;
|
|
136
|
+
if (request.jpeg && request.jpeg.length > 0) {
|
|
137
|
+
imageBase64 = request.jpeg.toString('base64');
|
|
138
|
+
}
|
|
139
|
+
else if (typeof request.imageBase64 === 'string' && request.imageBase64.length > 0) {
|
|
140
|
+
imageBase64 = request.imageBase64;
|
|
141
|
+
}
|
|
142
|
+
const payload = {
|
|
143
|
+
preAnalyzed,
|
|
144
|
+
capturedAt,
|
|
145
|
+
...(imageBase64 ? { imageBase64 } : {}),
|
|
146
|
+
...(this.screenId ? { screenId: this.screenId } : {}),
|
|
147
|
+
...(this.fingerprint ? { fingerprint: this.fingerprint } : {}),
|
|
148
|
+
...(request.captureMode ? { captureMode: request.captureMode } : {}),
|
|
149
|
+
...(request.extra || {}),
|
|
150
|
+
};
|
|
151
|
+
const result = await this.poster(this.endpoint, { method: 'POST', headers: this.authHeaders(), timeoutMs: this.timeoutMs }, JSON.stringify(payload));
|
|
152
|
+
let parsed = null;
|
|
153
|
+
try {
|
|
154
|
+
parsed = result.body ? JSON.parse(result.body) : null;
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
parsed = null;
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
statusCode: result.statusCode,
|
|
161
|
+
ok: result.statusCode >= 200 && result.statusCode < 300,
|
|
162
|
+
body: parsed,
|
|
163
|
+
rawBody: result.body,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* POST a FRAMELESS camera-health beacon. This is used when the connector can
|
|
168
|
+
* pair but cannot open the RTSP stream, so the portal can show "Camera login
|
|
169
|
+
* failed" / "not reachable" instead of looking like the connector is absent.
|
|
170
|
+
*/
|
|
171
|
+
async reportCameraHealth(cameraHealth) {
|
|
172
|
+
if (!cameraHealth || typeof cameraHealth !== 'object') {
|
|
173
|
+
throw new Error('reportCameraHealth() requires a cameraHealth object');
|
|
174
|
+
}
|
|
175
|
+
const payload = {
|
|
176
|
+
cameraHealth,
|
|
177
|
+
...(this.screenId ? { screenId: this.screenId } : {}),
|
|
178
|
+
...(this.fingerprint ? { fingerprint: this.fingerprint } : {}),
|
|
179
|
+
};
|
|
180
|
+
const result = await this.poster(this.endpoint, {
|
|
181
|
+
method: 'POST',
|
|
182
|
+
headers: this.authHeaders(),
|
|
183
|
+
timeoutMs: this.timeoutMs,
|
|
184
|
+
}, JSON.stringify(payload));
|
|
185
|
+
return parseAnalyzeResponse(result);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
exports.AudienceAnalyzeClient = AudienceAnalyzeClient;
|
|
189
|
+
function parseAnalyzeResponse(result) {
|
|
190
|
+
let parsed = null;
|
|
191
|
+
try {
|
|
192
|
+
parsed = result.body ? JSON.parse(result.body) : null;
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
parsed = null;
|
|
196
|
+
}
|
|
197
|
+
return {
|
|
198
|
+
statusCode: result.statusCode,
|
|
199
|
+
ok: result.statusCode >= 200 && result.statusCode < 300,
|
|
200
|
+
body: parsed,
|
|
201
|
+
rawBody: result.body,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Default transport using Node's built-in http/https. No third-party deps so it
|
|
206
|
+
* survives bundling into a single self-contained binary.
|
|
207
|
+
*/
|
|
208
|
+
const defaultHttpPoster = (url, options, body) => {
|
|
209
|
+
return new Promise((resolve, reject) => {
|
|
210
|
+
let parsed;
|
|
211
|
+
try {
|
|
212
|
+
parsed = new url_1.URL(url);
|
|
213
|
+
}
|
|
214
|
+
catch (err) {
|
|
215
|
+
reject(new Error(`Invalid audience-analyze URL: ${err.message}`));
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
const mod = parsed.protocol === 'https:' ? https : http;
|
|
219
|
+
const bodyBuffer = Buffer.from(body, 'utf-8');
|
|
220
|
+
const req = mod.request(url, {
|
|
221
|
+
method: options.method,
|
|
222
|
+
headers: {
|
|
223
|
+
...options.headers,
|
|
224
|
+
'Content-Length': String(bodyBuffer.length),
|
|
225
|
+
},
|
|
226
|
+
timeout: options.timeoutMs,
|
|
227
|
+
}, (res) => {
|
|
228
|
+
const chunks = [];
|
|
229
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
230
|
+
res.on('end', () => {
|
|
231
|
+
resolve({
|
|
232
|
+
statusCode: res.statusCode || 0,
|
|
233
|
+
body: Buffer.concat(chunks).toString('utf-8'),
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
req.on('error', (err) => reject(err));
|
|
238
|
+
req.on('timeout', () => {
|
|
239
|
+
req.destroy(new Error('audience-analyze request timed out'));
|
|
240
|
+
});
|
|
241
|
+
req.write(bodyBuffer);
|
|
242
|
+
req.end();
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
exports.defaultHttpPoster = defaultHttpPoster;
|
|
246
|
+
//# sourceMappingURL=AudienceAnalyzeClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudienceAnalyzeClient.js","sourceRoot":"","sources":["../src/AudienceAnalyzeClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import type { HttpPoster } from './AudienceAnalyzeClient';
|
|
3
|
+
/**
|
|
4
|
+
* ChannelProber — validate a recorder's channels BEFORE any screen exists.
|
|
5
|
+
* The engine behind the setup-session `probe` command, built NVR-SAFE per the
|
|
6
|
+
* adversarial review of the onboarding redesign:
|
|
7
|
+
*
|
|
8
|
+
* AUTH CIRCUIT-BREAKER: ONVIF and RTSP can use different auth realms. An
|
|
9
|
+
* ONVIF rejection therefore falls back to exactly ONE bounded RTSP proof;
|
|
10
|
+
* an RTSP 401 then stops the host. This avoids false "wrong password" errors
|
|
11
|
+
* without fanning bad credentials across channels (≤2 auth touches/host).
|
|
12
|
+
*
|
|
13
|
+
* SESSION-SLOT SAFETY: consumer NVRs cap concurrent RTSP pulls (main stream
|
|
14
|
+
* often 1-2) and a 16-way fan-out can evict the recorder's own live view.
|
|
15
|
+
* Per-host concurrency is capped (default 1) and SUBSTREAM is tried first.
|
|
16
|
+
*
|
|
17
|
+
* REAL ENUMERATION: with ONVIF creds accepted, channels come from
|
|
18
|
+
* GetProfiles + GetStreamUri (actual URIs — no path guessing, the Hiten
|
|
19
|
+
* /Streaming/Channels/101 assumption bug). Without ONVIF, a widened
|
|
20
|
+
* brand-candidate library covers the US SMB installed base, walking
|
|
21
|
+
* channels until MAX_CONSECUTIVE_DEAD in a row (no hand-typed counts).
|
|
22
|
+
*
|
|
23
|
+
* STABLE IDENTITY: channelKey = `onvif:<serial>:<sourceToken>` when the
|
|
24
|
+
* device exposes a serial (survives DHCP), else `nvr:<sha1(host:port:ch)>`
|
|
25
|
+
* — this becomes the server-side cameraKey, making re-onboarding reuse the
|
|
26
|
+
* same screens (the junk-camera fix). Names are NEVER part of the key.
|
|
27
|
+
*
|
|
28
|
+
* Every validated channel returns a small JPEG thumbnail (the wizard's "you
|
|
29
|
+
* can SEE it works" moment); every failure carries a failureClass the portal
|
|
30
|
+
* maps to a concrete action — including `rtsp_forbidden` (ONVIF creds OK but
|
|
31
|
+
* RTSP denied: the account lacks live-view permission; re-typing the password
|
|
32
|
+
* forever, which is what the generic copy caused, can never fix it).
|
|
33
|
+
*/
|
|
34
|
+
export type ProbeStatus = 'validated' | 'failed' | 'empty';
|
|
35
|
+
export type ProbeFailureClass = 'rtsp_auth' | 'rtsp_forbidden' | 'rtsp_unreachable' | 'rtsp_timeout' | 'bad_path' | 'nvr_busy' | 'no_frames' | 'decode_error' | 'empty_channel';
|
|
36
|
+
type RtspTransport = 'tcp' | 'udp';
|
|
37
|
+
export interface ChannelProbeResult {
|
|
38
|
+
channelKey: string;
|
|
39
|
+
status: ProbeStatus;
|
|
40
|
+
failureClass?: ProbeFailureClass;
|
|
41
|
+
message?: string;
|
|
42
|
+
name?: string;
|
|
43
|
+
brand?: string;
|
|
44
|
+
sourceType?: 'recorder' | 'direct_url';
|
|
45
|
+
host: string;
|
|
46
|
+
port: number;
|
|
47
|
+
channel?: number;
|
|
48
|
+
serial?: string;
|
|
49
|
+
profileToken?: string;
|
|
50
|
+
/** RTSP path WITHOUT credentials/host — the server stores only this. */
|
|
51
|
+
pathTemplate?: string;
|
|
52
|
+
transport?: 'tcp' | 'udp';
|
|
53
|
+
thumbnailBase64?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ProbeTarget {
|
|
56
|
+
host: string;
|
|
57
|
+
port?: number;
|
|
58
|
+
onvifPort?: number;
|
|
59
|
+
username: string;
|
|
60
|
+
password: string;
|
|
61
|
+
brandHint?: string;
|
|
62
|
+
channelHint?: number;
|
|
63
|
+
}
|
|
64
|
+
export interface ProbeOptions {
|
|
65
|
+
ffmpegPath?: string;
|
|
66
|
+
/** Per-host concurrent RTSP grabs. Default 1 (legacy recorder session-slot safety). */
|
|
67
|
+
concurrency?: number;
|
|
68
|
+
/** Per-grab budget. Default 6s connect+frame. */
|
|
69
|
+
grabTimeoutMs?: number;
|
|
70
|
+
/** Hard budget for the whole host probe. Default 90s (first-pass SLO). */
|
|
71
|
+
totalBudgetMs?: number;
|
|
72
|
+
/** Stop walking brand-candidate channels after N consecutive dead. Default 4. */
|
|
73
|
+
maxConsecutiveDead?: number;
|
|
74
|
+
/** Max channels to walk without ONVIF enumeration. Default 32. */
|
|
75
|
+
maxChannels?: number;
|
|
76
|
+
poster?: HttpPoster;
|
|
77
|
+
spawner?: typeof spawn;
|
|
78
|
+
onResult?: (r: ChannelProbeResult) => void | Promise<void>;
|
|
79
|
+
}
|
|
80
|
+
/** Stable, name-free channel identity → the server-side cameraKey. */
|
|
81
|
+
export declare function channelKeyFor(parts: {
|
|
82
|
+
serial?: string | null;
|
|
83
|
+
sourceToken?: string | null;
|
|
84
|
+
profileToken?: string | null;
|
|
85
|
+
host: string;
|
|
86
|
+
port: number;
|
|
87
|
+
channel?: number;
|
|
88
|
+
}): string;
|
|
89
|
+
/**
|
|
90
|
+
* Brand RTSP path candidates, SUBSTREAM FIRST (cheaper session slot; good
|
|
91
|
+
* enough for validation), widened to the US SMB installed base per the
|
|
92
|
+
* product review (Hikvision/Dahua/Reolink alone missed Lorex/Swann/XMeye-class
|
|
93
|
+
* recorders — exactly what gas stations bought retail).
|
|
94
|
+
*/
|
|
95
|
+
export declare function normalizeRecorderBrandHint(brand: string | undefined): string | undefined;
|
|
96
|
+
export declare function brandPathCandidates(brand: string | undefined, ch: number, credentials?: {
|
|
97
|
+
username: string;
|
|
98
|
+
password: string;
|
|
99
|
+
}): string[];
|
|
100
|
+
/** Remove XM query credentials before a probe result leaves the connector. */
|
|
101
|
+
export declare function credentialFreePathTemplate(pathValue: string, brand: string | undefined): string;
|
|
102
|
+
/** Restore a credential-free path recipe while writing the local-only config. */
|
|
103
|
+
export declare function materializeCredentialPathTemplate(pathTemplate: string, username: string, password: string): string;
|
|
104
|
+
/** Percent-encode credentials into an rtsp:// URL (the Hiten `pass@123` class). */
|
|
105
|
+
export declare function buildRtspUrl(host: string, port: number, path: string, username: string, password: string): string;
|
|
106
|
+
/** Inject creds into an ONVIF-returned rtsp URI (they usually come credless). */
|
|
107
|
+
export declare function injectCreds(uri: string, username: string, password: string): string;
|
|
108
|
+
/** Strip credentials+host → the storable path template. */
|
|
109
|
+
export declare function pathTemplateOf(uri: string): string;
|
|
110
|
+
export declare function directStreamChannelKey(streamUrl: string): string;
|
|
111
|
+
export declare function sanitizeRtspUrlForLog(text: string): string;
|
|
112
|
+
export interface FrameGrab {
|
|
113
|
+
ok: boolean;
|
|
114
|
+
failureClass?: ProbeFailureClass;
|
|
115
|
+
message?: string;
|
|
116
|
+
jpegBase64?: string;
|
|
117
|
+
}
|
|
118
|
+
export interface TransportFrameGrab extends FrameGrab {
|
|
119
|
+
transport?: RtspTransport;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Grab ONE frame (downscaled JPEG) from an RTSP URL via the bundled ffmpeg.
|
|
123
|
+
* `-timeout` (µs) is the rtsp demuxer's socket timeout — NOT `-rw_timeout`
|
|
124
|
+
* (the #7946 regression). Classification reads ffmpeg's stderr.
|
|
125
|
+
*/
|
|
126
|
+
export declare function grabOneFrame(rtspUrl: string, { ffmpegPath, timeoutMs, spawner, transport, }?: {
|
|
127
|
+
ffmpegPath?: string;
|
|
128
|
+
timeoutMs?: number;
|
|
129
|
+
spawner?: typeof spawn;
|
|
130
|
+
transport?: RtspTransport;
|
|
131
|
+
}): Promise<FrameGrab>;
|
|
132
|
+
export declare function grabOneFrameAnyTransport(rtspUrl: string, opts: {
|
|
133
|
+
ffmpegPath?: string;
|
|
134
|
+
timeoutMs?: number;
|
|
135
|
+
spawner?: typeof spawn;
|
|
136
|
+
}): Promise<TransportFrameGrab>;
|
|
137
|
+
/** Map ffmpeg's stderr to a failure class the portal can act on. */
|
|
138
|
+
export declare function classifyFfmpegStderr(stderr: string): {
|
|
139
|
+
failureClass: ProbeFailureClass;
|
|
140
|
+
message: string;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Probe one recorder. Streams results via opts.onResult as channels settle and
|
|
144
|
+
* returns the full list. NEVER throws for per-channel problems — only for
|
|
145
|
+
* programmer errors; credential rejection yields a single `rtsp_auth` result
|
|
146
|
+
* for the host (the circuit-breaker contract).
|
|
147
|
+
*/
|
|
148
|
+
export declare function probeHost(target: ProbeTarget, opts?: ProbeOptions): Promise<ChannelProbeResult[]>;
|
|
149
|
+
export {};
|
|
150
|
+
//# sourceMappingURL=ChannelProber.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChannelProber.d.ts","sourceRoot":"","sources":["../src/ChannelProber.ts"],"names":[],"mappings":"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"}
|