@camstack/addon-pipeline 1.1.18 → 1.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/audio-analyzer/index.js +1 -1
  2. package/dist/audio-analyzer/index.mjs +1 -1
  3. package/dist/audio-codec-nodeav/index.js +1 -1
  4. package/dist/audio-codec-nodeav/index.mjs +1 -1
  5. package/dist/decoder-ffmpeg/index.js +1179 -0
  6. package/dist/decoder-ffmpeg/index.mjs +1162 -0
  7. package/dist/detection-pipeline/index.js +1 -1
  8. package/dist/detection-pipeline/index.mjs +1 -1
  9. package/dist/{dist-CBcVKDyT.mjs → dist-7Yx2dmuV.mjs} +1 -0
  10. package/dist/{dist-CRzS7bK1.js → dist-BgoBMCez.js} +1 -0
  11. package/dist/ffmpeg-args-common-CASoNt42.js +68 -0
  12. package/dist/ffmpeg-args-common-c3p-nWtU.mjs +51 -0
  13. package/dist/motion-wasm/index.js +1 -1
  14. package/dist/motion-wasm/index.mjs +1 -1
  15. package/dist/pipeline-runner/index.js +1 -1
  16. package/dist/pipeline-runner/index.mjs +1 -1
  17. package/dist/recorder/index.js +1 -1
  18. package/dist/recorder/index.mjs +1 -1
  19. package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-Cu2RfLyo.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-w2pP0MYO.mjs} +1 -1
  20. package/dist/stream-broker/{hostInit-D2VENktw.mjs → hostInit-BUEbBinp.mjs} +1 -1
  21. package/dist/stream-broker/index.js +67 -64
  22. package/dist/stream-broker/index.mjs +57 -54
  23. package/dist/stream-broker/remoteEntry.js +1 -1
  24. package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-ohKbGSOY.js → MaskShapeCanvas-DI4BY7W2-CYmHXacX.js} +1 -1
  25. package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-m6kOetLh.js → MotionZonesSettings-NcxxQN8r-B-BkPQvX.js} +1 -1
  26. package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-BNbgX3su.js → PrivacyMaskSettings-APgPLF7p-DC3Jw85p.js} +1 -1
  27. package/embed-dist/assets/{index-CqqHOFtM.js → index-B0IQgci0.js} +4 -4
  28. package/embed-dist/index.html +1 -1
  29. package/package.json +8 -8
  30. package/dist/decoder-nodeav/index.js +0 -1393
  31. package/dist/decoder-nodeav/index.mjs +0 -1385
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BnQ_awK4.js");
6
- const require_dist = require("../dist-CRzS7bK1.js");
6
+ const require_dist = require("../dist-BgoBMCez.js");
7
7
  let node_fs = require("node:fs");
8
8
  node_fs = require_model_download_service_C_IHWnXx.__toESM(node_fs);
9
9
  let node_path = require("node:path");
@@ -1,5 +1,5 @@
1
1
  import { t as __require } from "../chunk-BdkLduGY.mjs";
2
- import { A as nodePin, B as BaseAddon, C as detectionPipelineCapability, J as hydrateSchema, L as supportedRuntimes$1, P as runtimeDevices$1, T as hfModelUrl, W as EventCategory, Z as parseJsonUnknown, a as COCO_TO_MACRO, et as sleep, i as COCO_80_LABELS, j as pipelineExecutorCapability, p as YAMNET_TO_MACRO, q as createEvent, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, w as evaluateZoneRules, x as defaultDeviceFor$1, z as errMsg } from "../dist-CBcVKDyT.mjs";
2
+ import { A as nodePin, B as BaseAddon, C as detectionPipelineCapability, J as hydrateSchema, L as supportedRuntimes$1, P as runtimeDevices$1, T as hfModelUrl, W as EventCategory, Z as parseJsonUnknown, a as COCO_TO_MACRO, et as sleep, i as COCO_80_LABELS, j as pipelineExecutorCapability, p as YAMNET_TO_MACRO, q as createEvent, r as AUDIO_MACRO_LABELS, t as APPLE_SA_TO_MACRO, w as evaluateZoneRules, x as defaultDeviceFor$1, z as errMsg } from "../dist-7Yx2dmuV.mjs";
3
3
  import { a as isModelDownloaded, i as ensureModel, n as deleteModelFromDisk } from "../model-download-service-C-IHWnXx-3Mmeob3l.mjs";
