@camera.ui/server 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (652) hide show
  1. package/dist/interface/assets/@babel-l0sNRNKZ.js +1 -0
  2. package/dist/interface/assets/@camera.ui-2NVnv26v.js +8 -0
  3. package/dist/interface/assets/@intlify-Ck2ZoCVz.js +15 -0
  4. package/dist/interface/assets/@mdi-C-QA1nE3.js +1 -0
  5. package/dist/interface/assets/@popperjs-BQBsAJpH.js +1 -0
  6. package/dist/interface/assets/@react-dnd-CcwRs9xb.js +1 -0
  7. package/dist/interface/assets/@socket.io-Dkula2eQ.js +1 -0
  8. package/dist/interface/assets/@tanstack-BqH4GyO-.js +1 -0
  9. package/dist/interface/assets/@vee-validate-DCBdnGo-.js +5 -0
  10. package/dist/interface/assets/@vue-C7-KaDG4.js +17 -0
  11. package/dist/interface/assets/@vueform-arggO0eF.js +1 -0
  12. package/dist/interface/assets/@vueform-h7tNX9p6.css +1 -0
  13. package/dist/interface/assets/@vueuse-C3WMTDqL.js +1 -0
  14. package/dist/interface/assets/@xterm-B4Ga69iL.js +9 -0
  15. package/dist/interface/assets/@xterm-CGrrDQr5.css +32 -0
  16. package/dist/interface/assets/Account-B_tHnXoX.css +1 -0
  17. package/dist/interface/assets/Account-gJpkf0nE.js +1 -0
  18. package/dist/interface/assets/Adminpanel-B_SY1GJM.css +0 -0
  19. package/dist/interface/assets/Adminpanel-Bge9nu5N.js +1 -0
  20. package/dist/interface/assets/Appearance-D22q-X_I.js +1 -0
  21. package/dist/interface/assets/Backup-DBv9xFPh.css +1 -0
  22. package/dist/interface/assets/Backup-pJm6s10G.js +1 -0
  23. package/dist/interface/assets/Camera-BgO2yRjb.js +1 -0
  24. package/dist/interface/assets/Camera-CWiLco3W.css +1 -0
  25. package/dist/interface/assets/Cameras-BM3vSM_R.css +1 -0
  26. package/dist/interface/assets/Cameras-DjeKruR_.js +1 -0
  27. package/dist/interface/assets/Camview-DfzlprzN.js +1 -0
  28. package/dist/interface/assets/Camview-vUAs5YHU.css +1 -0
  29. package/dist/interface/assets/Config-BKIOIkjC.js +1 -0
  30. package/dist/interface/assets/Config-DAiKsG7W.css +1 -0
  31. package/dist/interface/assets/Console-BsyX2S3R.css +1 -0
  32. package/dist/interface/assets/Console-Caz7y-T0.js +4 -0
  33. package/dist/interface/assets/FirstSteps-DNHhyDSw.css +1 -0
  34. package/dist/interface/assets/FirstSteps-mQK4XFTs.js +1 -0
  35. package/dist/interface/assets/NewCamera-B9t-0NCc.js +448 -0
  36. package/dist/interface/assets/NewCamera-CHMgUDbC.css +1 -0
  37. package/dist/interface/assets/Plugin-BSHKKjrl.css +1 -0
  38. package/dist/interface/assets/Plugin-Di_bBsg-.js +1 -0
  39. package/dist/interface/assets/Plugins-BsMITags.css +1 -0
  40. package/dist/interface/assets/Plugins-DhmzMNuO.js +1 -0
  41. package/dist/interface/assets/Recordings-Bu53bSBp.js +1 -0
  42. package/dist/interface/assets/Recordings-XY20w8yp.js +1 -0
  43. package/dist/interface/assets/Settings-JES2wb8p.css +1 -0
  44. package/dist/interface/assets/Settings-gGRBRVST.js +1 -0
  45. package/dist/interface/assets/System-ZDrcLNk0.js +1 -0
  46. package/dist/interface/assets/User-BXColIbU.css +1 -0
  47. package/dist/interface/assets/User-D4vEhhzi.js +1 -0
  48. package/dist/interface/assets/VConfigEditor.vue_vue_type_script_setup_true_lang-CXFI-IeE.js +2 -0
  49. package/dist/interface/assets/VConsole-BHo3xprq.js +1 -0
  50. package/dist/interface/assets/VConsole-f-nUkOuD.css +1 -0
  51. package/dist/interface/assets/VPlayer-D3KhRfx-.css +1 -0
  52. package/dist/interface/assets/VPlayer-YdRn97Bs.js +1 -0
  53. package/dist/interface/assets/VPluginCard--3bx6UJb.js +4 -0
  54. package/dist/interface/assets/VPluginCard-BJYMuCLk.css +1 -0
  55. package/dist/interface/assets/ace-builds-CigWTak4.js +956 -0
  56. package/dist/interface/assets/axios--Jv2L996.js +6 -0
  57. package/dist/interface/assets/dijkstrajs-D_NXgYpA.js +1 -0
  58. package/dist/interface/assets/dnd-core-SnWOpY0X.js +1 -0
  59. package/dist/interface/assets/draggabilly-Arakw9Dk.js +6 -0
  60. package/dist/interface/assets/encode-utf8-Cn5aGd7v.js +1 -0
  61. package/dist/interface/assets/engine.io-client-DBBxzneW.js +1 -0
  62. package/dist/interface/assets/engine.io-parser-BiEtp6m2.js +1 -0
  63. package/dist/interface/assets/entities-C20TfXL6.js +1 -0
  64. package/dist/interface/assets/ev-emitter-CXYwG0eJ.js +1 -0
  65. package/dist/interface/assets/fast-deep-equal-5pvsDbwX.js +1 -0
  66. package/dist/interface/assets/get-size-D1dS-IaP.js +5 -0
  67. package/dist/interface/assets/highlight-DgoK_Xib.css +1 -0
  68. package/dist/interface/assets/highlight.js-TxRCSjhv.js +2 -0
  69. package/dist/interface/assets/linkify-it-DmNjr4Kv.js +1 -0
  70. package/dist/interface/assets/logo-256-BCQk9H1-.png +0 -0
  71. package/dist/interface/assets/logo-512-DLKVOU2S.png +0 -0
  72. package/dist/interface/assets/logo-DmEiRk0z.png +0 -0
  73. package/dist/interface/assets/main-B3IVLctZ.css +1 -0
  74. package/dist/interface/assets/main-C4rYiRNz.js +2 -0
  75. package/dist/interface/assets/markdown-it-DI8MEbma.js +15 -0
  76. package/dist/interface/assets/mdurl-k9Sl0PQj.js +2 -0
  77. package/dist/interface/assets/mode-json-Br7xisR1.js +275 -0
  78. package/dist/interface/assets/mode-yaml-CIYL8U3d.js +395 -0
  79. package/dist/interface/assets/nprogress-DSyAi0LF.js +2 -0
  80. package/dist/interface/assets/pinia-D8MtiGcH.js +5 -0
  81. package/dist/interface/assets/plugins-Bf03y242.js +1 -0
  82. package/dist/interface/assets/punycode.js-Dj65hjkv.js +1 -0
  83. package/dist/interface/assets/qrcode-CGiDONbL.js +8 -0
  84. package/dist/interface/assets/react-dnd-html5-backend-1HQjlkwI.js +2 -0
  85. package/dist/interface/assets/react-dnd-touch-backend-NgACaG8W.js +1 -0
  86. package/dist/interface/assets/redux-CuxFRhX_.js +1 -0
  87. package/dist/interface/assets/rxjs-B53o3e_J.js +3 -0
  88. package/dist/interface/assets/socket.io-client-Bq_SHkin.js +1 -0
  89. package/dist/interface/assets/socket.io-parser-BBkuslX-.js +1 -0
  90. package/dist/interface/assets/system-BONnDA4y.js +1 -0
  91. package/dist/interface/assets/tslib-9k7AwCpt.js +1 -0
  92. package/dist/interface/assets/uc.micro-kMc2yuuw.js +1 -0
  93. package/dist/interface/assets/ui-CNpIJotI.js +1 -0
  94. package/dist/interface/assets/unidragger-BYtqgAQ0.js +5 -0
  95. package/dist/interface/assets/utils-BvINh1mj.js +1 -0
  96. package/dist/interface/assets/uuid-DvF23Exx.js +1 -0
  97. package/dist/interface/assets/v-calendar-CtSuDYZU.css +1 -0
  98. package/dist/interface/assets/v-calendar-uh0aTGqP.js +1 -0
  99. package/dist/interface/assets/vee-validate-D3FqbChK.js +5 -0
  100. package/dist/interface/assets/vue-i18n-1AU8MPys.js +5 -0
  101. package/dist/interface/assets/vue-inline-svg-2DDwYW6V.js +1 -0
  102. package/dist/interface/assets/vue-l0sNRNKZ.js +1 -0
  103. package/dist/interface/assets/vue-router-DfeQ8s4I.js +5 -0
  104. package/dist/interface/assets/vue3-dnd-BwxcSU9Z.js +1 -0
  105. package/dist/interface/assets/vue3-toastify-DTY1DMRs.css +1 -0
  106. package/dist/interface/assets/vue3-toastify-Ul-rf53I.js +1 -0
  107. package/dist/interface/assets/vuetify-B__3Y-at.css +5 -0
  108. package/dist/interface/assets/vuetify-_-Oqac3B.js +5 -0
  109. package/dist/interface/assets/zod-BaF2dDCd.js +1 -0
  110. package/dist/interface/browserconfig.xml +11 -0
  111. package/dist/interface/fonts/Inter/Inter-Regular.ttf +0 -0
  112. package/dist/interface/index.html +377 -0
  113. package/dist/interface/manifest.webmanifest +1 -0
  114. package/dist/interface/pwa/apple-splash-landscape-dark-1136x640.png +0 -0
  115. package/dist/interface/pwa/apple-splash-landscape-dark-1334x750.png +0 -0
  116. package/dist/interface/pwa/apple-splash-landscape-dark-1792x828.png +0 -0
  117. package/dist/interface/pwa/apple-splash-landscape-dark-2048x1536.png +0 -0
  118. package/dist/interface/pwa/apple-splash-landscape-dark-2160x1620.png +0 -0
  119. package/dist/interface/pwa/apple-splash-landscape-dark-2208x1242.png +0 -0
  120. package/dist/interface/pwa/apple-splash-landscape-dark-2224x1668.png +0 -0
  121. package/dist/interface/pwa/apple-splash-landscape-dark-2388x1668.png +0 -0
  122. package/dist/interface/pwa/apple-splash-landscape-dark-2436x1125.png +0 -0
  123. package/dist/interface/pwa/apple-splash-landscape-dark-2532x1170.png +0 -0
  124. package/dist/interface/pwa/apple-splash-landscape-dark-2556x1179.png +0 -0
  125. package/dist/interface/pwa/apple-splash-landscape-dark-2688x1242.png +0 -0
  126. package/dist/interface/pwa/apple-splash-landscape-dark-2732x2048.png +0 -0
  127. package/dist/interface/pwa/apple-splash-landscape-dark-2778x1284.png +0 -0
  128. package/dist/interface/pwa/apple-splash-landscape-dark-2796x1290.png +0 -0
  129. package/dist/interface/pwa/apple-splash-landscape-light-1136x640.png +0 -0
  130. package/dist/interface/pwa/apple-splash-landscape-light-1334x750.png +0 -0
  131. package/dist/interface/pwa/apple-splash-landscape-light-1792x828.png +0 -0
  132. package/dist/interface/pwa/apple-splash-landscape-light-2048x1536.png +0 -0
  133. package/dist/interface/pwa/apple-splash-landscape-light-2160x1620.png +0 -0
  134. package/dist/interface/pwa/apple-splash-landscape-light-2208x1242.png +0 -0
  135. package/dist/interface/pwa/apple-splash-landscape-light-2224x1668.png +0 -0
  136. package/dist/interface/pwa/apple-splash-landscape-light-2388x1668.png +0 -0
  137. package/dist/interface/pwa/apple-splash-landscape-light-2436x1125.png +0 -0
  138. package/dist/interface/pwa/apple-splash-landscape-light-2532x1170.png +0 -0
  139. package/dist/interface/pwa/apple-splash-landscape-light-2556x1179.png +0 -0
  140. package/dist/interface/pwa/apple-splash-landscape-light-2688x1242.png +0 -0
  141. package/dist/interface/pwa/apple-splash-landscape-light-2732x2048.png +0 -0
  142. package/dist/interface/pwa/apple-splash-landscape-light-2778x1284.png +0 -0
  143. package/dist/interface/pwa/apple-splash-landscape-light-2796x1290.png +0 -0
  144. package/dist/interface/pwa/apple-splash-portrait-dark-1125x2436.png +0 -0
  145. package/dist/interface/pwa/apple-splash-portrait-dark-1170x2532.png +0 -0
  146. package/dist/interface/pwa/apple-splash-portrait-dark-1179x2556.png +0 -0
  147. package/dist/interface/pwa/apple-splash-portrait-dark-1242x2208.png +0 -0
  148. package/dist/interface/pwa/apple-splash-portrait-dark-1242x2688.png +0 -0
  149. package/dist/interface/pwa/apple-splash-portrait-dark-1284x2778.png +0 -0
  150. package/dist/interface/pwa/apple-splash-portrait-dark-1290x2796.png +0 -0
  151. package/dist/interface/pwa/apple-splash-portrait-dark-1536x2048.png +0 -0
  152. package/dist/interface/pwa/apple-splash-portrait-dark-1620x2160.png +0 -0
  153. package/dist/interface/pwa/apple-splash-portrait-dark-1668x2224.png +0 -0
  154. package/dist/interface/pwa/apple-splash-portrait-dark-1668x2388.png +0 -0
  155. package/dist/interface/pwa/apple-splash-portrait-dark-2048x2732.png +0 -0
  156. package/dist/interface/pwa/apple-splash-portrait-dark-640x1136.png +0 -0
  157. package/dist/interface/pwa/apple-splash-portrait-dark-750x1334.png +0 -0
  158. package/dist/interface/pwa/apple-splash-portrait-dark-828x1792.png +0 -0
  159. package/dist/interface/pwa/apple-splash-portrait-light-1125x2436.png +0 -0
  160. package/dist/interface/pwa/apple-splash-portrait-light-1170x2532.png +0 -0
  161. package/dist/interface/pwa/apple-splash-portrait-light-1179x2556.png +0 -0
  162. package/dist/interface/pwa/apple-splash-portrait-light-1242x2208.png +0 -0
  163. package/dist/interface/pwa/apple-splash-portrait-light-1242x2688.png +0 -0
  164. package/dist/interface/pwa/apple-splash-portrait-light-1284x2778.png +0 -0
  165. package/dist/interface/pwa/apple-splash-portrait-light-1290x2796.png +0 -0
  166. package/dist/interface/pwa/apple-splash-portrait-light-1536x2048.png +0 -0
  167. package/dist/interface/pwa/apple-splash-portrait-light-1620x2160.png +0 -0
  168. package/dist/interface/pwa/apple-splash-portrait-light-1668x2224.png +0 -0
  169. package/dist/interface/pwa/apple-splash-portrait-light-1668x2388.png +0 -0
  170. package/dist/interface/pwa/apple-splash-portrait-light-2048x2732.png +0 -0
  171. package/dist/interface/pwa/apple-splash-portrait-light-640x1136.png +0 -0
  172. package/dist/interface/pwa/apple-splash-portrait-light-750x1334.png +0 -0
  173. package/dist/interface/pwa/apple-splash-portrait-light-828x1792.png +0 -0
  174. package/dist/interface/pwa/apple-touch-icon-180x180.png +0 -0
  175. package/dist/interface/pwa/favicon-16.ico +0 -0
  176. package/dist/interface/pwa/favicon-32.ico +0 -0
  177. package/dist/interface/pwa/favicon-48.ico +0 -0
  178. package/dist/interface/pwa/favicon-64.ico +0 -0
  179. package/dist/interface/pwa/logo.svg +1 -0
  180. package/dist/interface/pwa/maskable-icon-1240x600.png +0 -0
  181. package/dist/interface/pwa/maskable-icon-512x512.png +0 -0
  182. package/dist/interface/pwa/maskable-icon-620x300.png +0 -0
  183. package/dist/interface/pwa/pwa-1024x1024.png +0 -0
  184. package/dist/interface/pwa/pwa-120x120.png +0 -0
  185. package/dist/interface/pwa/pwa-144x144.png +0 -0
  186. package/dist/interface/pwa/pwa-152x152.png +0 -0
  187. package/dist/interface/pwa/pwa-167x167.png +0 -0
  188. package/dist/interface/pwa/pwa-180x180.png +0 -0
  189. package/dist/interface/pwa/pwa-192x192.png +0 -0
  190. package/dist/interface/pwa/pwa-24x24.png +0 -0
  191. package/dist/interface/pwa/pwa-300x300.png +0 -0
  192. package/dist/interface/pwa/pwa-36x36.png +0 -0
  193. package/dist/interface/pwa/pwa-48x48.png +0 -0
  194. package/dist/interface/pwa/pwa-50x50.png +0 -0
  195. package/dist/interface/pwa/pwa-64x64.png +0 -0
  196. package/dist/interface/pwa/pwa-72x72.png +0 -0
  197. package/dist/interface/pwa/pwa-88x88.png +0 -0
  198. package/dist/interface/pwa/pwa-96x96.png +0 -0
  199. package/dist/interface/registerSW.js +1 -0
  200. package/dist/interface/robots.txt +2 -0
  201. package/dist/interface/sw.js +1 -0
  202. package/dist/interface/workbox-3e911b1d.js +1 -0
  203. package/dist/server/bin/cui-service.d.ts +43 -0
  204. package/dist/server/bin/cui-service.js +472 -0
  205. package/dist/server/bin/cui-service.js.map +1 -0
  206. package/dist/server/bin/cui.d.ts +2 -0
  207. package/dist/server/bin/cui.js +8 -0
  208. package/dist/server/bin/cui.js.map +1 -0
  209. package/dist/server/bin/installer/base.d.ts +16 -0
  210. package/dist/server/bin/installer/base.js +41 -0
  211. package/dist/server/bin/installer/base.js.map +1 -0
  212. package/dist/server/bin/installer/darwin.d.ts +49 -0
  213. package/dist/server/bin/installer/darwin.js +200 -0
  214. package/dist/server/bin/installer/darwin.js.map +1 -0
  215. package/dist/server/bin/installer/freebsd.d.ts +61 -0
  216. package/dist/server/bin/installer/freebsd.js +252 -0
  217. package/dist/server/bin/installer/freebsd.js.map +1 -0
  218. package/dist/server/bin/installer/linux.d.ts +92 -0
  219. package/dist/server/bin/installer/linux.js +386 -0
  220. package/dist/server/bin/installer/linux.js.map +1 -0
  221. package/dist/server/bin/installer/win32.d.ts +37 -0
  222. package/dist/server/bin/installer/win32.js +158 -0
  223. package/dist/server/bin/installer/win32.js.map +1 -0
  224. package/dist/server/package.json +142 -0
  225. package/dist/server/requirements.txt +13 -0
  226. package/dist/server/src/api/controllers/api.controller.d.ts +6 -0
  227. package/dist/server/src/api/controllers/api.controller.js +11 -0
  228. package/dist/server/src/api/controllers/api.controller.js.map +1 -0
  229. package/dist/server/src/api/controllers/auth.controller.d.ts +20 -0
  230. package/dist/server/src/api/controllers/auth.controller.js +263 -0
  231. package/dist/server/src/api/controllers/auth.controller.js.map +1 -0
  232. package/dist/server/src/api/controllers/backup.controller.d.ts +10 -0
  233. package/dist/server/src/api/controllers/backup.controller.js +52 -0
  234. package/dist/server/src/api/controllers/backup.controller.js.map +1 -0
  235. package/dist/server/src/api/controllers/cameras.controller.d.ts +34 -0
  236. package/dist/server/src/api/controllers/cameras.controller.js +522 -0
  237. package/dist/server/src/api/controllers/cameras.controller.js.map +1 -0
  238. package/dist/server/src/api/controllers/config.controller.d.ts +14 -0
  239. package/dist/server/src/api/controllers/config.controller.js +89 -0
  240. package/dist/server/src/api/controllers/config.controller.js.map +1 -0
  241. package/dist/server/src/api/controllers/files.controller.d.ts +8 -0
  242. package/dist/server/src/api/controllers/files.controller.js +28 -0
  243. package/dist/server/src/api/controllers/files.controller.js.map +1 -0
  244. package/dist/server/src/api/controllers/frameWorkers.controller.d.ts +16 -0
  245. package/dist/server/src/api/controllers/frameWorkers.controller.js +85 -0
  246. package/dist/server/src/api/controllers/frameWorkers.controller.js.map +1 -0
  247. package/dist/server/src/api/controllers/plugins.controller.d.ts +59 -0
  248. package/dist/server/src/api/controllers/plugins.controller.js +1178 -0
  249. package/dist/server/src/api/controllers/plugins.controller.js.map +1 -0
  250. package/dist/server/src/api/controllers/system.controller.d.ts +14 -0
  251. package/dist/server/src/api/controllers/system.controller.js +149 -0
  252. package/dist/server/src/api/controllers/system.controller.js.map +1 -0
  253. package/dist/server/src/api/controllers/users.controller.d.ts +28 -0
  254. package/dist/server/src/api/controllers/users.controller.js +463 -0
  255. package/dist/server/src/api/controllers/users.controller.js.map +1 -0
  256. package/dist/server/src/api/database/index.d.ts +34 -0
  257. package/dist/server/src/api/database/index.js +185 -0
  258. package/dist/server/src/api/database/index.js.map +1 -0
  259. package/dist/server/src/api/database/migration.d.ts +12 -0
  260. package/dist/server/src/api/database/migration.js +47 -0
  261. package/dist/server/src/api/database/migration.js.map +1 -0
  262. package/dist/server/src/api/database/types.d.ts +209 -0
  263. package/dist/server/src/api/database/types.js +2 -0
  264. package/dist/server/src/api/database/types.js.map +1 -0
  265. package/dist/server/src/api/go2rtc/api/application.d.ts +9 -0
  266. package/dist/server/src/api/go2rtc/api/application.js +38 -0
  267. package/dist/server/src/api/go2rtc/api/application.js.map +1 -0
  268. package/dist/server/src/api/go2rtc/api/config.d.ts +8 -0
  269. package/dist/server/src/api/go2rtc/api/config.js +44 -0
  270. package/dist/server/src/api/go2rtc/api/config.js.map +1 -0
  271. package/dist/server/src/api/go2rtc/api/index.d.ts +1 -0
  272. package/dist/server/src/api/go2rtc/api/index.js +28 -0
  273. package/dist/server/src/api/go2rtc/api/index.js.map +1 -0
  274. package/dist/server/src/api/go2rtc/api/snapshot.d.ts +8 -0
  275. package/dist/server/src/api/go2rtc/api/snapshot.js +34 -0
  276. package/dist/server/src/api/go2rtc/api/snapshot.js.map +1 -0
  277. package/dist/server/src/api/go2rtc/api/streams.d.ts +10 -0
  278. package/dist/server/src/api/go2rtc/api/streams.js +67 -0
  279. package/dist/server/src/api/go2rtc/api/streams.js.map +1 -0
  280. package/dist/server/src/api/go2rtc/index.d.ts +13 -0
  281. package/dist/server/src/api/go2rtc/index.js +25 -0
  282. package/dist/server/src/api/go2rtc/index.js.map +1 -0
  283. package/dist/server/src/api/go2rtc/queue.d.ts +10 -0
  284. package/dist/server/src/api/go2rtc/queue.js +38 -0
  285. package/dist/server/src/api/go2rtc/queue.js.map +1 -0
  286. package/dist/server/src/api/go2rtc/types.d.ts +60 -0
  287. package/dist/server/src/api/go2rtc/types.js +2 -0
  288. package/dist/server/src/api/go2rtc/types.js.map +1 -0
  289. package/dist/server/src/api/index.d.ts +20 -0
  290. package/dist/server/src/api/index.js +233 -0
  291. package/dist/server/src/api/index.js.map +1 -0
  292. package/dist/server/src/api/middlewares/authPermission.middleware.d.ts +5 -0
  293. package/dist/server/src/api/middlewares/authPermission.middleware.js +28 -0
  294. package/dist/server/src/api/middlewares/authPermission.middleware.js.map +1 -0
  295. package/dist/server/src/api/middlewares/authValidation.middleware.d.ts +4 -0
  296. package/dist/server/src/api/middlewares/authValidation.middleware.js +129 -0
  297. package/dist/server/src/api/middlewares/authValidation.middleware.js.map +1 -0
  298. package/dist/server/src/api/middlewares/pagination.middleware.d.ts +3 -0
  299. package/dist/server/src/api/middlewares/pagination.middleware.js +65 -0
  300. package/dist/server/src/api/middlewares/pagination.middleware.js.map +1 -0
  301. package/dist/server/src/api/middlewares/socketAuth.middleware.d.ts +41 -0
  302. package/dist/server/src/api/middlewares/socketAuth.middleware.js +81 -0
  303. package/dist/server/src/api/middlewares/socketAuth.middleware.js.map +1 -0
  304. package/dist/server/src/api/plugins/cameraui.plugin.d.ts +11 -0
  305. package/dist/server/src/api/plugins/cameraui.plugin.js +6 -0
  306. package/dist/server/src/api/plugins/cameraui.plugin.js.map +1 -0
  307. package/dist/server/src/api/plugins/database.plugin.d.ts +11 -0
  308. package/dist/server/src/api/plugins/database.plugin.js +12 -0
  309. package/dist/server/src/api/plugins/database.plugin.js.map +1 -0
  310. package/dist/server/src/api/plugins/go2rtc.plugin.d.ts +11 -0
  311. package/dist/server/src/api/plugins/go2rtc.plugin.js +11 -0
  312. package/dist/server/src/api/plugins/go2rtc.plugin.js.map +1 -0
  313. package/dist/server/src/api/plugins/logger.plugin.d.ts +7 -0
  314. package/dist/server/src/api/plugins/logger.plugin.js +29 -0
  315. package/dist/server/src/api/plugins/logger.plugin.js.map +1 -0
  316. package/dist/server/src/api/plugins/socket.plugin.d.ts +11 -0
  317. package/dist/server/src/api/plugins/socket.plugin.js +12 -0
  318. package/dist/server/src/api/plugins/socket.plugin.js.map +1 -0
  319. package/dist/server/src/api/plugins/system.plugin.d.ts +21 -0
  320. package/dist/server/src/api/plugins/system.plugin.js +33 -0
  321. package/dist/server/src/api/plugins/system.plugin.js.map +1 -0
  322. package/dist/server/src/api/plugins/useragent.plugin.d.ts +8 -0
  323. package/dist/server/src/api/plugins/useragent.plugin.js +10 -0
  324. package/dist/server/src/api/plugins/useragent.plugin.js.map +1 -0
  325. package/dist/server/src/api/routes/api.routes.d.ts +2 -0
  326. package/dist/server/src/api/routes/api.routes.js +6 -0
  327. package/dist/server/src/api/routes/api.routes.js.map +1 -0
  328. package/dist/server/src/api/routes/auth.routes.d.ts +2 -0
  329. package/dist/server/src/api/routes/auth.routes.js +47 -0
  330. package/dist/server/src/api/routes/auth.routes.js.map +1 -0
  331. package/dist/server/src/api/routes/backup.routes.d.ts +2 -0
  332. package/dist/server/src/api/routes/backup.routes.js +23 -0
  333. package/dist/server/src/api/routes/backup.routes.js.map +1 -0
  334. package/dist/server/src/api/routes/cameras.routes.d.ts +2 -0
  335. package/dist/server/src/api/routes/cameras.routes.js +181 -0
  336. package/dist/server/src/api/routes/cameras.routes.js.map +1 -0
  337. package/dist/server/src/api/routes/config.routes.d.ts +2 -0
  338. package/dist/server/src/api/routes/config.routes.js +55 -0
  339. package/dist/server/src/api/routes/config.routes.js.map +1 -0
  340. package/dist/server/src/api/routes/files.routes.d.ts +2 -0
  341. package/dist/server/src/api/routes/files.routes.js +12 -0
  342. package/dist/server/src/api/routes/files.routes.js.map +1 -0
  343. package/dist/server/src/api/routes/frameWorkers.routes.d.ts +2 -0
  344. package/dist/server/src/api/routes/frameWorkers.routes.js +33 -0
  345. package/dist/server/src/api/routes/frameWorkers.routes.js.map +1 -0
  346. package/dist/server/src/api/routes/index.d.ts +6 -0
  347. package/dist/server/src/api/routes/index.js +32 -0
  348. package/dist/server/src/api/routes/index.js.map +1 -0
  349. package/dist/server/src/api/routes/plugins.routes.d.ts +2 -0
  350. package/dist/server/src/api/routes/plugins.routes.js +339 -0
  351. package/dist/server/src/api/routes/plugins.routes.js.map +1 -0
  352. package/dist/server/src/api/routes/system.routes.d.ts +2 -0
  353. package/dist/server/src/api/routes/system.routes.js +43 -0
  354. package/dist/server/src/api/routes/system.routes.js.map +1 -0
  355. package/dist/server/src/api/routes/users.routes.d.ts +2 -0
  356. package/dist/server/src/api/routes/users.routes.js +139 -0
  357. package/dist/server/src/api/routes/users.routes.js.map +1 -0
  358. package/dist/server/src/api/schemas/backup.schema.d.ts +118 -0
  359. package/dist/server/src/api/schemas/backup.schema.js +75 -0
  360. package/dist/server/src/api/schemas/backup.schema.js.map +1 -0
  361. package/dist/server/src/api/schemas/cameras.schema.d.ts +932 -0
  362. package/dist/server/src/api/schemas/cameras.schema.js +271 -0
  363. package/dist/server/src/api/schemas/cameras.schema.js.map +1 -0
  364. package/dist/server/src/api/schemas/config.schema.d.ts +202 -0
  365. package/dist/server/src/api/schemas/config.schema.js +68 -0
  366. package/dist/server/src/api/schemas/config.schema.js.map +1 -0
  367. package/dist/server/src/api/schemas/go2rtc.schema.d.ts +703 -0
  368. package/dist/server/src/api/schemas/go2rtc.schema.js +188 -0
  369. package/dist/server/src/api/schemas/go2rtc.schema.js.map +1 -0
  370. package/dist/server/src/api/schemas/plugins.schema.d.ts +72 -0
  371. package/dist/server/src/api/schemas/plugins.schema.js +103 -0
  372. package/dist/server/src/api/schemas/plugins.schema.js.map +1 -0
  373. package/dist/server/src/api/schemas/users.schema.d.ts +1008 -0
  374. package/dist/server/src/api/schemas/users.schema.js +151 -0
  375. package/dist/server/src/api/schemas/users.schema.js.map +1 -0
  376. package/dist/server/src/api/services/auth.service.d.ts +19 -0
  377. package/dist/server/src/api/services/auth.service.js +115 -0
  378. package/dist/server/src/api/services/auth.service.js.map +1 -0
  379. package/dist/server/src/api/services/backup.service.d.ts +11 -0
  380. package/dist/server/src/api/services/backup.service.js +108 -0
  381. package/dist/server/src/api/services/backup.service.js.map +1 -0
  382. package/dist/server/src/api/services/cameras.service.d.ts +55 -0
  383. package/dist/server/src/api/services/cameras.service.js +700 -0
  384. package/dist/server/src/api/services/cameras.service.js.map +1 -0
  385. package/dist/server/src/api/services/plugins.service.d.ts +25 -0
  386. package/dist/server/src/api/services/plugins.service.js +145 -0
  387. package/dist/server/src/api/services/plugins.service.js.map +1 -0
  388. package/dist/server/src/api/services/users.service.d.ts +25 -0
  389. package/dist/server/src/api/services/users.service.js +197 -0
  390. package/dist/server/src/api/services/users.service.js.map +1 -0
  391. package/dist/server/src/api/types/index.d.ts +580 -0
  392. package/dist/server/src/api/types/index.js +9 -0
  393. package/dist/server/src/api/types/index.js.map +1 -0
  394. package/dist/server/src/api/utils/cert.d.ts +11 -0
  395. package/dist/server/src/api/utils/cert.js +411 -0
  396. package/dist/server/src/api/utils/cert.js.map +1 -0
  397. package/dist/server/src/api/utils/constants.d.ts +15 -0
  398. package/dist/server/src/api/utils/constants.js +17 -0
  399. package/dist/server/src/api/utils/constants.js.map +1 -0
  400. package/dist/server/src/api/utils/fetch.d.ts +2 -0
  401. package/dist/server/src/api/utils/fetch.js +24 -0
  402. package/dist/server/src/api/utils/fetch.js.map +1 -0
  403. package/dist/server/src/api/utils/moveFiles.d.ts +1 -0
  404. package/dist/server/src/api/utils/moveFiles.js +38 -0
  405. package/dist/server/src/api/utils/moveFiles.js.map +1 -0
  406. package/dist/server/src/api/utils/parse.d.ts +2 -0
  407. package/dist/server/src/api/utils/parse.js +12 -0
  408. package/dist/server/src/api/utils/parse.js.map +1 -0
  409. package/dist/server/src/api/websocket/index.d.ts +15 -0
  410. package/dist/server/src/api/websocket/index.js +69 -0
  411. package/dist/server/src/api/websocket/index.js.map +1 -0
  412. package/dist/server/src/api/websocket/nsp/frameWorker.d.ts +13 -0
  413. package/dist/server/src/api/websocket/nsp/frameWorker.js +29 -0
  414. package/dist/server/src/api/websocket/nsp/frameWorker.js.map +1 -0
  415. package/dist/server/src/api/websocket/nsp/logs.d.ts +11 -0
  416. package/dist/server/src/api/websocket/nsp/logs.js +113 -0
  417. package/dist/server/src/api/websocket/nsp/logs.js.map +1 -0
  418. package/dist/server/src/api/websocket/nsp/metrics.d.ts +38 -0
  419. package/dist/server/src/api/websocket/nsp/metrics.js +266 -0
  420. package/dist/server/src/api/websocket/nsp/metrics.js.map +1 -0
  421. package/dist/server/src/api/websocket/nsp/notifications.d.ts +11 -0
  422. package/dist/server/src/api/websocket/nsp/notifications.js +35 -0
  423. package/dist/server/src/api/websocket/nsp/notifications.js.map +1 -0
  424. package/dist/server/src/api/websocket/nsp/plugins.d.ts +13 -0
  425. package/dist/server/src/api/websocket/nsp/plugins.js +29 -0
  426. package/dist/server/src/api/websocket/nsp/plugins.js.map +1 -0
  427. package/dist/server/src/api/websocket/nsp/server.d.ts +9 -0
  428. package/dist/server/src/api/websocket/nsp/server.js +48 -0
  429. package/dist/server/src/api/websocket/nsp/server.js.map +1 -0
  430. package/dist/server/src/api/websocket/nsp/status.d.ts +26 -0
  431. package/dist/server/src/api/websocket/nsp/status.js +59 -0
  432. package/dist/server/src/api/websocket/nsp/status.js.map +1 -0
  433. package/dist/server/src/api/websocket/types.d.ts +86 -0
  434. package/dist/server/src/api/websocket/types.js +2 -0
  435. package/dist/server/src/api/websocket/types.js.map +1 -0
  436. package/dist/server/src/api.d.ts +43 -0
  437. package/dist/server/src/api.js +90 -0
  438. package/dist/server/src/api.js.map +1 -0
  439. package/dist/server/src/camera/controller.d.ts +41 -0
  440. package/dist/server/src/camera/controller.js +220 -0
  441. package/dist/server/src/camera/controller.js.map +1 -0
  442. package/dist/server/src/camera/device.d.ts +18 -0
  443. package/dist/server/src/camera/device.js +21 -0
  444. package/dist/server/src/camera/device.js.map +1 -0
  445. package/dist/server/src/camera/index.d.ts +121 -0
  446. package/dist/server/src/camera/index.js +643 -0
  447. package/dist/server/src/camera/index.js.map +1 -0
  448. package/dist/server/src/camera/interfaces/camera.d.ts +11 -0
  449. package/dist/server/src/camera/interfaces/camera.js +31 -0
  450. package/dist/server/src/camera/interfaces/camera.js.map +1 -0
  451. package/dist/server/src/camera/interfaces/prebuffer.d.ts +11 -0
  452. package/dist/server/src/camera/interfaces/prebuffer.js +26 -0
  453. package/dist/server/src/camera/interfaces/prebuffer.js.map +1 -0
  454. package/dist/server/src/camera/interfaces/ptz.d.ts +13 -0
  455. package/dist/server/src/camera/interfaces/ptz.js +47 -0
  456. package/dist/server/src/camera/interfaces/ptz.js.map +1 -0
  457. package/dist/server/src/camera/polygon.d.ts +6 -0
  458. package/dist/server/src/camera/polygon.js +151 -0
  459. package/dist/server/src/camera/polygon.js.map +1 -0
  460. package/dist/server/src/camera/streaming/peer-connection.d.ts +46 -0
  461. package/dist/server/src/camera/streaming/peer-connection.js +150 -0
  462. package/dist/server/src/camera/streaming/peer-connection.js.map +1 -0
  463. package/dist/server/src/camera/streaming/webrtc-connection.d.ts +34 -0
  464. package/dist/server/src/camera/streaming/webrtc-connection.js +152 -0
  465. package/dist/server/src/camera/streaming/webrtc-connection.js.map +1 -0
  466. package/dist/server/src/camera/streaming/werift-session.d.ts +31 -0
  467. package/dist/server/src/camera/streaming/werift-session.js +168 -0
  468. package/dist/server/src/camera/streaming/werift-session.js.map +1 -0
  469. package/dist/server/src/camera/types.d.ts +202 -0
  470. package/dist/server/src/camera/types.js +7 -0
  471. package/dist/server/src/camera/types.js.map +1 -0
  472. package/dist/server/src/camera/videoFrame.d.ts +24 -0
  473. package/dist/server/src/camera/videoFrame.js +105 -0
  474. package/dist/server/src/camera/videoFrame.js.map +1 -0
  475. package/dist/server/src/decoder/ffmpeg.d.ts +2 -0
  476. package/dist/server/src/decoder/ffmpeg.js +61 -0
  477. package/dist/server/src/decoder/ffmpeg.js.map +1 -0
  478. package/dist/server/src/decoder/index.d.ts +11 -0
  479. package/dist/server/src/decoder/index.js +32 -0
  480. package/dist/server/src/decoder/index.js.map +1 -0
  481. package/dist/server/src/decoder/types.d.ts +156 -0
  482. package/dist/server/src/decoder/types.js +2 -0
  483. package/dist/server/src/decoder/types.js.map +1 -0
  484. package/dist/server/src/decoder/worker.d.ts +42 -0
  485. package/dist/server/src/decoder/worker.js +273 -0
  486. package/dist/server/src/decoder/worker.js.map +1 -0
  487. package/dist/server/src/go2rtc/index.d.ts +25 -0
  488. package/dist/server/src/go2rtc/index.js +211 -0
  489. package/dist/server/src/go2rtc/index.js.map +1 -0
  490. package/dist/server/src/go2rtc/types.d.ts +14 -0
  491. package/dist/server/src/go2rtc/types.js +73 -0
  492. package/dist/server/src/go2rtc/types.js.map +1 -0
  493. package/dist/server/src/index.d.ts +16 -0
  494. package/dist/server/src/index.js +5 -0
  495. package/dist/server/src/index.js.map +1 -0
  496. package/dist/server/src/main.d.ts +18 -0
  497. package/dist/server/src/main.js +118 -0
  498. package/dist/server/src/main.js.map +1 -0
  499. package/dist/server/src/nats/constants.d.ts +1 -0
  500. package/dist/server/src/nats/constants.js +2 -0
  501. package/dist/server/src/nats/constants.js.map +1 -0
  502. package/dist/server/src/nats/index.d.ts +35 -0
  503. package/dist/server/src/nats/index.js +150 -0
  504. package/dist/server/src/nats/index.js.map +1 -0
  505. package/dist/server/src/nats/messageQueue.d.ts +17 -0
  506. package/dist/server/src/nats/messageQueue.js +148 -0
  507. package/dist/server/src/nats/messageQueue.js.map +1 -0
  508. package/dist/server/src/nats/proxy/cameraDevice.d.ts +30 -0
  509. package/dist/server/src/nats/proxy/cameraDevice.js +252 -0
  510. package/dist/server/src/nats/proxy/cameraDevice.js.map +1 -0
  511. package/dist/server/src/nats/proxy/deviceManager.d.ts +16 -0
  512. package/dist/server/src/nats/proxy/deviceManager.js +110 -0
  513. package/dist/server/src/nats/proxy/deviceManager.js.map +1 -0
  514. package/dist/server/src/nats/proxy/index.d.ts +2 -0
  515. package/dist/server/src/nats/proxy/index.js +3 -0
  516. package/dist/server/src/nats/proxy/index.js.map +1 -0
  517. package/dist/server/src/nats/server.d.ts +38 -0
  518. package/dist/server/src/nats/server.js +325 -0
  519. package/dist/server/src/nats/server.js.map +1 -0
  520. package/dist/server/src/nats/types.d.ts +125 -0
  521. package/dist/server/src/nats/types.js +11 -0
  522. package/dist/server/src/nats/types.js.map +1 -0
  523. package/dist/server/src/nats/utils.d.ts +4 -0
  524. package/dist/server/src/nats/utils.js +12 -0
  525. package/dist/server/src/nats/utils.js.map +1 -0
  526. package/dist/server/src/nats/websocket.d.ts +27 -0
  527. package/dist/server/src/nats/websocket.js +214 -0
  528. package/dist/server/src/nats/websocket.js.map +1 -0
  529. package/dist/server/src/plugins/index.d.ts +32 -0
  530. package/dist/server/src/plugins/index.js +326 -0
  531. package/dist/server/src/plugins/index.js.map +1 -0
  532. package/dist/server/src/plugins/interfaces/audioDetection.d.ts +7 -0
  533. package/dist/server/src/plugins/interfaces/audioDetection.js +4 -0
  534. package/dist/server/src/plugins/interfaces/audioDetection.js.map +1 -0
  535. package/dist/server/src/plugins/interfaces/base.d.ts +6 -0
  536. package/dist/server/src/plugins/interfaces/base.js +3 -0
  537. package/dist/server/src/plugins/interfaces/base.js.map +1 -0
  538. package/dist/server/src/plugins/interfaces/motionDetection.d.ts +6 -0
  539. package/dist/server/src/plugins/interfaces/motionDetection.js +4 -0
  540. package/dist/server/src/plugins/interfaces/motionDetection.js.map +1 -0
  541. package/dist/server/src/plugins/interfaces/objectDetection.d.ts +7 -0
  542. package/dist/server/src/plugins/interfaces/objectDetection.js +4 -0
  543. package/dist/server/src/plugins/interfaces/objectDetection.js.map +1 -0
  544. package/dist/server/src/plugins/plugin.d.ts +42 -0
  545. package/dist/server/src/plugins/plugin.js +207 -0
  546. package/dist/server/src/plugins/plugin.js.map +1 -0
  547. package/dist/server/src/plugins/types.d.ts +181 -0
  548. package/dist/server/src/plugins/types.js +18 -0
  549. package/dist/server/src/plugins/types.js.map +1 -0
  550. package/dist/server/src/plugins/worker.d.ts +35 -0
  551. package/dist/server/src/plugins/worker.js +309 -0
  552. package/dist/server/src/plugins/worker.js.map +1 -0
  553. package/dist/server/src/polyglot/node/decoder/child.d.ts +1 -0
  554. package/dist/server/src/polyglot/node/decoder/child.js +703 -0
  555. package/dist/server/src/polyglot/node/decoder/child.js.map +1 -0
  556. package/dist/server/src/polyglot/node/decoder/imageUtils.d.ts +24 -0
  557. package/dist/server/src/polyglot/node/decoder/imageUtils.js +203 -0
  558. package/dist/server/src/polyglot/node/decoder/imageUtils.js.map +1 -0
  559. package/dist/server/src/polyglot/node/decoder/reader.d.ts +5 -0
  560. package/dist/server/src/polyglot/node/decoder/reader.js +41 -0
  561. package/dist/server/src/polyglot/node/decoder/reader.js.map +1 -0
  562. package/dist/server/src/polyglot/node/decoder/wasm/build/decoder.d.ts +144 -0
  563. package/dist/server/src/polyglot/node/decoder/wasm/build/decoder.js +65 -0
  564. package/dist/server/src/polyglot/node/decoder/wasm/build/decoder.wasm +0 -0
  565. package/dist/server/src/polyglot/node/decoder/wasm/test/imageUtils.py +106 -0
  566. package/dist/server/src/polyglot/node/plugins/api.d.ts +37 -0
  567. package/dist/server/src/polyglot/node/plugins/api.js +34 -0
  568. package/dist/server/src/polyglot/node/plugins/api.js.map +1 -0
  569. package/dist/server/src/polyglot/node/plugins/cameraStorage.d.ts +108 -0
  570. package/dist/server/src/polyglot/node/plugins/cameraStorage.js +310 -0
  571. package/dist/server/src/polyglot/node/plugins/cameraStorage.js.map +1 -0
  572. package/dist/server/src/polyglot/node/plugins/child.d.ts +25 -0
  573. package/dist/server/src/polyglot/node/plugins/child.js +206 -0
  574. package/dist/server/src/polyglot/node/plugins/child.js.map +1 -0
  575. package/dist/server/src/polyglot/node/plugins/config.d.ts +104 -0
  576. package/dist/server/src/polyglot/node/plugins/config.js +213 -0
  577. package/dist/server/src/polyglot/node/plugins/config.js.map +1 -0
  578. package/dist/server/src/polyglot/node/plugins/logger.d.ts +16 -0
  579. package/dist/server/src/polyglot/node/plugins/logger.js +128 -0
  580. package/dist/server/src/polyglot/node/plugins/logger.js.map +1 -0
  581. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.d.ts +75 -0
  582. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js +474 -0
  583. package/dist/server/src/polyglot/node/plugins/proxy/cameraDevice.js.map +1 -0
  584. package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.d.ts +49 -0
  585. package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.js +194 -0
  586. package/dist/server/src/polyglot/node/plugins/proxy/deviceManager.js.map +1 -0
  587. package/dist/server/src/polyglot/node/plugins/proxy/index.d.ts +2 -0
  588. package/dist/server/src/polyglot/node/plugins/proxy/index.js +3 -0
  589. package/dist/server/src/polyglot/node/plugins/proxy/index.js.map +1 -0
  590. package/dist/server/src/polyglot/node/plugins/proxy/messageQueue.d.ts +20 -0
  591. package/dist/server/src/polyglot/node/plugins/proxy/messageQueue.js +152 -0
  592. package/dist/server/src/polyglot/node/plugins/proxy/messageQueue.js.map +1 -0
  593. package/dist/server/src/polyglot/node/plugins/schema.d.ts +280 -0
  594. package/dist/server/src/polyglot/node/plugins/schema.js +719 -0
  595. package/dist/server/src/polyglot/node/plugins/schema.js.map +1 -0
  596. package/dist/server/src/polyglot/node/plugins/storageController.d.ts +28 -0
  597. package/dist/server/src/polyglot/node/plugins/storageController.js +38 -0
  598. package/dist/server/src/polyglot/node/plugins/storageController.js.map +1 -0
  599. package/dist/server/src/polyglot/python/camera/interfaces/camera.py +26 -0
  600. package/dist/server/src/polyglot/python/camera/interfaces/prebuffer.py +25 -0
  601. package/dist/server/src/polyglot/python/camera/interfaces/ptz.py +38 -0
  602. package/dist/server/src/polyglot/python/camera/polygon.py +173 -0
  603. package/dist/server/src/polyglot/python/camera/video_frame.py +196 -0
  604. package/dist/server/src/polyglot/python/camera_ui_types/__init__.py +1221 -0
  605. package/dist/server/src/polyglot/python/decoder/child.py +922 -0
  606. package/dist/server/src/polyglot/python/decoder/image_utils.py +149 -0
  607. package/dist/server/src/polyglot/python/decoder/typings.py +99 -0
  608. package/dist/server/src/polyglot/python/plugins/camera_storage.py +459 -0
  609. package/dist/server/src/polyglot/python/plugins/child.py +267 -0
  610. package/dist/server/src/polyglot/python/plugins/config_service.py +180 -0
  611. package/dist/server/src/polyglot/python/plugins/constants.py +2 -0
  612. package/dist/server/src/polyglot/python/plugins/logger.py +111 -0
  613. package/dist/server/src/polyglot/python/plugins/plugin_api.py +114 -0
  614. package/dist/server/src/polyglot/python/plugins/proxy/camera_device.py +1722 -0
  615. package/dist/server/src/polyglot/python/plugins/proxy/device_manager.py +265 -0
  616. package/dist/server/src/polyglot/python/plugins/proxy/message_queue.py +213 -0
  617. package/dist/server/src/polyglot/python/plugins/schema.py +392 -0
  618. package/dist/server/src/polyglot/python/plugins/storage_controller.py +57 -0
  619. package/dist/server/src/polyglot/python/plugins/typings.py +248 -0
  620. package/dist/server/src/polyglot/python/utilities/object_path.py +187 -0
  621. package/dist/server/src/polyglot/python/utilities/packer.py +11 -0
  622. package/dist/server/src/polyglot/python/utilities/task.py +25 -0
  623. package/dist/server/src/polyglot/python/utilities/thread.py +10 -0
  624. package/dist/server/src/polyglot/python/utilities/utils.py +48 -0
  625. package/dist/server/src/services/config/constants.d.ts +4 -0
  626. package/dist/server/src/services/config/constants.js +58 -0
  627. package/dist/server/src/services/config/constants.js.map +1 -0
  628. package/dist/server/src/services/config/index.d.ts +54 -0
  629. package/dist/server/src/services/config/index.js +288 -0
  630. package/dist/server/src/services/config/index.js.map +1 -0
  631. package/dist/server/src/services/config/types.d.ts +162 -0
  632. package/dist/server/src/services/config/types.js +11 -0
  633. package/dist/server/src/services/config/types.js.map +1 -0
  634. package/dist/server/src/services/logger/index.d.ts +30 -0
  635. package/dist/server/src/services/logger/index.js +179 -0
  636. package/dist/server/src/services/logger/index.js.map +1 -0
  637. package/dist/server/src/types.d.ts +4 -0
  638. package/dist/server/src/types.js +2 -0
  639. package/dist/server/src/types.js.map +1 -0
  640. package/dist/server/src/utils/packer.d.ts +2 -0
  641. package/dist/server/src/utils/packer.js +17 -0
  642. package/dist/server/src/utils/packer.js.map +1 -0
  643. package/dist/server/src/utils/pythonInstaller.d.ts +48 -0
  644. package/dist/server/src/utils/pythonInstaller.js +465 -0
  645. package/dist/server/src/utils/pythonInstaller.js.map +1 -0
  646. package/dist/server/src/utils/subscribed.d.ts +9 -0
  647. package/dist/server/src/utils/subscribed.js +17 -0
  648. package/dist/server/src/utils/subscribed.js.map +1 -0
  649. package/dist/server/src/utils/utils.d.ts +10 -0
  650. package/dist/server/src/utils/utils.js +165 -0
  651. package/dist/server/src/utils/utils.js.map +1 -0
  652. package/package.json +142 -0
