@camstack/addon-pipeline 1.1.34 → 1.1.35
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/assets/reference-audio/dog-bark.wav +0 -0
- package/assets/reference-audio/meow.wav +0 -0
- package/assets/reference-audio/silence.wav +0 -0
- package/assets/reference-audio/siren.wav +0 -0
- package/assets/reference-audio/speech.wav +0 -0
- package/assets/reference-audio/synthetic-alarm.wav +0 -0
- package/assets/reference-audio/synthetic-bark.wav +0 -0
- package/assets/reference-audio/synthetic-cry.wav +0 -0
- package/assets/reference-audio/synthetic-speech.wav +0 -0
- package/assets/reference-images/1-bird.jpg +0 -0
- package/assets/reference-images/1-car-plate.jpg +0 -0
- package/assets/reference-images/2-birds.jpg +0 -0
- package/assets/reference-images/2-cars-plates.jpg +0 -0
- package/assets/reference-images/3-persons.jpg +0 -0
- package/assets/reference-images/README.md +16 -0
- package/assets/reference-images/animals-group.jpg +0 -0
- package/assets/reference-images/ground-truth/1-bird.json +22 -0
- package/assets/reference-images/ground-truth/1-car-plate.json +85 -0
- package/assets/reference-images/ground-truth/2-birds.json +35 -0
- package/assets/reference-images/ground-truth/2-cars-plates.json +137 -0
- package/assets/reference-images/ground-truth/3-persons.json +186 -0
- package/assets/reference-images/ground-truth/animals-group.json +87 -0
- package/assets/reference-images/ground-truth/persons-cars-animal.json +136 -0
- package/assets/reference-images/ground-truth/sinner.json +73 -0
- package/assets/reference-images/persons-cars-animal.jpg +0 -0
- package/assets/reference-images/sinner.jpg +0 -0
- package/dist/audio-analyzer/index.js +1 -1
- package/dist/audio-analyzer/index.mjs +1 -1
- package/dist/audio-codec-ffmpeg/index.js +1 -1
- package/dist/audio-codec-ffmpeg/index.mjs +1 -1
- package/dist/detection-pipeline/index.js +3 -1
- package/dist/detection-pipeline/index.mjs +3 -1
- package/dist/{dist-CfSORkv2.mjs → dist-BESCfHIV.mjs} +35 -128
- package/dist/{dist-BrIE85BG.js → dist-BZBQc2QZ.js} +34 -145
- package/dist/{frame-handle-plane-C05rq9Zs.mjs → frame-handle-plane-CYtnVPIg.mjs} +1 -1
- package/dist/{frame-handle-plane-zMju9vmk.js → frame-handle-plane-ChjxN8oI.js} +1 -1
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/pipeline-runner/index.js +2 -2
- package/dist/pipeline-runner/index.mjs +2 -2
- package/dist/recorder/index.js +1 -1
- package/dist/recorder/index.mjs +1 -1
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-DPFAbcUo.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B0wZ-iCZ.mjs} +2 -2
- package/dist/stream-broker/{hostInit-C8slrxw1.mjs → hostInit-DuzG6QmV.mjs} +2 -2
- package/dist/stream-broker/index.js +133 -18
- package/dist/stream-broker/index.mjs +119 -4
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/embed-dist/assets/{MaskShapeCanvas-DI4BY7W2-WUVfFzT-.js → MaskShapeCanvas-DI4BY7W2-BL-S3O0Z.js} +1 -1
- package/embed-dist/assets/{MotionZonesSettings-NcxxQN8r-CF7FXXLs.js → MotionZonesSettings-NcxxQN8r-DcnKZAt6.js} +1 -1
- package/embed-dist/assets/{PrivacyMaskSettings-APgPLF7p-qQCpVob3.js → PrivacyMaskSettings-APgPLF7p-DQ0MK5T9.js} +1 -1
- package/embed-dist/assets/{index-BNhisVUZ.js → index-BCGUC-8v.js} +7 -7
- package/embed-dist/index.html +1 -1
- package/package.json +3 -57
- package/dist/decoder-ffmpeg/index.js +0 -1114
- package/dist/decoder-ffmpeg/index.mjs +0 -1097
- package/dist/decoder-nodeav/index.js +0 -1422
- package/dist/decoder-nodeav/index.mjs +0 -1414
- package/dist/ffmpeg-args-CpeRWwL4.mjs +0 -326
- package/dist/ffmpeg-args-Dl9mLcOC.js +0 -421
- package/dist/frame-dropper-AjheBGMG.mjs +0 -22
- package/dist/frame-dropper-DKLM6pMz.js +0 -27
- package/dist/frame-ring-sink-1aLGcNNf.mjs +0 -557
- package/dist/frame-ring-sink-CvlcAUOu.js +0 -604
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { t as __require } from "../chunk-BdkLduGY.mjs";
|
|
2
|
-
import { B as
|
|
3
|
-
import { n as DecoderSessionProxy, t as FrameHandlePlane } from "../frame-handle-plane-
|
|
2
|
+
import { $ as boolean, B as DeviceFeature, G as makeProfileBrokerId, H as EventCategory, I as webrtcSessionCapability, J as parseProfileBrokerId, K as makeSourceBrokerId, L as errMsg, O as nodePin, P as streamBrokerCapability, Q as array, R as BaseAddon, T as maskUrlCredentials, U as createEvent, V as DeviceType, Z as _enum, _ as cameraStreamsCapability, at as record, c as EncodeProfileSchema, d as RingBuffer, et as discriminatedUnion, it as object, nt as literal, ot as string, p as addonWidgetsSourceCapability, rt as number, st as union, z as CAM_PROFILE_ORDER } from "../dist-BESCfHIV.mjs";
|
|
3
|
+
import { n as DecoderSessionProxy, t as FrameHandlePlane } from "../frame-handle-plane-CYtnVPIg.mjs";
|
|
4
4
|
import { t as createFileDataPlaneHandler } from "../model-download-service-C-IHWnXx-BPy6aoAx.mjs";
|
|
5
|
-
import { f as rankDecodeHwAccels, g as logBannerArgs, h as audioEncoderArgs } from "../ffmpeg-args-CpeRWwL4.mjs";
|
|
6
|
-
import { t as FrameDropper } from "../frame-dropper-AjheBGMG.mjs";
|
|
7
5
|
import { createRequire } from "node:module";
|
|
8
6
|
import * as crypto$1 from "node:crypto";
|
|
9
7
|
import crypto, { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
@@ -2260,6 +2258,35 @@ var WEBRTC_FALLBACK_PROFILE = {
|
|
|
2260
2258
|
audio: "passthrough"
|
|
2261
2259
|
};
|
|
2262
2260
|
//#endregion
|
|
2261
|
+
//#region src/stream-broker/stream-broker/ffmpeg-args-common.ts
|
|
2262
|
+
var AUDIO_ENCODER_BY_CODEC = {
|
|
2263
|
+
opus: "libopus",
|
|
2264
|
+
aac: "aac",
|
|
2265
|
+
pcmu: "pcm_mulaw",
|
|
2266
|
+
pcma: "pcm_alaw",
|
|
2267
|
+
copy: "copy"
|
|
2268
|
+
};
|
|
2269
|
+
/**
|
|
2270
|
+
* Build the audio-encode args `-c:a <enc> [-b:a Nk] [-ar N] [-ac N]`. Each knob
|
|
2271
|
+
* is emitted only when provided, in this fixed order — matching what every
|
|
2272
|
+
* broker site already emitted by hand.
|
|
2273
|
+
*/
|
|
2274
|
+
function audioEncoderArgs(codec, opts = {}) {
|
|
2275
|
+
const args = ["-c:a", AUDIO_ENCODER_BY_CODEC[codec]];
|
|
2276
|
+
if (opts.bitrateKbps !== void 0) args.push("-b:a", `${opts.bitrateKbps}k`);
|
|
2277
|
+
if (opts.sampleRateHz !== void 0) args.push("-ar", String(opts.sampleRateHz));
|
|
2278
|
+
if (opts.channels !== void 0) args.push("-ac", String(opts.channels));
|
|
2279
|
+
return args;
|
|
2280
|
+
}
|
|
2281
|
+
/** The `-hide_banner -loglevel <level>` preamble every broker ffmpeg site opens with. */
|
|
2282
|
+
function logBannerArgs(level) {
|
|
2283
|
+
return [
|
|
2284
|
+
"-hide_banner",
|
|
2285
|
+
"-loglevel",
|
|
2286
|
+
level
|
|
2287
|
+
];
|
|
2288
|
+
}
|
|
2289
|
+
//#endregion
|
|
2263
2290
|
//#region src/stream-broker/webrtc/session.ts
|
|
2264
2291
|
var _werift;
|
|
2265
2292
|
async function loadWerift() {
|
|
@@ -6062,6 +6089,73 @@ function buildFfmpegArgs$1(inv) {
|
|
|
6062
6089
|
];
|
|
6063
6090
|
}
|
|
6064
6091
|
//#endregion
|
|
6092
|
+
//#region src/shared/ffmpeg-decode-args.ts
|
|
6093
|
+
/**
|
|
6094
|
+
* Canonical decode-hwaccel preference order for the ffmpeg-subprocess decoder.
|
|
6095
|
+
*
|
|
6096
|
+
* `vaapi` is ranked ABOVE `qsv` deliberately: on the Intel hub the `qsv` decode
|
|
6097
|
+
* child exits early (`code=171`, no frames) while the `vaapi` path decodes 8MP
|
|
6098
|
+
* h264 cleanly at ~50fps. The kernel probe (`resolveHwAccel`) tends to surface
|
|
6099
|
+
* `qsv` first on Intel, so we re-rank its result through this table before
|
|
6100
|
+
* building the attempt chain. `videotoolbox` leads for macOS; `cuda` / `nvdec`
|
|
6101
|
+
* trail for NVIDIA. A method not listed here keeps its incoming relative order,
|
|
6102
|
+
* placed AFTER every ranked one.
|
|
6103
|
+
*/
|
|
6104
|
+
var DECODE_HWACCEL_RANK = [
|
|
6105
|
+
"videotoolbox",
|
|
6106
|
+
"vaapi",
|
|
6107
|
+
"qsv",
|
|
6108
|
+
"cuda",
|
|
6109
|
+
"nvdec",
|
|
6110
|
+
"d3d11va",
|
|
6111
|
+
"dxva2",
|
|
6112
|
+
"amf",
|
|
6113
|
+
"vdpau",
|
|
6114
|
+
"drm"
|
|
6115
|
+
];
|
|
6116
|
+
/** Rank index for {@link DECODE_HWACCEL_RANK} — unranked methods sort last. */
|
|
6117
|
+
function decodeHwAccelRankIndex(method) {
|
|
6118
|
+
const idx = DECODE_HWACCEL_RANK.indexOf(method.toLowerCase());
|
|
6119
|
+
return idx < 0 ? DECODE_HWACCEL_RANK.length : idx;
|
|
6120
|
+
}
|
|
6121
|
+
/**
|
|
6122
|
+
* Build the ORDERED list of hardware `-hwaccel` methods to attempt for an
|
|
6123
|
+
* `'auto'` decode session, best-first. The session walks this chain on an
|
|
6124
|
+
* early-exit-with-no-frames and only falls to software once it is exhausted.
|
|
6125
|
+
*
|
|
6126
|
+
* Strategy:
|
|
6127
|
+
* - Seed candidates from the kernel-preferred order UNION the canonical rank
|
|
6128
|
+
* UNION the build's supported list, so a method the kernel omitted but the
|
|
6129
|
+
* build supports (the Intel `vaapi` case — kernel surfaces only `qsv`) is
|
|
6130
|
+
* still attempted.
|
|
6131
|
+
* - When the build's supported-method list is known (non-empty), keep only
|
|
6132
|
+
* methods it actually offers; on a probe miss (empty) keep just the kernel
|
|
6133
|
+
* preferences (avoid blindly spawning every backend).
|
|
6134
|
+
* - Re-rank the survivors by {@link DECODE_HWACCEL_RANK} so `vaapi` precedes
|
|
6135
|
+
* `qsv`. A supported method not in the rank table keeps its position AFTER
|
|
6136
|
+
* every ranked one (stable sort). Returns lowercased method names; empty ⇒
|
|
6137
|
+
* pure software.
|
|
6138
|
+
*/
|
|
6139
|
+
function rankDecodeHwAccels(preferred, supportedMethods) {
|
|
6140
|
+
const supported = new Set(supportedMethods.map((m) => m.toLowerCase()));
|
|
6141
|
+
const hasSupportList = supported.size > 0;
|
|
6142
|
+
const pool = hasSupportList ? [
|
|
6143
|
+
...preferred,
|
|
6144
|
+
...DECODE_HWACCEL_RANK,
|
|
6145
|
+
...supportedMethods
|
|
6146
|
+
] : [...preferred];
|
|
6147
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6148
|
+
const candidates = [];
|
|
6149
|
+
for (const raw of pool) {
|
|
6150
|
+
const method = raw.toLowerCase();
|
|
6151
|
+
if (seen.has(method)) continue;
|
|
6152
|
+
seen.add(method);
|
|
6153
|
+
if (hasSupportList && !supported.has(method)) continue;
|
|
6154
|
+
candidates.push(method);
|
|
6155
|
+
}
|
|
6156
|
+
return candidates.sort((a, b) => decodeHwAccelRankIndex(a) - decodeHwAccelRankIndex(b));
|
|
6157
|
+
}
|
|
6158
|
+
//#endregion
|
|
6065
6159
|
//#region src/stream-broker/stream-broker/profile-restreamers.ts
|
|
6066
6160
|
/**
|
|
6067
6161
|
* Diff the desired profile→source aliasing against the current
|
|
@@ -17943,6 +18037,27 @@ var StreamBrokerAddon = class extends BaseAddon {
|
|
|
17943
18037
|
}
|
|
17944
18038
|
};
|
|
17945
18039
|
//#endregion
|
|
18040
|
+
//#region src/stream-broker/stream-broker/frame-dropper.ts
|
|
18041
|
+
var FrameDropper = class {
|
|
18042
|
+
intervalMs;
|
|
18043
|
+
lastPassedAt = -Infinity;
|
|
18044
|
+
constructor(maxFps) {
|
|
18045
|
+
this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
|
|
18046
|
+
}
|
|
18047
|
+
shouldKeep() {
|
|
18048
|
+
if (this.intervalMs === 0) return true;
|
|
18049
|
+
const now = Date.now();
|
|
18050
|
+
if (now - this.lastPassedAt >= this.intervalMs) {
|
|
18051
|
+
this.lastPassedAt = now;
|
|
18052
|
+
return true;
|
|
18053
|
+
}
|
|
18054
|
+
return false;
|
|
18055
|
+
}
|
|
18056
|
+
setMaxFps(maxFps) {
|
|
18057
|
+
this.intervalMs = maxFps > 0 ? 1e3 / maxFps : 0;
|
|
18058
|
+
}
|
|
18059
|
+
};
|
|
18060
|
+
//#endregion
|
|
17946
18061
|
//#region src/stream-broker/stream-broker/ffmpeg-decoder-session.ts
|
|
17947
18062
|
/** Minimal no-op logger for default parameter */
|
|
17948
18063
|
var noopLogger = {
|
|
@@ -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-B0wZ-iCZ.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{d as e,f as t,g as n,h as r,m as i,p as a}from"./index-
|
|
1
|
+
import{d as e,f as t,g as n,h as r,m as i,p as a}from"./index-BCGUC-8v.js";var o=n(t()),s=n(e(),1),c=Math.PI/180;function l(){return typeof window<`u`&&({}.toString.call(window)===`[object Window]`||{}.toString.call(window)===`[object global]`)}var u=typeof global<`u`?global:typeof window<`u`?window:typeof WorkerGlobalScope<`u`?self:{},d={_global:u,version:`10.3.0`,isBrowser:l(),isUnminified:/param/.test(function(e){}.toString()),dblClickWindow:400,getAngle(e){return d.angleDeg?e*c:e},enableTrace:!1,pointerEventsEnabled:!0,autoDrawEnabled:!0,hitOnDragEnabled:!1,capturePointerEventsEnabled:!1,_mouseListenClick:!1,_touchListenClick:!1,_pointerListenClick:!1,_mouseInDblClickWindow:!1,_touchInDblClickWindow:!1,_pointerInDblClickWindow:!1,_mouseDblClickPointerId:null,_touchDblClickPointerId:null,_pointerDblClickPointerId:null,_renderBackend:`web`,legacyTextRendering:!1,pixelRatio:typeof window<`u`&&window.devicePixelRatio||1,dragDistance:3,angleDeg:!0,showWarnings:!0,dragButtons:[0,1],isDragging(){return d.DD.isDragging},isTransforming(){return d.Transformer?.isTransforming()??!1},isDragReady(){return!!d.DD.node},releaseCanvasOnDestroy:!0,document:u.document,_injectGlobal(e){u.Konva!==void 0&&console.error(`Several Konva instances detected. It is not recommended to use multiple Konva instances in the same environment.`),u.Konva=e}},f=e=>{d[e.prototype.getClassName()]=e};d._injectGlobal(d);var p=`Konva.js unsupported environment.
|
|
2
2
|
|
|
3
3
|
Looks like you are trying to use Konva.js in Node.js environment. because "document" object is undefined.
|
|
4
4
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,f as r,g as i,l as a,o,r as s,s as c,u as l}from"./index-
|
|
1
|
+
import{a as e,c as t,d as n,f as r,g as i,l as a,o,r as s,s as c,u as l}from"./index-BCGUC-8v.js";import{MaskShapeCanvas as u}from"./MaskShapeCanvas-DI4BY7W2-BL-S3O0Z.js";var d=i(r(),1),f=i(n(),1),p=o(`grid-2x2`,[[`path`,{d:`M12 3v18`,key:`108xh3`}],[`path`,{d:`M3 12h18`,key:`1i2n21`}],[`rect`,{x:`3`,y:`3`,width:`18`,height:`18`,rx:`2`,key:`h1oib`}]]),m=110,h=`motion-zones`,g=0,_=[1,2,3],v=1,y=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,b=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function x(e,t,n){let r=t*n,i=Array.from({length:r});for(let t=0;t<r;t+=1)i[t]=e[t]===!0;return i}function S(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}function C(e,t){return Math.ceil(e/t)}function w(e,t,n){return Math.min(n-1,Math.floor((e+.5)/t*n))}function T(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:i*a},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)e[r*t+n]===!0&&(o[s*i+w(n,t,i)]=!0)}return o}function E(e,t,n,r){let i=C(t,r),a=C(n,r),o=Array.from({length:t*n},()=>!1);for(let r=0;r<n;r+=1){let s=w(r,n,a);for(let n=0;n<t;n+=1)o[r*t+n]=e[s*i+w(n,t,i)]===!0}return o}function D({deviceId:n}){let r=t(l().trpcClient,n),[i,o]=(0,d.useState)(null),[w,D]=(0,d.useState)(!1),[O,k]=(0,d.useState)(null),[A,j]=(0,d.useState)(null),[M,N]=(0,d.useState)(v),[P,F]=(0,d.useState)(!1),[I,L]=(0,d.useState)(!1),R=(0,d.useRef)(!1);(0,d.useEffect)(()=>{if(!r)return;let e=!1;return R.current=!1,o(null),D(!1),k(null),j(null),N(v),L(!1),(async()=>{try{let t=await r.motionZones?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(o(t),R.current)return;let n=await r.motionZones?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);R.current=!0;let i=n.regions.find(e=>e.shape.kind===`grid`),a=x(i?i.shape.cells:[],t.grid.width,t.grid.height);j(a),k(T(a,t.grid.width,t.grid.height,v))}catch(t){if(e)return;c(t)?D(!0):console.error(`Motion Zones load failed`,t)}})(),()=>{e=!0}},[r]);let z=i?i.grid.width:0,B=i?i.grid.height:0,V=C(z,M),H=C(B,M),U=(0,d.useMemo)(()=>O&&i?E(O,z,B,M):null,[O,i,z,B,M]),W=(0,d.useMemo)(()=>U!==null&&A!==null&&!S(U,A),[U,A]),G=(0,d.useMemo)(()=>U?U.reduce((e,t)=>t?e+1:e,0):0,[U]),K=z*B,q=V*H,J=(0,d.useCallback)(e=>{q>0&&k(Array.from({length:q},()=>e))},[q]),Y=(0,d.useCallback)(()=>{k(e=>e&&e.map(e=>!e))},[]),X=(0,d.useCallback)(()=>{A&&i&&k(T(A,z,B,M))},[A,i,z,B,M]),Z=(0,d.useCallback)(e=>{e===M||!i||k(t=>{if(!t)return N(e),t;let n=T(E(t,z,B,M),z,B,e);return N(e),n})},[M,i,z,B]),Q=(0,d.useMemo)(()=>i&&O?[{id:g,shape:{kind:`grid`,gridWidth:V,gridHeight:H,cells:[...O]}}]:[],[i,O,V,H]),$=(0,d.useCallback)((e,t)=>{t.kind===`grid`&&k(t.cells)},[]),ee=(0,d.useCallback)(async()=>{if(!(!r||!O||!i)){F(!0);try{let e=E(O,i.grid.width,i.grid.height,M),t={kind:`grid`,gridWidth:i.grid.width,gridHeight:i.grid.height,cells:e};await r.motionZones?.setZone({patch:{regions:[{id:g,enabled:!0,shape:t}]}});let n=await r.motionZones?.getStatus({});if(n){let e=n.regions.find(e=>e.shape.kind===`grid`),t=x(e?e.shape.cells:[],i.grid.width,i.grid.height);j(t),k(T(t,i.grid.width,i.grid.height,M))}}catch(e){console.error(`Motion Zones save failed`,e)}finally{F(!1)}}},[r,O,i,M]);a((0,d.useMemo)(()=>I&&!w&&i&&O?{id:h,order:m,node:(0,f.jsx)(u,{transparent:!0,items:Q,supportedShapes:[`grid`],grid:{width:V,height:H},selectedId:g,onSelect:()=>{},onShapeChange:$,onDrawComplete:()=>{},drawingKind:null})}:null,[I,w,i,O,Q,$,V,H]));let te=!w&&i!==null&&O!==null;return r?(0,f.jsx)(e,{title:`Motion Zones`,icon:(0,f.jsx)(p,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,f.jsx)(`div`,{className:`flex flex-col gap-3`,children:w?(0,f.jsx)(`p`,{className:`${s} leading-relaxed`,children:`This camera doesn't expose an on-board motion zones grid.`}):te?(0,f.jsxs)(f.Fragment,{children:[(0,f.jsxs)(`p`,{className:`${s} leading-relaxed`,children:[`Toggle `,(0,f.jsx)(`strong`,{className:`text-foreground`,children:`Edit grid`}),` to paint the region directly on the live frame, then `,(0,f.jsx)(`strong`,{className:`text-foreground`,children:`Save`}),` to push the mask to the camera. Pick a bigger`,` `,(0,f.jsx)(`strong`,{className:`text-foreground`,children:`Cell size`}),` for quicker, broad-stroke painting — it's resampled to the camera's native `,i.grid.width,`×`,i.grid.height,` grid on save (×1 is the finest).`]}),(0,f.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,f.jsx)(`button`,{type:`button`,onClick:()=>L(e=>!e),disabled:P,"aria-pressed":I,className:I?b:y,children:I?`Done editing`:`Edit grid`}),(0,f.jsx)(`button`,{type:`button`,onClick:()=>J(!0),disabled:P,className:y,children:`All on`}),(0,f.jsx)(`button`,{type:`button`,onClick:()=>J(!1),disabled:P,className:y,children:`All off`}),(0,f.jsx)(`button`,{type:`button`,onClick:Y,disabled:P,className:y,children:`Invert`}),(0,f.jsxs)(`div`,{className:`flex items-center gap-1 ml-1`,role:`group`,"aria-label":`Cell size`,children:[(0,f.jsx)(`span`,{className:`${s} mr-0.5`,children:`Cell size`}),_.map(e=>(0,f.jsxs)(`button`,{type:`button`,onClick:()=>Z(e),disabled:P,"aria-pressed":M===e,title:e===1?`Camera grid ${z}×${B} (finest)`:`${C(z,e)}×${C(B,e)} painting grid · cells ×${e} bigger`,className:M===e?b:y,children:[`×`,e]},e))]}),(0,f.jsxs)(`span`,{className:`${s} ml-1 tabular-nums`,children:[G,` / `,K,` cells · `,i.grid.width,`×`,i.grid.height,M===1?``:` · paint ${V}×${H}`]}),(0,f.jsx)(`span`,{className:`flex-1`}),(0,f.jsx)(`button`,{type:`button`,onClick:X,disabled:P||!W,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:`Revert`}),(0,f.jsx)(`button`,{type:`button`,onClick:()=>void ee(),disabled:P||!W,className:b,children:P?`Saving…`:`Save`})]})]}):(0,f.jsx)(`p`,{className:`${s} leading-relaxed`,children:`Loading the camera's grid…`})})}):null}export{D as MotionZonesSettings};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as e,c as t,d as n,f as r,g as i,i as a,l as o,n as s,o as c,r as l,s as u,t as d,u as ee}from"./index-
|
|
1
|
+
import{a as e,c as t,d as n,f as r,g as i,i as a,l as o,n as s,o as c,r as l,s as u,t as d,u as ee}from"./index-BCGUC-8v.js";import{MaskShapeCanvas as te}from"./MaskShapeCanvas-DI4BY7W2-BL-S3O0Z.js";var f=i(r(),1),p=i(n(),1),m=c(`hexagon`,[[`path`,{d:`M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z`,key:`yt0hxn`}]]),h=120,g=`privacy-mask`,_=`rounded-md border border-border bg-surface px-2 py-1 text-[11px] font-medium text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,v=`rounded-md border border-primary/50 bg-primary/15 px-2.5 py-1 text-[11px] font-medium text-primary hover:bg-primary/25 disabled:opacity-40 transition-colors`;function y(e){return e.kind===`rect`||e.kind===`polygon`?e:null}function b(e){let t=new Set(e.map(e=>e.id)),n=0;for(;t.has(n);)n+=1;return n}function x(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(JSON.stringify(e[n])!==JSON.stringify(t[n]))return!1;return!0}function S({deviceId:n}){let r=t(ee().trpcClient,n),[i,c]=(0,f.useState)(null),[S,C]=(0,f.useState)(!1),[w,T]=(0,f.useState)(null),[E,D]=(0,f.useState)(null),[O,k]=(0,f.useState)(!1),[A,j]=(0,f.useState)(!1),[M,N]=(0,f.useState)(null),[P,F]=(0,f.useState)(null),I=(0,f.useRef)(!1);(0,f.useEffect)(()=>{if(!r)return;let e=!1;return I.current=!1,c(null),C(!1),T(null),D(null),j(!1),N(null),F(null),(async()=>{try{let t=await r.privacyMask?.getOptions({});if(e)return;if(!t)throw Error(`device proxy not ready`);if(c(t),I.current)return;let n=await r.privacyMask?.getStatus({});if(e)return;if(!n)throw Error(`device proxy not ready`);I.current=!0;let i={enabled:n.enabled,regions:n.regions};D(i),T(i)}catch(t){if(e)return;u(t)?C(!0):console.error(`Privacy Mask load failed`,t)}})(),()=>{e=!0}},[r]);let L=(0,f.useMemo)(()=>w!==null&&E!==null&&(w.enabled!==E.enabled||!x(w.regions,E.regions)),[w,E]),R=w?w.regions.length:0,z=i?i.maxRegions:0,B=(0,f.useRef)(0);(0,f.useEffect)(()=>{B.current=z},[z]);let V=z>0&&R>=z,H=(0,f.useCallback)(()=>{T(e=>e&&{...e,enabled:!e.enabled})},[]),U=(0,f.useCallback)(e=>{N(typeof e==`number`?e:null)},[]),W=(0,f.useMemo)(()=>w?w.regions.map(e=>({id:e.id,shape:e.shape,enabled:e.enabled,label:`Zone ${String(e.id)}`})):[],[w]),G=(0,f.useCallback)((e,t)=>{let n=y(t);n&&T(t=>t&&{...t,regions:t.regions.map(t=>t.id===e?{...t,shape:n}:t)})},[]),K=(0,f.useCallback)(e=>{let t=y(e);t&&(F(null),T(e=>{if(!e)return e;let n=B.current;if(n>0&&e.regions.length>=n)return e;let r=b(e.regions),i={id:r,enabled:!0,shape:t};return N(r),{...e,regions:[...e.regions,i]}}))},[]),q=(0,f.useCallback)(e=>{j(!0),N(null),F(e)},[]),J=(0,f.useCallback)(e=>{j(!0),F(null),N(e)},[]),Y=(0,f.useCallback)(e=>{N(t=>t===e?null:t),T(t=>t&&{...t,regions:t.regions.filter(t=>t.id!==e)})},[]),X=(0,f.useCallback)(()=>{F(null),N(null),E&&T({enabled:E.enabled,regions:E.regions})},[E]),Z=(0,f.useCallback)(async()=>{if(!(!r||!w)){k(!0);try{await r.privacyMask?.setMask({patch:{enabled:w.enabled,regions:[...w.regions]}});let e=await r.privacyMask?.getStatus({});if(e){let t={enabled:e.enabled,regions:e.regions};D(t),T(t)}}catch(e){console.error(`Privacy Mask save failed`,e)}finally{k(!1)}}},[r,w]),ne=(0,f.useCallback)(()=>{j(e=>(e&&(F(null),N(null)),!e))},[]),Q=i?.supportedShapes??[];o((0,f.useMemo)(()=>A&&!S&&i&&w?{id:g,order:h,node:(0,p.jsx)(te,{transparent:!0,items:W,supportedShapes:Q,polygonVertices:i.polygonVertices,selectedId:M,onSelect:U,onShapeChange:G,onDrawComplete:K,drawingKind:P})}:null,[A,S,i,w,W,Q,M,U,G,K,P]));let re=i?.supportedShapes.includes(`rect`)??!1,ie=i?.supportedShapes.includes(`polygon`)??!1,$=i!==null&&(i.maxRegions<=0||i.supportedShapes.length===0),ae=!S&&!$&&i!==null&&w!==null;return r?(0,p.jsx)(e,{title:`Privacy Mask`,icon:(0,p.jsx)(d,{className:`h-3.5 w-3.5 text-foreground-subtle`}),children:(0,p.jsx)(`div`,{className:`flex flex-col gap-3`,children:S||$?(0,p.jsx)(`p`,{className:`${l} leading-relaxed`,children:`This camera doesn't support an on-board privacy mask.`}):ae?(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(`p`,{className:`${l} leading-relaxed`,children:[`Toggle `,(0,p.jsx)(`strong`,{className:`text-foreground`,children:`Edit mask`}),` to draw blanked-out zones on the live frame, then `,(0,p.jsx)(`strong`,{className:`text-foreground`,children:`Save`}),` to push them to the camera. Drag a rectangle to move, its corner to resize; drag polygon vertices, click an edge midpoint to add one, or right-click a vertex to remove it.`]}),(0,p.jsxs)(`div`,{className:`flex items-center gap-2 flex-wrap`,children:[(0,p.jsx)(`button`,{type:`button`,onClick:ne,disabled:O,"aria-pressed":A,className:A?v:_,children:A?`Done editing`:`Edit mask`}),(0,p.jsx)(`button`,{type:`button`,onClick:H,disabled:O,"aria-pressed":w.enabled,className:w.enabled?v:_,children:w.enabled?`Mask on`:`Mask off`}),re&&(0,p.jsx)(`button`,{type:`button`,onClick:()=>q(`rect`),disabled:O||V,"aria-pressed":P===`rect`,className:P===`rect`?v:_,title:V?`Maximum zones reached`:`Add a rectangle zone`,children:`+ Rect`}),ie&&(0,p.jsx)(`button`,{type:`button`,onClick:()=>q(`polygon`),disabled:O||V,"aria-pressed":P===`polygon`,className:P===`polygon`?v:_,title:V?`Maximum zones reached`:`Add a polygon zone`,children:`+ Polygon`}),(0,p.jsxs)(`span`,{className:`${l} ml-1 tabular-nums`,children:[R,` / `,z,` zones`]}),(0,p.jsx)(`span`,{className:`flex-1`}),(0,p.jsx)(`button`,{type:`button`,onClick:X,disabled:O||!L,className:`rounded-md border border-border bg-surface px-2 py-1 text-[11px] text-foreground-subtle hover:bg-surface-hover disabled:opacity-40 transition-colors`,children:`Revert`}),(0,p.jsx)(`button`,{type:`button`,onClick:()=>void Z(),disabled:O||!L,className:v,children:O?`Saving…`:`Save`})]}),R>0?(0,p.jsx)(`div`,{className:`flex flex-col gap-1`,children:w.regions.map(e=>{let t=M===e.id,n=e.shape.kind===`polygon`?m:s;return(0,p.jsxs)(`div`,{className:`flex items-center gap-2 rounded-md border px-2 py-1 transition-colors ${t?`border-primary/50 bg-primary/10`:`border-border bg-surface`}`,children:[(0,p.jsxs)(`button`,{type:`button`,onClick:()=>J(e.id),disabled:O,className:`flex flex-1 items-center gap-2 text-left text-[11px] font-medium text-foreground-subtle hover:text-foreground disabled:opacity-40 transition-colors`,children:[(0,p.jsx)(n,{className:`h-3.5 w-3.5 shrink-0`}),(0,p.jsxs)(`span`,{children:[`Zone `,e.id]}),(0,p.jsx)(`span`,{className:`text-foreground-faint capitalize`,children:e.shape.kind})]}),(0,p.jsx)(`button`,{type:`button`,onClick:()=>Y(e.id),disabled:O,"aria-label":`Delete zone ${String(e.id)}`,title:`Delete zone`,className:`inline-flex h-6 w-6 items-center justify-center rounded border border-border bg-surface text-foreground-subtle hover:border-red-400/40 hover:bg-red-500/10 hover:text-red-400 disabled:opacity-40 transition-colors`,children:(0,p.jsx)(a,{className:`h-3.5 w-3.5`})})]},e.id)})}):null]}):(0,p.jsx)(`p`,{className:`${l} leading-relaxed`,children:`Loading the camera's privacy mask…`})})}):null}export{S as PrivacyMaskSettings};
|