@camstack/addon-pipeline 1.2.217 → 1.2.218
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 +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/{default-detection-model-BwNEV8Wl.mjs → default-detection-model-AJyhoTLF.mjs} +1 -1
- package/dist/{default-detection-model-DzzuINe-.js → default-detection-model-Bf45EQ98.js} +1 -1
- package/dist/detection-pipeline/index.js +5 -5
- package/dist/detection-pipeline/index.mjs +4 -4
- package/dist/{dist-D7hxiBnC.js → dist-BbvtiBNc.js} +41 -4
- package/dist/{dist-DgeXZfwn.mjs → dist-Dl6GntEh.mjs} +41 -4
- package/dist/{lazy-sharp-BSkbiuz5.js → lazy-sharp-L9Lcr62v.js} +1 -1
- package/dist/motion-wasm/index.js +2 -2
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-C9GcBrwk.mjs → node-CEyw52D2.mjs} +1 -1
- package/dist/{node-DDhmPcOx.js → node-CbCVHEvJ.js} +1 -1
- package/dist/pipeline-runner/index.js +13 -6
- package/dist/pipeline-runner/index.mjs +12 -5
- package/dist/{process-memory-ENqmiiis.js → process-memory-DBxdiCSF.js} +1 -1
- package/dist/{process-memory-Dw3CGS3D.mjs → process-memory-Du00R6-e.mjs} +1 -1
- package/dist/recorder/index.js +92 -14
- package/dist/recorder/index.mjs +92 -14
- package/dist/{segment-demux-js-BGbKlotF.mjs → segment-demux-js-B278aBtB.mjs} +1 -1
- package/dist/{segment-demux-js-sLs8mbZQ.js → segment-demux-js-D7bjzY8M.js} +1 -1
- package/dist/session-decode/decode-worker-child.js +2 -2
- package/dist/session-decode/decode-worker-child.mjs +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BULotDCb.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-BnmbfnAd.mjs} +3 -3
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-_RQxF72h.mjs → hostInit-MIKQqs86.mjs} +3 -3
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +3 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/dist/{worker-protocol-SzmaLNnP.mjs → worker-protocol-BEbD5adq.mjs} +1 -1
- package/dist/{worker-protocol-DGql9R4g.js → worker-protocol-C4rh5uiS.js} +1 -1
- package/package.json +1 -1
- package/python/__pycache__/inference_pool.cpython-312.pyc +0 -0
- package/python/__pycache__/inference_pool.cpython-313.pyc +0 -0
- package/python/__pycache__/inference_pool.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_backpressure.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_backpressure.cpython-312.pyc +0 -0
- package/python/__pycache__/test_inference_pool_backpressure.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_coreml_cache.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_coreml_cache.cpython-312.pyc +0 -0
- package/python/__pycache__/test_inference_pool_coreml_cache.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_deadline.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_device_selection.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_device_selection.cpython-312.pyc +0 -0
- package/python/__pycache__/test_inference_pool_device_selection.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_layout.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_layout.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_memstats.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_memstats.cpython-312.pyc +0 -0
- package/python/__pycache__/test_inference_pool_memstats.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_ov_ppp.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_ov_ppp.cpython-312.pyc +0 -0
- package/python/__pycache__/test_inference_pool_ov_ppp.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_preprocess.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_preprocess.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_reconfigure.cpython-314.pyc +0 -0
- package/python/__pycache__/test_inference_pool_static_batch.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/__pycache__/test_inference_pool_static_batch.cpython-312.pyc +0 -0
- package/python/__pycache__/test_inference_pool_static_batch.cpython-314.pyc +0 -0
- package/python/__pycache__/yamnet_audio.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/__init__.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/__init__.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/__init__.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/_safety.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/arcface.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/clip.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/clip.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/clip.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/ctc.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/plate_slots.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/plate_slots.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/rfdetr.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/rfdetr.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/saliency.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/scrfd.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/softmax.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/ssd.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/ssd.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/ssd.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/test_clip.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_clip.cpython-313-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-313-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/test_ctc.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/test_plate_slots.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_rfdetr.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_rfdetr.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/test_saliency.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_saliency.cpython-313-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_saliency.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/test_softmax.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_softmax.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/test_yolo_nms.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/test_yolo_nms.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/test_yolo_nms.cpython-39.pyc +0 -0
- package/python/postprocessors/__pycache__/test_yolonas.cpython-312-pytest-9.1.1.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yamnet.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo.cpython-39.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-313.pyc +0 -0
- package/python/postprocessors/__pycache__/yolo_seg.cpython-314.pyc +0 -0
- package/python/postprocessors/__pycache__/yolonas.cpython-312.pyc +0 -0
- package/python/postprocessors/__pycache__/yolonas.cpython-314.pyc +0 -0
|
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_process_memory = require("../process-memory-
|
|
5
|
+
const require_dist = require("../dist-BbvtiBNc.js");
|
|
6
|
+
const require_process_memory = require("../process-memory-DBxdiCSF.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
node_fs = require_dist.__toESM(node_fs);
|
|
9
9
|
let node_path = require("node:path");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { Dt as resolvePoolMemoryPolicy, It as errMsg, Jt as hydrateSchema, M as audioAnalyzerCapability, S as PoolMemoryWatchdog, Ut as BaseAddon, j as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL } from "../dist-
|
|
3
|
-
import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-
|
|
2
|
+
import { Dt as resolvePoolMemoryPolicy, It as errMsg, Jt as hydrateSchema, M as audioAnalyzerCapability, S as PoolMemoryWatchdog, Ut as BaseAddon, j as audioAnalysisCapability, n as AUDIO_BACKEND_CHOICES, ot as mapAudioLabelToMacro, s as DEFAULT_AUDIO_ANALYZER_CONFIG, v as HF_BASE_URL } from "../dist-Dl6GntEh.mjs";
|
|
3
|
+
import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Du00R6-e.mjs";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import * as path$1 from "node:path";
|
|
6
6
|
import { downloadFile } from "@camstack/system/addon-utils";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { N as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-
|
|
1
|
+
import { N as audioKindId, a as COCO_80_LABELS, o as COCO_TO_MACRO, r as AUDIO_MACRO_LABELS, tt as hfModelUrl } from "./dist-Dl6GntEh.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
//#region src/detection-pipeline/pipeline/landmark-precision-gate.ts
|
|
4
4
|
/**
|
|
@@ -2,11 +2,11 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_node = require("../node-
|
|
7
|
-
const require_default_detection_model = require("../default-detection-model-
|
|
8
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
9
|
-
const require_process_memory = require("../process-memory-
|
|
5
|
+
const require_dist = require("../dist-BbvtiBNc.js");
|
|
6
|
+
const require_node = require("../node-CbCVHEvJ.js");
|
|
7
|
+
const require_default_detection_model = require("../default-detection-model-Bf45EQ98.js");
|
|
8
|
+
const require_lazy_sharp = require("../lazy-sharp-L9Lcr62v.js");
|
|
9
|
+
const require_process_memory = require("../process-memory-DBxdiCSF.js");
|
|
10
10
|
let node_os = require("node:os");
|
|
11
11
|
node_os = require_dist.__toESM(node_os);
|
|
12
12
|
let node_fs = require("node:fs");
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { n as __require } from "../chunk-DnnnRqeS.mjs";
|
|
2
|
-
import { $t as parseJsonUnknown, B as defaultDeviceFor$1, Dt as resolvePoolMemoryPolicy, G as detectionPipelineCapability, It as errMsg, J as enumerateInferenceDevices, Jt as hydrateSchema, Pt as supportedRuntimes$1, Qt as nodePin, S as PoolMemoryWatchdog, Ut as BaseAddon, X as evaluateZoneRules, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as EventCategory, ht as pickClusterStepModels, in as array, it as loadContributionCapability, k as YAMNET_TO_MACRO, kt as runtimeDevices$1, l as DEFAULT_CLUSTER_STEP_SETTINGS, m as DEVICE_BACKEND_TO_FORMAT, mn as union, nn as sleep, nt as inferModelProvider, pn as string, pt as overlayClusterStepSettings, qt as createEvent, t as APPLE_SA_TO_MACRO, un as object, wt as resolveClusterStepModelId, yt as pipelineExecutorCapability } from "../dist-
|
|
3
|
-
import { o as readProcessCost } from "../node-
|
|
4
|
-
import { a as ALL_PIPELINE_STEPS, c as getStep, d as landmarkPrecisionVerdict, l as getStepDefinition, n as resolveDefaultDetectionModel, o as ALL_STEPS, r as localFrameRegistry, s as getDefaultModelForFormat, u as resolveModelForFormat } from "../default-detection-model-
|
|
2
|
+
import { $t as parseJsonUnknown, B as defaultDeviceFor$1, Dt as resolvePoolMemoryPolicy, G as detectionPipelineCapability, It as errMsg, J as enumerateInferenceDevices, Jt as hydrateSchema, Pt as supportedRuntimes$1, Qt as nodePin, S as PoolMemoryWatchdog, Ut as BaseAddon, X as evaluateZoneRules, c as DEFAULT_CLUSTER_STEP_MODELS, gt as pickClusterStepSettings, hn as EventCategory, ht as pickClusterStepModels, in as array, it as loadContributionCapability, k as YAMNET_TO_MACRO, kt as runtimeDevices$1, l as DEFAULT_CLUSTER_STEP_SETTINGS, m as DEVICE_BACKEND_TO_FORMAT, mn as union, nn as sleep, nt as inferModelProvider, pn as string, pt as overlayClusterStepSettings, qt as createEvent, t as APPLE_SA_TO_MACRO, un as object, wt as resolveClusterStepModelId, yt as pipelineExecutorCapability } from "../dist-Dl6GntEh.mjs";
|
|
3
|
+
import { o as readProcessCost } from "../node-CEyw52D2.mjs";
|
|
4
|
+
import { a as ALL_PIPELINE_STEPS, c as getStep, d as landmarkPrecisionVerdict, l as getStepDefinition, n as resolveDefaultDetectionModel, o as ALL_STEPS, r as localFrameRegistry, s as getDefaultModelForFormat, u as resolveModelForFormat } from "../default-detection-model-AJyhoTLF.mjs";
|
|
5
5
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
6
|
-
import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-
|
|
6
|
+
import { n as pickNodePlatformArch, t as readProcessMemory } from "../process-memory-Du00R6-e.mjs";
|
|
7
7
|
import * as os from "node:os";
|
|
8
8
|
import * as fs from "node:fs";
|
|
9
9
|
import * as path$1 from "node:path";
|
|
@@ -22284,7 +22284,17 @@ var EventDensityBucketSchema = object({
|
|
|
22284
22284
|
bucketStart: number(),
|
|
22285
22285
|
motion: number().int(),
|
|
22286
22286
|
object: number().int(),
|
|
22287
|
-
audio: number().int()
|
|
22287
|
+
audio: number().int(),
|
|
22288
|
+
/**
|
|
22289
|
+
* Energy-weighted mean dBFS of the audio events in this bucket — the LEVEL,
|
|
22290
|
+
* as opposed to `audio`, which is their COUNT (D431).
|
|
22291
|
+
*
|
|
22292
|
+
* ABSENT when the bucket holds no audio event. Absence means "nothing was
|
|
22293
|
+
* measured", which is not the same claim as silence, and a lane that cannot
|
|
22294
|
+
* tell them apart paints a quiet hour at full scale — which is exactly what
|
|
22295
|
+
* the count-on-a-level-meter did.
|
|
22296
|
+
*/
|
|
22297
|
+
audioDbfs: number().optional()
|
|
22288
22298
|
});
|
|
22289
22299
|
/**
|
|
22290
22300
|
* One camera's row in a `getEventDensityBatch` answer.
|
|
@@ -30816,7 +30826,23 @@ var RecordingRangeSchema = object({
|
|
|
30816
30826
|
});
|
|
30817
30827
|
var RecordingAvailabilitySchema = object({
|
|
30818
30828
|
deviceId: number(),
|
|
30819
|
-
ranges: array(RecordingRangeSchema)
|
|
30829
|
+
ranges: array(RecordingRangeSchema),
|
|
30830
|
+
/**
|
|
30831
|
+
* Every profile this camera has footage in — not only the one `ranges`
|
|
30832
|
+
* describes (D433).
|
|
30833
|
+
*
|
|
30834
|
+
* `ranges` answers for ONE profile by design: the timeline is a single bar,
|
|
30835
|
+
* and enumerating all of them triples the directory reads for a bar that
|
|
30836
|
+
* would look identical. But the answer used to say nothing about that, so a
|
|
30837
|
+
* caller asking "what can I export?" read the single preferred profile as
|
|
30838
|
+
* the only one that exists — on this deployment every camera records `high`
|
|
30839
|
+
* AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
|
|
30840
|
+
* UI could not see it.
|
|
30841
|
+
*
|
|
30842
|
+
* Cheap: it is the same shallow directory read the profile CHOICE already
|
|
30843
|
+
* makes. Ask for a specific profile's ranges with the `profile` input.
|
|
30844
|
+
*/
|
|
30845
|
+
profilesWithFootage: array(string())
|
|
30820
30846
|
});
|
|
30821
30847
|
var RecordingDaysSchema = object({
|
|
30822
30848
|
deviceId: number(),
|
|
@@ -30842,7 +30868,11 @@ var RecordingDaysSchema = object({
|
|
|
30842
30868
|
var RecordingAvailabilityForDeviceSchema = object({
|
|
30843
30869
|
deviceId: number(),
|
|
30844
30870
|
read: _enum(["read", "unreadable"]),
|
|
30845
|
-
ranges: array(RecordingRangeSchema).readonly()
|
|
30871
|
+
ranges: array(RecordingRangeSchema).readonly(),
|
|
30872
|
+
/** Same field, same meaning, as the singular answer (D433). A row that
|
|
30873
|
+
* dropped it would tell a grid caller the archive holds one profile.
|
|
30874
|
+
* Empty on an `'unreadable'` row: nobody looked. */
|
|
30875
|
+
profilesWithFootage: array(string()).readonly()
|
|
30846
30876
|
});
|
|
30847
30877
|
/**
|
|
30848
30878
|
* One camera's row in a `getDaysWithRecordingsBatch` answer. Same rule as
|
|
@@ -31142,7 +31172,14 @@ var recordingCapability = {
|
|
|
31142
31172
|
getAvailability: method(object({
|
|
31143
31173
|
deviceId: number(),
|
|
31144
31174
|
fromMs: number(),
|
|
31145
|
-
toMs: number()
|
|
31175
|
+
toMs: number(),
|
|
31176
|
+
/**
|
|
31177
|
+
* Answer for THIS profile instead of the preferred one (D433). Absent
|
|
31178
|
+
* keeps the timeline's behaviour — one bar, one profile, one set of
|
|
31179
|
+
* reads. `profilesWithFootage` on the answer says what may be asked
|
|
31180
|
+
* for.
|
|
31181
|
+
*/
|
|
31182
|
+
profile: string().optional()
|
|
31146
31183
|
}), RecordingAvailabilitySchema, {
|
|
31147
31184
|
kind: "query",
|
|
31148
31185
|
auth: "protected"
|
|
@@ -22261,7 +22261,17 @@ var EventDensityBucketSchema = object({
|
|
|
22261
22261
|
bucketStart: number(),
|
|
22262
22262
|
motion: number().int(),
|
|
22263
22263
|
object: number().int(),
|
|
22264
|
-
audio: number().int()
|
|
22264
|
+
audio: number().int(),
|
|
22265
|
+
/**
|
|
22266
|
+
* Energy-weighted mean dBFS of the audio events in this bucket — the LEVEL,
|
|
22267
|
+
* as opposed to `audio`, which is their COUNT (D431).
|
|
22268
|
+
*
|
|
22269
|
+
* ABSENT when the bucket holds no audio event. Absence means "nothing was
|
|
22270
|
+
* measured", which is not the same claim as silence, and a lane that cannot
|
|
22271
|
+
* tell them apart paints a quiet hour at full scale — which is exactly what
|
|
22272
|
+
* the count-on-a-level-meter did.
|
|
22273
|
+
*/
|
|
22274
|
+
audioDbfs: number().optional()
|
|
22265
22275
|
});
|
|
22266
22276
|
/**
|
|
22267
22277
|
* One camera's row in a `getEventDensityBatch` answer.
|
|
@@ -30793,7 +30803,23 @@ var RecordingRangeSchema = object({
|
|
|
30793
30803
|
});
|
|
30794
30804
|
var RecordingAvailabilitySchema = object({
|
|
30795
30805
|
deviceId: number(),
|
|
30796
|
-
ranges: array(RecordingRangeSchema)
|
|
30806
|
+
ranges: array(RecordingRangeSchema),
|
|
30807
|
+
/**
|
|
30808
|
+
* Every profile this camera has footage in — not only the one `ranges`
|
|
30809
|
+
* describes (D433).
|
|
30810
|
+
*
|
|
30811
|
+
* `ranges` answers for ONE profile by design: the timeline is a single bar,
|
|
30812
|
+
* and enumerating all of them triples the directory reads for a bar that
|
|
30813
|
+
* would look identical. But the answer used to say nothing about that, so a
|
|
30814
|
+
* caller asking "what can I export?" read the single preferred profile as
|
|
30815
|
+
* the only one that exists — on this deployment every camera records `high`
|
|
30816
|
+
* AND `low`, the low tree holding 14 GB for camera 615 alone, and the export
|
|
30817
|
+
* UI could not see it.
|
|
30818
|
+
*
|
|
30819
|
+
* Cheap: it is the same shallow directory read the profile CHOICE already
|
|
30820
|
+
* makes. Ask for a specific profile's ranges with the `profile` input.
|
|
30821
|
+
*/
|
|
30822
|
+
profilesWithFootage: array(string())
|
|
30797
30823
|
});
|
|
30798
30824
|
var RecordingDaysSchema = object({
|
|
30799
30825
|
deviceId: number(),
|
|
@@ -30819,7 +30845,11 @@ var RecordingDaysSchema = object({
|
|
|
30819
30845
|
var RecordingAvailabilityForDeviceSchema = object({
|
|
30820
30846
|
deviceId: number(),
|
|
30821
30847
|
read: _enum(["read", "unreadable"]),
|
|
30822
|
-
ranges: array(RecordingRangeSchema).readonly()
|
|
30848
|
+
ranges: array(RecordingRangeSchema).readonly(),
|
|
30849
|
+
/** Same field, same meaning, as the singular answer (D433). A row that
|
|
30850
|
+
* dropped it would tell a grid caller the archive holds one profile.
|
|
30851
|
+
* Empty on an `'unreadable'` row: nobody looked. */
|
|
30852
|
+
profilesWithFootage: array(string()).readonly()
|
|
30823
30853
|
});
|
|
30824
30854
|
/**
|
|
30825
30855
|
* One camera's row in a `getDaysWithRecordingsBatch` answer. Same rule as
|
|
@@ -31119,7 +31149,14 @@ var recordingCapability = {
|
|
|
31119
31149
|
getAvailability: method(object({
|
|
31120
31150
|
deviceId: number(),
|
|
31121
31151
|
fromMs: number(),
|
|
31122
|
-
toMs: number()
|
|
31152
|
+
toMs: number(),
|
|
31153
|
+
/**
|
|
31154
|
+
* Answer for THIS profile instead of the preferred one (D433). Absent
|
|
31155
|
+
* keeps the timeline's behaviour — one bar, one profile, one set of
|
|
31156
|
+
* reads. `profilesWithFootage` on the answer says what may be asked
|
|
31157
|
+
* for.
|
|
31158
|
+
*/
|
|
31159
|
+
profile: string().optional()
|
|
31123
31160
|
}), RecordingAvailabilitySchema, {
|
|
31124
31161
|
kind: "query",
|
|
31125
31162
|
auth: "protected"
|
|
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
5
|
+
const require_dist = require("../dist-BbvtiBNc.js");
|
|
6
|
+
const require_lazy_sharp = require("../lazy-sharp-L9Lcr62v.js");
|
|
7
7
|
let node_fs = require("node:fs");
|
|
8
8
|
let node_path = require("node:path");
|
|
9
9
|
//#region src/motion-wasm/region-grouping.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Jt as hydrateSchema, Kt as DeviceType, Ut as BaseAddon, X as evaluateZoneRules, ft as motionDetectionCapability } from "../dist-
|
|
1
|
+
import { Jt as hydrateSchema, Kt as DeviceType, Ut as BaseAddon, X as evaluateZoneRules, ft as motionDetectionCapability } from "../dist-Dl6GntEh.mjs";
|
|
2
2
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { It as errMsg, Rt as Fmp4BoxSplitter, Vt as isSoftwareDecode, zt as buildFfmpegArgs } from "./dist-
|
|
1
|
+
import { It as errMsg, Rt as Fmp4BoxSplitter, Vt as isSoftwareDecode, zt as buildFfmpegArgs } from "./dist-Dl6GntEh.mjs";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
3
|
import { realpathSync } from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -2,12 +2,12 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_node = require("../node-
|
|
7
|
-
const require_default_detection_model = require("../default-detection-model-
|
|
8
|
-
const require_worker_protocol = require("../worker-protocol-
|
|
5
|
+
const require_dist = require("../dist-BbvtiBNc.js");
|
|
6
|
+
const require_node = require("../node-CbCVHEvJ.js");
|
|
7
|
+
const require_default_detection_model = require("../default-detection-model-Bf45EQ98.js");
|
|
8
|
+
const require_worker_protocol = require("../worker-protocol-C4rh5uiS.js");
|
|
9
9
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
10
|
-
const require_lazy_sharp = require("../lazy-sharp-
|
|
10
|
+
const require_lazy_sharp = require("../lazy-sharp-L9Lcr62v.js");
|
|
11
11
|
const require_restream_intent = require("../restream-intent-B1Difcnq.js");
|
|
12
12
|
const require_remote_restream = require("../remote-restream-CO36Sr30.js");
|
|
13
13
|
let node_os = require("node:os");
|
|
@@ -9868,7 +9868,13 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9868
9868
|
recipe,
|
|
9869
9869
|
ms: Date.now() - started,
|
|
9870
9870
|
now,
|
|
9871
|
-
classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`)
|
|
9871
|
+
classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`),
|
|
9872
|
+
boxes: fused.slice(result.detections.length).map((d) => ({
|
|
9873
|
+
x: Math.round(d.bbox.x),
|
|
9874
|
+
y: Math.round(d.bbox.y),
|
|
9875
|
+
w: Math.round(d.bbox.width),
|
|
9876
|
+
h: Math.round(d.bbox.height)
|
|
9877
|
+
}))
|
|
9872
9878
|
});
|
|
9873
9879
|
return added > 0 ? {
|
|
9874
9880
|
...result,
|
|
@@ -9958,6 +9964,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends require_dist.BaseAdd
|
|
|
9958
9964
|
crops: sample.crops,
|
|
9959
9965
|
recovered: sample.recovered,
|
|
9960
9966
|
classes: sample.classes,
|
|
9967
|
+
boxes: sample.boxes,
|
|
9961
9968
|
ms: sample.ms
|
|
9962
9969
|
}
|
|
9963
9970
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { $ as failureContributionCapability, It as errMsg, Qt as nodePin, R as customAction, U as deriveDetailCropRect, Ut as BaseAddon, V as defineCustomActions, _ as FailureCounters, _t as pickDetailCropConvention, an as boolean, bt as pipelineRunnerCapability, cn as literal, hn as EventCategory, in as array, it as loadContributionCapability, ln as number, m as DEVICE_BACKEND_TO_FORMAT, p as DEFAULT_NATIVE_LEASE_SETTINGS, pn as string, qt as createEvent, rn as _enum, sn as lazy, u as DEFAULT_DETAIL_CROP_CONVENTION, un as object, vt as pickNativeLeaseOverride } from "../dist-
|
|
2
|
-
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-
|
|
3
|
-
import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-
|
|
4
|
-
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-
|
|
1
|
+
import { $ as failureContributionCapability, It as errMsg, Qt as nodePin, R as customAction, U as deriveDetailCropRect, Ut as BaseAddon, V as defineCustomActions, _ as FailureCounters, _t as pickDetailCropConvention, an as boolean, bt as pipelineRunnerCapability, cn as literal, hn as EventCategory, in as array, it as loadContributionCapability, ln as number, m as DEVICE_BACKEND_TO_FORMAT, p as DEFAULT_NATIVE_LEASE_SETTINGS, pn as string, qt as createEvent, rn as _enum, sn as lazy, u as DEFAULT_DETAIL_CROP_CONVENTION, un as object, vt as pickNativeLeaseOverride } from "../dist-Dl6GntEh.mjs";
|
|
2
|
+
import { i as NO_COST_CLAIM, t as ChildCostRegistry } from "../node-CEyw52D2.mjs";
|
|
3
|
+
import { i as resolveFrameViewGeometry, l as getStepDefinition, r as localFrameRegistry } from "../default-detection-model-AJyhoTLF.mjs";
|
|
4
|
+
import { a as nativeLeaseSettingEnv, t as isWorkerReply } from "../worker-protocol-BEbD5adq.mjs";
|
|
5
5
|
import { t as resolveHubHostname } from "../hub-hostname-cCknRYKj.mjs";
|
|
6
6
|
import { t as getSharp } from "../lazy-sharp-DXsqwpph.mjs";
|
|
7
7
|
import { a as preRollRequestOf, o as withDetectionIntent, t as DETECTION_PRE_ROLL_REQUEST_MS } from "../restream-intent-DWe2kInY.mjs";
|
|
@@ -9861,7 +9861,13 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
9861
9861
|
recipe,
|
|
9862
9862
|
ms: Date.now() - started,
|
|
9863
9863
|
now,
|
|
9864
|
-
classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`)
|
|
9864
|
+
classes: fused.slice(result.detections.length).map((d) => `${d.macroClass}:${d.score.toFixed(3)}`),
|
|
9865
|
+
boxes: fused.slice(result.detections.length).map((d) => ({
|
|
9866
|
+
x: Math.round(d.bbox.x),
|
|
9867
|
+
y: Math.round(d.bbox.y),
|
|
9868
|
+
w: Math.round(d.bbox.width),
|
|
9869
|
+
h: Math.round(d.bbox.height)
|
|
9870
|
+
}))
|
|
9865
9871
|
});
|
|
9866
9872
|
return added > 0 ? {
|
|
9867
9873
|
...result,
|
|
@@ -9951,6 +9957,7 @@ var PipelineRunnerAddon = class PipelineRunnerAddon extends BaseAddon {
|
|
|
9951
9957
|
crops: sample.crops,
|
|
9952
9958
|
recovered: sample.recovered,
|
|
9953
9959
|
classes: sample.classes,
|
|
9960
|
+
boxes: sample.boxes,
|
|
9954
9961
|
ms: sample.ms
|
|
9955
9962
|
}
|
|
9956
9963
|
});
|
package/dist/recorder/index.js
CHANGED
|
@@ -2,8 +2,8 @@ Object.defineProperties(exports, {
|
|
|
2
2
|
__esModule: { value: true },
|
|
3
3
|
[Symbol.toStringTag]: { value: "Module" }
|
|
4
4
|
});
|
|
5
|
-
const require_dist = require("../dist-
|
|
6
|
-
const require_node = require("../node-
|
|
5
|
+
const require_dist = require("../dist-BbvtiBNc.js");
|
|
6
|
+
const require_node = require("../node-CbCVHEvJ.js");
|
|
7
7
|
const require_hub_hostname = require("../hub-hostname-DAJXlOgV.js");
|
|
8
8
|
const require_restream_intent = require("../restream-intent-B1Difcnq.js");
|
|
9
9
|
const require_retire_root_keys = require("../retire-root-keys-Csb8z2f3.js");
|
|
@@ -3817,6 +3817,40 @@ async function segmentsOfHour(root, deviceId, profile, hourStartMs) {
|
|
|
3817
3817
|
* the directory route serve the profile the client asked for when it exists,
|
|
3818
3818
|
* and fall back to the availability pick when it does not.
|
|
3819
3819
|
*/
|
|
3820
|
+
/**
|
|
3821
|
+
* EVERY profile this camera holds footage in, across every root.
|
|
3822
|
+
*
|
|
3823
|
+
* {@link availabilityProfile} deliberately returns ONE — the timeline is a
|
|
3824
|
+
* single bar. That is right for the bar and wrong for the ANSWER: on
|
|
3825
|
+
* 2026-09-10 `getAvailability` reported twenty `high` ranges for camera 615
|
|
3826
|
+
* and the conclusion drawn was that this deployment records no `low` at all,
|
|
3827
|
+
* while `/media-fast/recordingsLow/615/low/` held 14 GB on a different
|
|
3828
|
+
* location (D433).
|
|
3829
|
+
*
|
|
3830
|
+
* Unions across roots for exactly that reason: `high` and `low` do not share a
|
|
3831
|
+
* location here, so a per-root answer sees one of them.
|
|
3832
|
+
*
|
|
3833
|
+
* Non-emptiness, not existence — the same rule {@link availabilityProfile}
|
|
3834
|
+
* keeps, so a directory left behind by a config change is not offered. And
|
|
3835
|
+
* only {@link KNOWN_PROFILES}: the camera dir also hosts `events/` and the
|
|
3836
|
+
* retired `strips/` trees, which a walker that trusts readdir would present as
|
|
3837
|
+
* playable.
|
|
3838
|
+
*
|
|
3839
|
+
* `list` is injectable for the test; production passes the module's own
|
|
3840
|
+
* directory read.
|
|
3841
|
+
*/
|
|
3842
|
+
async function profilesWithFootage(roots, deviceId, list = listDir) {
|
|
3843
|
+
const found = /* @__PURE__ */ new Set();
|
|
3844
|
+
for (const root of roots) {
|
|
3845
|
+
const entries = await list(node_path.default.join(root, String(deviceId)));
|
|
3846
|
+
for (const entry of entries) {
|
|
3847
|
+
if (!KNOWN_PROFILES$1.has(entry)) continue;
|
|
3848
|
+
if (found.has(entry)) continue;
|
|
3849
|
+
if ((await list(node_path.default.join(root, String(deviceId), entry))).length > 0) found.add(entry);
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
return [...found].sort();
|
|
3853
|
+
}
|
|
3820
3854
|
async function profileHasFootage(root, deviceId, profile) {
|
|
3821
3855
|
return (await listDir(node_path.default.join(root, String(deviceId), profile))).length > 0;
|
|
3822
3856
|
}
|
|
@@ -3938,6 +3972,8 @@ var CalendarIndex = class {
|
|
|
3938
3972
|
segsReadAt = /* @__PURE__ */ new Map();
|
|
3939
3973
|
/** The profile availability reads from, resolved once per device. */
|
|
3940
3974
|
profileFor = /* @__PURE__ */ new Map();
|
|
3975
|
+
profilesFor = /* @__PURE__ */ new Map();
|
|
3976
|
+
profilesInFlight = /* @__PURE__ */ new Map();
|
|
3941
3977
|
/** `deviceId:profile` → whether the device records that profile, resolved
|
|
3942
3978
|
* once. Same stability trade as {@link profileFor}: a config change that
|
|
3943
3979
|
* adds a profile mid-session is picked up on restart, not on a timer. */
|
|
@@ -4220,6 +4256,31 @@ var CalendarIndex = class {
|
|
|
4220
4256
|
* reads at a time and they ALL ask for the profile before the first answer
|
|
4221
4257
|
* lands, so a cache alone let the pick run eight times. Parallelism found it.
|
|
4222
4258
|
*/
|
|
4259
|
+
/**
|
|
4260
|
+
* Every profile this camera holds footage in, across every root — cached
|
|
4261
|
+
* like the pick, because it is the same shallow read (D433).
|
|
4262
|
+
*
|
|
4263
|
+
* {@link availabilityProfileFor} answers with ONE; this says what the one
|
|
4264
|
+
* was chosen FROM, so a caller cannot mistake the timeline's single bar for
|
|
4265
|
+
* the whole archive.
|
|
4266
|
+
*/
|
|
4267
|
+
async profilesWithFootageFor(deviceId) {
|
|
4268
|
+
const cached = this.profilesFor.get(deviceId);
|
|
4269
|
+
if (cached !== void 0) return cached;
|
|
4270
|
+
const running = this.profilesInFlight.get(deviceId);
|
|
4271
|
+
if (running) return running;
|
|
4272
|
+
const resolve = (async () => {
|
|
4273
|
+
const found = await profilesWithFootage(this.deps.roots(), deviceId);
|
|
4274
|
+
this.profilesFor.set(deviceId, found);
|
|
4275
|
+
return found;
|
|
4276
|
+
})();
|
|
4277
|
+
this.profilesInFlight.set(deviceId, resolve);
|
|
4278
|
+
try {
|
|
4279
|
+
return await resolve;
|
|
4280
|
+
} finally {
|
|
4281
|
+
if (this.profilesInFlight.get(deviceId) === resolve) this.profilesInFlight.delete(deviceId);
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4223
4284
|
async availabilityProfileFor(deviceId) {
|
|
4224
4285
|
const cached = this.profileFor.get(deviceId);
|
|
4225
4286
|
if (cached !== void 0) return cached;
|
|
@@ -5864,6 +5925,8 @@ var TIME_RE = /time=(\d+):(\d+):(\d+(?:\.\d+)?)/;
|
|
|
5864
5925
|
* whatever ffmpeg build is installed.
|
|
5865
5926
|
*/
|
|
5866
5927
|
var EXPORT_MIN_PLAUSIBLE_BYTES = 1024;
|
|
5928
|
+
/** ffmpeg's own announcement of that pass — the only signal it gives. */
|
|
5929
|
+
var FASTSTART_RE = /Starting second pass: moving the moov atom/i;
|
|
5867
5930
|
/** Expected OUTPUT duration (seconds) for progress scaling. */
|
|
5868
5931
|
function expectedOutSeconds(rec) {
|
|
5869
5932
|
const rangeSec = Math.max(.001, (rec.toMs - rec.fromMs) / 1e3);
|
|
@@ -6173,6 +6236,7 @@ var ExportEngine = class {
|
|
|
6173
6236
|
args
|
|
6174
6237
|
} });
|
|
6175
6238
|
const stallMs = this.deps.stallMs ?? 9e4;
|
|
6239
|
+
const faststartStallMs = this.deps.faststartStallMs ?? 9e5;
|
|
6176
6240
|
return new Promise((resolve) => {
|
|
6177
6241
|
const proc = this.deps.spawn(this.deps.ffmpegPath ?? "ffmpeg", args);
|
|
6178
6242
|
this.active.set(id, proc);
|
|
@@ -6184,14 +6248,16 @@ var ExportEngine = class {
|
|
|
6184
6248
|
stallTimer = null;
|
|
6185
6249
|
}
|
|
6186
6250
|
};
|
|
6251
|
+
let budgetMs = stallMs;
|
|
6187
6252
|
const armStall = () => {
|
|
6188
6253
|
clearStall();
|
|
6254
|
+
const armedFor = budgetMs;
|
|
6189
6255
|
stallTimer = setTimeout(() => {
|
|
6190
|
-
stderrTail.push(`ffmpeg stalled: no progress for ${
|
|
6256
|
+
stderrTail.push(`ffmpeg stalled: no progress for ${armedFor}ms`);
|
|
6191
6257
|
try {
|
|
6192
6258
|
proc.kill("SIGKILL");
|
|
6193
6259
|
} catch {}
|
|
6194
|
-
},
|
|
6260
|
+
}, armedFor);
|
|
6195
6261
|
};
|
|
6196
6262
|
armStall();
|
|
6197
6263
|
proc.stderr?.on("data", (chunk) => {
|
|
@@ -6202,6 +6268,10 @@ var ExportEngine = class {
|
|
|
6202
6268
|
stderrTail.push(trimmed);
|
|
6203
6269
|
if (stderrTail.length > STDERR_TAIL_LINES$1) stderrTail.shift();
|
|
6204
6270
|
}
|
|
6271
|
+
if (FASTSTART_RE.test(line)) {
|
|
6272
|
+
budgetMs = faststartStallMs;
|
|
6273
|
+
armStall();
|
|
6274
|
+
}
|
|
6205
6275
|
const m = TIME_RE.exec(line);
|
|
6206
6276
|
if (m) {
|
|
6207
6277
|
armStall();
|
|
@@ -7379,13 +7449,15 @@ function buildRecordingProvider(deps) {
|
|
|
7379
7449
|
* and by the batch alike — the batch collapses the TRANSPORT, and sharing the
|
|
7380
7450
|
* function is what makes that literally true instead of aspirational.
|
|
7381
7451
|
*/
|
|
7382
|
-
const availabilityFor = async (deviceId, fromMs, toMs) => {
|
|
7452
|
+
const availabilityFor = async (deviceId, fromMs, toMs, requestedProfile) => {
|
|
7383
7453
|
const calendar = deps.calendar;
|
|
7384
7454
|
if (calendar) {
|
|
7385
|
-
const
|
|
7455
|
+
const profilesWithFootage = await calendar.profilesWithFootageFor(deviceId);
|
|
7456
|
+
const profile = await calendar.servedProfileFor(deviceId, requestedProfile);
|
|
7386
7457
|
if (profile === null) return {
|
|
7387
7458
|
deviceId,
|
|
7388
|
-
ranges: []
|
|
7459
|
+
ranges: [],
|
|
7460
|
+
profilesWithFootage: [...profilesWithFootage]
|
|
7389
7461
|
};
|
|
7390
7462
|
const ranges = [];
|
|
7391
7463
|
for (const r of await calendar.rangesIn(deviceId, profile, fromMs, toMs)) ranges.push({
|
|
@@ -7395,16 +7467,20 @@ function buildRecordingProvider(deps) {
|
|
|
7395
7467
|
});
|
|
7396
7468
|
return {
|
|
7397
7469
|
deviceId,
|
|
7398
|
-
ranges
|
|
7470
|
+
ranges,
|
|
7471
|
+
profilesWithFootage: [...profilesWithFootage]
|
|
7399
7472
|
};
|
|
7400
7473
|
}
|
|
7474
|
+
const profiles = new Set(deps.index.segments(deviceId).map((s) => s.profile));
|
|
7475
|
+
const asked = requestedProfile !== void 0 && profiles.has(requestedProfile);
|
|
7401
7476
|
return {
|
|
7402
7477
|
deviceId,
|
|
7403
|
-
ranges: [...
|
|
7478
|
+
ranges: [...profiles].filter((p) => !asked || p === requestedProfile).flatMap((profile) => deps.index.ranges(deviceId, profile, fromMs, toMs, RANGE_MERGE_GAP_MS).map((r) => ({
|
|
7404
7479
|
profile,
|
|
7405
7480
|
startMs: r.startMs,
|
|
7406
7481
|
endMs: r.endMs
|
|
7407
|
-
})))
|
|
7482
|
+
}))),
|
|
7483
|
+
profilesWithFootage: [...profiles].sort()
|
|
7408
7484
|
};
|
|
7409
7485
|
};
|
|
7410
7486
|
/** The per-camera day read. Same rule as {@link availabilityFor}: one body. */
|
|
@@ -7434,7 +7510,7 @@ function buildRecordingProvider(deps) {
|
|
|
7434
7510
|
getStatus: async ({ deviceId }) => {
|
|
7435
7511
|
return statusFor(deps, deviceId, await loadDeviceConfig(deps.configStore, deviceId));
|
|
7436
7512
|
},
|
|
7437
|
-
getAvailability: ({ deviceId, fromMs, toMs }) => availabilityFor(deviceId, fromMs, toMs),
|
|
7513
|
+
getAvailability: ({ deviceId, fromMs, toMs, profile }) => availabilityFor(deviceId, fromMs, toMs, profile),
|
|
7438
7514
|
/**
|
|
7439
7515
|
* `getAvailability` for a SET of cameras. Same body per camera, run
|
|
7440
7516
|
* concurrently; only the transport collapses.
|
|
@@ -7448,11 +7524,12 @@ function buildRecordingProvider(deps) {
|
|
|
7448
7524
|
refuseOverCap("getAvailabilityBatch", deviceIds.length);
|
|
7449
7525
|
return Promise.all(deviceIds.map(async (deviceId) => {
|
|
7450
7526
|
try {
|
|
7451
|
-
const { ranges } = await availabilityFor(deviceId, fromMs, toMs);
|
|
7527
|
+
const { ranges, profilesWithFootage } = await availabilityFor(deviceId, fromMs, toMs);
|
|
7452
7528
|
return {
|
|
7453
7529
|
deviceId,
|
|
7454
7530
|
read: "read",
|
|
7455
|
-
ranges
|
|
7531
|
+
ranges,
|
|
7532
|
+
profilesWithFootage
|
|
7456
7533
|
};
|
|
7457
7534
|
} catch (err) {
|
|
7458
7535
|
deps.logger.warn("recording availability could not be read", {
|
|
@@ -7466,7 +7543,8 @@ function buildRecordingProvider(deps) {
|
|
|
7466
7543
|
return {
|
|
7467
7544
|
deviceId,
|
|
7468
7545
|
read: "unreadable",
|
|
7469
|
-
ranges: []
|
|
7546
|
+
ranges: [],
|
|
7547
|
+
profilesWithFootage: []
|
|
7470
7548
|
};
|
|
7471
7549
|
}
|
|
7472
7550
|
}));
|