@@ -0,0 +1,922 @@
1
+ import asyncio
2
+ import os
3
+ import random
4
+ import re
5
+ import signal
6
+ import string
7
+ import traceback
8
+ from contextlib import suppress
9
+ from datetime import datetime
10
+ from typing import Any, Literal, Optional, Union, cast
11
+
12
+ import nats
13
+ from camera_ui_types import DecoderFormat, FrameData, FrameMetadata, ImageOptions
14
+ from image_utils import process_image_threaded
15
+ from nats.aio.client import Client as NatsConnection
16
+ from nats.aio.msg import Msg
17
+ from nats.aio.subscription import Subscription
18
+ from nats.errors import NoRespondersError, TimeoutError
19
+ from plugins.logger import PluginLogger
20
+ from plugins.typings import ProcessPrebufferedImageRequest
21
+ from typings import (
22
+ BaseFrameWorkerConfig,
23
+ FfmpegArgs,
24
+ FfmpegArgsResponse,
25
+ FrameWorkerClient,
26
+ MainToWorkerMessage,
27
+ MainToWorkerResponse,
28
+ PingMessage,
29
+ PongMessage,
30
+ PrebufferContainer,
31
+ RecoveredClient,
32
+ SignalingRequest,
33
+ SignalingResponse,
34
+ WorkerMessage,
35
+ WorkerToMainMessage,
36
+ WorkerToMainResponse,
37
+ )
38
+ from utilities.packer import pack, unpack
39
+ from utilities.task import TaskSet
40
+
41
+ config: BaseFrameWorkerConfig = {
42
+ "frameWorkerId": os.environ["FRAME_WORKER_ID"],
43
+ "cameraId": os.environ["CAMERA_ID"],
44
+ "cameraName": os.environ["CAMERA_NAME"],
45
+ "ffmpegPath": os.environ["FFMPEG_PATH"],
46
+ "logLevel": os.environ.get("LOGGER_LEVEL") or "debug",
47
+ "disableTimestamps": os.environ.get("LOGGER_DISABLE_TIMESTAMPS") == "true",
48
+ "auth": {
49
+ "user": os.environ["PROXY_USER"],
50
+ "password": os.environ["PROXY_PASSWORD"],
51
+ },
52
+ "proxyEndpoints": [endpoint for endpoint in os.environ["PROXY_ENDPOINTS"].split(",")],
53
+ "fps": int(os.environ["FPS"]) if "FPS" in os.environ else 10,
54
+ "resolution": int(os.environ["RESOLUTION"]) if "RESOLUTION" in os.environ else 640,
55
+ }
56
+
57
+ PIX_FMT: Literal["yuv420p", "rgb24"] = "yuv420p"
58
+
59
+
60
+ class FrameWorkerChild:
61
+ def __init__(self):
62
+ self.camera_id = config["cameraId"]
63
+ self.camera_name = config["cameraName"]
64
+ self.ffmpeg_path = config["ffmpegPath"]
65
+
66
+ self.logger = PluginLogger("Frame Worker", config["disableTimestamps"])
67
+ self.logger.debug_enabled = config["logLevel"] == "debug" or config["logLevel"] == "trace"
68
+ self.logger.trace_enabled = config["logLevel"] == "trace"
69
+
70
+ self.subject = f"{config['frameWorkerId']}.frameWorkerChild"
71
+ self.ipc_subject = f"{config['frameWorkerId']}.frameWorker"
72
+ self.image_subject = f"{config['cameraId']}.frameGenerator"
73
+ self.signaling_subject = f"{config['cameraId']}.frameGenerator.signaling"
74
+ self.frame_subject = f"{config['cameraId']}.frameReceiver"
75
+
76
+ self.publisher: Optional[NatsConnection] = None
77
+ self.signaling_publisher: Optional[NatsConnection] = None
78
+ self.image_publisher: Optional[NatsConnection] = None
79
+ self.frame_publisher: Optional[NatsConnection] = None
80
+
81
+ self.subscriber: Optional[Subscription] = None
82
+ self.image_subscriber: Optional[Subscription] = None
83
+ self.signal_subscriber: Optional[Subscription] = None
84
+
85
+ self.max_diff_frame = 3
86
+ self.restart_delay = 5
87
+ self.stopped = False
88
+ self.closed = False
89
+ self.restarting = False
90
+ self.clients: dict[str, FrameWorkerClient] = {}
91
+ self.tasks: TaskSet = TaskSet(f"{self.camera_name} FrameWorkerChild")
92
+
93
+ self.prebuffer_full = False
94
+ self.prebuffer_duration = 7
95
+ self.prebuffer_container: list[PrebufferContainer] = []
96
+
97
+ self.shutdown_event = asyncio.Event()
98
+ self.loop = asyncio.get_event_loop()
99
+
100
+ self._metadata: Optional[FrameMetadata] = None
101
+ self.metadata_event = asyncio.Event()
102
+ self.ffmpeg_process = None
103
+
104
+ self.stderr_task: Optional[asyncio.Task[None]] = None
105
+ self.stdout_task: Optional[asyncio.Task[None]] = None
106
+ self.close_task: Optional[asyncio.Task[None]] = None
107
+
108
+ @property
109
+ def log_prefix(self) -> str:
110
+ return f"{self.camera_name}:"
111
+
112
+ @property
113
+ async def metadata(self) -> FrameMetadata:
114
+ if not self._metadata:
115
+ await self.metadata_event.wait()
116
+
117
+ return cast(FrameMetadata, self._metadata)
118
+
119
+ async def listen(self) -> None:
120
+ self.setup_signal_handlers()
121
+
122
+ async def ignore_cb(e: Optional[Any] = None):
123
+ pass
124
+
125
+ self.publisher = await nats.connect(
126
+ servers=[endpoint for endpoint in config["proxyEndpoints"] if endpoint.startswith("nats://")],
127
+ name=self.subject,
128
+ user=config["auth"]["user"],
129
+ password=config["auth"]["password"],
130
+ max_reconnect_attempts=-1,
131
+ error_cb=ignore_cb,
132
+ disconnected_cb=ignore_cb,
133
+ closed_cb=ignore_cb,
134
+ reconnected_cb=ignore_cb,
135
+ discovered_server_cb=ignore_cb,
136
+ )
137
+
138
+ self.image_publisher = await nats.connect(
139
+ servers=[endpoint for endpoint in config["proxyEndpoints"] if endpoint.startswith("nats://")],
140
+ name=self.image_subject,
141
+ user=config["auth"]["user"],
142
+ password=config["auth"]["password"],
143
+ max_reconnect_attempts=-1,
144
+ error_cb=ignore_cb,
145
+ disconnected_cb=ignore_cb,
146
+ closed_cb=ignore_cb,
147
+ reconnected_cb=ignore_cb,
148
+ discovered_server_cb=ignore_cb,
149
+ )
150
+
151
+ self.frame_publisher = await nats.connect(
152
+ servers=[endpoint for endpoint in config["proxyEndpoints"] if endpoint.startswith("nats://")],
153
+ name=self.frame_subject,
154
+ user=config["auth"]["user"],
155
+ password=config["auth"]["password"],
156
+ max_reconnect_attempts=-1,
157
+ error_cb=ignore_cb,
158
+ disconnected_cb=ignore_cb,
159
+ closed_cb=ignore_cb,
160
+ reconnected_cb=ignore_cb,
161
+ discovered_server_cb=ignore_cb,
162
+ )
163
+
164
+ self.signaling_publisher = await nats.connect(
165
+ servers=[endpoint for endpoint in config["proxyEndpoints"] if endpoint.startswith("nats://")],
166
+ name=self.signaling_subject,
167
+ user=config["auth"]["user"],
168
+ password=config["auth"]["password"],
169
+ max_reconnect_attempts=-1,
170
+ error_cb=ignore_cb,
171
+ disconnected_cb=ignore_cb,
172
+ closed_cb=ignore_cb,
173
+ reconnected_cb=ignore_cb,
174
+ discovered_server_cb=ignore_cb,
175
+ )
176
+
177
+ self.subscriber = await self.publisher.subscribe(subject=self.subject)
178
+ self.image_subscriber = await self.image_publisher.subscribe(subject=self.image_subject)
179
+ self.signal_subscriber = await self.signaling_publisher.subscribe(subject=self.signaling_subject)
180
+
181
+ await asyncio.gather(
182
+ self.send("started"),
183
+ self.listen_to_ipc_messages(),
184
+ self.listen_to_signaling_messages(),
185
+ self.listen_to_prebuffered_image_messages(),
186
+ )
187
+
188
+ await self.shutdown_event.wait()
189
+
190
+ async def close(self) -> None:
191
+ self.closed = True
192
+ # await self.stop()
193
+
194
+ with suppress(Exception):
195
+ if self.publisher:
196
+ await self.publisher.close()
197
+
198
+ if self.image_publisher:
199
+ await self.image_publisher.close()
200
+
201
+ if self.signaling_publisher:
202
+ await self.signaling_publisher.close()
203
+
204
+ if self.frame_publisher:
205
+ await self.frame_publisher.close()
206
+
207
+ self.shutdown_event.set()
208
+
209
+ async def start(self) -> None:
210
+ try:
211
+ self.closed = False
212
+ await self.start_video_session()
213
+ except Exception as e:
214
+ self.logger.error(
215
+ f"{self.log_prefix} An error occurred while starting frame session:",
216
+ e,
217
+ )
218
+
219
+ await self.restart_ffmpeg()
220
+
221
+ async def stop(self) -> None:
222
+ self.stopped = True
223
+ await self.disconnect_all_clients()
224
+ await self.reset()
225
+
226
+ async def reset(self) -> None:
227
+ self.reset_prebuffer()
228
+ self.reset_metadata()
229
+ await self.reset_video_session()
230
+
231
+ def reset_prebuffer(self) -> None:
232
+ self.prebuffer_full = False
233
+ self.prebuffer_container = []
234
+
235
+ def reset_metadata(self) -> None:
236
+ self.metadata_event.clear()
237
+ self._metadata = None
238
+
239
+ async def reset_video_session(self) -> None:
240
+ if self.stderr_task:
241
+ self.stderr_task.cancel()
242
+ self.stderr_task = None
243
+
244
+ if self.stdout_task:
245
+ self.stdout_task.cancel()
246
+ self.stdout_task = None
247
+
248
+ if self.close_task:
249
+ self.close_task.cancel()
250
+ self.close_task = None
251
+
252
+ if self.ffmpeg_process:
253
+ self.logger.debug(f"{self.log_prefix} Stopping FFmpeg process...")
254
+ self.ffmpeg_process.kill()
255
+ await self.ffmpeg_process.wait()
256
+ self.ffmpeg_process = None
257
+
258
+ async def start_video_session(self) -> None:
259
+ if self.ffmpeg_process:
260
+ return
261
+
262
+ # await self.reset()
263
+ self.stopped = False
264
+
265
+ try:
266
+ self.tasks.add(self.spawn_ffmpeg())
267
+ await asyncio.wait_for(self.metadata_event.wait(), timeout=15)
268
+ self.logger.debug(f"{self.log_prefix} Frame session started")
269
+ except asyncio.TimeoutError:
270
+ ffmpeg_process = cast(Optional[asyncio.subprocess.Process], self.ffmpeg_process)
271
+ if ffmpeg_process and ffmpeg_process.returncode is None:
272
+ ffmpeg_process.kill()
273
+ raise Exception("FFmpeg process timed out") from None
274
+
275
+ def build_ffmpeg_args(self, ffmpeg_path: str, camera_source: str, ffmpeg_args: FfmpegArgs) -> list[str]:
276
+ return [
277
+ ffmpeg_path,
278
+ "-hide_banner",
279
+ # "-vsync",
280
+ # "0",
281
+ "-hwaccel",
282
+ ffmpeg_args["hwaccel"],
283
+ *ffmpeg_args["hwaccelArgs"],
284
+ "-fflags",
285
+ "nobuffer",
286
+ "-flags",
287
+ "low_delay",
288
+ "-analyzeduration",
289
+ "0",
290
+ "-probesize",
291
+ "500000",
292
+ "-reorder_queue_size",
293
+ "0",
294
+ "-user_agent",
295
+ "camera.ui/decoder",
296
+ "-rtsp_transport",
297
+ "tcp",
298
+ "-i",
299
+ camera_source,
300
+ "-threads",
301
+ ffmpeg_args["threads"],
302
+ "-vf",
303
+ f"showinfo=checksum=0,{ffmpeg_args['hwaccelFilter'].replace('640', str(config['resolution']))},fps=fps={config['fps']}",
304
+ "-an",
305
+ "-dn",
306
+ "-sn",
307
+ "-vcodec",
308
+ "rawvideo",
309
+ "-f",
310
+ "rawvideo",
311
+ "-pix_fmt",
312
+ PIX_FMT,
313
+ "-",
314
+ ]
315
+
316
+ async def spawn_ffmpeg(self) -> None:
317
+ response = cast(Union[FfmpegArgsResponse, None], await self.send("getFFmpegArgs"))
318
+
319
+ if not response:
320
+ raise Exception("Error getting FFmpeg args from main process")
321
+
322
+ args = self.build_ffmpeg_args(self.ffmpeg_path, response["cameraSource"], response["ffmpegArgs"])
323
+
324
+ self.logger.debug(f"{self.log_prefix} Starting FFmpeg process: {' '.join(args)}")
325
+
326
+ self.ffmpeg_process = await asyncio.create_subprocess_exec(
327
+ *args,
328
+ stdout=asyncio.subprocess.PIPE,
329
+ stderr=asyncio.subprocess.PIPE,
330
+ limit=10**8,
331
+ )
332
+
333
+ self.stderr_task = self.tasks.add(self.handle_ffmpeg_stderr())
334
+ self.stdout_task = self.tasks.add(self.handle_ffmpeg_stdout())
335
+ self.close_task = self.tasks.add(self.handle_ffmpeg_close())
336
+
337
+ async def restart_ffmpeg(self) -> None:
338
+ if not self.stopped and not self.closed and not self.restarting:
339
+ self.restarting = True
340
+
341
+ self.logger.log(f"{self.log_prefix} Restarting FFmpeg process in {self.restart_delay} seconds...")
342
+
343
+ with suppress(asyncio.TimeoutError):
344
+ await asyncio.wait_for(asyncio.sleep(self.restart_delay), timeout=self.restart_delay)
345
+
346
+ if not self.stopped and not self.closed:
347
+ await self.start()
348
+
349
+ self.restarting = False
350
+
351
+ async def handle_ffmpeg_stderr(self) -> None:
352
+ try:
353
+
354
+ def is_closed() -> bool:
355
+ return (
356
+ self.stopped
357
+ or self.closed
358
+ or not self.ffmpeg_process
359
+ or not self.ffmpeg_process.stderr
360
+ or self.ffmpeg_process.returncode is not None
361
+ )
362
+
363
+ while not is_closed():
364
+ try:
365
+ line = await self.ffmpeg_process.stderr.readline() # type: ignore
366
+
367
+ if is_closed():
368
+ break
369
+
370
+ if not line or len(line) == 0:
371
+ continue
372
+
373
+ line = line.decode("utf-8").strip()
374
+ metadata = self.parse_frame_info(line)
375
+
376
+ if metadata:
377
+ self.logger.debug(f"{self.log_prefix} Metadata:", metadata)
378
+ self._metadata = metadata
379
+ self.metadata_event.set()
380
+ break
381
+
382
+ except Exception as e:
383
+ self.logger.error(
384
+ f"{self.log_prefix} An error occurred while reading ffmpeg stderr:",
385
+ e,
386
+ )
387
+
388
+ break
389
+ except asyncio.CancelledError:
390
+ pass
391
+
392
+ async def handle_ffmpeg_stdout(self) -> None:
393
+ try:
394
+ metadata = (await self.metadata).copy()
395
+ restart_timeout = None
396
+
397
+ def is_closed() -> bool:
398
+ return (
399
+ self.stopped
400
+ or self.closed
401
+ or not self.frame_publisher
402
+ or self.frame_publisher.is_closed
403
+ or not self.ffmpeg_process
404
+ or not self.ffmpeg_process.stdout
405
+ or self.ffmpeg_process.returncode is not None
406
+ )
407
+
408
+ def restart_watchdog():
409
+ nonlocal restart_timeout
410
+ if restart_timeout:
411
+ restart_timeout.cancel()
412
+ restart_timeout = asyncio.get_event_loop().call_later(
413
+ 3, lambda: asyncio.create_task(restart_ffmpeg())
414
+ )
415
+
416
+ async def restart_ffmpeg():
417
+ if not self.stopped and not self.closed and not self.restarting:
418
+ self.logger.error(
419
+ f"{self.log_prefix} FFmpeg process is not producing frames, restarting..."
420
+ )
421
+ await self.reset()
422
+ await self.restart_ffmpeg()
423
+
424
+ while not is_closed():
425
+ try:
426
+ restart_watchdog()
427
+
428
+ frame = await self.ffmpeg_process.stdout.readexactly( # type: ignore
429
+ int(metadata["frameSize"]),
430
+ )
431
+
432
+ if is_closed():
433
+ break
434
+
435
+ frame_id = self.generate_id()
436
+ now = int(datetime.now().timestamp() * 1000)
437
+
438
+ self.prebuffer_container.append(
439
+ {
440
+ "frame_id": frame_id,
441
+ "time": now,
442
+ "frame": frame,
443
+ }
444
+ )
445
+
446
+ if (
447
+ len(self.prebuffer_container) > 0
448
+ and now - self.prebuffer_container[0]["time"] >= (self.prebuffer_duration * 1000)
449
+ and not self.prebuffer_full
450
+ ):
451
+ self.logger.debug(f"{self.log_prefix} Prebuffer is full")
452
+ self.prebuffer_full = True
453
+
454
+ while len(self.prebuffer_container) > 0 and self.prebuffer_container[0]["time"] < now - (
455
+ self.prebuffer_duration * 1000
456
+ ):
457
+ self.prebuffer_container.pop(0)
458
+
459
+ if self.prebuffer_full:
460
+ frame_data: FrameData = {"frameId": frame_id, "timestamp": now}
461
+
462
+ await self.frame_publisher.publish(self.frame_subject, pack(frame_data)) # type: ignore
463
+
464
+ except asyncio.IncompleteReadError as e:
465
+ if not is_closed() and not self.restarting:
466
+ self.logger.error(f"{self.log_prefix} Incomplete read error:", e)
467
+ await asyncio.sleep(0.1)
468
+
469
+ except Exception as e:
470
+ if not is_closed() and not self.restarting:
471
+ self.logger.error(
472
+ f"{self.log_prefix} An error occurred while reading ffmpeg stdout:",
473
+ e,
474
+ )
475
+ break
476
+ except asyncio.CancelledError:
477
+ pass
478
+
479
+ async def handle_ffmpeg_close(self) -> None:
480
+ try:
481
+ if self.ffmpeg_process:
482
+ code = await self.ffmpeg_process.wait()
483
+ self.ffmpeg_process = None
484
+
485
+ await self.reset()
486
+
487
+ if code != 0 and code != -9 or not self.stopped:
488
+ self.logger.error(
489
+ self.log_prefix,
490
+ f"FFmpeg process has exited with code {code} (unexpected)",
491
+ )
492
+ else:
493
+ self.logger.debug(
494
+ f"{self.log_prefix} FFmpeg process has exited with code {code} (expected)"
495
+ )
496
+
497
+ await self.restart_ffmpeg()
498
+ except asyncio.CancelledError:
499
+ pass
500
+
501
+ def parse_frame_info(self, stderr: str) -> Optional[FrameMetadata]:
502
+ patterns = {
503
+ "s": r"s:\s*(\d+x\d+)",
504
+ }
505
+
506
+ matches: dict[str, str] = {}
507
+
508
+ for key, pattern in patterns.items():
509
+ match = re.search(pattern, stderr)
510
+ if match:
511
+ matches[key] = match.group(1)
512
+
513
+ if "s" not in matches:
514
+ return None
515
+
516
+ width, height = map(int, matches["s"].split("x"))
517
+ new_width = config["resolution"]
518
+ new_height = round((new_width * height) / width)
519
+ format: DecoderFormat = "yuv" if PIX_FMT == "yuv420p" else "rgb"
520
+ bytes_per_pixel = 1.5 if format == "yuv" else 3
521
+ frame_size = new_width * new_height * bytes_per_pixel
522
+
523
+ metadata: FrameMetadata = {
524
+ "format": format,
525
+ "frameSize": frame_size,
526
+ "width": new_width,
527
+ "height": new_height,
528
+ "origHeight": height,
529
+ "origWidth": width,
530
+ }
531
+
532
+ return metadata
533
+
534
+ async def send(
535
+ self,
536
+ message: WorkerMessage,
537
+ data: Optional[dict[str, Any]] = None,
538
+ ) -> Union[dict[str, Any], None]:
539
+ if self.publisher is None:
540
+ raise Exception("Publisher not initialized")
541
+
542
+ if data is None:
543
+ data = {}
544
+
545
+ worker_message: WorkerToMainMessage = {
546
+ "message": message,
547
+ "data": data,
548
+ }
549
+
550
+ msg = await self.publisher.request(
551
+ self.ipc_subject,
552
+ pack(worker_message),
553
+ timeout=30,
554
+ )
555
+
556
+ response: MainToWorkerResponse = unpack(msg.data)
557
+
558
+ return response.get("response")
559
+
560
+ async def add_client(self, plugin_id: str, request_id: str) -> None:
561
+ if not self.clients.get(plugin_id):
562
+ self.clients[plugin_id] = FrameWorkerClient(plugin_id, [request_id])
563
+
564
+ client = self.clients[plugin_id]
565
+
566
+ if request_id not in client.request_ids:
567
+ client.request_ids.append(request_id)
568
+
569
+ self.logger.trace(f"{self.log_prefix} New client {self.client_identifier(plugin_id, request_id)}")
570
+
571
+ await self.send("updateClient", {"pluginId": client.plugin_id, "requestIds": client.request_ids})
572
+
573
+ if len(self.clients) == 1:
574
+ await self.start()
575
+
576
+ async def remove_client(self, plugin_id: str, request_id: str) -> None:
577
+ client = self.clients[plugin_id]
578
+
579
+ if not client or request_id not in client.request_ids:
580
+ return
581
+
582
+ self.logger.trace(
583
+ f"{self.log_prefix} Removing client {self.client_identifier(plugin_id, request_id)}"
584
+ )
585
+
586
+ if request_id in client.request_ids:
587
+ client.request_ids.remove(request_id)
588
+
589
+ if len(client.request_ids) == 0:
590
+ del self.clients[plugin_id]
591
+ await self.send("removeClient", {"pluginId": client.plugin_id, "requestIds": client.request_ids})
592
+ else:
593
+ await self.send("updateClient", {"pluginId": client.plugin_id, "requestIds": client.request_ids})
594
+
595
+ if len(self.clients) == 0:
596
+ await self.stop()
597
+
598
+ async def recover_clients(self, clients: list[RecoveredClient]) -> None:
599
+ for client in clients:
600
+ for request_id in client["requestIds"]:
601
+ self.logger.trace(
602
+ f"{self.log_prefix} Recovering client {self.client_identifier(client['pluginId'], request_id)}"
603
+ )
604
+
605
+ self.clients[client["pluginId"]] = FrameWorkerClient(client["pluginId"], client["requestIds"])
606
+
607
+ if len(self.clients) > 0:
608
+ await self.start()
609
+
610
+ async def disconnect_client(self, camera_id: str, plugin_id: str, request_id: str) -> None:
611
+ client = self.clients.get(plugin_id)
612
+
613
+ if not self.signaling_publisher or not client or request_id not in client.request_ids:
614
+ return
615
+
616
+ ping_target_subject = f"{plugin_id}.camera.{camera_id}.signaling"
617
+
618
+ response: SignalingResponse = {"type": "disconnect", "requestId": request_id}
619
+
620
+ await self.signaling_publisher.publish(ping_target_subject, pack(response))
621
+ await self.remove_client(plugin_id, request_id)
622
+
623
+ async def disconnect_all_clients(self) -> None:
624
+ for client in self.clients.values():
625
+ for request_id in client.request_ids:
626
+ await self.disconnect_client(self.camera_id, client.plugin_id, request_id)
627
+
628
+ async def handle_connect_message(self, message: SignalingRequest) -> None:
629
+ await self.add_client(message["pluginId"], message["requestId"])
630
+ self.tasks.add(self.start_ping_pong(message["cameraId"], message["pluginId"], message["requestId"]))
631
+
632
+ async def handle_disconnect_message(self, message: SignalingRequest) -> None:
633
+ await self.remove_client(message["pluginId"], message["requestId"])
634
+
635
+ async def handle_metadata_message(self, msg: Msg, message: SignalingRequest) -> None:
636
+ metadata = (await self.metadata).copy()
637
+
638
+ response: SignalingResponse = {
639
+ "type": "metadata",
640
+ "requestId": message["requestId"],
641
+ "metadata": metadata,
642
+ }
643
+
644
+ await msg.respond(pack(response))
645
+
646
+ async def start_ping_pong(self, camera_id: str, plugin_id: str, request_id: str) -> None:
647
+ ping_target_subject = f"{plugin_id}.camera.{camera_id}.signaling"
648
+ ping_interval = 3
649
+ ping_timeout = 2
650
+
651
+ def request_id_exists() -> bool:
652
+ return self.clients.get(plugin_id, False) and request_id in self.clients[plugin_id].request_ids
653
+
654
+ while self.signaling_publisher and request_id_exists():
655
+ try:
656
+ ping_message: PingMessage = {"type": "ping", "requestId": request_id}
657
+
658
+ # self.logger.trace(f"{self.log_prefix} Sending ping to {camera_id}:{plugin_id}")
659
+
660
+ msg = await self.signaling_publisher.request(
661
+ ping_target_subject,
662
+ pack(ping_message),
663
+ timeout=ping_timeout,
664
+ )
665
+
666
+ ping_response: PongMessage = unpack(msg.data)
667
+
668
+ if not request_id_exists():
669
+ break
670
+
671
+ if ping_response["type"] != "pong":
672
+ raise Exception("Invalid response to ping")
673
+
674
+ # self.logger.trace(f"{self.log_prefix} Received pong from {camera_id}:{plugin_id}")
675
+
676
+ await asyncio.sleep(ping_interval)
677
+ except (Exception, NoRespondersError, TimeoutError) as e:
678
+ if request_id_exists():
679
+ if isinstance(e, (NoRespondersError, TimeoutError)):
680
+ self.logger.trace(f"{self.log_prefix} Ping/Pong timeout for {camera_id}:{plugin_id}")
681
+ await self.remove_client(plugin_id, request_id)
682
+ else:
683
+ self.logger.error(f"{self.log_prefix} Error during ping/pong:", e)
684
+
685
+ break
686
+
687
+ async def listen_to_ipc_messages(self) -> None:
688
+ if not self.subscriber:
689
+ raise Exception("Subscriber not initialized")
690
+
691
+ async for msg in self.subscriber.messages:
692
+ try:
693
+ if self.closed:
694
+ break
695
+
696
+ if len(msg.data) == 0:
697
+ continue
698
+
699
+ self.tasks.add(self.respond_on_ipc_message(msg))
700
+ except Exception as e:
701
+ if not self.closed:
702
+ self.logger.error(f"{self.log_prefix} Error while processing IPC message:", e)
703
+ else:
704
+ break
705
+
706
+ async def listen_to_signaling_messages(self) -> None:
707
+ if not self.signal_subscriber:
708
+ raise Exception("Subscriber not initialized")
709
+
710
+ async for msg in self.signal_subscriber.messages:
711
+ try:
712
+ if self.closed:
713
+ break
714
+
715
+ if len(msg.data) == 0:
716
+ continue
717
+
718
+ self.tasks.add(self.respond_on_signaling_message(msg))
719
+ except Exception as e:
720
+ if not self.closed:
721
+ self.logger.error(f"{self.log_prefix} Error while processing signaling message:", e)
722
+ else:
723
+ break
724
+
725
+ async def listen_to_prebuffered_image_messages(self) -> None:
726
+ if not self.image_subscriber:
727
+ raise Exception("Subscriber not initialized")
728
+
729
+ async for msg in self.image_subscriber.messages:
730
+ try:
731
+ if self.closed:
732
+ break
733
+
734
+ if len(msg.data) == 0:
735
+ continue
736
+
737
+ self.tasks.add(self.respond_on_prebuffered_image_message(msg))
738
+ except Exception as e:
739
+ if not self.closed:
740
+ self.logger.error(f"{self.log_prefix} Error while processing image message:", e)
741
+ else:
742
+ break
743
+
744
+ async def respond_on_ipc_message(self, msg: Msg) -> None:
745
+ try:
746
+ main_message: MainToWorkerMessage = unpack(msg.data)
747
+ response: WorkerToMainResponse = {}
748
+ message = main_message["message"]
749
+
750
+ if message == "setCameraName":
751
+ self.camera_name = main_message["data"]["cameraName"]
752
+ elif message == "recoverClients":
753
+ await self.recover_clients(main_message["data"]["clients"])
754
+
755
+ await msg.respond(pack(response))
756
+ except Exception as e:
757
+ self.logger.error(f"{self.log_prefix} Error while processing IPC respond:", e)
758
+
759
+ async def respond_on_signaling_message(self, msg: Msg) -> None:
760
+ try:
761
+ message: SignalingRequest = unpack(msg.data)
762
+
763
+ if message["type"] == "connect":
764
+ await self.handle_connect_message(message)
765
+ elif message["type"] == "disconnect":
766
+ await self.handle_disconnect_message(message)
767
+ elif message["type"] == "metadata":
768
+ await self.handle_metadata_message(msg, message)
769
+ except Exception as e:
770
+ self.logger.error(f"{self.log_prefix} Error while processing signaling respond:", e)
771
+
772
+ async def respond_on_prebuffered_image_message(self, msg: Msg) -> None:
773
+ try:
774
+ message: ProcessPrebufferedImageRequest = unpack(msg.data)
775
+ metadata = message["metadata"]
776
+ frame_data = message["frameData"]
777
+ options = message["options"]
778
+ prebuffer_duration = message["prebufferDuration"]
779
+ width = metadata["width"]
780
+ height = metadata["height"]
781
+ format = metadata["format"]
782
+
783
+ target_frame = self.find_target_frame(frame_data, prebuffer_duration)
784
+
785
+ if not target_frame:
786
+ self.log_frame_not_found()
787
+ else:
788
+ processed_image = await self.process_frame(
789
+ target_frame["frame"], width, height, format, options
790
+ )
791
+ await msg.respond(processed_image)
792
+ return
793
+
794
+ await msg.respond(b"")
795
+ except Exception as e:
796
+ self.logger.error(f"{self.log_prefix} Error while processing image respond:", e)
797
+
798
+ def find_target_frame(
799
+ self, frame_data: FrameData, prebuffer_duration: int
800
+ ) -> Optional[PrebufferContainer]:
801
+ target_index = next(
802
+ (
803
+ i
804
+ for i, frame in enumerate(self.prebuffer_container)
805
+ if frame["frame_id"] == frame_data["frameId"]
806
+ ),
807
+ -1,
808
+ )
809
+
810
+ if target_index == -1:
811
+ return self.find_nearest_frame(frame_data)
812
+
813
+ if prebuffer_duration > 0:
814
+ target_time = self.prebuffer_container[target_index]["time"] - prebuffer_duration * 1000
815
+ result = self.find_nearest_frame_by_time(target_time)
816
+ if result is not None:
817
+ return result
818
+
819
+ return self.prebuffer_container[target_index]
820
+
821
+ def find_nearest_frame(self, frame_data: FrameData) -> Optional[PrebufferContainer]:
822
+ max_time_diff = self.max_diff_frame * (1000 / config["fps"])
823
+
824
+ nearest_frame = None
825
+ min_time_diff = float("inf")
826
+
827
+ for frame in self.prebuffer_container:
828
+ current_time_diff = abs(frame["time"] - frame_data["timestamp"])
829
+
830
+ if current_time_diff <= max_time_diff and (
831
+ nearest_frame is None or current_time_diff < min_time_diff
832
+ ):
833
+ nearest_frame = frame
834
+ min_time_diff = current_time_diff
835
+
836
+ return nearest_frame
837
+
838
+ def find_nearest_frame_by_time(self, target_time: float) -> Optional[PrebufferContainer]:
839
+ max_time_diff = (self.max_diff_frame / config["fps"]) * 1000
840
+ nearest_frame = None
841
+ min_diff = float("inf")
842
+
843
+ for frame in self.prebuffer_container:
844
+ if frame["time"] <= target_time:
845
+ time_diff = abs(frame["time"] - target_time)
846
+ if time_diff <= max_time_diff and time_diff < min_diff:
847
+ nearest_frame = frame
848
+ min_diff = time_diff
849
+
850
+ return nearest_frame
851
+
852
+ async def process_frame(
853
+ self,
854
+ frame: bytes,
855
+ width: int,
856
+ height: int,
857
+ format: Union[DecoderFormat, Literal["rgba", "gray"]],
858
+ options: ImageOptions,
859
+ ) -> bytes:
860
+ return await process_image_threaded(
861
+ frame,
862
+ width,
863
+ height,
864
+ format,
865
+ options,
866
+ )
867
+
868
+ def log_frame_not_found(self):
869
+ if len(self.prebuffer_container) > 0:
870
+ self.logger.warn(f"{self.log_prefix} Frame not found in prebuffer")
871
+ else:
872
+ self.logger.warn(f"{self.log_prefix} Prebuffer is empty! FFmpeg is not producing frames?")
873
+
874
+ def client_identifier(self, plugin_id: str, request_id: str) -> str:
875
+ return f"{plugin_id}:{request_id}"
876
+
877
+ def generate_id(self, length: int = 9) -> str:
878
+ characters = string.ascii_letters + string.digits
879
+ return "".join(random.choice(characters) for _ in range(length))
880
+
881
+ def setup_signal_handlers(self) -> None:
882
+ loop = asyncio.get_running_loop()
883
+ loop.set_exception_handler(self.handle_exception)
884
+
885
+ for signame in ("SIGINT", "SIGTERM"):
886
+ loop.add_signal_handler(
887
+ getattr(signal, signame),
888
+ lambda signame=signame: self.gracefully_close(signame, getattr(signal, signame)),
889
+ )
890
+
891
+ def gracefully_close(self, signame: str, reason: Any = "unknown") -> None:
892
+ if self.stopped:
893
+ return
894
+
895
+ self.logger.debug(
896
+ f"{self.log_prefix} Frame Worker is gracefully closing from signal='{signame}' reason='{reason}'..."
897
+ )
898
+
899
+ self.tasks.add(self.close())
900
+ self.shutdown_event.set()
901
+
902
+ def handle_exception(self, loop: asyncio.AbstractEventLoop, context: Any) -> None:
903
+ print(f"{self.log_prefix} Exception context:", context)
904
+ traceback.print_exc()
905
+
906
+ msg = context.get("message", "Unknown error")
907
+ exception = context.get("exception")
908
+
909
+ if exception:
910
+ tb_str = "".join(traceback.format_exception(type(exception), exception, exception.__traceback__)) # type: ignore
911
+
912
+ self.logger.error(f"{self.log_prefix} Caught exception: {msg}\n{tb_str}")
913
+ else:
914
+ self.logger.error(f"{self.log_prefix} Caught exception: {msg}")
915
+
916
+ if loop.is_running():
917
+ self.gracefully_close("uncaughtException", msg)
918
+
919
+
920
+ if __name__ == "__main__":
921
+ worker = FrameWorkerChild()
922
+ asyncio.run(worker.listen(), debug=True)