4
4
  import * as fs from "node:fs";
5
5
  import * as path$1 from "node:path";
@@ -13396,6 +13396,7 @@ var decoderCapability = {
13396
13396
  name: "decoder",
13397
13397
  scope: "system",
13398
13398
  mode: "singleton",
13399
+ preferredProvider: "decoder-ffmpeg",
13399
13400
  methods: {
13400
13401
  supportsCodec: method(object({ codec: string() }), boolean()),
13401
13402
  getInfo: method(_void(), object({
@@ -13396,6 +13396,7 @@ var decoderCapability = {
13396
13396
  name: "decoder",
13397
13397
  scope: "system",
13398
13398
  mode: "singleton",
13399
+ preferredProvider: "decoder-ffmpeg",
13399
13400
  methods: {
13400
13401
  supportsCodec: method(object({ codec: string() }), boolean()),
13401
13402
  getInfo: method(_void(), object({
@@ -0,0 +1,68 @@
1
+ //#region src/stream-broker/stream-broker/frame-dropper.ts
2
+ var FrameDropper = class {
3
+ intervalMs;
4
+ lastPassedAt = -Infinity;
5
+ constructor(maxFps) {
6
+ this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
7
+ }
8
+ shouldKeep() {
9
+ if (this.intervalMs === 0) return true;
10
+ const now = Date.now();
11
+ if (now - this.lastPassedAt >= this.intervalMs) {
12
+ this.lastPassedAt = now;
13
+ return true;
14
+ }
15
+ return false;
16
+ }
17
+ setMaxFps(maxFps) {
18
+ this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
19
+ }
20
+ };
21
+ //#endregion
22
+ //#region src/stream-broker/stream-broker/ffmpeg-args-common.ts
23
+ var AUDIO_ENCODER_BY_CODEC = {
24
+ opus: "libopus",
25
+ aac: "aac",
26
+ pcmu: "pcm_mulaw",
27
+ pcma: "pcm_alaw",
28
+ copy: "copy"
29
+ };
30
+ /**
31
+ * Build the audio-encode args `-c:a <enc> [-b:a Nk] [-ar N] [-ac N]`. Each knob
32
+ * is emitted only when provided, in this fixed order — matching what every
33
+ * broker site already emitted by hand.
34
+ */
35
+ function audioEncoderArgs(codec, opts = {}) {
36
+ const args = ["-c:a", AUDIO_ENCODER_BY_CODEC[codec]];
37
+ if (opts.bitrateKbps !== void 0) args.push("-b:a", `${opts.bitrateKbps}k`);
38
+ if (opts.sampleRateHz !== void 0) args.push("-ar", String(opts.sampleRateHz));
39
+ if (opts.channels !== void 0) args.push("-ac", String(opts.channels));
40
+ return args;
41
+ }
42
+ /** The `-hide_banner -loglevel <level>` preamble every broker ffmpeg site opens with. */
43
+ function logBannerArgs(level) {
44
+ return [
45
+ "-hide_banner",
46
+ "-loglevel",
47
+ level
48
+ ];
49
+ }
50
+ //#endregion
51
+ Object.defineProperty(exports, "FrameDropper", {
52
+ enumerable: true,
53
+ get: function() {
54
+ return FrameDropper;
55
+ }
56
+ });
57
+ Object.defineProperty(exports, "audioEncoderArgs", {
58
+ enumerable: true,
59
+ get: function() {
60
+ return audioEncoderArgs;
61
+ }
62
+ });
63
+ Object.defineProperty(exports, "logBannerArgs", {
64
+ enumerable: true,
65
+ get: function() {
66
+ return logBannerArgs;
67
+ }
68
+ });
@@ -0,0 +1,51 @@
1
+ //#region src/stream-broker/stream-broker/frame-dropper.ts
2
+ var FrameDropper = class {
3
+ intervalMs;
4
+ lastPassedAt = -Infinity;
5
+ constructor(maxFps) {
6
+ this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
7
+ }
8
+ shouldKeep() {
9
+ if (this.intervalMs === 0) return true;
10
+ const now = Date.now();
11
+ if (now - this.lastPassedAt >= this.intervalMs) {
12
+ this.lastPassedAt = now;
13
+ return true;
14
+ }
15
+ return false;
16
+ }
17
+ setMaxFps(maxFps) {
18
+ this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
19
+ }
20
+ };
21
+ //#endregion
22
+ //#region src/stream-broker/stream-broker/ffmpeg-args-common.ts
23
+ var AUDIO_ENCODER_BY_CODEC = {
24
+ opus: "libopus",
25
+ aac: "aac",
26
+ pcmu: "pcm_mulaw",
27
+ pcma: "pcm_alaw",
28
+ copy: "copy"
29
+ };
30
+ /**
31
+ * Build the audio-encode args `-c:a <enc> [-b:a Nk] [-ar N] [-ac N]`. Each knob
32
+ * is emitted only when provided, in this fixed order — matching what every
33
+ * broker site already emitted by hand.
34
+ */
35
+ function audioEncoderArgs(codec, opts = {}) {
36
+ const args = ["-c:a", AUDIO_ENCODER_BY_CODEC[codec]];
37
+ if (opts.bitrateKbps !== void 0) args.push("-b:a", `${opts.bitrateKbps}k`);
38
+ if (opts.sampleRateHz !== void 0) args.push("-ar", String(opts.sampleRateHz));
39
+ if (opts.channels !== void 0) args.push("-ac", String(opts.channels));
40
+ return args;
41
+ }
42
+ /** The `-hide_banner -loglevel <level>` preamble every broker ffmpeg site opens with. */
43
+ function logBannerArgs(level) {
44
+ return [
45
+ "-hide_banner",
46
+ "-loglevel",
47
+ level
48
+ ];
49
+ }
50
+ //#endregion
51
+ export { logBannerArgs as n, FrameDropper as r, audioEncoderArgs as t };
@@ -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-CRzS7bK1.js");
5
+ const require_dist = require("../dist-BgoBMCez.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 BaseAddon, J as hydrateSchema, U as DeviceType, k as motionDetectionCapability, w as evaluateZoneRules } from "../dist-CBcVKDyT.mjs";
1
+ import { B as BaseAddon, J as hydrateSchema, U as DeviceType, k as motionDetectionCapability, w as evaluateZoneRules } from "../dist-7Yx2dmuV.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-CRzS7bK1.js");
5
+ const require_dist = require("../dist-BgoBMCez.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 { A as nodePin, B as BaseAddon, M as pipelineRunnerCapability, S as defineCustomActions, W as EventCategory, X as makeSourceBrokerId, at as lazy, ct as object, nt as array, q as createEvent, rt as boolean, st as number, tt as _enum, ut as string, y as customAction, z as errMsg } from "../dist-CBcVKDyT.mjs";
1
+ import { A as nodePin, B as BaseAddon, M as pipelineRunnerCapability, S as defineCustomActions, W as EventCategory, X as makeSourceBrokerId, at as lazy, ct as object, nt as array, q as createEvent, rt as boolean, st as number, tt as _enum, ut as string, y as customAction, z as errMsg } from "../dist-7Yx2dmuV.mjs";
2
2
  import { FrameRingReaderCache } from "@camstack/shm-ring";
3
3
  //#region src/pipeline-runner/frame-queue.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BnQ_awK4.js");
2
- const require_dist = require("../dist-CRzS7bK1.js");
2
+ const require_dist = require("../dist-BgoBMCez.js");
3
3
  let node_fs = require("node:fs");
4
4
  let node_path = require("node:path");
5
5
  node_path = require_model_download_service_C_IHWnXx.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { $ as selectAssignedProfileSlots, B as BaseAddon, F as storageEvictableCapability, J as hydrateSchema, K as createDurableState, N as recordingCapability, O as migrateConfigToBands, U as DeviceType, W as EventCategory, d as RecordingConfigSchema, lt as record, ut as string, z as errMsg } from "../dist-CBcVKDyT.mjs";
1
+ import { $ as selectAssignedProfileSlots, B as BaseAddon, F as storageEvictableCapability, J as hydrateSchema, K as createDurableState, N as recordingCapability, O as migrateConfigToBands, U as DeviceType, W as EventCategory, d as RecordingConfigSchema, lt as record, ut as string, z as errMsg } from "../dist-7Yx2dmuV.mjs";
2
2
  import { t as createFileDataPlaneHandler } from "../model-download-service-C-IHWnXx-3Mmeob3l.mjs";
3
3
  import { promises } from "node:fs";
4
4
  import path from "node:path";
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.1.14",
21
+ version: "1.1.15",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_stream_broker_widgets",
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.1.14",
39
+ version: "1.1.15",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
@@ -3,7 +3,8 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_model_download_service_C_IHWnXx = require("../model-download-service-C-IHWnXx-BnQ_awK4.js");
6
- const require_dist = require("../dist-CRzS7bK1.js");
6
+ const require_dist = require("../dist-BgoBMCez.js");
7
+ const require_ffmpeg_args_common = require("../ffmpeg-args-common-CASoNt42.js");
7
8
  const require_codec_runtime = require("../codec-runtime-BOk-13PN.js");
8
9
  let node_fs = require("node:fs");
9
10
  node_fs = require_model_download_service_C_IHWnXx.__toESM(node_fs);
@@ -308,6 +309,31 @@ var DecoderSessionProxy = class {
308
309
  * broker supplies a `pullModeUrl` and the plane calls `openStream` once the
309
310
  * session exists.
310
311
  */
312
+ /**
313
+ * Collapse a hierarchical Moleculer nodeID (`hub/child-abc`) to its owning
314
+ * node (`hub`). Frame-plane co-location only cares about the physical node, not
315
+ * which forked child within it hosts the session.
316
+ */
317
+ function collapseNodeId(nodeId) {
318
+ const slash = nodeId.indexOf("/");
319
+ return slash >= 0 ? nodeId.slice(0, slash) : nodeId;
320
+ }
321
+ /**
322
+ * Decide whether a decoder session created on `decoderNodeId` is co-located
323
+ * with the broker whose local node is `brokerNodeId`.
324
+ *
325
+ * The broker's shm frame ring is NODE-LOCAL: a decoder session on any other
326
+ * node can never deliver frame handles to this broker's consumers, so a
327
+ * mis-placed session must be rejected. Both ids are collapsed (`hub/child`→
328
+ * `hub`) before comparison.
329
+ *
330
+ * A `null` `brokerNodeId` means the broker's own node is unknown — enforcement
331
+ * is skipped (legacy behavior, accept any placement).
332
+ */
333
+ function isDecoderNodeColocated(brokerNodeId, decoderNodeId) {
334
+ if (brokerNodeId === null) return true;
335
+ return collapseNodeId(brokerNodeId) === collapseNodeId(decoderNodeId);
336
+ }
311
337
  /** Per-subscription handle-queue capacity. A handle is tiny; 64 absorbs a
312
338
  * burst between two `pullFrameHandles` polls without unbounded growth. */
313
339
  var HANDLE_QUEUE_CAPACITY = 64;
@@ -324,6 +350,7 @@ var FrameHandlePlane = class {
324
350
  decoderApi;
325
351
  logger;
326
352
  resolveStreamInfo;
353
+ localNodeId;
327
354
  subscriptions = /* @__PURE__ */ new Map();
328
355
  sessions = /* @__PURE__ */ new Map();
329
356
  disposed = false;
@@ -339,6 +366,7 @@ var FrameHandlePlane = class {
339
366
  this.decoderApi = options.decoderApi;
340
367
  this.logger = options.logger;
341
368
  this.resolveStreamInfo = options.resolveStreamInfo;
369
+ this.localNodeId = options.localNodeId;
342
370
  }
343
371
  /** Number of active handle subscriptions — surfaced for diagnostics. */
344
372
  get subscriberCount() {
@@ -639,6 +667,22 @@ var FrameHandlePlane = class {
639
667
  ...info.numericDeviceId !== void 0 ? { deviceId: info.numericDeviceId } : {},
640
668
  tag: `${info.tag}:shm:${format}`
641
669
  });
670
+ if (!isDecoderNodeColocated(this.localNodeId, nodeId)) {
671
+ this.logger?.warn("frame-handle plane: decoder session landed on a non-local node — destroying (shm ring is node-local)", { meta: {
672
+ format,
673
+ requestedNode: this.localNodeId,
674
+ gotNode: nodeId,
675
+ sessionId
676
+ } });
677
+ await this.decoderApi.destroySession({ sessionId }).catch((err) => {
678
+ this.logger?.warn("frame-handle plane: failed to destroy mis-placed decoder session", { meta: {
679
+ format,
680
+ sessionId,
681
+ error: require_dist.errMsg(err)
682
+ } });
683
+ });
684
+ return false;
685
+ }
642
686
  const proxy = new DecoderSessionProxy(this.decoderApi, sessionId);
643
687
  session.proxy = proxy;
644
688
  session.nodeId = nodeId;
@@ -4083,6 +4127,13 @@ var StreamBroker = class StreamBroker {
4083
4127
  decoderApi;
4084
4128
  audioCodecApi;
4085
4129
  logger;
4130
+ /**
4131
+ * This broker's OWN local Moleculer node id, threaded from the manager
4132
+ * (`ctx.kernel.localNodeId`). Passed to the `FrameHandlePlane` so it can
4133
+ * reject decoder sessions that land on a different node (the shm frame ring
4134
+ * is node-local). `null` = unknown → co-location enforcement skipped.
4135
+ */
4136
+ localNodeId;
4086
4137
  startedAt = Date.now();
4087
4138
  nativeClient = null;
4088
4139
  rfc4571Reader = null;
@@ -4269,11 +4320,12 @@ var StreamBroker = class StreamBroker {
4269
4320
  static DEFAULT_PRE_BUFFER_SEC = 10;
4270
4321
  /** Maximum allowed pre-buffer duration in seconds */
4271
4322
  static MAX_PRE_BUFFER_SEC = 30;
4272
- constructor(deviceId, decoderApi, logger, audioCodecApi) {
4323
+ constructor(deviceId, decoderApi, logger, audioCodecApi, localNodeId) {
4273
4324
  this.deviceId = deviceId;
4274
4325
  this.decoderApi = decoderApi;
4275
4326
  this.audioCodecApi = audioCodecApi ?? null;
4276
4327
  this.logger = logger;
4328
+ this.localNodeId = localNodeId ?? null;
4277
4329
  this.pipeServer = new StreamPipeServer(logger?.child("pipe-server"));
4278
4330
  this.rtspRestreamer = new RtspRestreamer(deviceId);
4279
4331
  if (logger) this.rtspRestreamer.setLogger(logger.child("rtsp"));
@@ -5019,7 +5071,8 @@ var StreamBroker = class StreamBroker {
5019
5071
  this.frameHandlePlane = new FrameHandlePlane({
5020
5072
  decoderApi: this.decoderApi,
5021
5073
  logger: this.logger?.child("frame-handle-plane"),
5022
- resolveStreamInfo: () => this.resolveFrameHandleStreamInfo()
5074
+ resolveStreamInfo: () => this.resolveFrameHandleStreamInfo(),
5075
+ localNodeId: this.localNodeId
5023
5076
  });
5024
5077
  return this.frameHandlePlane;
5025
5078
  }
@@ -6585,35 +6638,6 @@ var RtspRestreamProviderImpl = class {
6585
6638
  }
6586
6639
  };
6587
6640
  //#endregion
6588
- //#region src/stream-broker/stream-broker/ffmpeg-args-common.ts
6589
- var AUDIO_ENCODER_BY_CODEC = {
6590
- opus: "libopus",
6591
- aac: "aac",
6592
- pcmu: "pcm_mulaw",
6593
- pcma: "pcm_alaw",
6594
- copy: "copy"
6595
- };
6596
- /**
6597
- * Build the audio-encode args `-c:a <enc> [-b:a Nk] [-ar N] [-ac N]`. Each knob
6598
- * is emitted only when provided, in this fixed order — matching what every
6599
- * broker site already emitted by hand.
6600
- */
6601
- function audioEncoderArgs(codec, opts = {}) {
6602
- const args = ["-c:a", AUDIO_ENCODER_BY_CODEC[codec]];
6603
- if (opts.bitrateKbps !== void 0) args.push("-b:a", `${opts.bitrateKbps}k`);
6604
- if (opts.sampleRateHz !== void 0) args.push("-ar", String(opts.sampleRateHz));
6605
- if (opts.channels !== void 0) args.push("-ac", String(opts.channels));
6606
- return args;
6607
- }
6608
- /** The `-hide_banner -loglevel <level>` preamble every broker ffmpeg site opens with. */
6609
- function logBannerArgs(level) {
6610
- return [
6611
- "-hide_banner",
6612
- "-loglevel",
6613
- level
6614
- ];
6615
- }
6616
- //#endregion
6617
6641
  //#region src/stream-broker/stream-broker/ffmpeg-invocation.ts
6618
6642
  /** The full set of hwaccel settings (for validation + option surfaces). */
6619
6643
  var FFMPEG_HW_ACCEL_SETTINGS = [
@@ -6673,23 +6697,23 @@ function pickVideoEncoder(target, encoders, hwAccel) {
6673
6697
  /** Audio encoder args for a transcode target (preset values over the shared low-level builder). */
6674
6698
  function pickAudioEncoderArgs(audio) {
6675
6699
  switch (audio) {
6676
- case "aac": return audioEncoderArgs("aac", {
6700
+ case "aac": return require_ffmpeg_args_common.audioEncoderArgs("aac", {
6677
6701
  bitrateKbps: 128,
6678
6702
  sampleRateHz: 48e3,
6679
6703
  channels: 2
6680
6704
  });
6681
- case "opus": return audioEncoderArgs("opus", {
6705
+ case "opus": return require_ffmpeg_args_common.audioEncoderArgs("opus", {
6682
6706
  bitrateKbps: 64,
6683
6707
  sampleRateHz: 48e3,
6684
6708
  channels: 2
6685
6709
  });
6686
- case "pcmu": return audioEncoderArgs("pcmu", {
6710
+ case "pcmu": return require_ffmpeg_args_common.audioEncoderArgs("pcmu", {
6687
6711
  sampleRateHz: 8e3,
6688
6712
  channels: 1
6689
6713
  });
6690
- case "copy": return audioEncoderArgs("copy");
6714
+ case "copy": return require_ffmpeg_args_common.audioEncoderArgs("copy");
6691
6715
  case "none": return ["-an"];
6692
- default: return audioEncoderArgs("aac", { bitrateKbps: 128 });
6716
+ default: return require_ffmpeg_args_common.audioEncoderArgs("aac", { bitrateKbps: 128 });
6693
6717
  }
6694
6718
  }
6695
6719
  /**
@@ -6754,7 +6778,7 @@ function buildFfmpegArgs$1(inv) {
6754
6778
  const threadArgs = inv.threadCount > 0 ? ["-threads", String(inv.threadCount)] : [];
6755
6779
  const audioArgs = inv.sink.kind === "stdout" && (inv.sink.container === "h264" || inv.sink.container === "hevc") ? ["-an"] : pickAudioEncoderArgs(inv.audio);
6756
6780
  return [
6757
- ...logBannerArgs("warning"),
6781
+ ...require_ffmpeg_args_common.logBannerArgs("warning"),
6758
6782
  ...decodeArgs,
6759
6783
  "-rtsp_transport",
6760
6784
  "tcp",
@@ -9643,7 +9667,7 @@ var StreamBrokerManager = class {
9643
9667
  camStreamId
9644
9668
  });
9645
9669
  const source = this.buildSourceFromCamStream(cam);
9646
- const broker = new StreamBroker(brokerId, this.buildDecoderCapApi(deviceId), brokerLogger, buildAudioCodecCapApi(this.api));
9670
+ const broker = new StreamBroker(brokerId, this.buildDecoderCapApi(deviceId), brokerLogger, buildAudioCodecCapApi(this.api), this.localNodeId);
9647
9671
  broker.setRestreamers(this.restreamers);
9648
9672
  this.applyPreBufferConfig(broker, deviceId, camStreamId, cam);
9649
9673
  if (this.deviceOverrides.get(deviceId)?.streamingDebug) broker.setStreamingDebug(true);
@@ -11555,7 +11579,7 @@ function planAudioSilencePadPackets(input) {
11555
11579
  * audio plane honours the profile literally.
11556
11580
  */
11557
11581
  function buildTranscodeFfmpegArgs(inputFormat, profile, decodeHwAccel, sourceUrl) {
11558
- const args = [...logBannerArgs("error")];
11582
+ const args = [...require_ffmpeg_args_common.logBannerArgs("error")];
11559
11583
  if (profile.inputArgs?.length) args.push(...profile.inputArgs);
11560
11584
  if (decodeHwAccel && decodeHwAccel !== "none") args.push("-hwaccel", decodeHwAccel);
11561
11585
  args.push("-fflags", "+discardcorrupt", "-rtsp_transport", "tcp", "-i", sourceUrl);
@@ -11577,7 +11601,7 @@ function buildTranscodeFfmpegArgs(inputFormat, profile, decodeHwAccel, sourceUrl
11577
11601
  if (profile.audio === "passthrough") args.push("-an");
11578
11602
  else {
11579
11603
  const a = profile.audio;
11580
- args.push(...audioEncoderArgs(a.codec, {
11604
+ args.push(...require_ffmpeg_args_common.audioEncoderArgs(a.codec, {
11581
11605
  bitrateKbps: a.bitrateKbps,
11582
11606
  sampleRateHz: a.sampleRateHz,
11583
11607
  channels: a.channels
@@ -16867,27 +16891,6 @@ var StreamBrokerAddon = class extends require_dist.BaseAddon {
16867
16891
  }
16868
16892
  };
16869
16893
  //#endregion
16870
- //#region src/stream-broker/stream-broker/frame-dropper.ts
16871
- var FrameDropper = class {
16872
- intervalMs;
16873
- lastPassedAt = -Infinity;
16874
- constructor(maxFps) {
16875
- this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
16876
- }
16877
- shouldKeep() {
16878
- if (this.intervalMs === 0) return true;
16879
- const now = Date.now();
16880
- if (now - this.lastPassedAt >= this.intervalMs) {
16881
- this.lastPassedAt = now;
16882
- return true;
16883
- }
16884
- return false;
16885
- }
16886
- setMaxFps(maxFps) {
16887
- this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
16888
- }
16889
- };
16890
- //#endregion
16891
16894
  //#region src/stream-broker/stream-broker/ffmpeg-decoder-session.ts
16892
16895
  /** Minimal no-op logger for default parameter */
16893
16896
  var noopLogger = {
@@ -16915,7 +16918,7 @@ function codecToInputFormat(codec) {
16915
16918
  function buildFfmpegArgs(config) {
16916
16919
  const inputFormat = codecToInputFormat(config.codec);
16917
16920
  const args = [
16918
- ...logBannerArgs("error"),
16921
+ ...require_ffmpeg_args_common.logBannerArgs("error"),
16919
16922
  "-fflags",
16920
16923
  "+nobuffer+flush_packets",
16921
16924
  "-flags",
@@ -16952,7 +16955,7 @@ var FfmpegDecoderSession = class {
16952
16955
  constructor(config, logger = noopLogger) {
16953
16956
  this.config = { ...config };
16954
16957
  this.logger = logger;
16955
- this.frameDropper = new FrameDropper(config.maxFps);
16958
+ this.frameDropper = new require_ffmpeg_args_common.FrameDropper(config.maxFps);
16956
16959
  this.spawnFfmpeg();
16957
16960
  }
16958
16961
  spawnFfmpeg() {