@camera.ui/server 2.1.9 → 2.1.10
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/interface/assets/{404-BEb5gvkW.js → 404-BLNSh-sA.js} +1 -1
- package/dist/interface/assets/{About-BKkjuIVJ.js → About-ZakRzon7.js} +1 -1
- package/dist/interface/assets/Automation-DoVhkuVY.js +3 -0
- package/dist/interface/assets/AutomationImport-DVxK1R1y.js +2 -0
- package/dist/interface/assets/{AutomationStore-DKhnExZn.js → AutomationStore-DaNO9_9S.js} +2 -2
- package/dist/interface/assets/{AutomationStoreDetail-DmqqEOir.js → AutomationStoreDetail-CTDCEaIz.js} +2 -2
- package/dist/interface/assets/Automations-mdnUitWx.js +2 -0
- package/dist/interface/assets/Camera-B3cv5IVC.js +2 -0
- package/dist/interface/assets/Camera-LSq1bWmA.css +1 -0
- package/dist/interface/assets/{CameraConsole-DVpyGhx8.js → CameraConsole-C32X5I91.js} +2 -2
- package/dist/interface/assets/Cameras-Drv48-Eb.js +652 -0
- package/dist/interface/assets/Camview-Bvy39jSt.js +1 -0
- package/dist/interface/assets/{Config-DeUec_TN.js → Config-B-LDdaS6.js} +1 -1
- package/dist/interface/assets/{ConfigActionCameraControl-DWHg-YEU.js → ConfigActionCameraControl-As2qXvnd.js} +1 -1
- package/dist/interface/assets/{ConfigActionDelay-C8nNA7TC.js → ConfigActionDelay-Cj3yWfEV.js} +1 -1
- package/dist/interface/assets/{ConfigActionHttp-Dc97gItH.js → ConfigActionHttp-PlS5vI0v.js} +1 -1
- package/dist/interface/assets/{ConfigActionImageInput-DpOGqlzA.js → ConfigActionImageInput-BHflOA-T.js} +1 -1
- package/dist/interface/assets/{ConfigActionMqtt-D5DJ21oe.js → ConfigActionMqtt-DByOwVPe.js} +1 -1
- package/dist/interface/assets/{ConfigActionNotification-4wKfanGB.js → ConfigActionNotification-D_8_lp96.js} +1 -1
- package/dist/interface/assets/{ConfigActionNotificationControl-jSgxCZmV.js → ConfigActionNotificationControl-ClFMom6m.js} +1 -1
- package/dist/interface/assets/{ConfigActionOutput-C8Esieni.js → ConfigActionOutput-YTAw-Are.js} +1 -1
- package/dist/interface/assets/{ConfigActionPlugin-C_cv60d3.js → ConfigActionPlugin-lF2IH2Bo.js} +1 -1
- package/dist/interface/assets/{ConfigActionSensor-CFIKoJ3-.js → ConfigActionSensor-DQZW_Jxr.js} +1 -1
- package/dist/interface/assets/{ConfigActionSnapshot-BqaTwtN3.js → ConfigActionSnapshot-CHxIQ5J0.js} +1 -1
- package/dist/interface/assets/{ConfigActionVariable-De9RCGU4.js → ConfigActionVariable-0VLGuhwP.js} +1 -1
- package/dist/interface/assets/{ConfigConditionIfElse-CeNDIucw.js → ConfigConditionIfElse-D-Ibn8QL.js} +1 -1
- package/dist/interface/assets/{ConfigConditionSensorState-C_Q9gU23.js → ConfigConditionSensorState-BKSGYRdv.js} +1 -1
- package/dist/interface/assets/{ConfigConditionSwitch-DR63IGcD.js → ConfigConditionSwitch-CzkEyWb1.js} +1 -1
- package/dist/interface/assets/{ConfigConditionTime-C9iuSxxe.js → ConfigConditionTime-BFKsDI_t.js} +1 -1
- package/dist/interface/assets/{ConfigSensorValueInput-DnMlFzil.js → ConfigSensorValueInput-yTiHhlXG.js} +1 -1
- package/dist/interface/assets/ConfigTriggerDetection-DFTgRaE0.js +1 -0
- package/dist/interface/assets/ConfigTriggerGeofence-B2Cqi5Id.js +1 -0
- package/dist/interface/assets/{ConfigTriggerManual-DPkRlUqD.js → ConfigTriggerManual-BDK6OYxg.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerMqtt-kd65tGJE.js → ConfigTriggerMqtt-BZO14RrW.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerSchedule-D6MoVDPc.js → ConfigTriggerSchedule-sMkzMLgn.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerSensor-AMQM6f2r.js → ConfigTriggerSensor-D6W_exDW.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerSystem-CNBgtDF1.js → ConfigTriggerSystem-D4cx1GqI.js} +1 -1
- package/dist/interface/assets/{ConfigTriggerWebhook-B70DobSi.js → ConfigTriggerWebhook-DxZziGkL.js} +1 -1
- package/dist/interface/assets/Console-DjA3ZPU_.js +1 -0
- package/dist/interface/assets/CuiAutomationRunsDialog-B4ABK72A.js +1 -0
- package/dist/interface/assets/CuiBottomSheet-D1zDWsoK.js +1 -0
- package/dist/interface/assets/{CuiBottomSheet-D5N8X1K-.js → CuiBottomSheet-N9MHq4yZ.js} +1 -1
- package/dist/interface/assets/CuiCameraPipCard-CnWs2fAC.js +1 -0
- package/dist/interface/assets/CuiCameraRecordings-CahW-f8_.js +1 -0
- package/dist/interface/assets/{CuiCameraShares-DMHwZEf1.js → CuiCameraShares-B2RdPWWh.js} +1 -1
- package/dist/interface/assets/CuiCameraTable-4ikGv8QA.js +1 -0
- package/dist/interface/assets/{CuiCameraTable-AnEPu3XS.js → CuiCameraTable-BKBvhRDc.js} +2 -2
- package/dist/interface/assets/CuiChartTable-CqKo74Tf.css +1 -0
- package/dist/interface/assets/CuiChartTable-Lvz9Zq0k.js +1 -0
- package/dist/interface/assets/{CuiConsole-CqEvNGe_.js → CuiConsole-DUswVhFC.js} +2 -2
- package/dist/interface/assets/CuiDataTable-CIP95jVF.js +1 -0
- package/dist/interface/assets/CuiLightControl-CvfWo8mY.js +1 -0
- package/dist/interface/assets/{CuiList-DrYuFhK4.js → CuiList-CajC6jpE.js} +1 -1
- package/dist/interface/assets/CuiPluginCard-CQS8C87-.js +2 -0
- package/dist/interface/assets/CuiPluginCategoryChip-DCNG8zl1.js +1 -0
- package/dist/interface/assets/{CuiPluginOAuthButton-vMuRa9Qd.js → CuiPluginOAuthButton-CvZrOWr8.js} +2 -2
- package/dist/interface/assets/{CuiPluginTrustBadge-2wsPzYZA.js → CuiPluginTrustBadge-Bc1dQgX8.js} +1 -1
- package/dist/interface/assets/CuiQRCode-CjLcB644.js +1 -0
- package/dist/interface/assets/CuiRecordingsGrid-DrpErbux.js +1 -0
- package/dist/interface/assets/{CuiRecordingsGrid-Q4C3aeLo.css → CuiRecordingsGrid-EAumRo5E.css} +1 -1
- package/dist/interface/assets/CuiSchema-BYYeh269.css +1 -0
- package/dist/interface/assets/CuiSchema-DG8peseE.js +1 -0
- package/dist/interface/assets/{CuiTopNavbarItem-CSdvkKHR.js → CuiTopNavbarItem-Dq3Esl1S.js} +1 -1
- package/dist/interface/assets/Faces-D0yRgOMj.js +1 -0
- package/dist/interface/assets/FirstSteps-BW8AVmd4.js +1 -0
- package/dist/interface/assets/{Instances-Cw7A4I7E.js → Instances-BgXJvs0_.js} +1 -1
- package/dist/interface/assets/{Logs-4Mgj7YWu.js → Logs-DH3rWnlV.js} +2 -2
- package/dist/interface/assets/Menu-D9FVgjwT.js +1 -0
- package/dist/interface/assets/Metrics-7bYWyGWU.js +9 -0
- package/dist/interface/assets/Metrics-DX59XXDc.css +1 -0
- package/dist/interface/assets/{OAuthDeviceFlow-DGikOkgK.js → OAuthDeviceFlow-BS0FQbZh.js} +1 -1
- package/dist/interface/assets/Plugin-ZwkTp6C4.js +1 -0
- package/dist/interface/assets/{PluginConsole-ZZvJlgIh.js → PluginConsole-Dt39TWaO.js} +2 -2
- package/dist/interface/assets/{PluginDetail-B9NgbzkJ.js → PluginDetail-D7ZtOG9Y.js} +2 -2
- package/dist/interface/assets/{PluginSchema-Cx_LInpM.js → PluginSchema-8T7EBq-Z.js} +1 -1
- package/dist/interface/assets/PluginSearch-DN3o0wfs.js +1 -0
- package/dist/interface/assets/PluginSearch-eRDCvu_8.js +2 -0
- package/dist/interface/assets/{PluginUpdateProgress-0nV-8LvI.js → PluginUpdateProgress-CxjpzkGa.js} +1 -1
- package/dist/interface/assets/Plugins-DVsMpyvr.js +1 -0
- package/dist/interface/assets/Recordings-BKxSEiQo.js +1 -0
- package/dist/interface/assets/SensorEdit-BmaMQKEa.js +1 -0
- package/dist/interface/assets/{SensorHistory-IgMpuLdC.js → SensorHistory-CmOAk-tD.js} +1 -1
- package/dist/interface/assets/Sensors-x08al7Je.js +2 -0
- package/dist/interface/assets/Settings-Cp1lzG1i.js +1 -0
- package/dist/interface/assets/SettingsAccount-BwCNddkW.js +1 -0
- package/dist/interface/assets/SettingsAccount-DC9AxqHe.js +1 -0
- package/dist/interface/assets/SettingsAppearance-CMzzDZCX.js +1 -0
- package/dist/interface/assets/{SettingsAppearance-C8EEBVZN.js → SettingsAppearance-Dr8hJloI.js} +1 -1
- package/dist/interface/assets/SettingsBackup-Dc8pDM3Y.js +1 -0
- package/dist/interface/assets/{SettingsList-MXYSQMZ3.js → SettingsList-3peF3gFZ.js} +1 -1
- package/dist/interface/assets/SettingsMqtt-k-cHaOoA.js +1 -0
- package/dist/interface/assets/SettingsNotifications-BJHYlSKX.js +1 -0
- package/dist/interface/assets/{SettingsPermissions-Dd_yfNlk.js → SettingsPermissions-CymqvfR9.js} +1 -1
- package/dist/interface/assets/{SettingsRecordings-85B2bQIf.js → SettingsRecordings-gWTD_djR.js} +1 -1
- package/dist/interface/assets/SettingsRemote-BWAhI1Gw.js +2 -0
- package/dist/interface/assets/SettingsRemote-CtP6Gz9C.css +1 -0
- package/dist/interface/assets/SettingsSystem-BGBUQvjg.js +2 -0
- package/dist/interface/assets/SettingsUsers-B_Ri5OrM.js +1 -0
- package/dist/interface/assets/Terminal-eYxvgFHE.js +4 -0
- package/dist/interface/assets/Updates-CweZekTf.js +2 -0
- package/dist/interface/assets/{VariableInput-7c7Px-DM.js → VariableInput-CM6T3pUW.js} +1 -1
- package/dist/interface/assets/{VariableSuggestions-CrEa2zN-.js → VariableSuggestions-BGxZxS6U.js} +1 -1
- package/dist/interface/assets/{VersionsHandler-BFuLGk6Y.js → VersionsHandler-BWIiBPPa.js} +2 -2
- package/dist/interface/assets/{VirtualSensorCreate-uumfOHgB.js → VirtualSensorCreate-CFQC2-9D.js} +1 -1
- package/dist/interface/assets/Workers-B-sp43t3.js +2 -0
- package/dist/interface/assets/{Workers-7hKMBU4w.css → Workers-DH59zE1C.css} +1 -1
- package/dist/interface/assets/{api-DLVsQBAO.js → api-CG0j1twy.js} +1 -1
- package/dist/interface/assets/api-CVOj5SYs.css +2 -0
- package/dist/interface/assets/api-C_bOaXk2.js +2 -0
- package/dist/interface/assets/{auth-uQlIia9h.js → auth-BPSOBTDX.js} +1 -1
- package/dist/interface/assets/{automations-ChG1qcO7.js → automations-BrtwUIUz.js} +1 -1
- package/dist/interface/assets/brain-7IVdhMyV.js +1 -0
- package/dist/interface/assets/{cameras.schema-Cv7cjMz3.js → cameras.schema-CoIOnGzE.js} +1 -1
- package/dist/interface/assets/cloudHandoff-BiFzJEYx.js +1 -0
- package/dist/interface/assets/{config-B1aWtF-N.js → config-BjldP5A6.js} +1 -1
- package/dist/interface/assets/{flowSchema-CNnBxcwy.js → flowSchema-B_Otn6RU.js} +1 -1
- package/dist/interface/assets/{intercomService-DJHBix4X.js → intercomService-BpTOoSQi.js} +1 -1
- package/dist/interface/assets/lan-BP0NuDr7.js +1 -0
- package/dist/interface/assets/main-BG-VCb--.js +3 -0
- package/dist/interface/assets/main-CFQGq2Yn.css +1 -0
- package/dist/interface/assets/{mqtt-Cyhv8shC.js → mqtt-DSPPQwxJ.js} +1 -1
- package/dist/interface/assets/{notifications-DniREnpL.js → notifications-DEEM2oP2.js} +1 -1
- package/dist/interface/assets/{plugins-5gXj0utE.js → plugins-DBBFdZKH.js} +1 -1
- package/dist/interface/assets/refresh-Ds2EayhZ.js +1 -0
- package/dist/interface/assets/sensorIcons-CP5EQZ60.js +1 -0
- package/dist/interface/assets/{sensors-Bc02Z1G9.js → sensors-CKTPsYYH.js} +1 -1
- package/dist/interface/assets/{server-D2KGja0u.js → server-B_MuqJ5z.js} +1 -1
- package/dist/interface/assets/{theme-vkX_uBgJ.js → theme-FztlStyg.js} +1 -1
- package/dist/interface/assets/types-BHAzjgi3.js +1 -0
- package/dist/interface/assets/types-G1_espGV.js +1 -0
- package/dist/interface/assets/{types-fCQkAGfW.js → types-bCt9IrFD.js} +1 -1
- package/dist/interface/assets/updates-CVapvGAI.js +1 -0
- package/dist/interface/assets/{useAppVersion-9zH_FspP.js → useAppVersion-SrF7tGCe.js} +1 -1
- package/dist/interface/assets/useBackupRestore-Tc23Huvm.js +1 -0
- package/dist/interface/assets/{useCameraOptions-BIaDXHeq.js → useCameraOptions-zsIqf0i9.js} +1 -1
- package/dist/interface/assets/{useLogsSocket-BLV7dWSG.js → useLogsSocket-DSltWBh4.js} +1 -1
- package/dist/interface/assets/{useNavLayout-wq-6JyWK.js → useNavLayout-BhlxDHV7.js} +1 -1
- package/dist/interface/assets/{usePermissions-BiBlyeQl.js → usePermissions-4HqGU99G.js} +1 -1
- package/dist/interface/assets/{usePluginUpdates-BZJSqnSF.js → usePluginUpdates-CKH0Hb87.js} +1 -1
- package/dist/interface/assets/{usePushRegistration-CGFiyCuv.js → usePushRegistration-DAE3goyn.js} +1 -1
- package/dist/interface/assets/{useServerRestart-CjPAgzoX.js → useServerRestart-DoLrF47t.js} +1 -1
- package/dist/interface/assets/{useStreamStatus-BFCF1B3T.js → useStreamStatus-B3QIWjDE.js} +1 -1
- package/dist/interface/assets/useTabSwipe-BYFLQ9EY.js +1 -0
- package/dist/interface/assets/{useUpdateChannel-F4WpbMJR.js → useUpdateChannel-DWEw-ZyB.js} +1 -1
- package/dist/interface/assets/useUpdatesSocket-CoxkS7Hr.js +1 -0
- package/dist/interface/assets/{useUserOptions-GbSC7_qt.js → useUserOptions-DCDeuz2p.js} +1 -1
- package/dist/interface/assets/vendor-cameraui-4iwjOYwz.js +2326 -0
- package/dist/interface/assets/vendor-core-gJradu21.js +1 -0
- package/dist/interface/assets/{vendor-primevue-b9CB9Uh0.js → vendor-primevue-DMAuiM9b.js} +72 -72
- package/dist/interface/index.html +31 -27
- package/dist/interface/sw.js +1 -1
- package/dist/server/package.json +9 -8
- package/dist/server/requirements.txt +1 -1
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/__init__.py +4 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/__init__.py +4 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/config.py +6 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/detection.py +3 -3
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/camera/enums.py +6 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/plugin/interfaces.py +24 -0
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/detection.py +3 -3
- package/dist/server/src/_camera_ui_tools/camera_ui_sdk/sensor/object.py +6 -1
- package/dist/server/src/api/controllers/frameWorkers.controller.d.ts +2 -2
- package/dist/server/src/api/controllers/frameWorkers.controller.js +26 -49
- package/dist/server/src/api/controllers/frameWorkers.controller.js.map +1 -1
- package/dist/server/src/api/controllers/remote.controller.d.ts +1 -0
- package/dist/server/src/api/controllers/remote.controller.js +13 -12
- package/dist/server/src/api/controllers/remote.controller.js.map +1 -1
- package/dist/server/src/api/controllers/server.controller.js +5 -2
- package/dist/server/src/api/controllers/server.controller.js.map +1 -1
- package/dist/server/src/api/controllers/updates.controller.d.ts +8 -0
- package/dist/server/src/api/controllers/updates.controller.js +40 -0
- package/dist/server/src/api/controllers/updates.controller.js.map +1 -0
- package/dist/server/src/api/controllers/workers.controller.js +8 -2
- package/dist/server/src/api/controllers/workers.controller.js.map +1 -1
- package/dist/server/src/api/database/index.d.ts +1 -1
- package/dist/server/src/api/database/index.js +1 -1
- package/dist/server/src/api/database/migrations/v2-1-11.js.map +1 -1
- package/dist/server/src/api/database/migrations/v2-1-13.d.ts +3 -0
- package/dist/server/src/api/database/migrations/v2-1-13.js +51 -0
- package/dist/server/src/api/database/migrations/v2-1-13.js.map +1 -0
- package/dist/server/src/api/database/migrations/v2-1-14.d.ts +3 -0
- package/dist/server/src/api/database/migrations/v2-1-14.js +87 -0
- package/dist/server/src/api/database/migrations/v2-1-14.js.map +1 -0
- package/dist/server/src/api/routes/index.js +3 -1
- package/dist/server/src/api/routes/index.js.map +1 -1
- package/dist/server/src/api/routes/updates.routes.d.ts +2 -0
- package/dist/server/src/api/routes/updates.routes.js +47 -0
- package/dist/server/src/api/routes/updates.routes.js.map +1 -0
- package/dist/server/src/api/routes/workers.routes.js +3 -2
- package/dist/server/src/api/routes/workers.routes.js.map +1 -1
- package/dist/server/src/api/schemas/cameras.schema.d.ts +101 -51
- package/dist/server/src/api/schemas/cameras.schema.js +18 -2
- package/dist/server/src/api/schemas/cameras.schema.js.map +1 -1
- package/dist/server/src/api/schemas/workers.schema.d.ts +3 -0
- package/dist/server/src/api/schemas/workers.schema.js +5 -0
- package/dist/server/src/api/schemas/workers.schema.js.map +1 -1
- package/dist/server/src/api/services/plugins.service.d.ts +4 -1
- package/dist/server/src/api/services/plugins.service.js +23 -4
- package/dist/server/src/api/services/plugins.service.js.map +1 -1
- package/dist/server/src/api/services/server.service.d.ts +3 -1
- package/dist/server/src/api/services/server.service.js +6 -1
- package/dist/server/src/api/services/server.service.js.map +1 -1
- package/dist/server/src/api/services/updates.service.d.ts +108 -0
- package/dist/server/src/api/services/updates.service.js +476 -0
- package/dist/server/src/api/services/updates.service.js.map +1 -0
- package/dist/server/src/api/types/index.d.ts +6 -1
- package/dist/server/src/api/websocket/index.js +2 -0
- package/dist/server/src/api/websocket/index.js.map +1 -1
- package/dist/server/src/api/websocket/nsp/metrics.d.ts +2 -0
- package/dist/server/src/api/websocket/nsp/metrics.js +36 -4
- package/dist/server/src/api/websocket/nsp/metrics.js.map +1 -1
- package/dist/server/src/api/websocket/nsp/server.js +43 -7
- package/dist/server/src/api/websocket/nsp/server.js.map +1 -1
- package/dist/server/src/api/websocket/types.d.ts +3 -0
- package/dist/server/src/camera/decoder/debug/detection-record.d.ts +6 -0
- package/dist/server/src/camera/decoder/debug/detection-record.js +21 -0
- package/dist/server/src/camera/decoder/debug/detection-record.js.map +1 -1
- package/dist/server/src/camera/decoder/detection-coordinator.d.ts +19 -1
- package/dist/server/src/camera/decoder/detection-coordinator.js +306 -84
- package/dist/server/src/camera/decoder/detection-coordinator.js.map +1 -1
- package/dist/server/src/camera/decoder/detection-pipeline.d.ts +3 -1
- package/dist/server/src/camera/decoder/detection-pipeline.js +12 -4
- package/dist/server/src/camera/decoder/detection-pipeline.js.map +1 -1
- package/dist/server/src/camera/decoder/detection-window.d.ts +17 -0
- package/dist/server/src/camera/decoder/detection-window.js +188 -0
- package/dist/server/src/camera/decoder/detection-window.js.map +1 -0
- package/dist/server/src/camera/decoder/event-manager.d.ts +1 -0
- package/dist/server/src/camera/decoder/event-manager.js +12 -0
- package/dist/server/src/camera/decoder/event-manager.js.map +1 -1
- package/dist/server/src/camera/decoder/frame-scaler.d.ts +12 -0
- package/dist/server/src/camera/decoder/frame-scaler.js +38 -7
- package/dist/server/src/camera/decoder/frame-scaler.js.map +1 -1
- package/dist/server/src/camera/decoder/motion-localizer.d.ts +16 -0
- package/dist/server/src/camera/decoder/motion-localizer.js +49 -0
- package/dist/server/src/camera/decoder/motion-localizer.js.map +1 -0
- package/dist/server/src/camera/decoder/perf-tracker.d.ts +2 -0
- package/dist/server/src/camera/decoder/perf-tracker.js +4 -0
- package/dist/server/src/camera/decoder/perf-tracker.js.map +1 -1
- package/dist/server/src/camera/decoder/plugin-registry.js +1 -6
- package/dist/server/src/camera/decoder/plugin-registry.js.map +1 -1
- package/dist/server/src/camera/decoder/sources/analysis-source.d.ts +1 -0
- package/dist/server/src/camera/decoder/sources/buffered-source.d.ts +1 -0
- package/dist/server/src/camera/decoder/sources/buffered-source.js +38 -0
- package/dist/server/src/camera/decoder/sources/buffered-source.js.map +1 -1
- package/dist/server/src/camera/decoder/types.d.ts +9 -8
- package/dist/server/src/camera/decoder/types.js.map +1 -1
- package/dist/server/src/main.js +22 -2
- package/dist/server/src/main.js.map +1 -1
- package/dist/server/src/manager/types.d.ts +1 -0
- package/dist/server/src/manager/types.js +2 -0
- package/dist/server/src/manager/types.js.map +1 -1
- package/dist/server/src/mqtt/ha-discovery.js +0 -1
- package/dist/server/src/mqtt/ha-discovery.js.map +1 -1
- package/dist/server/src/plugins/index.js +0 -2
- package/dist/server/src/plugins/index.js.map +1 -1
- package/dist/server/src/remote/types.d.ts +1 -2
- package/dist/server/src/rpc/leafConnection.d.ts +12 -0
- package/dist/server/src/rpc/leafConnection.js +60 -0
- package/dist/server/src/rpc/leafConnection.js.map +1 -0
- package/dist/server/src/rpc/server.d.ts +2 -0
- package/dist/server/src/rpc/server.js +7 -1
- package/dist/server/src/rpc/server.js.map +1 -1
- package/dist/server/src/services/config/index.js +2 -0
- package/dist/server/src/services/config/index.js.map +1 -1
- package/dist/server/src/types.d.ts +10 -1
- package/dist/server/src/utils/ipc.d.ts +9 -0
- package/dist/server/src/utils/ipc.js +31 -5
- package/dist/server/src/utils/ipc.js.map +1 -1
- package/dist/server/src/utils/system-info.d.ts +9 -0
- package/dist/server/src/utils/system-info.js +48 -0
- package/dist/server/src/utils/system-info.js.map +1 -0
- package/dist/server/src/workers/agent.d.ts +3 -0
- package/dist/server/src/workers/agent.js +35 -7
- package/dist/server/src/workers/agent.js.map +1 -1
- package/dist/server/src/workers/capabilities/frame-decoding.d.ts +2 -2
- package/dist/server/src/workers/capabilities/frame-decoding.js +5 -5
- package/dist/server/src/workers/capabilities/frame-decoding.js.map +1 -1
- package/dist/server/src/workers/capabilities/handler.d.ts +2 -2
- package/dist/server/src/workers/capabilities/plugin-host.d.ts +2 -2
- package/dist/server/src/workers/capabilities/plugin-host.js +6 -6
- package/dist/server/src/workers/capabilities/plugin-host.js.map +1 -1
- package/dist/server/src/workers/manager.d.ts +9 -1
- package/dist/server/src/workers/manager.js +24 -0
- package/dist/server/src/workers/manager.js.map +1 -1
- package/dist/server/src/workers/types.d.ts +14 -0
- package/dist/server/src/workers/types.js.map +1 -1
- package/package.json +9 -8
- package/dist/interface/assets/Automation-DA89AEEI.js +0 -3
- package/dist/interface/assets/AutomationImport-hYr3Lp8F.js +0 -2
- package/dist/interface/assets/Automations-B6WFJyxS.js +0 -2
- package/dist/interface/assets/Camera-C5gF7yVN.css +0 -1
- package/dist/interface/assets/Camera-DmsSKvpY.js +0 -2
- package/dist/interface/assets/Cameras-KOOphtlx.js +0 -652
- package/dist/interface/assets/Camview-BPQIinyP.js +0 -1
- package/dist/interface/assets/ConfigTriggerDetection-iThbCKOO.js +0 -1
- package/dist/interface/assets/ConfigTriggerGeofence-BeKwVWvS.js +0 -1
- package/dist/interface/assets/Console-N_2Vornl.js +0 -1
- package/dist/interface/assets/CuiAutomationRunsDialog-Cp6Apki9.js +0 -1
- package/dist/interface/assets/CuiBottomSheet-CIR_fmSk.js +0 -1
- package/dist/interface/assets/CuiCameraPipCard-DP6X45oq.js +0 -1
- package/dist/interface/assets/CuiCameraRecordings-CRjXsdO4.js +0 -1
- package/dist/interface/assets/CuiCameraTable-D5ZqTLVt.js +0 -1
- package/dist/interface/assets/CuiDataTable-wA_LbHH8.js +0 -1
- package/dist/interface/assets/CuiLightControl-CB_Tp4tI.js +0 -1
- package/dist/interface/assets/CuiPluginCard-DEuNt5ni.js +0 -2
- package/dist/interface/assets/CuiPluginCategoryChip-BbkbkYj6.js +0 -1
- package/dist/interface/assets/CuiQRCode-Dh9EcaVc.js +0 -1
- package/dist/interface/assets/CuiRecordingsGrid-HjZEiSyp.js +0 -1
- package/dist/interface/assets/CuiSchema--yMBD996.css +0 -1
- package/dist/interface/assets/CuiSchema-CSFoI6cg.js +0 -1
- package/dist/interface/assets/Faces-CPZ5RA68.js +0 -1
- package/dist/interface/assets/FirstSteps-CaF8STWH.js +0 -1
- package/dist/interface/assets/Menu-T-54ZSSD.js +0 -1
- package/dist/interface/assets/Metrics-CQGKmHev.css +0 -1
- package/dist/interface/assets/Metrics-Dgm5qpzh.js +0 -6
- package/dist/interface/assets/Plugin-YxqbMbUc.js +0 -1
- package/dist/interface/assets/PluginSearch-5AgSWlmi.js +0 -1
- package/dist/interface/assets/PluginSearch-P274oMvy.js +0 -2
- package/dist/interface/assets/Plugins-Bvru3q2P.js +0 -1
- package/dist/interface/assets/Recordings-BWGWC6Kq.js +0 -1
- package/dist/interface/assets/SensorEdit-gEw6HHZs.js +0 -1
- package/dist/interface/assets/Sensors-DukA8Xqx.js +0 -2
- package/dist/interface/assets/Settings-DWpeWPJh.js +0 -1
- package/dist/interface/assets/SettingsAccount-C1OpCtob.js +0 -1
- package/dist/interface/assets/SettingsAccount-CrLcqzSn.js +0 -1
- package/dist/interface/assets/SettingsAppearance-AhUjml5E.js +0 -1
- package/dist/interface/assets/SettingsBackup-BJupyZCJ.js +0 -1
- package/dist/interface/assets/SettingsMqtt-F3pV1Bvo.js +0 -1
- package/dist/interface/assets/SettingsNotifications-BmaAccX9.js +0 -1
- package/dist/interface/assets/SettingsRemote-C_ikoXW7.js +0 -2
- package/dist/interface/assets/SettingsRemote-DzrfpHjw.css +0 -1
- package/dist/interface/assets/SettingsSystem-Ct3qms5O.js +0 -2
- package/dist/interface/assets/SettingsUsers-D36vZ8Zf.js +0 -1
- package/dist/interface/assets/Terminal-ltPiB9CB.js +0 -4
- package/dist/interface/assets/Workers-Bowrc1AF.js +0 -2
- package/dist/interface/assets/api-daCggwpn.css +0 -2
- package/dist/interface/assets/api-py5HP4SF.js +0 -2
- package/dist/interface/assets/cloudHandoff-CL4sircA.js +0 -1
- package/dist/interface/assets/deployed-code-update-xHE-blDN.js +0 -1
- package/dist/interface/assets/main-CLvcwWW7.js +0 -3
- package/dist/interface/assets/main-mJXdi_gx.css +0 -1
- package/dist/interface/assets/round-restart-alt-D3jT5i_T.js +0 -1
- package/dist/interface/assets/round-restart-alt-DdIfy7mU.css +0 -1
- package/dist/interface/assets/sensorIcons-BXauWntX.js +0 -1
- package/dist/interface/assets/types-CrvnT4-i.js +0 -1
- package/dist/interface/assets/types-D6IQ6ssc.js +0 -1
- package/dist/interface/assets/useBackupRestore-Dbf24OqP.js +0 -1
- package/dist/interface/assets/vendor-cameraui-0EJfDg8o.js +0 -2326
- package/dist/interface/assets/vendor-core-RnPzfwaA.js +0 -1
|
@@ -19,11 +19,13 @@ import { AudioDetectionLoop } from './audio-loop.js';
|
|
|
19
19
|
import { CascadeManager } from './cascade-manager.js';
|
|
20
20
|
import { detectionRecord } from './debug/detection-record.js';
|
|
21
21
|
import { DetectionPipeline } from './detection-pipeline.js';
|
|
22
|
+
import { clusterBoxes, DetectionWindow, mergeWindowDetections, MOTION_PAD, planWindowsOnce, TRACK_PAD } from './detection-window.js';
|
|
22
23
|
import { DwellManager } from './dwell-manager.js';
|
|
23
24
|
import { DetectionEventManager, MOMENT_RANK_ATTRIBUTE, MOMENT_RANK_OBJECT } from './event-manager.js';
|
|
24
25
|
import { EventThumbnailer } from './event-thumbnailer.js';
|
|
25
26
|
import { FrameScaler } from './frame-scaler.js';
|
|
26
27
|
import { directionBetween, directionOf, MOMENT_FORMATS, MOMENT_QUALITY, momentWindow, unionBox } from './moment-crop.js';
|
|
28
|
+
import { MotionLocalizer } from './motion-localizer.js';
|
|
27
29
|
import { PerfTracker } from './perf-tracker.js';
|
|
28
30
|
import { normalizePlateText } from './plate-vote.js';
|
|
29
31
|
import { isVideoInputSpec, modelIdentity, PluginRegistry } from './plugin-registry.js';
|
|
@@ -74,6 +76,13 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
74
76
|
perf = new PerfTracker();
|
|
75
77
|
benchmarkRunning = false;
|
|
76
78
|
hqUpgrade;
|
|
79
|
+
localizer;
|
|
80
|
+
lastLocalizeAt = 0;
|
|
81
|
+
anchorBoxes = [];
|
|
82
|
+
trackAnchorBoxes = [];
|
|
83
|
+
farewellBoxes = [];
|
|
84
|
+
lastTrackedById = new Map();
|
|
85
|
+
detectionWindow = new DetectionWindow();
|
|
77
86
|
mainStreamActive = false;
|
|
78
87
|
idleSince = 0;
|
|
79
88
|
lastMotionAt = 0;
|
|
@@ -115,6 +124,7 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
115
124
|
if (config.streamHot)
|
|
116
125
|
this.frameSource.start();
|
|
117
126
|
this.frameScaler = new FrameScaler(null, logger, this.privacy);
|
|
127
|
+
this.localizer = new MotionLocalizer();
|
|
118
128
|
this.pipeline = new DetectionPipeline(this.pipelineZones(), config.detectionSettings);
|
|
119
129
|
this.secondaries = new SecondaryStage(this, this.plugins, this.pipeline, this.frameScaler, this.proxy, this.perf, logger);
|
|
120
130
|
if (config.zones.lines.length > 0) {
|
|
@@ -167,6 +177,7 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
167
177
|
this.cascadeUnsubscribe = this.cascade.onChange((event) => {
|
|
168
178
|
if (event.type === 'activated') {
|
|
169
179
|
this.startAdHocVideoLoopIfNeeded();
|
|
180
|
+
this.seedLocalizerReference();
|
|
170
181
|
}
|
|
171
182
|
else {
|
|
172
183
|
this.stopAdHocVideoLoopIfIdle();
|
|
@@ -194,6 +205,7 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
194
205
|
if (!this.dwell.hasActive() && this.worldSpans.size === 0 && !this.eventManager.hasActiveSegment()) {
|
|
195
206
|
this.eventManager.forceEndActiveEvent();
|
|
196
207
|
}
|
|
208
|
+
this.stopAdHocVideoLoopIfIdle();
|
|
197
209
|
}
|
|
198
210
|
});
|
|
199
211
|
}
|
|
@@ -390,6 +402,9 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
390
402
|
this.ptzAutotracker.handlePresenceDetections(externalDetections);
|
|
391
403
|
if (this.ptzAutotracker.suppressionActive)
|
|
392
404
|
return;
|
|
405
|
+
detectionRecord.tick({
|
|
406
|
+
externalObject: { detected: filtered.detected === true, count: (filtered.detections ?? []).length },
|
|
407
|
+
});
|
|
393
408
|
this.ingestDetectionResult(SensorType.Object, sensorId, filtered);
|
|
394
409
|
this.eventManager.processResults(this.buildSnapshot());
|
|
395
410
|
// re-shoot the event thumbnail: smart-camera reports arrive after the
|
|
@@ -403,8 +418,10 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
403
418
|
if (filtered.detected !== true)
|
|
404
419
|
return;
|
|
405
420
|
// assist alone is enough: its boxes upgrade zones, bboxes and thumbnails
|
|
406
|
-
// even when no face/plate/clip secondary consumes them
|
|
407
|
-
|
|
421
|
+
// even when no face/plate/clip secondary consumes them; without either,
|
|
422
|
+
// the embedded diff's anchors can still localize a moment crop
|
|
423
|
+
const hasAnchors = this.anchorBoxes.length > 0 || this.farewellBoxes.length > 0;
|
|
424
|
+
if (!this.plugins.hasFrameBasedSecondary() && !this.plugins.hasEligibleObjectAssist() && !hasAnchors)
|
|
408
425
|
return;
|
|
409
426
|
if (this.processingExternalSecondary)
|
|
410
427
|
return; // previous RPC still running
|
|
@@ -416,42 +433,60 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
416
433
|
return;
|
|
417
434
|
try {
|
|
418
435
|
const results = { timestamp: Date.now() };
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
this.logger.error('Thumbnail generation error:', error);
|
|
441
|
-
}
|
|
442
|
-
this.ingestResultsForAllSecondaries(results);
|
|
443
|
-
const snapshot = this.buildSnapshot();
|
|
444
|
-
if (results.thumbnails && results.thumbnails.length > 0) {
|
|
445
|
-
snapshot.thumbnails = results.thumbnails;
|
|
436
|
+
// anchors may have switched analysis to the main stream: the assist
|
|
437
|
+
// windows and secondary crops should see those native pixels
|
|
438
|
+
const analysis = await this.acquireAnalysisFrame(handle.frame);
|
|
439
|
+
try {
|
|
440
|
+
const objects = await this.runObjectAssist(analysis.frame, rawExternal, analysis.scaler);
|
|
441
|
+
this.ingestAssistedObjects(sensorId, objects);
|
|
442
|
+
if (objects.assisted) {
|
|
443
|
+
// real boxes: crop the object like the frame pipeline, so face and
|
|
444
|
+
// plate secondaries run on the subject instead of the whole scene
|
|
445
|
+
// (processExternal only adapts the shape, external boxes get no real tracking)
|
|
446
|
+
const objectDetections = this.pipeline.processExternal(objects.detections);
|
|
447
|
+
detectionRecord.tick({ assistProcessed: { count: objectDetections.length, bufferedObjects: this.currentDetectionState.object?.detections?.length ?? 0 } });
|
|
448
|
+
await this.runSecondariesAndThumbnails(analysis, objectDetections, results);
|
|
449
|
+
await this.captureExternalMoment(objectDetections, analysis, results.timestamp);
|
|
450
|
+
this.ingestResultsForAllSecondaries(results);
|
|
451
|
+
const snapshot = this.buildSnapshot();
|
|
452
|
+
detectionRecord.tick({ assistSnapshot: { objects: snapshot.objects.length } });
|
|
453
|
+
if (results.thumbnails && results.thumbnails.length > 0) {
|
|
454
|
+
snapshot.thumbnails = results.thumbnails;
|
|
455
|
+
}
|
|
456
|
+
this.eventManager.processResults(snapshot);
|
|
446
457
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
458
|
+
else {
|
|
459
|
+
// no assist boxes: the diff's motion clusters are the only
|
|
460
|
+
// localization, still better than a full-scene card
|
|
461
|
+
const anchorDetections = this.anchorMomentDetections(rawExternal);
|
|
462
|
+
if (anchorDetections.length > 0) {
|
|
463
|
+
await this.captureExternalMoment(anchorDetections, analysis, results.timestamp);
|
|
464
|
+
}
|
|
465
|
+
const sceneJpeg = await this.secondaries.detectFullFrame(analysis.frame, results);
|
|
466
|
+
try {
|
|
467
|
+
results.thumbnails = await this.secondaries.generateThumbnails(analysis.frame, analysis.scaler, results);
|
|
468
|
+
}
|
|
469
|
+
catch (error) {
|
|
470
|
+
this.logger.error('Thumbnail generation error:', error);
|
|
471
|
+
}
|
|
472
|
+
this.ingestResultsForAllSecondaries(results);
|
|
473
|
+
const snapshot = this.buildSnapshot();
|
|
474
|
+
if (results.thumbnails && results.thumbnails.length > 0) {
|
|
475
|
+
snapshot.thumbnails = results.thumbnails;
|
|
476
|
+
}
|
|
477
|
+
if (sceneJpeg)
|
|
478
|
+
snapshot.eventThumbnail = sceneJpeg;
|
|
479
|
+
const wantsEventThumb = this.eventManager.needsThumbnail() || this.snapshotWillStartEvent(snapshot);
|
|
480
|
+
this.eventManager.processResults(snapshot);
|
|
481
|
+
if (wantsEventThumb) {
|
|
482
|
+
this.thumbnailer.upgradeEventThumbnailAsync();
|
|
483
|
+
}
|
|
453
484
|
}
|
|
454
485
|
}
|
|
486
|
+
finally {
|
|
487
|
+
if (analysis.frame !== handle.frame)
|
|
488
|
+
analysis.frame[Symbol.dispose]?.();
|
|
489
|
+
}
|
|
455
490
|
}
|
|
456
491
|
finally {
|
|
457
492
|
await handle[Symbol.asyncDispose]();
|
|
@@ -511,18 +546,28 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
511
546
|
hasPlugin(sensorType) {
|
|
512
547
|
return this.plugins.has(sensorType);
|
|
513
548
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
for
|
|
521
|
-
|
|
549
|
+
get windowAnchorsWanted() {
|
|
550
|
+
return this.plugins.get(SensorType.Object)?.requiresFrames === true || this.plugins.hasEligibleObjectAssist();
|
|
551
|
+
}
|
|
552
|
+
get localizerWanted() {
|
|
553
|
+
// the registry only holds frame-based providers; a smart-camera object
|
|
554
|
+
// sensor (Reolink AI, ONVIF) feeds externally and needs the anchors just
|
|
555
|
+
// as much — for assist zoom windows and for framing its moment pictures
|
|
556
|
+
if (this.plugins.has(SensorType.Object) || this.plugins.hasEligibleObjectAssist())
|
|
557
|
+
return true;
|
|
558
|
+
for (const sensorType of this.feedingSensors.values()) {
|
|
559
|
+
if (sensorType === SensorType.Object)
|
|
522
560
|
return true;
|
|
523
561
|
}
|
|
524
562
|
return false;
|
|
525
563
|
}
|
|
564
|
+
get windowWantsMainStream() {
|
|
565
|
+
if (!this.cascade.isActive)
|
|
566
|
+
return false;
|
|
567
|
+
if (this.anchorBoxes.length === 0 && this.trackAnchorBoxes.length === 0)
|
|
568
|
+
return false;
|
|
569
|
+
return this.windowAnchorsWanted;
|
|
570
|
+
}
|
|
526
571
|
get cascadeEnabled() {
|
|
527
572
|
return this.config.detectionSettings.cascadeDetection !== false;
|
|
528
573
|
}
|
|
@@ -539,7 +584,22 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
539
584
|
const [w, h] = this.config.interfaceSettings.aspectRatio.split(':').map(Number);
|
|
540
585
|
return w / h;
|
|
541
586
|
}
|
|
587
|
+
externalObjectSpanActive() {
|
|
588
|
+
// the registry holds frame-based providers only; a smart-camera object
|
|
589
|
+
// sensor (Reolink AI, ONVIF) lives in the feeding set, and its dwell is
|
|
590
|
+
// what keeps the span open between its report edges
|
|
591
|
+
if (this.plugins.get(SensorType.Object)?.requiresFrames)
|
|
592
|
+
return false;
|
|
593
|
+
for (const [sensorId, sensorType] of this.feedingSensors) {
|
|
594
|
+
if (sensorType === SensorType.Object && this.dwell.isActive(sensorId))
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
542
599
|
handleCascadeDeactivated() {
|
|
600
|
+
this.anchorBoxes = [];
|
|
601
|
+
this.farewellBoxes = [];
|
|
602
|
+
this.detectionWindow.reset();
|
|
543
603
|
// clear cascade-gated buffer slots, keep motion/audio
|
|
544
604
|
const cs = this.currentDetectionState;
|
|
545
605
|
cs.object = undefined;
|
|
@@ -965,18 +1025,26 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
965
1025
|
}
|
|
966
1026
|
}
|
|
967
1027
|
startAdHocVideoLoopIfNeeded() {
|
|
968
|
-
|
|
1028
|
+
// localizerWanted covers what the registry cannot see: an object assist or
|
|
1029
|
+
// an external object sensor needs the loop for the localizer's anchors
|
|
1030
|
+
if (!this.loopRunning && (this.plugins.needsAdHocLoop() || this.localizerWanted)) {
|
|
969
1031
|
this.adHocVideoLoop = true;
|
|
970
1032
|
this.logger.debug('Starting ad-hoc video loop for sensor cascade trigger');
|
|
971
1033
|
this.startVideoLoop();
|
|
972
1034
|
}
|
|
973
1035
|
}
|
|
974
1036
|
stopAdHocVideoLoopIfIdle() {
|
|
975
|
-
if (this.adHocVideoLoop
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
1037
|
+
if (!this.adHocVideoLoop || this.plugins.shouldVideoBeActive())
|
|
1038
|
+
return;
|
|
1039
|
+
// the localizer and assist still need frames while the event runs;
|
|
1040
|
+
// stopping on the cascade edge alone churned the main-stream decoder
|
|
1041
|
+
// open/closed mid-event, which starves the hw device (vaapi surface sync
|
|
1042
|
+
// failures) right when the next report arrives
|
|
1043
|
+
if (this.cascade.isActive || this.dwell.hasActive() || this.eventManager.hasActiveSegment())
|
|
1044
|
+
return;
|
|
1045
|
+
this.adHocVideoLoop = false;
|
|
1046
|
+
this.logger.debug('Stopping ad-hoc video loop — idle');
|
|
1047
|
+
this.stopVideoLoop();
|
|
980
1048
|
}
|
|
981
1049
|
async runDetectionLoop() {
|
|
982
1050
|
// the source reconnects on its own, nextFrame simply waits it out
|
|
@@ -1009,6 +1077,8 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1009
1077
|
this.frameScaler.updateHardwareContext(this.frameSource.hardwareContext);
|
|
1010
1078
|
this.frameScaler.clearCache();
|
|
1011
1079
|
this.thumbnailer.sync(this.mainStreamAnalysisWanted);
|
|
1080
|
+
this.localizer.reset();
|
|
1081
|
+
this.detectionWindow.reset();
|
|
1012
1082
|
}
|
|
1013
1083
|
// motion always reads the low stream: switching its input resolution
|
|
1014
1084
|
// would reset the background model on every transition
|
|
@@ -1106,7 +1176,7 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1106
1176
|
return undefined;
|
|
1107
1177
|
}
|
|
1108
1178
|
updateStreamState() {
|
|
1109
|
-
if (this.worldSpans.size > 0 || this.eventManager.hasActiveSegment()) {
|
|
1179
|
+
if (this.worldSpans.size > 0 || this.eventManager.hasActiveSegment() || this.windowWantsMainStream) {
|
|
1110
1180
|
this.idleSince = 0;
|
|
1111
1181
|
if (!this.mainStreamActive && this.mainStreamAvailable) {
|
|
1112
1182
|
this.mainStreamActive = true;
|
|
@@ -1141,6 +1211,7 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1141
1211
|
const t0 = Date.now();
|
|
1142
1212
|
let motionDetected = false;
|
|
1143
1213
|
let objectDetections = [];
|
|
1214
|
+
let staticDetections = [];
|
|
1144
1215
|
const results = { timestamp: t0 };
|
|
1145
1216
|
// while the PTZ repositions: motion and object keep running so the
|
|
1146
1217
|
// background model and track ids survive the pan, but nothing below
|
|
@@ -1160,6 +1231,8 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1160
1231
|
return;
|
|
1161
1232
|
if (motionFrame) {
|
|
1162
1233
|
this.lastMotionAt = t0;
|
|
1234
|
+
if (this.localizerWanted)
|
|
1235
|
+
this.feedLocalizer(motionFrame, t0, ptzSuppressed);
|
|
1163
1236
|
try {
|
|
1164
1237
|
const motionInferStart = Date.now();
|
|
1165
1238
|
const result = await motionPlugin.proxy.detectMotion(motionFrame);
|
|
@@ -1193,6 +1266,17 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1193
1266
|
// no frame-based motion plugin, the cascade is the only motion-equivalent signal
|
|
1194
1267
|
motionDetected = true;
|
|
1195
1268
|
results.cascadeTriggered = true;
|
|
1269
|
+
// the localizer scales its own gray here, nobody else needed one
|
|
1270
|
+
const localizeDue = t0 - this.lastLocalizeAt >= MOTION_INTERVAL_MS - TICK_SLACK_MS;
|
|
1271
|
+
if (localizeDue && this.localizerWanted) {
|
|
1272
|
+
const scaleStart = Date.now();
|
|
1273
|
+
const gray = await this.scaleForMotionInput(motionRawFrame);
|
|
1274
|
+
this.perf.scaleMs += Date.now() - scaleStart;
|
|
1275
|
+
if (!this.loopRunning)
|
|
1276
|
+
return;
|
|
1277
|
+
if (gray)
|
|
1278
|
+
this.feedLocalizer(gray, t0, ptzSuppressed);
|
|
1279
|
+
}
|
|
1196
1280
|
}
|
|
1197
1281
|
// detected is re-derived after zone filtering, the plugin's own flag is ignored
|
|
1198
1282
|
if (results.motion && motionPlugin) {
|
|
@@ -1206,25 +1290,16 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1206
1290
|
const objectPlugin = this.plugins.get(SensorType.Object);
|
|
1207
1291
|
const shouldDetectObjects = objectPlugin?.requiresFrames === true && (ptzSuppressed || !this.cascadeEnabled || this.cascade.isActive);
|
|
1208
1292
|
if (shouldDetectObjects) {
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
if (objectFrame) {
|
|
1215
|
-
try {
|
|
1216
|
-
const inferStart = Date.now();
|
|
1217
|
-
const result = await PromiseTimeout(objectPlugin.proxy.detectObjects(objectFrame.model), DETECT_TIMEOUT_MS, undefined, `Object detection timed out after ${DETECT_TIMEOUT_MS}ms`);
|
|
1218
|
-
this.perf.objectMs += Date.now() - inferStart;
|
|
1219
|
-
this.perf.objectCount++;
|
|
1220
|
-
if (!this.loopRunning)
|
|
1221
|
-
return;
|
|
1293
|
+
try {
|
|
1294
|
+
const detected = await this.runObjectDetection(objectPlugin, analysis, results.motion?.detections ?? []);
|
|
1295
|
+
if (!this.loopRunning)
|
|
1296
|
+
return;
|
|
1297
|
+
if (detected) {
|
|
1222
1298
|
this.trackDetectionCadence();
|
|
1223
1299
|
// run the pipeline even on empty frames so Norfair advances its
|
|
1224
1300
|
// Kalman state; the pose delta keeps predictions stable across pans
|
|
1225
1301
|
const poseDelta = this.ptzAutotracker.consumePoseDelta();
|
|
1226
1302
|
const postStart = Date.now();
|
|
1227
|
-
const detected = FrameScaler.undoLetterbox(ensureDetectionBoxes(result.detections), objectFrame.geometry);
|
|
1228
1303
|
const pipelineResult = this.pipeline.process(detected, poseDelta);
|
|
1229
1304
|
this.perf.postMs += Date.now() - postStart;
|
|
1230
1305
|
// the tick that opens a span analysed the low stream (the switch lands
|
|
@@ -1258,25 +1333,35 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1258
1333
|
return cx > -0.1 && cx < 1.1 && cy > -0.1 && cy < 1.1;
|
|
1259
1334
|
});
|
|
1260
1335
|
objectDetections = visibleTracks.filter((t) => !t.trackLost);
|
|
1261
|
-
results.object = {
|
|
1336
|
+
results.object = { detected: objectDetections.length > 0, detections: visibleTracks };
|
|
1337
|
+
staticDetections = pipelineResult.staticTracks;
|
|
1262
1338
|
if (pipelineResult.crossings.length > 0)
|
|
1263
1339
|
results.lineCrossings = pipelineResult.crossings;
|
|
1264
1340
|
// incl. extrapolated tracks, otherwise a single missed detector
|
|
1265
1341
|
// frame flips the autotracker into LOST/REACQUIRE churn
|
|
1266
1342
|
this.ptzAutotracker.handleObjectDetections(pipelineResult.tracked);
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1343
|
+
// live tracks anchor the next tick's window; a track that just died
|
|
1344
|
+
// gets one farewell look at its last position
|
|
1345
|
+
this.trackAnchorBoxes = objectDetections.map((t) => t.box);
|
|
1346
|
+
for (const id of pipelineResult.removed) {
|
|
1347
|
+
const last = this.lastTrackedById.get(id);
|
|
1348
|
+
if (last)
|
|
1349
|
+
this.farewellBoxes.push(last);
|
|
1350
|
+
}
|
|
1351
|
+
this.lastTrackedById = new Map(pipelineResult.tracked.filter((t) => t.trackId !== undefined).map((t) => [t.trackId, t.box]));
|
|
1272
1352
|
}
|
|
1273
1353
|
}
|
|
1354
|
+
catch (error) {
|
|
1355
|
+
if (!this.loopRunning || isNoRespondersError(error))
|
|
1356
|
+
return;
|
|
1357
|
+
this.logger.error('Object detection error:', error);
|
|
1358
|
+
}
|
|
1274
1359
|
}
|
|
1275
1360
|
// tracker and autotracker are fed, everything event-facing stays quiet
|
|
1276
1361
|
if (ptzSuppressed) {
|
|
1277
1362
|
// object boxes stay live in the UI through the move, bbox publish only
|
|
1278
1363
|
if (objectPlugin && results.object) {
|
|
1279
|
-
this.writeSensorProperties(objectPlugin.sensorId, { detections: results.object.detections });
|
|
1364
|
+
this.writeSensorProperties(objectPlugin.sensorId, { detections: results.object.detections, staticDetections });
|
|
1280
1365
|
}
|
|
1281
1366
|
// keep an already-running object dwell alive so a chase doesn't end its
|
|
1282
1367
|
// own event, but never activate it from suppressed frames
|
|
@@ -1295,6 +1380,7 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1295
1380
|
this.ingestDetectionResult(SensorType.Object, objectPlugin.sensorId, {
|
|
1296
1381
|
detected: objectDetections.length > 0,
|
|
1297
1382
|
detections: results.object.detections,
|
|
1383
|
+
staticDetections,
|
|
1298
1384
|
});
|
|
1299
1385
|
}
|
|
1300
1386
|
if (!this.loopRunning)
|
|
@@ -1493,6 +1579,41 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1493
1579
|
return;
|
|
1494
1580
|
await this.captureMoment(subject, bestScore, trigger, result.tracked, analysis, at);
|
|
1495
1581
|
}
|
|
1582
|
+
anchorMomentDetections(reported) {
|
|
1583
|
+
const anchors = [...this.anchorBoxes, ...this.farewellBoxes];
|
|
1584
|
+
if (anchors.length === 0 || reported.length === 0)
|
|
1585
|
+
return [];
|
|
1586
|
+
const subject = reported.find((d) => d.label !== 'motion') ?? reported[0];
|
|
1587
|
+
const clusters = clusterBoxes(anchors);
|
|
1588
|
+
const largest = Math.max(...clusters.map((b) => b.width * b.height));
|
|
1589
|
+
// specks would drag the base union across the frame
|
|
1590
|
+
return clusters.filter((b) => b.width * b.height >= largest * 0.2).map((b) => ({ label: subject.label, confidence: subject.confidence, box: b }));
|
|
1591
|
+
}
|
|
1592
|
+
async captureExternalMoment(detections, analysis, at) {
|
|
1593
|
+
let subject;
|
|
1594
|
+
let bestScore = 0;
|
|
1595
|
+
for (const detection of detections) {
|
|
1596
|
+
const box = detection.box;
|
|
1597
|
+
if (!box)
|
|
1598
|
+
continue;
|
|
1599
|
+
const score = detection.confidence * Math.sqrt(box.width * box.height);
|
|
1600
|
+
if (score > bestScore) {
|
|
1601
|
+
bestScore = score;
|
|
1602
|
+
subject = detection;
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
if (!subject)
|
|
1606
|
+
return;
|
|
1607
|
+
if (!this.eventManager.wantsMoment(MOMENT_RANK_OBJECT, bestScore, 'low', at))
|
|
1608
|
+
return;
|
|
1609
|
+
const target = { subject: subject.box, base: unionBox(detections.map((d) => d.box).filter(Boolean)) };
|
|
1610
|
+
const rendered = await this.renderMoment(target, analysis);
|
|
1611
|
+
if (!rendered)
|
|
1612
|
+
return;
|
|
1613
|
+
this.eventManager.offerMoment({ strip: rendered.strip, card: rendered.card, capturedAt: at, score: bestScore, rank: MOMENT_RANK_OBJECT, stream: 'low' });
|
|
1614
|
+
// debugging
|
|
1615
|
+
await this.recordMoment(target, rendered, analysis, `${subject.label}-external`, bestScore, 'external', at);
|
|
1616
|
+
}
|
|
1496
1617
|
async captureMoment(subject, score, trigger, tracked, analysis, at) {
|
|
1497
1618
|
const box = { x: subject.x, y: subject.y, width: subject.width, height: subject.height };
|
|
1498
1619
|
const moving = tracked.filter((d) => (d.trackSpeed ?? 0) >= MOMENT_MOVING_SPEED).map((d) => d.box);
|
|
@@ -1527,7 +1648,6 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1527
1648
|
// legible one frames the shot, the rest stay their own attribute tiles
|
|
1528
1649
|
let best;
|
|
1529
1650
|
let bestScore = -1;
|
|
1530
|
-
let bestCard;
|
|
1531
1651
|
for (const candidate of candidates) {
|
|
1532
1652
|
const cut = results.thumbnails?.find((t) => t.label === candidate.label);
|
|
1533
1653
|
// a subject cut off by the frame edge makes a poor card
|
|
@@ -1542,20 +1662,21 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1542
1662
|
if (score > bestScore) {
|
|
1543
1663
|
bestScore = score;
|
|
1544
1664
|
best = candidate;
|
|
1545
|
-
bestCard = cut?.jpeg;
|
|
1546
1665
|
}
|
|
1547
1666
|
}
|
|
1548
1667
|
// ask before cutting: the same face rides along on every tick of a segment
|
|
1549
1668
|
// and re-encoding for a picture that loses anyway is pure cost
|
|
1550
1669
|
if (!best || !this.eventManager.wantsMoment(MOMENT_RANK_ATTRIBUTE, bestScore, analysis.isMainStream ? 'main' : 'low', at))
|
|
1551
1670
|
return;
|
|
1671
|
+
// the card frames the whole person with the face as its center, not the
|
|
1672
|
+
// bare face box: the zoomed face already exists as an attribute tile, and
|
|
1673
|
+
// a misdetected "face" zoomed to card size ruins the event picture
|
|
1552
1674
|
const target = {
|
|
1553
1675
|
subject: best.box,
|
|
1676
|
+
base: best.parentBox ?? best.box,
|
|
1554
1677
|
hint: best.parentBox ? directionBetween(best.box, best.parentBox) : undefined,
|
|
1555
1678
|
};
|
|
1556
|
-
|
|
1557
|
-
// card is already encoded; only the 16:9 companion is still missing
|
|
1558
|
-
const rendered = await this.renderMoment(target, analysis, bestCard);
|
|
1679
|
+
const rendered = await this.renderMoment(target, analysis);
|
|
1559
1680
|
if (!rendered)
|
|
1560
1681
|
return;
|
|
1561
1682
|
const stream = analysis.isMainStream ? 'main' : 'low';
|
|
@@ -1619,10 +1740,42 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1619
1740
|
const motionPlugin = this.plugins.get(SensorType.Motion);
|
|
1620
1741
|
if (!motionPlugin?.requiresFrames)
|
|
1621
1742
|
return undefined;
|
|
1743
|
+
return this.scaleForMotionInput(rawFrame);
|
|
1744
|
+
}
|
|
1745
|
+
async scaleForMotionInput(rawFrame) {
|
|
1622
1746
|
const maxWidth = MOTION_WIDTH_MAP[this.motionResolution];
|
|
1623
1747
|
const scaled = await this.frameScaler.scaleProportional(rawFrame, maxWidth, 'gray');
|
|
1624
1748
|
return scaled ? this.frameScaler.toVideoFrameData(scaled) : undefined;
|
|
1625
1749
|
}
|
|
1750
|
+
feedLocalizer(gray, t0, ptzSuppressed) {
|
|
1751
|
+
this.lastLocalizeAt = t0;
|
|
1752
|
+
const data = Buffer.isBuffer(gray.data) ? gray.data : Buffer.from(gray.data);
|
|
1753
|
+
const boxes = this.localizer.localize({ data, width: gray.width, height: gray.height });
|
|
1754
|
+
// during ego-motion the diff is garbage, feeding keeps the reference alive
|
|
1755
|
+
this.anchorBoxes = ptzSuppressed ? [] : boxes;
|
|
1756
|
+
}
|
|
1757
|
+
async seedLocalizerReference() {
|
|
1758
|
+
if (!this.localizerWanted || !this.frameSource.decodeOldestKeyframe)
|
|
1759
|
+
return;
|
|
1760
|
+
try {
|
|
1761
|
+
const frame = await this.frameSource.decodeOldestKeyframe();
|
|
1762
|
+
if (!frame)
|
|
1763
|
+
return;
|
|
1764
|
+
try {
|
|
1765
|
+
const gray = await this.scaleForMotionInput(frame);
|
|
1766
|
+
if (gray) {
|
|
1767
|
+
const data = Buffer.isBuffer(gray.data) ? gray.data : Buffer.from(gray.data);
|
|
1768
|
+
this.localizer.seedReference({ data, width: gray.width, height: gray.height });
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
finally {
|
|
1772
|
+
frame[Symbol.dispose]?.();
|
|
1773
|
+
}
|
|
1774
|
+
}
|
|
1775
|
+
catch (error) {
|
|
1776
|
+
this.logger.debug('Localizer reference seed failed:', error);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1626
1779
|
trackDetectionCadence() {
|
|
1627
1780
|
const now = Date.now();
|
|
1628
1781
|
const previous = this.lastObjectCallAt;
|
|
@@ -1656,6 +1809,43 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1656
1809
|
return undefined;
|
|
1657
1810
|
return this.scaleFrameForPlugin(rawFrame, objectPlugin, scaler);
|
|
1658
1811
|
}
|
|
1812
|
+
async runObjectDetection(objectPlugin, analysis, pluginMotionBoxes) {
|
|
1813
|
+
const inputSpec = objectPlugin.modelSpec?.input;
|
|
1814
|
+
const motionAnchors = [...this.anchorBoxes, ...pluginMotionBoxes.map((d) => d.box).filter((box) => box !== undefined), ...this.farewellBoxes];
|
|
1815
|
+
this.farewellBoxes = [];
|
|
1816
|
+
const windows = isVideoInputSpec(inputSpec)
|
|
1817
|
+
? this.detectionWindow.plan(motionAnchors, this.trackAnchorBoxes, analysis.frame.width, analysis.frame.height, inputSpec.width)
|
|
1818
|
+
: null;
|
|
1819
|
+
if (windows && windows.length > 0) {
|
|
1820
|
+
this.perf.zoomTicks++;
|
|
1821
|
+
this.perf.zoomWindows += windows.length;
|
|
1822
|
+
detectionRecord.zoom({ kind: 'object', anchors: motionAnchors, tracks: this.trackAnchorBoxes, windows });
|
|
1823
|
+
const inferStart = Date.now();
|
|
1824
|
+
const perWindow = await Promise.all(windows.map((window) => this.detectInWindow(objectPlugin, analysis.frame, analysis.scaler, window, inputSpec)));
|
|
1825
|
+
this.perf.objectMs += Date.now() - inferStart;
|
|
1826
|
+
this.perf.objectCount++;
|
|
1827
|
+
return mergeWindowDetections(perWindow.flat());
|
|
1828
|
+
}
|
|
1829
|
+
const scaleStart = Date.now();
|
|
1830
|
+
const objectFrame = await this.scaleForObject(analysis.frame, analysis.scaler);
|
|
1831
|
+
this.perf.scaleMs += Date.now() - scaleStart;
|
|
1832
|
+
if (!objectFrame || !this.loopRunning)
|
|
1833
|
+
return undefined;
|
|
1834
|
+
const inferStart = Date.now();
|
|
1835
|
+
const result = await PromiseTimeout(objectPlugin.proxy.detectObjects(objectFrame.model), DETECT_TIMEOUT_MS, undefined, `Object detection timed out after ${DETECT_TIMEOUT_MS}ms`);
|
|
1836
|
+
this.perf.objectMs += Date.now() - inferStart;
|
|
1837
|
+
this.perf.objectCount++;
|
|
1838
|
+
return FrameScaler.undoLetterbox(ensureDetectionBoxes(result.detections), objectFrame.geometry);
|
|
1839
|
+
}
|
|
1840
|
+
async detectInWindow(plugin, frame, scaler, window, spec) {
|
|
1841
|
+
const scaleStart = Date.now();
|
|
1842
|
+
const cropped = await scaler.cropToSpec(frame, window, spec);
|
|
1843
|
+
this.perf.scaleMs += Date.now() - scaleStart;
|
|
1844
|
+
if (!cropped)
|
|
1845
|
+
return [];
|
|
1846
|
+
const result = await PromiseTimeout(plugin.proxy.detectObjects(scaler.toVideoFrameData(cropped.padded, 'model')), DETECT_TIMEOUT_MS, undefined, `Object detection timed out after ${DETECT_TIMEOUT_MS}ms`);
|
|
1847
|
+
return FrameScaler.undoLetterbox(ensureDetectionBoxes(result.detections), cropped.geometry);
|
|
1848
|
+
}
|
|
1659
1849
|
async scaleFrameForPlugin(rawFrame, plugin, scaler = this.frameScaler) {
|
|
1660
1850
|
const inputSpec = plugin.modelSpec?.input;
|
|
1661
1851
|
if (!isVideoInputSpec(inputSpec))
|
|
@@ -1672,27 +1862,34 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1672
1862
|
ingestAssistedObjects(sensorId, objects) {
|
|
1673
1863
|
if (!objects.assisted)
|
|
1674
1864
|
return;
|
|
1865
|
+
// the assist returns raw detector output; the frame path dedupes via NMS
|
|
1866
|
+
// before ingest, so this path must merge too or near-identical candidate
|
|
1867
|
+
// boxes inflate the object count
|
|
1868
|
+
const merged = this.pipeline.runMergeAndZoneFilter(objects.detections);
|
|
1675
1869
|
const refiltered = this.applyExternalDetectionFilters(SensorType.Object, {
|
|
1676
|
-
detected:
|
|
1677
|
-
detections:
|
|
1870
|
+
detected: merged.length > 0,
|
|
1871
|
+
detections: merged,
|
|
1872
|
+
});
|
|
1873
|
+
detectionRecord.tick({
|
|
1874
|
+
assistIngest: {
|
|
1875
|
+
raw: objects.detections.map((d) => ({ label: d.label, score: d.confidence, box: d.box })),
|
|
1876
|
+
merged: merged.length,
|
|
1877
|
+
kept: (refiltered.detections ?? []).length,
|
|
1878
|
+
},
|
|
1678
1879
|
});
|
|
1679
1880
|
this.ingestDetectionResult(SensorType.Object, sensorId, refiltered);
|
|
1680
1881
|
}
|
|
1681
|
-
async runObjectAssist(frame, reported) {
|
|
1882
|
+
async runObjectAssist(frame, reported, scaler = this.frameScaler) {
|
|
1682
1883
|
if (!this.plugins.hasEligibleObjectAssist()) {
|
|
1683
1884
|
return { detections: reported, assisted: false };
|
|
1684
1885
|
}
|
|
1685
1886
|
const assist = this.plugins.get(SensorType.ObjectAssist);
|
|
1686
|
-
const scaled = await this.scaleFrameForPlugin(frame, assist);
|
|
1687
|
-
if (!scaled)
|
|
1688
|
-
return { detections: reported, assisted: false };
|
|
1689
1887
|
try {
|
|
1690
1888
|
const inferStart = Date.now();
|
|
1691
|
-
const
|
|
1889
|
+
const boxed = await this.assistDetections(assist, frame, scaler, reported);
|
|
1692
1890
|
this.perf.assistMs += Date.now() - inferStart;
|
|
1693
1891
|
this.perf.assistCount++;
|
|
1694
1892
|
const reportedLabels = new Set(reported.map((d) => d.label.toLowerCase()));
|
|
1695
|
-
const boxed = FrameScaler.undoLetterbox(ensureDetectionBoxes(result?.detections ?? []), scaled.geometry);
|
|
1696
1893
|
const found = boxed.filter((d) => reportedLabels.size === 0 || reportedLabels.has(d.label.toLowerCase()));
|
|
1697
1894
|
if (found.length === 0)
|
|
1698
1895
|
return { detections: reported, assisted: false };
|
|
@@ -1706,6 +1903,31 @@ let DetectionCoordinator = class DetectionCoordinator {
|
|
|
1706
1903
|
return { detections: reported, assisted: false };
|
|
1707
1904
|
}
|
|
1708
1905
|
}
|
|
1906
|
+
async assistDetections(assist, frame, scaler, reported) {
|
|
1907
|
+
const inputSpec = assist.modelSpec?.input;
|
|
1908
|
+
const reportedBoxes = reported.map((d) => d.box).filter((box) => box !== undefined);
|
|
1909
|
+
// a coordinate-less report still has the localizer's diff anchors: zoom
|
|
1910
|
+
// the assist into the moving regions instead of letterboxing the whole
|
|
1911
|
+
// frame, which shrinks the subject to nothing on a main-stream frame
|
|
1912
|
+
const anchors = reportedBoxes.length > 0 ? reportedBoxes : [...this.anchorBoxes, ...this.farewellBoxes];
|
|
1913
|
+
const pad = reportedBoxes.length > 0 ? TRACK_PAD : MOTION_PAD;
|
|
1914
|
+
if (isVideoInputSpec(inputSpec) && anchors.length > 0) {
|
|
1915
|
+
const windows = planWindowsOnce(anchors, pad, frame.width, frame.height, inputSpec.width);
|
|
1916
|
+
if (windows.length > 0) {
|
|
1917
|
+
detectionRecord.zoom({ kind: 'assist', anchors, windows });
|
|
1918
|
+
const perWindow = await Promise.all(windows.map((window) => this.detectInWindow(assist, frame, scaler, window, inputSpec)));
|
|
1919
|
+
return mergeWindowDetections(perWindow.flat());
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1922
|
+
detectionRecord.tick({
|
|
1923
|
+
assistFullFrame: { anchors: anchors.length, videoSpec: isVideoInputSpec(inputSpec), loop: this.loopRunning, cascade: this.cascade.isActive },
|
|
1924
|
+
});
|
|
1925
|
+
const scaled = await this.scaleFrameForPlugin(frame, assist, scaler);
|
|
1926
|
+
if (!scaled)
|
|
1927
|
+
return [];
|
|
1928
|
+
const result = await PromiseTimeout(assist.proxy.detectObjects(scaled.model), DETECT_TIMEOUT_MS, undefined, `Object assist timed out after ${DETECT_TIMEOUT_MS}ms`);
|
|
1929
|
+
return FrameScaler.undoLetterbox(ensureDetectionBoxes(result?.detections ?? []), scaled.geometry);
|
|
1930
|
+
}
|
|
1709
1931
|
};
|
|
1710
1932
|
__decorate([
|
|
1711
1933
|
RPCMethod,
|