@apocaliss92/nodelink-js 0.3.9 → 0.4.1
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/{DiagnosticsTools-DQDDBRM6.js → DiagnosticsTools-XIIYZDXL.js} +6 -2
- package/dist/{chunk-6Q6MK4WG.js → chunk-DUHWTZ7U.js} +286 -25
- package/dist/chunk-DUHWTZ7U.js.map +1 -0
- package/dist/{chunk-OGIKBDON.js → chunk-SDRNJQ5U.js} +5 -5
- package/dist/chunk-SDRNJQ5U.js.map +1 -0
- package/dist/cli/rtsp-server.cjs +287 -26
- package/dist/cli/rtsp-server.cjs.map +1 -1
- package/dist/cli/rtsp-server.js +2 -2
- package/dist/index.cjs +291 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -1
- package/dist/index.d.ts +27 -0
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-6Q6MK4WG.js.map +0 -1
- package/dist/chunk-OGIKBDON.js.map +0 -1
- /package/dist/{DiagnosticsTools-DQDDBRM6.js.map → DiagnosticsTools-XIIYZDXL.js.map} +0 -0
|
@@ -4,24 +4,28 @@ import {
|
|
|
4
4
|
collectMultifocalDiagnostics,
|
|
5
5
|
collectNativeDiagnostics,
|
|
6
6
|
collectNvrDiagnostics,
|
|
7
|
+
computeExpectedStreamCompatibility,
|
|
7
8
|
createDiagnosticsBundle,
|
|
8
9
|
printNvrDiagnostics,
|
|
9
10
|
runAllDiagnosticsConsecutively,
|
|
10
11
|
runMultifocalDiagnosticsConsecutively,
|
|
11
12
|
sampleStreams,
|
|
13
|
+
sanitizeFixtureData,
|
|
12
14
|
testChannelStreams
|
|
13
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-DUHWTZ7U.js";
|
|
14
16
|
export {
|
|
15
17
|
captureModelFixtures,
|
|
16
18
|
collectCgiDiagnostics,
|
|
17
19
|
collectMultifocalDiagnostics,
|
|
18
20
|
collectNativeDiagnostics,
|
|
19
21
|
collectNvrDiagnostics,
|
|
22
|
+
computeExpectedStreamCompatibility,
|
|
20
23
|
createDiagnosticsBundle,
|
|
21
24
|
printNvrDiagnostics,
|
|
22
25
|
runAllDiagnosticsConsecutively,
|
|
23
26
|
runMultifocalDiagnosticsConsecutively,
|
|
24
27
|
sampleStreams,
|
|
28
|
+
sanitizeFixtureData,
|
|
25
29
|
testChannelStreams
|
|
26
30
|
};
|
|
27
|
-
//# sourceMappingURL=DiagnosticsTools-
|
|
31
|
+
//# sourceMappingURL=DiagnosticsTools-XIIYZDXL.js.map
|
|
@@ -7170,10 +7170,123 @@ async function runAllDiagnosticsConsecutively(params) {
|
|
|
7170
7170
|
streamsDir
|
|
7171
7171
|
};
|
|
7172
7172
|
}
|
|
7173
|
+
var REDACT_KEYS = /* @__PURE__ */ new Set([
|
|
7174
|
+
"password",
|
|
7175
|
+
"pass",
|
|
7176
|
+
"token",
|
|
7177
|
+
"secret",
|
|
7178
|
+
"apiKey",
|
|
7179
|
+
"api_key"
|
|
7180
|
+
]);
|
|
7181
|
+
var MASK_KEYS = /* @__PURE__ */ new Set([
|
|
7182
|
+
"serialNumber",
|
|
7183
|
+
"serial",
|
|
7184
|
+
"uid",
|
|
7185
|
+
"mac",
|
|
7186
|
+
"ssid",
|
|
7187
|
+
"wifiPassword",
|
|
7188
|
+
"userName",
|
|
7189
|
+
"username",
|
|
7190
|
+
"user"
|
|
7191
|
+
]);
|
|
7192
|
+
var IPV4_RE = /\b(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\b/g;
|
|
7193
|
+
var MAC_RE = /\b([0-9a-fA-F]{2}[:-]){5}[0-9a-fA-F]{2}\b/g;
|
|
7194
|
+
function maskIp(ip) {
|
|
7195
|
+
const parts = ip.split(".");
|
|
7196
|
+
return `${parts[0]}.***.***.***`;
|
|
7197
|
+
}
|
|
7198
|
+
function maskMac(mac) {
|
|
7199
|
+
const sep = mac.includes("-") ? "-" : ":";
|
|
7200
|
+
const parts = mac.split(/[:-]/);
|
|
7201
|
+
return `${parts[0]}${sep}${parts[1]}${sep}**${sep}**${sep}**${sep}**`;
|
|
7202
|
+
}
|
|
7203
|
+
function maskSerial(val) {
|
|
7204
|
+
if (val.length <= 4) return "****";
|
|
7205
|
+
return val.slice(0, 2) + "*".repeat(val.length - 4) + val.slice(-2);
|
|
7206
|
+
}
|
|
7207
|
+
function sanitizeString(s) {
|
|
7208
|
+
let out = s;
|
|
7209
|
+
out = out.replace(/:\/\/([^:@]+):([^@]+)@/g, "://***:***@");
|
|
7210
|
+
out = out.replace(/(password=)[^&\s]*/gi, "$1***");
|
|
7211
|
+
out = out.replace(/(user=)[^&\s]*/gi, "$1***");
|
|
7212
|
+
out = out.replace(IPV4_RE, (match) => maskIp(match));
|
|
7213
|
+
out = out.replace(MAC_RE, (match) => maskMac(match));
|
|
7214
|
+
return out;
|
|
7215
|
+
}
|
|
7216
|
+
function sanitizeFixtureData(value) {
|
|
7217
|
+
if (value === null || value === void 0) return value;
|
|
7218
|
+
if (typeof value === "string") {
|
|
7219
|
+
return sanitizeString(value);
|
|
7220
|
+
}
|
|
7221
|
+
if (Array.isArray(value)) {
|
|
7222
|
+
return value.map(sanitizeFixtureData);
|
|
7223
|
+
}
|
|
7224
|
+
if (typeof value === "object") {
|
|
7225
|
+
const out = {};
|
|
7226
|
+
for (const [k, v] of Object.entries(value)) {
|
|
7227
|
+
const kLower = k.toLowerCase();
|
|
7228
|
+
if (REDACT_KEYS.has(kLower)) {
|
|
7229
|
+
out[k] = "***";
|
|
7230
|
+
} else if (MASK_KEYS.has(kLower) || kLower === "serialnumber") {
|
|
7231
|
+
out[k] = typeof v === "string" ? maskSerial(v) : "***";
|
|
7232
|
+
} else if (kLower === "mac") {
|
|
7233
|
+
out[k] = typeof v === "string" ? maskMac(v) : "***";
|
|
7234
|
+
} else if (kLower === "ip" || kLower === "ipaddress" || kLower === "host") {
|
|
7235
|
+
out[k] = typeof v === "string" ? maskIp(v) : v;
|
|
7236
|
+
} else if (kLower === "name" && typeof v === "string" && k !== "name") {
|
|
7237
|
+
out[k] = v;
|
|
7238
|
+
} else {
|
|
7239
|
+
out[k] = sanitizeFixtureData(v);
|
|
7240
|
+
}
|
|
7241
|
+
}
|
|
7242
|
+
return out;
|
|
7243
|
+
}
|
|
7244
|
+
return value;
|
|
7245
|
+
}
|
|
7246
|
+
function computeExpectedStreamCompatibility(params) {
|
|
7247
|
+
const { channelCount } = params;
|
|
7248
|
+
const profiles = params.profiles ?? ["main", "sub", "ext"];
|
|
7249
|
+
const expectedStreamType = { main: 0, sub: 1, ext: 0 };
|
|
7250
|
+
const allStreams = [];
|
|
7251
|
+
for (let ch = 0; ch < channelCount; ch++) {
|
|
7252
|
+
for (const p of profiles) {
|
|
7253
|
+
allStreams.push({ ch, profile: p, label: channelCount > 1 ? `ch${ch}_${p}` : p });
|
|
7254
|
+
}
|
|
7255
|
+
}
|
|
7256
|
+
const results = [];
|
|
7257
|
+
for (let i = 0; i < allStreams.length; i++) {
|
|
7258
|
+
for (let j = i + 1; j < allStreams.length; j++) {
|
|
7259
|
+
const a = allStreams[i];
|
|
7260
|
+
const b = allStreams[j];
|
|
7261
|
+
const stA = expectedStreamType[a.profile] ?? 0;
|
|
7262
|
+
const stB = expectedStreamType[b.profile] ?? 0;
|
|
7263
|
+
const sameChannel = a.ch === b.ch;
|
|
7264
|
+
let expectedOk;
|
|
7265
|
+
let reason;
|
|
7266
|
+
if (sameChannel && stA === stB) {
|
|
7267
|
+
expectedOk = false;
|
|
7268
|
+
reason = `same streamType (${stA}) on same channel`;
|
|
7269
|
+
} else if (!sameChannel && a.profile === b.profile) {
|
|
7270
|
+
expectedOk = false;
|
|
7271
|
+
reason = `multifocal rejects same profile (${a.profile}) across channels`;
|
|
7272
|
+
} else if (!sameChannel && stA === stB) {
|
|
7273
|
+
expectedOk = false;
|
|
7274
|
+
reason = `same streamType (${stA}) across channels`;
|
|
7275
|
+
} else {
|
|
7276
|
+
expectedOk = true;
|
|
7277
|
+
reason = `different streamTypes (${stA} vs ${stB})`;
|
|
7278
|
+
}
|
|
7279
|
+
results.push({ pair: [a.label, b.label], expectedOk, reason });
|
|
7280
|
+
}
|
|
7281
|
+
}
|
|
7282
|
+
return results;
|
|
7283
|
+
}
|
|
7173
7284
|
async function captureModelFixtures(params) {
|
|
7174
7285
|
const { api, channel, outDir } = params;
|
|
7175
7286
|
const log = params.log ?? console.log;
|
|
7176
7287
|
mkdirp(outDir);
|
|
7288
|
+
const writeJsonSafe = (filePath, data) => writeJson(filePath, sanitizeFixtureData(data));
|
|
7289
|
+
const writeTextSafe = (filePath, text) => writeText(filePath, sanitizeString(text));
|
|
7177
7290
|
const calls = {};
|
|
7178
7291
|
const errors = [];
|
|
7179
7292
|
async function capture(name, fn, writer) {
|
|
@@ -7196,123 +7309,269 @@ async function captureModelFixtures(params) {
|
|
|
7196
7309
|
const info = await capture(
|
|
7197
7310
|
"getInfo",
|
|
7198
7311
|
() => api.getInfo(channel),
|
|
7199
|
-
(v) =>
|
|
7312
|
+
(v) => writeJsonSafe(path4.join(outDir, "device-info.json"), v)
|
|
7200
7313
|
);
|
|
7201
7314
|
const support = await capture(
|
|
7202
7315
|
"getSupportInfo",
|
|
7203
7316
|
() => api.getSupportInfo(),
|
|
7204
|
-
(v) =>
|
|
7317
|
+
(v) => writeJsonSafe(path4.join(outDir, "support-info.json"), v)
|
|
7205
7318
|
);
|
|
7206
7319
|
const abilities = await capture(
|
|
7207
7320
|
"getAbilityInfo",
|
|
7208
7321
|
() => api.getAbilityInfo(),
|
|
7209
|
-
(v) =>
|
|
7322
|
+
(v) => writeJsonSafe(path4.join(outDir, "ability-info.json"), v)
|
|
7210
7323
|
);
|
|
7211
7324
|
await capture(
|
|
7212
7325
|
"getDeviceCapabilities",
|
|
7213
7326
|
() => api.getDeviceCapabilities(channel),
|
|
7214
|
-
(v) =>
|
|
7327
|
+
(v) => writeJsonSafe(path4.join(outDir, "capabilities.json"), v)
|
|
7215
7328
|
);
|
|
7216
7329
|
await capture("cmd289-WhiteLed", () => api.sendXml({
|
|
7217
7330
|
cmdId: BC_CMD_ID_GET_WHITE_LED,
|
|
7218
7331
|
channel,
|
|
7219
7332
|
timeoutMs: 3e3
|
|
7220
|
-
}), (v) =>
|
|
7333
|
+
}), (v) => writeTextSafe(path4.join(outDir, "cmd289-white-led.xml"), v));
|
|
7221
7334
|
await capture(
|
|
7222
7335
|
"getStreamMetadata",
|
|
7223
7336
|
() => api.getStreamMetadata(channel),
|
|
7224
|
-
(v) =>
|
|
7337
|
+
(v) => writeJsonSafe(path4.join(outDir, "stream-metadata.json"), v)
|
|
7225
7338
|
);
|
|
7226
7339
|
await capture(
|
|
7227
7340
|
"getEncXml",
|
|
7228
7341
|
() => api.getEncXml(channel),
|
|
7229
|
-
(v) =>
|
|
7342
|
+
(v) => writeTextSafe(path4.join(outDir, "enc-config.xml"), v)
|
|
7230
7343
|
);
|
|
7231
7344
|
await capture(
|
|
7232
7345
|
"getPorts",
|
|
7233
7346
|
() => api.getPorts(),
|
|
7234
|
-
(v) =>
|
|
7347
|
+
(v) => writeJsonSafe(path4.join(outDir, "ports.json"), v)
|
|
7235
7348
|
);
|
|
7236
7349
|
await capture(
|
|
7237
7350
|
"getTalkAbility",
|
|
7238
7351
|
() => api.getTalkAbility(channel),
|
|
7239
|
-
(v) =>
|
|
7352
|
+
(v) => writeJsonSafe(path4.join(outDir, "talk-ability.json"), v)
|
|
7240
7353
|
);
|
|
7241
7354
|
await capture(
|
|
7242
7355
|
"getTwoWayAudioConfig",
|
|
7243
7356
|
() => api.getTwoWayAudioConfig(channel),
|
|
7244
|
-
(v) =>
|
|
7357
|
+
(v) => writeJsonSafe(path4.join(outDir, "two-way-audio-config.json"), v)
|
|
7245
7358
|
);
|
|
7246
7359
|
await capture(
|
|
7247
7360
|
"getAiState",
|
|
7248
7361
|
() => api.getAiState(channel),
|
|
7249
|
-
(v) =>
|
|
7362
|
+
(v) => writeJsonSafe(path4.join(outDir, "ai-state.json"), v)
|
|
7250
7363
|
);
|
|
7251
7364
|
await capture(
|
|
7252
7365
|
"getAiCfg",
|
|
7253
7366
|
() => api.getAiCfg(channel),
|
|
7254
|
-
(v) =>
|
|
7367
|
+
(v) => writeJsonSafe(path4.join(outDir, "ai-cfg.json"), v)
|
|
7255
7368
|
);
|
|
7256
7369
|
await capture(
|
|
7257
7370
|
"getOsd",
|
|
7258
7371
|
() => api.getOsd(channel),
|
|
7259
|
-
(v) =>
|
|
7372
|
+
(v) => writeJsonSafe(path4.join(outDir, "osd.json"), v)
|
|
7260
7373
|
);
|
|
7261
7374
|
await capture(
|
|
7262
7375
|
"getMotionAlarm",
|
|
7263
7376
|
() => api.getMotionAlarm(channel),
|
|
7264
|
-
(v) =>
|
|
7377
|
+
(v) => writeJsonSafe(path4.join(outDir, "motion-alarm.json"), v)
|
|
7265
7378
|
);
|
|
7266
7379
|
await capture(
|
|
7267
7380
|
"getRecordCfg",
|
|
7268
7381
|
() => api.getRecordCfg(channel),
|
|
7269
|
-
(v) =>
|
|
7382
|
+
(v) => writeJsonSafe(path4.join(outDir, "record-cfg.json"), v)
|
|
7270
7383
|
);
|
|
7271
7384
|
await capture(
|
|
7272
7385
|
"getVideoInput",
|
|
7273
7386
|
() => api.getVideoInput(channel),
|
|
7274
|
-
(v) =>
|
|
7387
|
+
(v) => writeJsonSafe(path4.join(outDir, "video-input.json"), v)
|
|
7275
7388
|
);
|
|
7276
7389
|
await capture(
|
|
7277
7390
|
"getPtzPresets",
|
|
7278
7391
|
() => api.getPtzPresets(channel),
|
|
7279
|
-
(v) =>
|
|
7392
|
+
(v) => writeJsonSafe(path4.join(outDir, "ptz-presets.json"), v)
|
|
7280
7393
|
);
|
|
7281
7394
|
await capture(
|
|
7282
7395
|
"getNetworkInfo",
|
|
7283
7396
|
() => api.getNetworkInfo(),
|
|
7284
|
-
(v) =>
|
|
7397
|
+
(v) => writeJsonSafe(path4.join(outDir, "network-info.json"), v)
|
|
7285
7398
|
);
|
|
7286
7399
|
await capture(
|
|
7287
7400
|
"getSystemGeneral",
|
|
7288
7401
|
() => api.getSystemGeneral(),
|
|
7289
|
-
(v) =>
|
|
7402
|
+
(v) => writeJsonSafe(path4.join(outDir, "system-general.json"), v)
|
|
7290
7403
|
);
|
|
7291
7404
|
await capture(
|
|
7292
7405
|
"getWifiSignal",
|
|
7293
7406
|
() => api.getWifiSignal(channel),
|
|
7294
|
-
(v) =>
|
|
7407
|
+
(v) => writeJsonSafe(path4.join(outDir, "wifi-signal.json"), v)
|
|
7295
7408
|
);
|
|
7296
7409
|
await capture(
|
|
7297
7410
|
"getWhiteLedState",
|
|
7298
7411
|
() => api.getWhiteLedState(channel),
|
|
7299
|
-
(v) =>
|
|
7412
|
+
(v) => writeJsonSafe(path4.join(outDir, "white-led-state.json"), v)
|
|
7300
7413
|
);
|
|
7301
7414
|
await capture(
|
|
7302
7415
|
"getFloodlightOnMotion",
|
|
7303
7416
|
() => api.getFloodlightOnMotion(channel),
|
|
7304
|
-
(v) =>
|
|
7417
|
+
(v) => writeJsonSafe(path4.join(outDir, "floodlight-on-motion.json"), v)
|
|
7305
7418
|
);
|
|
7306
7419
|
await capture(
|
|
7307
7420
|
"buildVideoStreamOptions",
|
|
7308
7421
|
() => api.buildVideoStreamOptions({ channel }),
|
|
7309
|
-
(v) =>
|
|
7422
|
+
(v) => writeJsonSafe(path4.join(outDir, "video-stream-options.json"), v)
|
|
7423
|
+
);
|
|
7424
|
+
await capture(
|
|
7425
|
+
"getDualLensChannelInfo",
|
|
7426
|
+
() => api.getDualLensChannelInfo(channel),
|
|
7427
|
+
(v) => writeJsonSafe(path4.join(outDir, "dual-lens-info.json"), v)
|
|
7310
7428
|
);
|
|
7429
|
+
await capture("streamCombinationTest", async () => {
|
|
7430
|
+
let dualLensInfo;
|
|
7431
|
+
try {
|
|
7432
|
+
dualLensInfo = await api.getDualLensChannelInfo(channel);
|
|
7433
|
+
} catch {
|
|
7434
|
+
}
|
|
7435
|
+
const isMultifocal = dualLensInfo?.isDualLens === true;
|
|
7436
|
+
const channelCount = dualLensInfo?.streamChannelCount ?? 1;
|
|
7437
|
+
const allStreams = [];
|
|
7438
|
+
const profiles = ["main", "sub", "ext"];
|
|
7439
|
+
for (let ch = 0; ch < channelCount; ch++) {
|
|
7440
|
+
for (const p of profiles) {
|
|
7441
|
+
const label = channelCount > 1 ? `ch${ch}_${p}` : p;
|
|
7442
|
+
allStreams.push({ ch, profile: p, label });
|
|
7443
|
+
}
|
|
7444
|
+
}
|
|
7445
|
+
const pairs = [];
|
|
7446
|
+
for (let i = 0; i < allStreams.length; i++) {
|
|
7447
|
+
for (let j = i + 1; j < allStreams.length; j++) {
|
|
7448
|
+
pairs.push([allStreams[i], allStreams[j]]);
|
|
7449
|
+
}
|
|
7450
|
+
}
|
|
7451
|
+
const expectedStreamType = { main: 0, sub: 1, ext: 0 };
|
|
7452
|
+
const expectedCompat = [];
|
|
7453
|
+
for (const [a, b] of pairs) {
|
|
7454
|
+
const stA = expectedStreamType[a.profile];
|
|
7455
|
+
const stB = expectedStreamType[b.profile];
|
|
7456
|
+
const sameChannel = a.ch === b.ch;
|
|
7457
|
+
let expectedOk;
|
|
7458
|
+
let reason;
|
|
7459
|
+
if (sameChannel && stA === stB) {
|
|
7460
|
+
expectedOk = false;
|
|
7461
|
+
reason = `same streamType (${stA}) on same channel`;
|
|
7462
|
+
} else if (!sameChannel && a.profile === b.profile) {
|
|
7463
|
+
expectedOk = false;
|
|
7464
|
+
reason = `multifocal rejects same profile (${a.profile}) across channels`;
|
|
7465
|
+
} else if (!sameChannel && stA === stB) {
|
|
7466
|
+
expectedOk = false;
|
|
7467
|
+
reason = `same streamType (${stA}) across channels`;
|
|
7468
|
+
} else {
|
|
7469
|
+
expectedOk = true;
|
|
7470
|
+
reason = `different streamTypes (${stA} vs ${stB})`;
|
|
7471
|
+
}
|
|
7472
|
+
expectedCompat.push({ pair: [a.label, b.label], expectedOk, reason });
|
|
7473
|
+
}
|
|
7474
|
+
const results = [];
|
|
7475
|
+
const TEST_DURATION_MS = 4e3;
|
|
7476
|
+
for (let pairIdx = 0; pairIdx < pairs.length; pairIdx++) {
|
|
7477
|
+
const [a, b] = pairs[pairIdx];
|
|
7478
|
+
const expected = expectedCompat[pairIdx];
|
|
7479
|
+
log(` testing ${a.label}+${b.label} on shared socket...`);
|
|
7480
|
+
let session;
|
|
7481
|
+
try {
|
|
7482
|
+
session = await api.createDedicatedSession(
|
|
7483
|
+
`test:combo:${a.label}_${b.label}`
|
|
7484
|
+
);
|
|
7485
|
+
} catch (e) {
|
|
7486
|
+
const result2 = {
|
|
7487
|
+
pair: [a.label, b.label],
|
|
7488
|
+
ok: false,
|
|
7489
|
+
framesA: 0,
|
|
7490
|
+
framesB: 0,
|
|
7491
|
+
mismatches: 0,
|
|
7492
|
+
error: `session: ${e instanceof Error ? e.message : String(e)}`,
|
|
7493
|
+
durationMs: 0,
|
|
7494
|
+
expectedOk: expected.expectedOk,
|
|
7495
|
+
expectedReason: expected.reason,
|
|
7496
|
+
matchesExpected: !expected.expectedOk
|
|
7497
|
+
// failed as expected if we expected failure
|
|
7498
|
+
};
|
|
7499
|
+
results.push(result2);
|
|
7500
|
+
continue;
|
|
7501
|
+
}
|
|
7502
|
+
const testClient = session.client;
|
|
7503
|
+
let framesA = 0;
|
|
7504
|
+
let framesB = 0;
|
|
7505
|
+
let mismatches = 0;
|
|
7506
|
+
const start = Date.now();
|
|
7507
|
+
const stTypes = {
|
|
7508
|
+
main: /* @__PURE__ */ new Set([0, 2]),
|
|
7509
|
+
sub: /* @__PURE__ */ new Set([1, 3]),
|
|
7510
|
+
ext: /* @__PURE__ */ new Set([0, 2])
|
|
7511
|
+
};
|
|
7512
|
+
const setA = stTypes[a.profile];
|
|
7513
|
+
const setB = stTypes[b.profile];
|
|
7514
|
+
const onFrame = (frame) => {
|
|
7515
|
+
if (frame.header?.cmdId !== BC_CMD_ID_VIDEO) return;
|
|
7516
|
+
const st = frame.header.streamType;
|
|
7517
|
+
if (setA.has(st)) framesA++;
|
|
7518
|
+
else if (setB.has(st)) framesB++;
|
|
7519
|
+
else mismatches++;
|
|
7520
|
+
};
|
|
7521
|
+
testClient.on("frame", onFrame);
|
|
7522
|
+
let error;
|
|
7523
|
+
try {
|
|
7524
|
+
await api.startVideoStream(a.ch, a.profile, { client: testClient });
|
|
7525
|
+
await api.startVideoStream(b.ch, b.profile, { client: testClient });
|
|
7526
|
+
await new Promise((r) => setTimeout(r, TEST_DURATION_MS));
|
|
7527
|
+
await api.stopVideoStream(a.ch, a.profile, { client: testClient }).catch(() => {
|
|
7528
|
+
});
|
|
7529
|
+
await api.stopVideoStream(b.ch, b.profile, { client: testClient }).catch(() => {
|
|
7530
|
+
});
|
|
7531
|
+
} catch (e) {
|
|
7532
|
+
error = e instanceof Error ? e.message : String(e);
|
|
7533
|
+
} finally {
|
|
7534
|
+
testClient.removeListener("frame", onFrame);
|
|
7535
|
+
await session.release().catch(() => {
|
|
7536
|
+
});
|
|
7537
|
+
}
|
|
7538
|
+
const elapsed = Date.now() - start;
|
|
7539
|
+
const ok2 = !error && framesA > 0 && framesB > 0 && mismatches === 0;
|
|
7540
|
+
const result = {
|
|
7541
|
+
pair: [a.label, b.label],
|
|
7542
|
+
ok: ok2,
|
|
7543
|
+
framesA,
|
|
7544
|
+
framesB,
|
|
7545
|
+
mismatches,
|
|
7546
|
+
...error ? { error } : {},
|
|
7547
|
+
durationMs: elapsed,
|
|
7548
|
+
expectedOk: expected.expectedOk,
|
|
7549
|
+
expectedReason: expected.reason,
|
|
7550
|
+
matchesExpected: ok2 === expected.expectedOk
|
|
7551
|
+
};
|
|
7552
|
+
results.push(result);
|
|
7553
|
+
const matchStr = result.matchesExpected ? "" : " *** UNEXPECTED ***";
|
|
7554
|
+
log(` ${a.label}+${b.label}: ${ok2 ? "OK" : "FAIL"} (expected=${expected.expectedOk ? "OK" : "FAIL"}) A=${framesA} B=${framesB} mismatch=${mismatches}${matchStr}`);
|
|
7555
|
+
}
|
|
7556
|
+
const unexpected = results.filter((r) => !r.matchesExpected);
|
|
7557
|
+
return {
|
|
7558
|
+
isMultifocal,
|
|
7559
|
+
channelCount,
|
|
7560
|
+
results,
|
|
7561
|
+
summary: {
|
|
7562
|
+
total: results.length,
|
|
7563
|
+
ok: results.filter((r) => r.ok).length,
|
|
7564
|
+
failed: results.filter((r) => !r.ok).length,
|
|
7565
|
+
matchesExpected: results.filter((r) => r.matchesExpected).length,
|
|
7566
|
+
unexpected: unexpected.map((r) => `${r.pair[0]}+${r.pair[1]}: got ${r.ok ? "OK" : "FAIL"}, expected ${r.expectedOk ? "OK" : "FAIL"}`)
|
|
7567
|
+
}
|
|
7568
|
+
};
|
|
7569
|
+
}, (v) => writeJsonSafe(path4.join(outDir, "stream-combination-test.json"), v));
|
|
7311
7570
|
const total = Object.keys(calls).length;
|
|
7312
7571
|
const ok = Object.values(calls).filter((c) => c.ok).length;
|
|
7313
7572
|
const failed = total - ok;
|
|
7314
7573
|
const summary = { total, ok, failed, errors };
|
|
7315
|
-
|
|
7574
|
+
writeJsonSafe(path4.join(outDir, "_summary.json"), {
|
|
7316
7575
|
collectedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
7317
7576
|
model: info?.type ?? "unknown",
|
|
7318
7577
|
itemNo: info?.itemNo ?? "unknown",
|
|
@@ -7518,8 +7777,10 @@ export {
|
|
|
7518
7777
|
collectMultifocalDiagnostics,
|
|
7519
7778
|
runMultifocalDiagnosticsConsecutively,
|
|
7520
7779
|
runAllDiagnosticsConsecutively,
|
|
7780
|
+
sanitizeFixtureData,
|
|
7781
|
+
computeExpectedStreamCompatibility,
|
|
7521
7782
|
captureModelFixtures,
|
|
7522
7783
|
parseRecordingFileName,
|
|
7523
7784
|
ReolinkCgiApi
|
|
7524
7785
|
};
|
|
7525
|
-
//# sourceMappingURL=chunk-
|
|
7786
|
+
//# sourceMappingURL=chunk-DUHWTZ7U.js.map
|