@camstack/addon-pipeline 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/audio-analyzer/index.js +146 -56
- package/dist/audio-analyzer/index.mjs +145 -54
- package/dist/audio-codec-nodeav/index.js +1 -1
- package/dist/audio-codec-nodeav/index.mjs +1 -1
- package/dist/decoder-nodeav/index.js +2 -2
- package/dist/decoder-nodeav/index.mjs +2 -2
- package/dist/detection-pipeline/index.js +127 -330
- package/dist/detection-pipeline/index.mjs +120 -324
- package/dist/{dist-7ewQjTle.js → dist-C1goFC50.js} +4 -4
- package/dist/{dist-C5jnNl0n.mjs → dist-XRXnZrVC.mjs} +4 -4
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +1 -1
- package/dist/pipeline-runner/index.mjs +1 -1
- package/dist/recorder/index.js +3 -3
- package/dist/recorder/index.mjs +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Bak8zYXf.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-qX99--rF.mjs} +3 -3
- package/dist/stream-broker/{hostInit-CYCw2DW3.mjs → hostInit-Bx41KdYV.mjs} +3 -3
- package/dist/stream-broker/index.js +5 -5
- package/dist/stream-broker/index.mjs +4 -4
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +4 -9
- package/python/requirements-audio.txt +5 -0
- package/python/yamnet_audio.py +113 -0
- package/dist/constants-B_b0a-6h.mjs +0 -3119
- package/dist/constants-D65v6yp6.js +0 -5963
|
@@ -13314,7 +13314,7 @@ method(_void(), DeviceExportStatusSchema), method(_void(), array(DeviceKindSchem
|
|
|
13314
13314
|
* rebuilds without manual reload.
|
|
13315
13315
|
*
|
|
13316
13316
|
* The hub-local builtin `addon-pages-aggregator` (see
|
|
13317
|
-
* `@camstack/
|
|
13317
|
+
* `@camstack/system/builtins/addon-pages-aggregator`) registers the
|
|
13318
13318
|
* provider. Splitting the public aggregator from the raw collection
|
|
13319
13319
|
* keeps both ends in codegen — there's no hand-written
|
|
13320
13320
|
* `addon-pages.router.ts` wrapper anymore.
|
|
@@ -13503,7 +13503,7 @@ var addonWidgetsSourceCapability = {
|
|
|
13503
13503
|
* manual reload — same scheme used by `addon-pages`.
|
|
13504
13504
|
*
|
|
13505
13505
|
* The hub-local builtin `addon-widgets-aggregator` (see
|
|
13506
|
-
* `@camstack/
|
|
13506
|
+
* `@camstack/system/builtins/addon-widgets-aggregator`) registers the
|
|
13507
13507
|
* provider. Splitting the public aggregator from the raw collection
|
|
13508
13508
|
* keeps both ends in codegen — there's no hand-written wrapper.
|
|
13509
13509
|
*/
|
|
@@ -16569,7 +16569,7 @@ method(_void(), PlatformCapabilitiesSchema), method(_void(), HardwareInfoSchema)
|
|
|
16569
16569
|
* clients — they reverse-connect to the hub. Exposing their interfaces
|
|
16570
16570
|
* via the same surface would leak internal topology with no upside.
|
|
16571
16571
|
*
|
|
16572
|
-
* Implementation in `@camstack/
|
|
16572
|
+
* Implementation in `@camstack/system/builtins/local-network/`.
|
|
16573
16573
|
*/
|
|
16574
16574
|
/** Coarse classification derived from the interface name + IP range. */
|
|
16575
16575
|
var InterfaceKindEnum = _enum([
|
|
@@ -17116,7 +17116,7 @@ method(_void(), FeatureManifestSchema), method(_void(), HealthStatusSchema), met
|
|
|
17116
17116
|
* jitter, and observed/peak bandwidth per device + per client.
|
|
17117
17117
|
*
|
|
17118
17118
|
* Implementation lives in the server's `NetworkQualityService` (thin
|
|
17119
|
-
* wrapper over the shared `NetworkQualityTracker` from `@camstack/
|
|
17119
|
+
* wrapper over the shared `NetworkQualityTracker` from `@camstack/system`).
|
|
17120
17120
|
* The provider is registered from `trpc.router.ts` against the existing
|
|
17121
17121
|
* service instance — no addon owns this state.
|
|
17122
17122
|
*
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
6
6
|
let node_fs = require("node:fs");
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as motionDetectionCapability, M as evaluateZoneRules, P as hydrateSchema, d as DeviceType, i as BaseAddon } from "../dist-
|
|
1
|
+
import { B as motionDetectionCapability, M as evaluateZoneRules, P as hydrateSchema, d as DeviceType, i as BaseAddon } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
//#region src/motion-wasm/wasm-motion-detector.ts
|
|
@@ -2,7 +2,7 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
5
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
6
6
|
let _camstack_shm_ring = require("@camstack/shm-ring");
|
|
7
7
|
//#region src/pipeline-runner/frame-queue.ts
|
|
8
8
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as boolean, D as customAction, E as createEvent, I as makeSourceBrokerId, Q as array, W as pipelineRunnerCapability, Z as _enum, i as BaseAddon, it as object, j as errMsg, k as defineCustomActions, ot as string, p as EventCategory, rt as number, tt as lazy } from "../dist-
|
|
1
|
+
import { $ as boolean, D as customAction, E as createEvent, I as makeSourceBrokerId, Q as array, W as pipelineRunnerCapability, Z as _enum, i as BaseAddon, it as object, j as errMsg, k as defineCustomActions, ot as string, p as EventCategory, rt as number, tt as lazy } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { FrameRingReaderCache } from "@camstack/shm-ring";
|
|
3
3
|
//#region src/pipeline-runner/frame-queue.ts
|
|
4
4
|
/**
|
package/dist/recorder/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
const require_chunk = require("../chunk-D6vf50IK.js");
|
|
2
|
-
const require_dist = require("../dist-
|
|
2
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
3
3
|
let node_fs = require("node:fs");
|
|
4
4
|
let node_path = require("node:path");
|
|
5
5
|
node_path = require_chunk.__toESM(node_path);
|
|
6
|
-
let
|
|
6
|
+
let _camstack_system = require("@camstack/system");
|
|
7
7
|
let node_child_process = require("node:child_process");
|
|
8
8
|
//#region src/recorder/segment-path.ts
|
|
9
9
|
function segmentRelPath(deviceId, profile, startMs, durMs, bytes) {
|
|
@@ -1935,7 +1935,7 @@ var RecorderV2Addon = class extends require_dist.BaseAddon {
|
|
|
1935
1935
|
store: this.segmentStore
|
|
1936
1936
|
});
|
|
1937
1937
|
try {
|
|
1938
|
-
const handler = (0,
|
|
1938
|
+
const handler = (0, _camstack_system.createFileDataPlaneHandler)({ getRoots: () => this.playbackRoots() });
|
|
1939
1939
|
const served = await this.ctx.dataPlane?.serve({
|
|
1940
1940
|
prefix: PLAYBACK_PREFIX,
|
|
1941
1941
|
access: "authenticated",
|
package/dist/recorder/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { G as recordingCapability, J as storageEvictableCapability, K as selectAssignedProfileSlots, P as hydrateSchema, T as createDurableState, at as record, g as RecordingConfigSchema, i as BaseAddon, j as errMsg, ot as string, p as EventCategory, z as migrateConfigToBands } from "../dist-
|
|
1
|
+
import { G as recordingCapability, J as storageEvictableCapability, K as selectAssignedProfileSlots, P as hydrateSchema, T as createDurableState, at as record, g as RecordingConfigSchema, i as BaseAddon, j as errMsg, ot as string, p as EventCategory, z as migrateConfigToBands } from "../dist-XRXnZrVC.mjs";
|
|
2
2
|
import { promises } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { createFileDataPlaneHandler } from "@camstack/
|
|
4
|
+
import { createFileDataPlaneHandler } from "@camstack/system";
|
|
5
5
|
import { spawn } from "node:child_process";
|
|
6
6
|
//#region src/recorder/segment-path.ts
|
|
7
7
|
function segmentRelPath(deviceId, profile, startMs, durMs, bytes) {
|
|
@@ -3,7 +3,7 @@ import "./dist-CYZr2fwk.mjs";
|
|
|
3
3
|
var e = {
|
|
4
4
|
"@camstack/sdk": {
|
|
5
5
|
name: "@camstack/sdk",
|
|
6
|
-
version: "1.0.
|
|
6
|
+
version: "1.0.1",
|
|
7
7
|
scope: ["default"],
|
|
8
8
|
loaded: !1,
|
|
9
9
|
from: "addon_stream_broker_widgets",
|
|
@@ -18,7 +18,7 @@ var e = {
|
|
|
18
18
|
},
|
|
19
19
|
"@camstack/types": {
|
|
20
20
|
name: "@camstack/types",
|
|
21
|
-
version: "1.0.
|
|
21
|
+
version: "1.0.1",
|
|
22
22
|
scope: ["default"],
|
|
23
23
|
loaded: !1,
|
|
24
24
|
from: "addon_stream_broker_widgets",
|
|
@@ -33,7 +33,7 @@ var e = {
|
|
|
33
33
|
},
|
|
34
34
|
"@camstack/ui-library": {
|
|
35
35
|
name: "@camstack/ui-library",
|
|
36
|
-
version: "1.0.
|
|
36
|
+
version: "1.0.1",
|
|
37
37
|
scope: ["default"],
|
|
38
38
|
loaded: !1,
|
|
39
39
|
from: "addon_stream_broker_widgets",
|
|
@@ -36,7 +36,7 @@ async function r() {
|
|
|
36
36
|
}
|
|
37
37
|
},
|
|
38
38
|
"@camstack/types": {
|
|
39
|
-
version: "1.0.
|
|
39
|
+
version: "1.0.1",
|
|
40
40
|
scope: "default",
|
|
41
41
|
shareConfig: {
|
|
42
42
|
singleton: !0,
|
|
@@ -45,7 +45,7 @@ async function r() {
|
|
|
45
45
|
}
|
|
46
46
|
},
|
|
47
47
|
"@camstack/sdk": {
|
|
48
|
-
version: "1.0.
|
|
48
|
+
version: "1.0.1",
|
|
49
49
|
scope: "default",
|
|
50
50
|
shareConfig: {
|
|
51
51
|
singleton: !0,
|
|
@@ -81,7 +81,7 @@ async function r() {
|
|
|
81
81
|
}
|
|
82
82
|
},
|
|
83
83
|
"@camstack/ui-library": {
|
|
84
|
-
version: "1.0.
|
|
84
|
+
version: "1.0.1",
|
|
85
85
|
scope: "default",
|
|
86
86
|
shareConfig: {
|
|
87
87
|
singleton: !0,
|
|
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
|
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
5
|
const require_chunk = require("../chunk-D6vf50IK.js");
|
|
6
|
-
const require_dist = require("../dist-
|
|
6
|
+
const require_dist = require("../dist-C1goFC50.js");
|
|
7
7
|
const require_codec_runtime = require("../codec-runtime-BOk-13PN.js");
|
|
8
8
|
let node_fs = require("node:fs");
|
|
9
9
|
node_fs = require_chunk.__toESM(node_fs);
|
|
@@ -11,7 +11,7 @@ let node_path = require("node:path");
|
|
|
11
11
|
node_path = require_chunk.__toESM(node_path);
|
|
12
12
|
let node_os = require("node:os");
|
|
13
13
|
node_os = require_chunk.__toESM(node_os);
|
|
14
|
-
let
|
|
14
|
+
let _camstack_system = require("@camstack/system");
|
|
15
15
|
let node_child_process = require("node:child_process");
|
|
16
16
|
let node_crypto = require("node:crypto");
|
|
17
17
|
node_crypto = require_chunk.__toESM(node_crypto);
|
|
@@ -27,7 +27,7 @@ let node_events = require("node:events");
|
|
|
27
27
|
/** Build a `(req, res)` handler serving the embed bundle at `root` with SPA fallback.
|
|
28
28
|
* Web MIME types (`.html`/`.js`/`.css`/…) come from the core handler's defaults. */
|
|
29
29
|
function createEmbedSpaHandler(root) {
|
|
30
|
-
const fileHandler = (0,
|
|
30
|
+
const fileHandler = (0, _camstack_system.createFileDataPlaneHandler)({ getRoots: () => [root] });
|
|
31
31
|
return (req, res) => {
|
|
32
32
|
const [pathPart = "/", query] = (req.url ?? "/").split("?");
|
|
33
33
|
const lastSegment = pathPart.split("/").pop() ?? "";
|
|
@@ -14289,7 +14289,7 @@ function getNodeAv$1() {
|
|
|
14289
14289
|
return _navPromise$1 ??= import("node-av");
|
|
14290
14290
|
}
|
|
14291
14291
|
function getConstants$1() {
|
|
14292
|
-
return _constsPromise$1 ??=
|
|
14292
|
+
return _constsPromise$1 ??= import("node-av/constants");
|
|
14293
14293
|
}
|
|
14294
14294
|
/** Convert a presentation timestamp in stream ticks to milliseconds. */
|
|
14295
14295
|
function ticksToMs$1(ptsTicks, timeBase) {
|
|
@@ -14665,7 +14665,7 @@ var AV_NOPTS_VALUE = -9223372036854775808n;
|
|
|
14665
14665
|
var _navPromise = null;
|
|
14666
14666
|
var _constsPromise = null;
|
|
14667
14667
|
var getNodeAv = () => _navPromise ??= import("node-av");
|
|
14668
|
-
var getConstants = () => _constsPromise ??=
|
|
14668
|
+
var getConstants = () => _constsPromise ??= import("node-av/constants");
|
|
14669
14669
|
function ticksToMs(pts, tb) {
|
|
14670
14670
|
return Math.round(Number(pts) * 1e3 * tb.num / tb.den);
|
|
14671
14671
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { t as __require } from "../chunk-BdkLduGY.mjs";
|
|
2
|
-
import { $ as boolean, E as createEvent, F as makeProfileBrokerId, H as parseProfileBrokerId, I as makeSourceBrokerId, R as maskUrlCredentials, X as webrtcSessionCapability, Y as streamBrokerCapability, Z as _enum, _ as RingBuffer, a as CAM_PROFILE_ORDER, at as record, b as asJsonObject, d as DeviceType, et as discriminatedUnion, f as EncodeProfileSchema, i as BaseAddon, it as object, j as errMsg, nt as literal, ot as string, p as EventCategory, rt as number, st as union, u as DeviceFeature, w as cameraStreamsCapability, y as addonWidgetsSourceCapability } from "../dist-
|
|
2
|
+
import { $ as boolean, E as createEvent, F as makeProfileBrokerId, H as parseProfileBrokerId, I as makeSourceBrokerId, R as maskUrlCredentials, X as webrtcSessionCapability, Y as streamBrokerCapability, Z as _enum, _ as RingBuffer, a as CAM_PROFILE_ORDER, at as record, b as asJsonObject, d as DeviceType, et as discriminatedUnion, f as EncodeProfileSchema, i as BaseAddon, it as object, j as errMsg, nt as literal, ot as string, p as EventCategory, rt as number, st as union, u as DeviceFeature, w as cameraStreamsCapability, y as addonWidgetsSourceCapability } from "../dist-XRXnZrVC.mjs";
|
|
3
3
|
import { t as DecodeRuntime } from "../codec-runtime-BsqlEjPi.mjs";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import * as path$1 from "node:path";
|
|
6
6
|
import path, { join } from "node:path";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import { networkInterfaces, tmpdir } from "node:os";
|
|
9
|
-
import { createFileDataPlaneHandler } from "@camstack/
|
|
9
|
+
import { createFileDataPlaneHandler } from "@camstack/system";
|
|
10
10
|
import { spawn } from "node:child_process";
|
|
11
11
|
import * as crypto$1 from "node:crypto";
|
|
12
12
|
import crypto, { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
@@ -14284,7 +14284,7 @@ function getNodeAv$1() {
|
|
|
14284
14284
|
return _navPromise$1 ??= import("node-av");
|
|
14285
14285
|
}
|
|
14286
14286
|
function getConstants$1() {
|
|
14287
|
-
return _constsPromise$1 ??= import("
|
|
14287
|
+
return _constsPromise$1 ??= import("node-av/constants");
|
|
14288
14288
|
}
|
|
14289
14289
|
/** Convert a presentation timestamp in stream ticks to milliseconds. */
|
|
14290
14290
|
function ticksToMs$1(ptsTicks, timeBase) {
|
|
@@ -14660,7 +14660,7 @@ var AV_NOPTS_VALUE = -9223372036854775808n;
|
|
|
14660
14660
|
var _navPromise = null;
|
|
14661
14661
|
var _constsPromise = null;
|
|
14662
14662
|
var getNodeAv = () => _navPromise ??= import("node-av");
|
|
14663
|
-
var getConstants = () => _constsPromise ??= import("
|
|
14663
|
+
var getConstants = () => _constsPromise ??= import("node-av/constants");
|
|
14664
14664
|
function ticksToMs(pts, tb) {
|
|
14665
14665
|
return Math.round(Number(pts) * 1e3 * tb.num / tb.den);
|
|
14666
14666
|
}
|
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-qX99--rF.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "CamStack Pipeline bundle — runner, detection, motion, decoders, audio + stream broker. Multi-entry npm package shipping 7 addons under a single bundle.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -69,9 +69,7 @@
|
|
|
69
69
|
"description": "Detection, motion, decoders, audio + stream broker."
|
|
70
70
|
},
|
|
71
71
|
"nativeDependencies": {
|
|
72
|
-
"node-av": "^5.2.4"
|
|
73
|
-
"onnxruntime-node": "^1.24.3",
|
|
74
|
-
"sharp": "^0.34.0"
|
|
72
|
+
"node-av": "^5.2.4"
|
|
75
73
|
},
|
|
76
74
|
"addons": [
|
|
77
75
|
{
|
|
@@ -293,19 +291,16 @@
|
|
|
293
291
|
"publish": "npm publish --access public"
|
|
294
292
|
},
|
|
295
293
|
"peerDependencies": {
|
|
296
|
-
"@camstack/types": "
|
|
294
|
+
"@camstack/types": "*",
|
|
297
295
|
"react": ">=18",
|
|
298
296
|
"react-dom": ">=18",
|
|
299
|
-
"sharp": "^0.34.0",
|
|
300
297
|
"werift": "^0.22.9"
|
|
301
298
|
},
|
|
302
299
|
"dependencies": {
|
|
303
|
-
"@camstack/
|
|
300
|
+
"@camstack/system": "*",
|
|
304
301
|
"lucide-react": "^0.511.0",
|
|
305
302
|
"mp4box": "0.5.4",
|
|
306
303
|
"node-av": "^5.2.4",
|
|
307
|
-
"onnxruntime-node": "^1.24.3",
|
|
308
|
-
"sharp": "^0.35.2",
|
|
309
304
|
"zod": "^4.3.6"
|
|
310
305
|
},
|
|
311
306
|
"devDependencies": {
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""YAMNet audio classification subprocess.
|
|
3
|
+
|
|
4
|
+
Runs YAMNet ONNX inference via the embedded portable Python's onnxruntime,
|
|
5
|
+
replacing the former Node `onnxruntime-node` path. Persistent process: reads
|
|
6
|
+
length-prefixed float32 waveforms (16 kHz mono) from stdin, writes
|
|
7
|
+
length-prefixed JSON results to stdout. Mirrors the Apple SoundAnalysis Swift
|
|
8
|
+
CLI wire protocol so the Node side (YamnetPythonPipeline) reuses one receive
|
|
9
|
+
loop.
|
|
10
|
+
|
|
11
|
+
Wire protocol (both directions): [4B little-endian length][payload]
|
|
12
|
+
stdin payload = raw float32 waveform bytes (16 kHz mono)
|
|
13
|
+
stdout payload = JSON {"classifications":[{"className","score"}], "inferenceMs"}
|
|
14
|
+
Startup: emits {"status":"ready"} once the model is loaded. Diagnostics go to
|
|
15
|
+
stderr (stdout is the binary framing channel only).
|
|
16
|
+
"""
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import json
|
|
21
|
+
import struct
|
|
22
|
+
import sys
|
|
23
|
+
import time
|
|
24
|
+
|
|
25
|
+
import numpy as np
|
|
26
|
+
import onnxruntime as ort
|
|
27
|
+
|
|
28
|
+
# Match the former Node YamnetOnnxPipeline thresholds.
|
|
29
|
+
MIN_SCORE = 0.05
|
|
30
|
+
TOP_K = 10
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def write_msg(obj: dict) -> None:
|
|
34
|
+
data = json.dumps(obj).encode("utf-8")
|
|
35
|
+
sys.stdout.buffer.write(struct.pack("<I", len(data)))
|
|
36
|
+
sys.stdout.buffer.write(data)
|
|
37
|
+
sys.stdout.buffer.flush()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def read_exact(n: int) -> bytes | None:
|
|
41
|
+
buf = bytearray()
|
|
42
|
+
while len(buf) < n:
|
|
43
|
+
chunk = sys.stdin.buffer.read(n - len(buf))
|
|
44
|
+
if not chunk:
|
|
45
|
+
return None
|
|
46
|
+
buf.extend(chunk)
|
|
47
|
+
return bytes(buf)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def main() -> None:
|
|
51
|
+
ap = argparse.ArgumentParser()
|
|
52
|
+
ap.add_argument("--model", required=True)
|
|
53
|
+
ap.add_argument("--labels", default="")
|
|
54
|
+
args = ap.parse_args()
|
|
55
|
+
|
|
56
|
+
labels: list[str] = []
|
|
57
|
+
if args.labels:
|
|
58
|
+
try:
|
|
59
|
+
with open(args.labels, "r", encoding="utf-8") as f:
|
|
60
|
+
labels = json.load(f)
|
|
61
|
+
except Exception as exc: # noqa: BLE001 — labels are best-effort
|
|
62
|
+
print(f"yamnet_audio: failed to read labels: {exc}", file=sys.stderr)
|
|
63
|
+
labels = []
|
|
64
|
+
|
|
65
|
+
session = ort.InferenceSession(args.model, providers=["CPUExecutionProvider"])
|
|
66
|
+
input_name = session.get_inputs()[0].name
|
|
67
|
+
output_name = session.get_outputs()[0].name
|
|
68
|
+
|
|
69
|
+
write_msg({"status": "ready", "labels": len(labels)})
|
|
70
|
+
|
|
71
|
+
while True:
|
|
72
|
+
header = read_exact(4)
|
|
73
|
+
if header is None:
|
|
74
|
+
break
|
|
75
|
+
(length,) = struct.unpack("<I", header)
|
|
76
|
+
payload = read_exact(length)
|
|
77
|
+
if payload is None:
|
|
78
|
+
break
|
|
79
|
+
|
|
80
|
+
start = time.time()
|
|
81
|
+
try:
|
|
82
|
+
waveform = np.frombuffer(payload, dtype=np.float32)
|
|
83
|
+
outputs = session.run([output_name], {input_name: waveform})
|
|
84
|
+
scores = np.asarray(outputs[0], dtype=np.float32)
|
|
85
|
+
if scores.ndim == 1:
|
|
86
|
+
scores = scores.reshape(1, -1)
|
|
87
|
+
# Average across frames → [num_classes]
|
|
88
|
+
avg = np.mean(scores, axis=0)
|
|
89
|
+
results = []
|
|
90
|
+
for c in range(avg.shape[0]):
|
|
91
|
+
s = float(avg[c])
|
|
92
|
+
if s >= MIN_SCORE:
|
|
93
|
+
label = labels[c] if c < len(labels) else str(c)
|
|
94
|
+
results.append({"className": label, "score": round(s, 3)})
|
|
95
|
+
results.sort(key=lambda x: x["score"], reverse=True)
|
|
96
|
+
write_msg(
|
|
97
|
+
{
|
|
98
|
+
"classifications": results[:TOP_K],
|
|
99
|
+
"inferenceMs": int((time.time() - start) * 1000),
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
except Exception as exc: # noqa: BLE001 — never kill the loop on one chunk
|
|
103
|
+
write_msg(
|
|
104
|
+
{
|
|
105
|
+
"classifications": [],
|
|
106
|
+
"inferenceMs": int((time.time() - start) * 1000),
|
|
107
|
+
"error": str(exc),
|
|
108
|
+
}
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
if __name__ == "__main__":
|
|
113
|
+
main()
|