@camera.ui/server 0.0.50-internal.0 → 0.0.50-internal.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 (387) hide show
  1. package/dist/interface/index.html +44 -44
  2. package/dist/interface/js/{@primevue.OhxoO3MD.0.0.50-internal.0.js → @primevue.CiB2EGly.0.0.50-internal.1.js} +1 -1
  3. package/dist/interface/js/{@tanstack.D1IL6eOv.0.0.50-internal.0.js → @tanstack.DxMw_rJn.0.0.50-internal.1.js} +1 -1
  4. package/dist/interface/js/{@vee-validate.BGPyWWTh.0.0.50-internal.0.js → @vee-validate.RxZ3hn6V.0.0.50-internal.1.js} +1 -1
  5. package/dist/interface/js/{@vueuse.BsKtqdiG.0.0.50-internal.0.js → @vueuse.C-k73ACm.0.0.50-internal.1.js} +1 -1
  6. package/dist/interface/js/{Adminpanel.D93Kvbwp.0.0.50-internal.0.js → Adminpanel.DumNu6GD.0.0.50-internal.1.js} +1 -1
  7. package/dist/interface/js/{Camera.DF2l3OMA.0.0.50-internal.0.js → Camera.BuosoqFl.0.0.50-internal.1.js} +1 -1
  8. package/dist/interface/js/{Cameras.YzvZccdv.0.0.50-internal.0.js → Cameras.A7NJflGG.0.0.50-internal.1.js} +2 -2
  9. package/dist/interface/js/Cammesh.Dv3C0UiR.0.0.50-internal.1.js +1 -0
  10. package/dist/interface/js/{Camview.CB7_HnoQ.0.0.50-internal.0.js → Camview.GgjJp7JR.0.0.50-internal.1.js} +1 -1
  11. package/dist/interface/js/{Config.BwflsWTm.0.0.50-internal.0.js → Config.BL3L-BFE.0.0.50-internal.1.js} +2 -2
  12. package/dist/interface/js/{Console.DZM8pN8Q.0.0.50-internal.0.js → Console.CxwRmUVF.0.0.50-internal.1.js} +1 -1
  13. package/dist/interface/js/{CuiConsole.BXXU7Gth.0.0.50-internal.0.js → CuiConsole.D16kkT6R.0.0.50-internal.1.js} +1 -1
  14. package/dist/interface/js/{CuiPluginCard.YFOrpbVD.0.0.50-internal.0.js → CuiPluginCard.Bkp__d8n.0.0.50-internal.1.js} +1 -1
  15. package/dist/interface/js/{CuiTimeline.VV5KSJd5.0.0.50-internal.0.js → CuiTimeline.C9HKvo0G.0.0.50-internal.1.js} +1 -1
  16. package/dist/interface/js/{FirstSteps.b-nvymgb.0.0.50-internal.0.js → FirstSteps.QuJjtAtF.0.0.50-internal.1.js} +1 -1
  17. package/dist/interface/js/{Plugin.BOMpVEwM.0.0.50-internal.0.js → Plugin.BLUUbEej.0.0.50-internal.1.js} +1 -1
  18. package/dist/interface/js/{Plugins.DdPwaUDA.0.0.50-internal.0.js → Plugins.DviCIk7w.0.0.50-internal.1.js} +1 -1
  19. package/dist/interface/js/Recordings.Dsp07cHs.0.0.50-internal.1.js +1 -0
  20. package/dist/interface/js/{Settings.D24ttaPu.0.0.50-internal.0.js → Settings.Clx4y9gP.0.0.50-internal.1.js} +1 -1
  21. package/dist/interface/js/{SettingsAccount.ms3aqz4E.0.0.50-internal.0.js → SettingsAccount.cfY4-PYd.0.0.50-internal.1.js} +1 -1
  22. package/dist/interface/js/SettingsAppearance.CBGZAazb.0.0.50-internal.1.js +1 -0
  23. package/dist/interface/js/{SettingsAppearance.vue_vue_type_script_setup_true_lang.CBQ6lL3T.0.0.50-internal.0.js → SettingsAppearance.vue_vue_type_script_setup_true_lang.kxAPXcBy.0.0.50-internal.1.js} +1 -1
  24. package/dist/interface/js/{SettingsBackup.BPEc4Rjg.0.0.50-internal.0.js → SettingsBackup.DOaJA4pp.0.0.50-internal.1.js} +1 -1
  25. package/dist/interface/js/SettingsRecordings.BGcwL6tk.0.0.50-internal.1.js +1 -0
  26. package/dist/interface/js/{SettingsRemote.BL5nXbUT.0.0.50-internal.0.js → SettingsRemote.BVU_w1Jm.0.0.50-internal.1.js} +1 -1
  27. package/dist/interface/js/{SettingsSystem.D7T0AIpm.0.0.50-internal.0.js → SettingsSystem.P0vy90vA.0.0.50-internal.1.js} +1 -1
  28. package/dist/interface/js/{SettingsUsers.1u0vCOVG.0.0.50-internal.0.js → SettingsUsers.DaP5m7eo.0.0.50-internal.1.js} +1 -1
  29. package/dist/interface/js/{VersionsHandler.vue_vue_type_script_setup_true_lang.xDishkkS.0.0.50-internal.0.js → VersionsHandler.vue_vue_type_script_setup_true_lang.MmrWYW3K.0.0.50-internal.1.js} +1 -1
  30. package/dist/interface/js/{ace-builds.D1nmvCwb.0.0.50-internal.0.js → ace-builds.C0aqA_3x.0.0.50-internal.1.js} +2 -2
  31. package/dist/interface/js/{ace.config.G96T2z54.0.0.50-internal.0.js → ace.config.C9wgzklI.0.0.50-internal.1.js} +1 -1
  32. package/dist/interface/js/{backup.B_Gzxtp_.0.0.50-internal.0.js → backup.BeH6lJ5t.0.0.50-internal.1.js} +1 -1
  33. package/dist/interface/js/{chart.js.CP_nMnnf.0.0.50-internal.0.js → chart.js.BQHSWV_g.0.0.50-internal.1.js} +1 -1
  34. package/dist/interface/js/{close-circle.DYLuVIOg.0.0.50-internal.0.js → close-circle.DDKMxauw.0.0.50-internal.1.js} +1 -1
  35. package/dist/interface/js/{dnd-core.T9OeW7mu.0.0.50-internal.0.js → dnd-core.dWz9rJqH.0.0.50-internal.1.js} +1 -1
  36. package/dist/interface/js/{draggabilly.D3zGcBb3.0.0.50-internal.0.js → draggabilly.D-iZIS1n.0.0.50-internal.1.js} +1 -1
  37. package/dist/interface/js/{engine.io-client.kITRnq-g.0.0.50-internal.0.js → engine.io-client.BwxOddB_.0.0.50-internal.1.js} +1 -1
  38. package/dist/interface/js/{fast-deep-equal.Bpc9mIsj.0.0.50-internal.0.js → fast-deep-equal.Dz96RC_N.0.0.50-internal.1.js} +1 -1
  39. package/dist/interface/js/{highlight.js.BlSXU-Wb.0.0.50-internal.0.js → highlight.js.CmcM8OM6.0.0.50-internal.1.js} +1 -1
  40. package/dist/interface/js/{linkify-it.C3N1lWsJ.0.0.50-internal.0.js → linkify-it.BgLcBzlw.0.0.50-internal.1.js} +1 -1
  41. package/dist/interface/js/{main.D0YR3Jat.0.0.50-internal.0.js → main.6bOgRV7D.0.0.50-internal.1.js} +3 -3
  42. package/dist/interface/js/{markdown-it.Dj0dt5s2.0.0.50-internal.0.js → markdown-it.CTgfs-3p.0.0.50-internal.1.js} +1 -1
  43. package/dist/interface/js/{nprogress.BwQWDcGj.0.0.50-internal.0.js → nprogress.CMhnq8jS.0.0.50-internal.1.js} +1 -1
  44. package/dist/interface/js/{pinia.DRh7plEC.0.0.50-internal.0.js → pinia.CuC5ZfNs.0.0.50-internal.1.js} +1 -1
  45. package/dist/interface/js/{primevue.Cl58krXf.0.0.50-internal.0.js → primevue.DmwjJ4xV.0.0.50-internal.1.js} +1 -1
  46. package/dist/interface/js/{qrcode.C1sDj6P8.0.0.50-internal.0.js → qrcode.DGZO3j1c.0.0.50-internal.1.js} +1 -1
  47. package/dist/interface/js/{react-dnd-touch-backend.BA4WhUJo.0.0.50-internal.0.js → react-dnd-touch-backend.CEGHlD-T.0.0.50-internal.1.js} +1 -1
  48. package/dist/interface/js/{refresh-rounded.D_SmhhUf.0.0.50-internal.0.js → refresh-rounded.D0keXzBc.0.0.50-internal.1.js} +1 -1
  49. package/dist/interface/js/{rxjs.C-fTBwEO.0.0.50-internal.0.js → rxjs.CiDbFOB0.0.0.50-internal.1.js} +1 -1
  50. package/dist/interface/js/{socket.io-client.DKrRxgjP.0.0.50-internal.0.js → socket.io-client.BPcXPAHG.0.0.50-internal.1.js} +1 -1
  51. package/dist/interface/js/{socket.io-parser.EXj3YDH2.0.0.50-internal.0.js → socket.io-parser.DSGzrW_l.0.0.50-internal.1.js} +1 -1
  52. package/dist/interface/js/{system.CY8rGd-Q.0.0.50-internal.0.js → system.BKlEObmx.0.0.50-internal.1.js} +1 -1
  53. package/dist/interface/js/{trash-fill.CMnCN3Oy.0.0.50-internal.0.js → trash-fill.BDFILs86.0.0.50-internal.1.js} +1 -1
  54. package/dist/interface/js/{unidragger.D0w6Tqtt.0.0.50-internal.0.js → unidragger.DcxsxHCS.0.0.50-internal.1.js} +1 -1
  55. package/dist/interface/js/{vee-validate.BeiObIH8.0.0.50-internal.0.js → vee-validate.BGRg3oQ8.0.0.50-internal.1.js} +1 -1
  56. package/dist/interface/js/{vue-chartjs.DtdZdiYw.0.0.50-internal.0.js → vue-chartjs.B9yk2de7.0.0.50-internal.1.js} +1 -1
  57. package/dist/interface/js/{vue-i18n.BW2bx_6z.0.0.50-internal.0.js → vue-i18n.DXDZITpf.0.0.50-internal.1.js} +1 -1
  58. package/dist/interface/js/{vue-inline-svg.BJkQGmKz.0.0.50-internal.0.js → vue-inline-svg.BDYaTfbi.0.0.50-internal.1.js} +1 -1
  59. package/dist/interface/js/{vue-router.B2mOXHaC.0.0.50-internal.0.js → vue-router.CFEDA008.0.0.50-internal.1.js} +1 -1
  60. package/dist/interface/js/{vue-zoomable.BKDyCJE7.0.0.50-internal.0.js → vue-zoomable.zqTafMgD.0.0.50-internal.1.js} +1 -1
  61. package/dist/interface/js/{vue3-dnd.DRK24CBp.0.0.50-internal.0.js → vue3-dnd.BxM3dbYs.0.0.50-internal.1.js} +1 -1
  62. package/dist/interface/js/{zoom-out.DxvzgVEo.0.0.50-internal.0.js → zoom-out.B6SY9IIj.0.0.50-internal.1.js} +1 -1
  63. package/dist/interface/sw.js +1 -1
  64. package/dist/server/package.json +1 -1
  65. package/package.json +1 -1
  66. package/.prettierignore +0 -12
  67. package/.prettierrc.json +0 -12
  68. package/artillery.yaml +0 -29
  69. package/bin/cameraui-server.ts +0 -11
  70. package/dist/interface/js/Cammesh.D-6dAROQ.0.0.50-internal.0.js +0 -1
  71. package/dist/interface/js/Recordings.DhxjIW7e.0.0.50-internal.0.js +0 -1
  72. package/dist/interface/js/SettingsAppearance.DsTjKXk1.0.0.50-internal.0.js +0 -1
  73. package/dist/interface/js/SettingsRecordings.DgW7M0jj.0.0.50-internal.0.js +0 -1
  74. package/eslint.config.js +0 -103
  75. package/localdeps.txt +0 -10
  76. package/mypy.ini +0 -30
  77. package/requirements.txt +0 -15
  78. package/ruff.toml +0 -90
  79. package/src/__init__.py +0 -0
  80. package/src/_camera_ui_tools/__init__.py +0 -0
  81. package/src/_camera_ui_tools/__pycache__/__init__.cpython-311.pyc +0 -0
  82. package/src/api/controllers/api.controller.ts +0 -19
  83. package/src/api/controllers/auth.controller.ts +0 -294
  84. package/src/api/controllers/backup.controller.ts +0 -72
  85. package/src/api/controllers/cameras.controller.ts +0 -1029
  86. package/src/api/controllers/config.controller.ts +0 -102
  87. package/src/api/controllers/files.controller.ts +0 -35
  88. package/src/api/controllers/frameWorkers.controller.ts +0 -109
  89. package/src/api/controllers/plugins.controller.ts +0 -1206
  90. package/src/api/controllers/system.controller.ts +0 -273
  91. package/src/api/controllers/users.controller.ts +0 -648
  92. package/src/api/database/checks.ts +0 -268
  93. package/src/api/database/constants.ts +0 -8
  94. package/src/api/database/index.ts +0 -262
  95. package/src/api/database/migration.ts +0 -62
  96. package/src/api/database/selfcheck.ts +0 -492
  97. package/src/api/database/types.ts +0 -104
  98. package/src/api/go2rtc/api/application.ts +0 -48
  99. package/src/api/go2rtc/api/config.ts +0 -61
  100. package/src/api/go2rtc/api/discover.ts +0 -197
  101. package/src/api/go2rtc/api/index.ts +0 -49
  102. package/src/api/go2rtc/api/snapshot.ts +0 -44
  103. package/src/api/go2rtc/api/streams.ts +0 -168
  104. package/src/api/go2rtc/index.ts +0 -43
  105. package/src/api/go2rtc/queue.ts +0 -50
  106. package/src/api/go2rtc/types.ts +0 -174
  107. package/src/api/index.ts +0 -286
  108. package/src/api/middlewares/authPermission.middleware.ts +0 -46
  109. package/src/api/middlewares/authValidation.middleware.ts +0 -160
  110. package/src/api/middlewares/pagination.middleware.ts +0 -67
  111. package/src/api/middlewares/socketAuth.middleware.ts +0 -136
  112. package/src/api/plugins/header.plugin.ts +0 -15
  113. package/src/api/plugins/logger.plugin.ts +0 -44
  114. package/src/api/plugins/proxy.plugin.ts +0 -255
  115. package/src/api/plugins/socket.plugin.ts +0 -28
  116. package/src/api/plugins/system.plugin.ts +0 -48
  117. package/src/api/plugins/useragent.plugin.ts +0 -19
  118. package/src/api/routes/api.routes.ts +0 -10
  119. package/src/api/routes/auth.routes.ts +0 -56
  120. package/src/api/routes/backup.routes.ts +0 -28
  121. package/src/api/routes/cameras.routes.ts +0 -281
  122. package/src/api/routes/config.routes.ts +0 -66
  123. package/src/api/routes/files.routes.ts +0 -15
  124. package/src/api/routes/frameWorkers.routes.ts +0 -39
  125. package/src/api/routes/index.ts +0 -37
  126. package/src/api/routes/plugins.routes.ts +0 -420
  127. package/src/api/routes/system.routes.ts +0 -101
  128. package/src/api/routes/users.routes.ts +0 -167
  129. package/src/api/schemas/backup.schema.ts +0 -112
  130. package/src/api/schemas/cameras.schema.ts +0 -479
  131. package/src/api/schemas/config.schema.ts +0 -38
  132. package/src/api/schemas/go2rtc.schema.ts +0 -189
  133. package/src/api/schemas/plugins.schema.ts +0 -126
  134. package/src/api/schemas/storage.schema.ts +0 -11
  135. package/src/api/schemas/system.schema.ts +0 -45
  136. package/src/api/schemas/users.schema.ts +0 -185
  137. package/src/api/services/auth.service.ts +0 -210
  138. package/src/api/services/backup.service.ts +0 -144
  139. package/src/api/services/cameras.service.ts +0 -671
  140. package/src/api/services/plugins.service.ts +0 -470
  141. package/src/api/services/system.service.ts +0 -85
  142. package/src/api/services/users.service.ts +0 -276
  143. package/src/api/types/index.ts +0 -675
  144. package/src/api/utils/cert.ts +0 -254
  145. package/src/api/utils/constants.ts +0 -17
  146. package/src/api/utils/fetch.ts +0 -21
  147. package/src/api/utils/moveFiles.ts +0 -45
  148. package/src/api/utils/parse.ts +0 -17
  149. package/src/api/websocket/index.ts +0 -110
  150. package/src/api/websocket/nsp/logs.ts +0 -240
  151. package/src/api/websocket/nsp/main.ts +0 -27
  152. package/src/api/websocket/nsp/metrics.ts +0 -301
  153. package/src/api/websocket/nsp/notifications.ts +0 -43
  154. package/src/api/websocket/nsp/plugins.ts +0 -37
  155. package/src/api/websocket/nsp/server.ts +0 -220
  156. package/src/api/websocket/nsp/status.ts +0 -77
  157. package/src/api/websocket/types.ts +0 -55
  158. package/src/api.ts +0 -163
  159. package/src/camera/classes.ts +0 -32
  160. package/src/camera/controller.ts +0 -579
  161. package/src/camera/device.ts +0 -422
  162. package/src/camera/frameWorker.ts +0 -403
  163. package/src/camera/index.ts +0 -679
  164. package/src/camera/interfaces.ts +0 -95
  165. package/src/camera/iou.ts +0 -153
  166. package/src/camera/polygon.ts +0 -226
  167. package/src/camera/python/__init__.py +0 -0
  168. package/src/camera/python/__pycache__/__init__.cpython-311.pyc +0 -0
  169. package/src/camera/python/__pycache__/classes.cpython-311.pyc +0 -0
  170. package/src/camera/python/__pycache__/delegate_controller.cpython-311.pyc +0 -0
  171. package/src/camera/python/__pycache__/interfaces.cpython-311.pyc +0 -0
  172. package/src/camera/python/__pycache__/iou.cpython-310.pyc +0 -0
  173. package/src/camera/python/__pycache__/iou.cpython-311.pyc +0 -0
  174. package/src/camera/python/__pycache__/iou2.cpython-310.pyc +0 -0
  175. package/src/camera/python/__pycache__/polygon.cpython-311.pyc +0 -0
  176. package/src/camera/python/__pycache__/typings.cpython-311.pyc +0 -0
  177. package/src/camera/python/__pycache__/video_frame.cpython-311.pyc +0 -0
  178. package/src/camera/python/classes.py +0 -41
  179. package/src/camera/python/interfaces.py +0 -130
  180. package/src/camera/python/iou.py +0 -158
  181. package/src/camera/python/polygon.py +0 -230
  182. package/src/camera/python/test/__pycache__/polygon.cpython-310.pyc +0 -0
  183. package/src/camera/python/test/iou_test.py +0 -799
  184. package/src/camera/python/test/polygon.py +0 -238
  185. package/src/camera/python/test/polygon_test.py +0 -256
  186. package/src/camera/python/test/polygon_test2.py +0 -484
  187. package/src/camera/python/typings.py +0 -50
  188. package/src/camera/python/video_frame.py +0 -143
  189. package/src/camera/session.ts +0 -192
  190. package/src/camera/streaming/fmp4-session.ts +0 -390
  191. package/src/camera/streaming/peer-connection.ts +0 -273
  192. package/src/camera/streaming/rtsp-session.ts +0 -331
  193. package/src/camera/streaming/webrtc-connection.ts +0 -260
  194. package/src/camera/streaming/werift-session.ts +0 -317
  195. package/src/camera/test/iou_test.ts +0 -761
  196. package/src/camera/test/polygon.test.ts +0 -611
  197. package/src/camera/test/polygon_test.ts +0 -210
  198. package/src/camera/types.ts +0 -48
  199. package/src/camera/utils.ts +0 -489
  200. package/src/camera/videoFrame.ts +0 -123
  201. package/src/cloud/index.ts +0 -61
  202. package/src/cloud/remote/cloudflare.ts +0 -18
  203. package/src/cloud/remote/upnp.ts +0 -18
  204. package/src/cloud/remote/utils.ts +0 -24
  205. package/src/cloud/types.ts +0 -16
  206. package/src/decoder/child.ts +0 -883
  207. package/src/decoder/imageUtils.ts +0 -275
  208. package/src/decoder/manager.ts +0 -251
  209. package/src/decoder/python/__init__.py +0 -0
  210. package/src/decoder/python/__pycache__/__init__.cpython-311.pyc +0 -0
  211. package/src/decoder/python/__pycache__/image_utils.cpython-311.pyc +0 -0
  212. package/src/decoder/python/__pycache__/typings.cpython-311.pyc +0 -0
  213. package/src/decoder/python/__pycache__/utils.cpython-311.pyc +0 -0
  214. package/src/decoder/python/child.py +0 -903
  215. package/src/decoder/python/image_utils.py +0 -196
  216. package/src/decoder/python/pool.py +0 -45
  217. package/src/decoder/python/test/group.py +0 -62
  218. package/src/decoder/python/test/motion.mp4 +0 -0
  219. package/src/decoder/python/test/motion2.mp4 +0 -0
  220. package/src/decoder/python/test/opencl.cl +0 -70
  221. package/src/decoder/python/test/opencl2.cl +0 -130
  222. package/src/decoder/python/test/test.py +0 -427
  223. package/src/decoder/python/test/test1.jpg +0 -0
  224. package/src/decoder/python/test/test1_resized.jpg +0 -0
  225. package/src/decoder/python/test/test2.jpg +0 -0
  226. package/src/decoder/python/test/test2.py +0 -451
  227. package/src/decoder/python/test/test2_resized.jpg +0 -0
  228. package/src/decoder/python/test/test3.jpg +0 -0
  229. package/src/decoder/python/test/utils.py +0 -50
  230. package/src/decoder/python/typings.py +0 -57
  231. package/src/decoder/python/utils.py +0 -70
  232. package/src/decoder/test/child.ts +0 -117
  233. package/src/decoder/test/ffmpeg.ts +0 -371
  234. package/src/decoder/test/test.ts +0 -182
  235. package/src/decoder/types.ts +0 -27
  236. package/src/decoder/utils.ts +0 -64
  237. package/src/decoder/wasm/asconfig.json +0 -28
  238. package/src/decoder/wasm/assembly/console.ts +0 -1
  239. package/src/decoder/wasm/assembly/index.ts +0 -890
  240. package/src/decoder/wasm/build/decoder.d.ts +0 -43
  241. package/src/decoder/wasm/build/decoder.js +0 -108
  242. package/src/decoder/wasm/build/decoder.wasm +0 -0
  243. package/src/decoder/wasm/tsconfig.json +0 -5
  244. package/src/decoder/worker.ts +0 -113
  245. package/src/go2rtc/index.ts +0 -324
  246. package/src/go2rtc/types.ts +0 -88
  247. package/src/main.ts +0 -267
  248. package/src/manager/coreManager.ts +0 -78
  249. package/src/manager/deviceManager.ts +0 -132
  250. package/src/manager/types.ts +0 -17
  251. package/src/plugins/index.ts +0 -443
  252. package/src/plugins/plugin.ts +0 -177
  253. package/src/plugins/runtime/base.ts +0 -282
  254. package/src/plugins/runtime/index.ts +0 -15
  255. package/src/plugins/runtime/node/child.ts +0 -193
  256. package/src/plugins/runtime/node/index.ts +0 -67
  257. package/src/plugins/runtime/node/plugin.ts +0 -122
  258. package/src/plugins/runtime/node/pluginApi.ts +0 -27
  259. package/src/plugins/runtime/node/proxy/cameraDevice.ts +0 -299
  260. package/src/plugins/runtime/node/proxy/coreManager.ts +0 -128
  261. package/src/plugins/runtime/node/proxy/deviceManager.ts +0 -187
  262. package/src/plugins/runtime/node/storage.ts +0 -312
  263. package/src/plugins/runtime/node/storageController.ts +0 -91
  264. package/src/plugins/runtime/python/__init__.py +0 -0
  265. package/src/plugins/runtime/python/__pycache__/__init__.cpython-311.pyc +0 -0
  266. package/src/plugins/runtime/python/__pycache__/camera_storage.cpython-311.pyc +0 -0
  267. package/src/plugins/runtime/python/__pycache__/config_service.cpython-311.pyc +0 -0
  268. package/src/plugins/runtime/python/__pycache__/constants.cpython-311.pyc +0 -0
  269. package/src/plugins/runtime/python/__pycache__/ipc.cpython-311.pyc +0 -0
  270. package/src/plugins/runtime/python/__pycache__/logger.cpython-311.pyc +0 -0
  271. package/src/plugins/runtime/python/__pycache__/message_queue.cpython-311.pyc +0 -0
  272. package/src/plugins/runtime/python/__pycache__/namespaces.cpython-311.pyc +0 -0
  273. package/src/plugins/runtime/python/__pycache__/plugin.cpython-311.pyc +0 -0
  274. package/src/plugins/runtime/python/__pycache__/plugin_api.cpython-311.pyc +0 -0
  275. package/src/plugins/runtime/python/__pycache__/plugin_logger.cpython-311.pyc +0 -0
  276. package/src/plugins/runtime/python/__pycache__/proxy_utils.cpython-311.pyc +0 -0
  277. package/src/plugins/runtime/python/__pycache__/schema.cpython-311.pyc +0 -0
  278. package/src/plugins/runtime/python/__pycache__/storage.cpython-311.pyc +0 -0
  279. package/src/plugins/runtime/python/__pycache__/storage_controller.cpython-311.pyc +0 -0
  280. package/src/plugins/runtime/python/__pycache__/typings.cpython-311.pyc +0 -0
  281. package/src/plugins/runtime/python/child.py +0 -248
  282. package/src/plugins/runtime/python/index.ts +0 -73
  283. package/src/plugins/runtime/python/namespaces.py +0 -101
  284. package/src/plugins/runtime/python/plugin.py +0 -155
  285. package/src/plugins/runtime/python/plugin_api.py +0 -29
  286. package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-310.pyc +0 -0
  287. package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-311.pyc +0 -0
  288. package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-38.pyc +0 -0
  289. package/src/plugins/runtime/python/proxy/__pycache__/camera_device.cpython-39.pyc +0 -0
  290. package/src/plugins/runtime/python/proxy/__pycache__/constants.cpython-311.pyc +0 -0
  291. package/src/plugins/runtime/python/proxy/__pycache__/constants.cpython-39.pyc +0 -0
  292. package/src/plugins/runtime/python/proxy/__pycache__/core_manager.cpython-311.pyc +0 -0
  293. package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-310.pyc +0 -0
  294. package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-311.pyc +0 -0
  295. package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-38.pyc +0 -0
  296. package/src/plugins/runtime/python/proxy/__pycache__/device_manager.cpython-39.pyc +0 -0
  297. package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-310.pyc +0 -0
  298. package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-311.pyc +0 -0
  299. package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-38.pyc +0 -0
  300. package/src/plugins/runtime/python/proxy/__pycache__/generate_keys.cpython-39.pyc +0 -0
  301. package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-310.pyc +0 -0
  302. package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-311.pyc +0 -0
  303. package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-38.pyc +0 -0
  304. package/src/plugins/runtime/python/proxy/__pycache__/message_queue.cpython-39.pyc +0 -0
  305. package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-310.pyc +0 -0
  306. package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-311.pyc +0 -0
  307. package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-38.pyc +0 -0
  308. package/src/plugins/runtime/python/proxy/__pycache__/plugins_manager.cpython-39.pyc +0 -0
  309. package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-310.pyc +0 -0
  310. package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-311.pyc +0 -0
  311. package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-38.pyc +0 -0
  312. package/src/plugins/runtime/python/proxy/__pycache__/system_manager.cpython-39.pyc +0 -0
  313. package/src/plugins/runtime/python/proxy/camera_device.py +0 -1732
  314. package/src/plugins/runtime/python/proxy/core_manager.py +0 -126
  315. package/src/plugins/runtime/python/proxy/device_manager.py +0 -197
  316. package/src/plugins/runtime/python/schema.py +0 -99
  317. package/src/plugins/runtime/python/storage.py +0 -353
  318. package/src/plugins/runtime/python/storage_controller.py +0 -102
  319. package/src/plugins/runtime/python/typings.py +0 -195
  320. package/src/plugins/schema.ts +0 -472
  321. package/src/plugins/types.ts +0 -60
  322. package/src/plugins/worker.ts +0 -250
  323. package/src/rpc/index.ts +0 -149
  324. package/src/rpc/namespaces.ts +0 -79
  325. package/src/rpc/server.ts +0 -422
  326. package/src/rpc/types.ts +0 -119
  327. package/src/rpc/utils.ts +0 -16
  328. package/src/services/config/constants.ts +0 -47
  329. package/src/services/config/defaults.ts +0 -57
  330. package/src/services/config/index.ts +0 -744
  331. package/src/services/config/types.ts +0 -211
  332. package/src/services/logger/index.ts +0 -96
  333. package/src/types.ts +0 -47
  334. package/src/utils/path.ts +0 -16
  335. package/src/utils/pythonInstaller.ts +0 -597
  336. package/tsconfig.json +0 -37
  337. package/updates.config.js +0 -3
  338. /package/dist/interface/assets/{@xterm.DYP7pi_n.0.0.50-internal.0.css → @xterm.DYP7pi_n.0.0.50-internal.1.css} +0 -0
  339. /package/dist/interface/assets/{Adminpanel.BKek2EMH.0.0.50-internal.0.css → Adminpanel.BKek2EMH.0.0.50-internal.1.css} +0 -0
  340. /package/dist/interface/assets/{Cameras.BDWZJqPN.0.0.50-internal.0.css → Cameras.BDWZJqPN.0.0.50-internal.1.css} +0 -0
  341. /package/dist/interface/assets/{Camview.BFUFMoNX.0.0.50-internal.0.css → Camview.BFUFMoNX.0.0.50-internal.1.css} +0 -0
  342. /package/dist/interface/assets/{CuiConsole.DCYyxdVg.0.0.50-internal.0.css → CuiConsole.DCYyxdVg.0.0.50-internal.1.css} +0 -0
  343. /package/dist/interface/assets/{CuiPluginCard.yF8V0SZY.0.0.50-internal.0.css → CuiPluginCard.yF8V0SZY.0.0.50-internal.1.css} +0 -0
  344. /package/dist/interface/assets/{CuiTimeline.BkIwlYtw.0.0.50-internal.0.css → CuiTimeline.BkIwlYtw.0.0.50-internal.1.css} +0 -0
  345. /package/dist/interface/assets/{Plugin.DJElsAn5.0.0.50-internal.0.css → Plugin.DJElsAn5.0.0.50-internal.1.css} +0 -0
  346. /package/dist/interface/assets/{Plugins.0h77qnmN.0.0.50-internal.0.css → Plugins.0h77qnmN.0.0.50-internal.1.css} +0 -0
  347. /package/dist/interface/assets/{Settings.CkgfRkQr.0.0.50-internal.0.css → Settings.CkgfRkQr.0.0.50-internal.1.css} +0 -0
  348. /package/dist/interface/assets/{SettingsAccount.DeFul3eQ.0.0.50-internal.0.css → SettingsAccount.DeFul3eQ.0.0.50-internal.1.css} +0 -0
  349. /package/dist/interface/assets/{SettingsBackup.CX0rT0QJ.0.0.50-internal.0.css → SettingsBackup.CX0rT0QJ.0.0.50-internal.1.css} +0 -0
  350. /package/dist/interface/assets/{highlight.Ch2EwETz.0.0.50-internal.0.css → highlight.Ch2EwETz.0.0.50-internal.1.css} +0 -0
  351. /package/dist/interface/assets/{logo-256.BCQk9H1-.0.0.50-internal.0.png → logo-256.BCQk9H1-.0.0.50-internal.1.png} +0 -0
  352. /package/dist/interface/assets/{logo-512.DLKVOU2S.0.0.50-internal.0.png → logo-512.DLKVOU2S.0.0.50-internal.1.png} +0 -0
  353. /package/dist/interface/assets/{logo.DmEiRk0z.0.0.50-internal.0.png → logo.DmEiRk0z.0.0.50-internal.1.png} +0 -0
  354. /package/dist/interface/assets/{main.Cip9LkS3.0.0.50-internal.0.css → main.Cip9LkS3.0.0.50-internal.1.css} +0 -0
  355. /package/dist/interface/assets/{mode-json.Br7xisR1.0.0.50-internal.0.js → mode-json.Br7xisR1.0.0.50-internal.1.js} +0 -0
  356. /package/dist/interface/assets/{mode-yaml.CIYL8U3d.0.0.50-internal.0.js → mode-yaml.CIYL8U3d.0.0.50-internal.1.js} +0 -0
  357. /package/dist/interface/assets/{worker-base.jEXLGV2h.0.0.50-internal.0.js → worker-base.jEXLGV2h.0.0.50-internal.1.js} +0 -0
  358. /package/dist/interface/assets/{worker-json.DgwNIOck.0.0.50-internal.0.js → worker-json.DgwNIOck.0.0.50-internal.1.js} +0 -0
  359. /package/dist/interface/assets/{worker-yaml.B3uUYINB.0.0.50-internal.0.js → worker-yaml.B3uUYINB.0.0.50-internal.1.js} +0 -0
  360. /package/dist/interface/js/{@babel.l0sNRNKZ.0.0.50-internal.0.js → @babel.l0sNRNKZ.0.0.50-internal.1.js} +0 -0
  361. /package/dist/interface/js/{@intlify.BkGPX90O.0.0.50-internal.0.js → @intlify.BkGPX90O.0.0.50-internal.1.js} +0 -0
  362. /package/dist/interface/js/{@kurkle.D8fDXNIl.0.0.50-internal.0.js → @kurkle.D8fDXNIl.0.0.50-internal.1.js} +0 -0
  363. /package/dist/interface/js/{@primeuix.BFAY2Bk9.0.0.50-internal.0.js → @primeuix.BFAY2Bk9.0.0.50-internal.1.js} +0 -0
  364. /package/dist/interface/js/{@react-dnd.CcwRs9xb.0.0.50-internal.0.js → @react-dnd.CcwRs9xb.0.0.50-internal.1.js} +0 -0
  365. /package/dist/interface/js/{@socket.io.Dkula2eQ.0.0.50-internal.0.js → @socket.io.Dkula2eQ.0.0.50-internal.1.js} +0 -0
  366. /package/dist/interface/js/{@vue.B5vqhCp2.0.0.50-internal.0.js → @vue.B5vqhCp2.0.0.50-internal.1.js} +0 -0
  367. /package/dist/interface/js/{@xterm.CAa7rpjv.0.0.50-internal.0.js → @xterm.DIUBesyz.0.0.50-internal.1.js} +0 -0
  368. /package/dist/interface/js/{axios.DHr9lByg.0.0.50-internal.0.js → axios.DHr9lByg.0.0.50-internal.1.js} +0 -0
  369. /package/dist/interface/js/{birpc.l0sNRNKZ.0.0.50-internal.0.js → birpc.l0sNRNKZ.0.0.50-internal.1.js} +0 -0
  370. /package/dist/interface/js/{compare-versions.DqEOhma6.0.0.50-internal.0.js → compare-versions.DqEOhma6.0.0.50-internal.1.js} +0 -0
  371. /package/dist/interface/js/{dijkstrajs.C00ieaqj.0.0.50-internal.0.js → dijkstrajs.C00ieaqj.0.0.50-internal.1.js} +0 -0
  372. /package/dist/interface/js/{engine.io-parser.BiEtp6m2.0.0.50-internal.0.js → engine.io-parser.BiEtp6m2.0.0.50-internal.1.js} +0 -0
  373. /package/dist/interface/js/{entities.C20TfXL6.0.0.50-internal.0.js → entities.C20TfXL6.0.0.50-internal.1.js} +0 -0
  374. /package/dist/interface/js/{ev-emitter.X5f1qa-c.0.0.50-internal.0.js → ev-emitter.X5f1qa-c.0.0.50-internal.1.js} +0 -0
  375. /package/dist/interface/js/{get-size.D1dS-IaP.0.0.50-internal.0.js → get-size.D1dS-IaP.0.0.50-internal.1.js} +0 -0
  376. /package/dist/interface/js/{hookable.l0sNRNKZ.0.0.50-internal.0.js → hookable.l0sNRNKZ.0.0.50-internal.1.js} +0 -0
  377. /package/dist/interface/js/{mdurl.k9Sl0PQj.0.0.50-internal.0.js → mdurl.k9Sl0PQj.0.0.50-internal.1.js} +0 -0
  378. /package/dist/interface/js/{perfect-debounce.l0sNRNKZ.0.0.50-internal.0.js → perfect-debounce.l0sNRNKZ.0.0.50-internal.1.js} +0 -0
  379. /package/dist/interface/js/{primelocale.Bga3dOQu.0.0.50-internal.0.js → primelocale.Bga3dOQu.0.0.50-internal.1.js} +0 -0
  380. /package/dist/interface/js/{punycode.js.Dj65hjkv.0.0.50-internal.0.js → punycode.js.Dj65hjkv.0.0.50-internal.1.js} +0 -0
  381. /package/dist/interface/js/{react-dnd-html5-backend.1HQjlkwI.0.0.50-internal.0.js → react-dnd-html5-backend.1HQjlkwI.0.0.50-internal.1.js} +0 -0
  382. /package/dist/interface/js/{redux.BFxtlG_c.0.0.50-internal.0.js → redux.BFxtlG_c.0.0.50-internal.1.js} +0 -0
  383. /package/dist/interface/js/{tslib.9k7AwCpt.0.0.50-internal.0.js → tslib.9k7AwCpt.0.0.50-internal.1.js} +0 -0
  384. /package/dist/interface/js/{uc.micro.kMc2yuuw.0.0.50-internal.0.js → uc.micro.kMc2yuuw.0.0.50-internal.1.js} +0 -0
  385. /package/dist/interface/js/{uuid.C6aID195.0.0.50-internal.0.js → uuid.C6aID195.0.0.50-internal.1.js} +0 -0
  386. /package/dist/interface/js/{vue.l0sNRNKZ.0.0.50-internal.0.js → vue.l0sNRNKZ.0.0.50-internal.1.js} +0 -0
  387. /package/dist/interface/js/{zod.SKKegNRO.0.0.50-internal.0.js → zod.SKKegNRO.0.0.50-internal.1.js} +0 -0
@@ -1,883 +0,0 @@
1
- process.title = process.argv[2] ?? 'camera.ui - Frame Worker';
2
-
3
- import { Logger, SignalHandler, sleep } from '@camera.ui/common';
4
- import { ClientInstance } from '@camera.ui/rpc-client';
5
- import { rpc } from '@camera.ui/rpc-common';
6
- import { spawn } from 'node:child_process';
7
- import { fileURLToPath } from 'node:url';
8
-
9
- import { NamespaceManager } from '../rpc/namespaces.js';
10
- import { ImageUtils } from './imageUtils.js';
11
- import { createSingleConnectionServer } from './utils.js';
12
-
13
- import type { LoggerOptions } from '@camera.ui/common';
14
- import type { Promisify } from '@camera.ui/rpc-common';
15
- import type {
16
- CameraFrameWorkerDecoder,
17
- CameraFrameWorkerResolution,
18
- CoreManager as CoreManagerInterface,
19
- DecoderFormat,
20
- FfmpegArgs,
21
- FrameBuffer,
22
- FrameData,
23
- FrameMetadata,
24
- ImageInformation,
25
- ImageOptions,
26
- } from '@camera.ui/types';
27
- import type { ChildProcess } from 'node:child_process';
28
- import type { Socket } from 'node:net';
29
- import type { CoreManagerNamespaces, FrameWorkerNamespaces } from '../rpc/namespaces.js';
30
- import type { BaseFrameWorkerConfig, FrameWorkerInterface, PixelFormat, WorkerToMainMessage } from './types.js';
31
- import type { TCPConnectionDetails } from './utils.js';
32
-
33
- const PIXEL_FORMAT: PixelFormat = 'yuv420p';
34
- const METADATA_REGEX = /s:\s*(\d+x\d+)/;
35
-
36
- interface Frame {
37
- data: Buffer;
38
- timestamp: number;
39
- metadata: FrameMetadata;
40
- }
41
-
42
- class FFmpegStream {
43
- private readonly frameSize: number;
44
- private readonly width: number;
45
- private readonly height: number;
46
-
47
- // Process Management
48
- private ffmpegProcess?: ChildProcess;
49
- private activeViewers = 0;
50
- private ffmpegHwOptions?: FfmpegArgs;
51
- private server?: TCPConnectionDetails;
52
- public socket?: Socket;
53
-
54
- // State
55
- public streamActive = false;
56
- public metadata?: FrameMetadata;
57
- private isShuttingDown = false;
58
- private streamStartTimeout = 60000;
59
- private initializationPromise: Promise<void> | null = null;
60
-
61
- // Reconnection Logic
62
- private reconnectCount = 0;
63
-
64
- // Frame Queue Management
65
- private frameBuffer: Frame[] = [];
66
- private lastFrame: Frame | null = null;
67
- private queueConsumers = new Set<FrameConsumer>();
68
- private frameProcessingActive = false;
69
- private bufferDurationMs = 5000;
70
-
71
- // Health Check
72
- private healthCheckInterval?: NodeJS.Timeout;
73
- private lastFrameTimestamp = 0;
74
- private healthCheckTime = 5000;
75
- private maxFrameTime = 15000;
76
-
77
- // Consumer management
78
- private nextConsumerId = 0;
79
-
80
- private get bytesPerPixel(): number {
81
- switch (this.pixelFormat) {
82
- case 'yuv420p':
83
- case 'nv12':
84
- return 1.5;
85
- case 'rgb24':
86
- return 3;
87
- }
88
- }
89
-
90
- private get pixelFormat(): PixelFormat {
91
- if (this.worker.imageUtils.decoder === 'gpu') {
92
- return 'nv12';
93
- } else {
94
- return PIXEL_FORMAT;
95
- }
96
- }
97
-
98
- constructor(private worker: FrameWorkerChild) {
99
- const [width, height] = worker.config.resolution.split('x').map(Number);
100
- this.width = width;
101
- this.height = height;
102
- this.frameSize = width * height * this.bytesPerPixel;
103
- }
104
-
105
- public async initialize(): Promise<void> {
106
- if (this.initializationPromise) {
107
- return this.initializationPromise;
108
- }
109
-
110
- if (this.streamActive) {
111
- return;
112
- }
113
-
114
- try {
115
- this.initializationPromise = this.startStreamProcess();
116
- await this.initializationPromise;
117
- } finally {
118
- this.initializationPromise = null;
119
- }
120
- }
121
-
122
- public close(): void {
123
- if (!this.streamActive) {
124
- return;
125
- }
126
-
127
- this.worker.logger.trace('Closing FFmpeg stream');
128
- this.cleanupResources();
129
- }
130
-
131
- public cleanup(): void {
132
- this.isShuttingDown = true;
133
- this.cleanupResources();
134
- }
135
-
136
- public registerViewer(): FrameConsumer {
137
- this.activeViewers++;
138
- const consumer = new FrameConsumer(this.nextConsumerId++, this);
139
- this.queueConsumers.add(consumer);
140
- return consumer;
141
- }
142
-
143
- public unregisterViewer(consumer: FrameConsumer): void {
144
- this.queueConsumers.delete(consumer);
145
- this.activeViewers--;
146
- if (this.activeViewers <= 0) {
147
- this.activeViewers = 0;
148
- this.close();
149
- }
150
- }
151
-
152
- public getNextFrame(timestamp: number): Frame | null {
153
- if (!this.lastFrame) {
154
- return null;
155
- }
156
-
157
- if (this.lastFrame.timestamp <= timestamp) {
158
- return null;
159
- }
160
-
161
- return {
162
- data: Buffer.from(this.lastFrame.data),
163
- timestamp: this.lastFrame.timestamp,
164
- metadata: this.lastFrame.metadata,
165
- };
166
- }
167
-
168
- public getFrameByTimestamp(timestamp: number, maxDifference = 0): Frame | undefined {
169
- if (this.frameBuffer.length === 0) {
170
- return undefined;
171
- }
172
-
173
- // Quick boundary checks
174
- const firstFrame = this.frameBuffer[0];
175
- const lastFrame = this.frameBuffer[this.frameBuffer.length - 1];
176
-
177
- // Check if timestamp is outside our buffer range (plus maxDifference)
178
- if (timestamp < firstFrame.timestamp - maxDifference || timestamp > lastFrame.timestamp + maxDifference) {
179
- return undefined;
180
- }
181
-
182
- // Binary search for closest frame
183
- let left = 0;
184
- let right = this.frameBuffer.length - 1;
185
-
186
- while (left <= right) {
187
- const mid = Math.floor((left + right) / 2);
188
- const frame = this.frameBuffer[mid];
189
- const diff = frame.timestamp - timestamp;
190
-
191
- // Exact match
192
- if (diff === 0) {
193
- return frame;
194
- }
195
-
196
- if (diff < 0) {
197
- left = mid + 1;
198
- } else {
199
- right = mid - 1;
200
- }
201
- }
202
-
203
- // If we need exact match only
204
- if (maxDifference === 0) {
205
- return undefined;
206
- }
207
-
208
- // Find closest frame within maxDifference
209
- // After binary search, 'left' points to the insertion point
210
- // Check frames around this point
211
- const candidates = [this.frameBuffer[Math.max(0, left - 1)], this.frameBuffer[Math.min(this.frameBuffer.length - 1, left)]];
212
-
213
- let bestMatch: Frame | undefined;
214
- let smallestDiff = Infinity;
215
-
216
- for (const frame of candidates) {
217
- const diff = Math.abs(frame.timestamp - timestamp);
218
- if (diff <= maxDifference && diff < smallestDiff) {
219
- smallestDiff = diff;
220
- bestMatch = frame;
221
- }
222
- }
223
-
224
- if (bestMatch) {
225
- return bestMatch;
226
- }
227
-
228
- return undefined;
229
- }
230
-
231
- private async startStreamProcess(): Promise<void> {
232
- try {
233
- await this.launchStream();
234
- this.reconnectCount = 0;
235
- } catch (error) {
236
- if (this.isShuttingDown || this.activeViewers === 0) {
237
- return;
238
- }
239
-
240
- this.reconnectCount = this.reconnectCount < 10 ? this.reconnectCount + 1 : 10;
241
- const delay = this.calculateReconnectDelay();
242
- this.worker.logger.warn(`Connection failed, retrying in ${delay / 1000}s`);
243
- this.worker.logger.debug('Error:', error.message);
244
-
245
- await sleep(delay);
246
- this.worker.logger.debug('Retrying connection...');
247
- return this.startStreamProcess();
248
- }
249
- }
250
-
251
- private async launchStream(): Promise<void> {
252
- if (this.activeViewers === 0) {
253
- this.worker.logger.debug('No active consumers, not starting stream');
254
- return;
255
- }
256
-
257
- this.cleanupResources();
258
-
259
- this.server = await createSingleConnectionServer('127.0.0.1', {
260
- noDelay: true,
261
- // keepAlive: true,
262
- highWaterMark: this.frameSize * 10,
263
- });
264
-
265
- const ffmpegArguments = await this.prepareFfmpegArguments(this.server.serverUrl);
266
- this.worker.logger.trace('Starting FFmpeg with args:', this.worker.config.ffmpegPath, ffmpegArguments.join(' '));
267
-
268
- this.ffmpegProcess = spawn(this.worker.config.ffmpegPath, ffmpegArguments, {
269
- stdio: ['ignore', 'ignore', 'pipe'],
270
- });
271
-
272
- this.ffmpegProcess.once('exit', async () => {
273
- if (this.activeViewers > 0 && !this.isShuttingDown) {
274
- this.cleanupResources();
275
- this.worker.logger.warn('FFmpeg process exited unexpectedly, restarting in 10 seconds...');
276
- await sleep(10000);
277
- this.initialize();
278
- } else {
279
- this.worker.logger.debug('FFmpeg process exited');
280
- }
281
- });
282
-
283
- try {
284
- this.socket = await this.server.connectionPromise;
285
- this.metadata = await this.extractMetadata();
286
- this.ffmpegProcess.stderr?.destroy();
287
- this.streamActive = true;
288
- this.startFrameProcessing();
289
- this.startHealthCheck();
290
- } catch (error) {
291
- this.cleanupResources();
292
- throw error;
293
- }
294
- }
295
-
296
- private startHealthCheck(): void {
297
- clearInterval(this.healthCheckInterval);
298
- this.healthCheckInterval = setInterval(() => {
299
- if (!this.streamActive || this.activeViewers === 0) {
300
- return;
301
- }
302
-
303
- const now = Date.now();
304
- const timeSinceLastFrame = now - this.lastFrameTimestamp;
305
-
306
- // If no frames for 30 seconds and we have active viewers, restart
307
- if (this.lastFrameTimestamp > 0 && timeSinceLastFrame > this.maxFrameTime && this.activeViewers > 0) {
308
- this.worker.logger.warn(`No frames received in ${timeSinceLastFrame / 1000}s! This may be due to a network issue, FFmpeg failure or high load on the system.`);
309
- this.worker.logger.log('Restarting...');
310
- this.cleanupResources();
311
- this.initialize();
312
- }
313
- }, this.healthCheckTime);
314
- }
315
-
316
- private async startFrameProcessing(): Promise<void> {
317
- if (this.frameProcessingActive || !this.socket || !this.metadata) {
318
- return;
319
- }
320
-
321
- let firstChunkReceived = false;
322
- let firstFrameReceived = false;
323
- this.frameProcessingActive = true;
324
- const metadata = this.metadata;
325
- let buffer = Buffer.alloc(0);
326
- let lastBufferSize = 0;
327
-
328
- try {
329
- for await (const chunk of this.socket as AsyncIterable<Buffer>) {
330
- if (!this.frameProcessingActive) {
331
- break;
332
- }
333
-
334
- if (!chunk.length) {
335
- this.worker.logger.warn('Received empty chunk from FFmpeg');
336
- continue;
337
- }
338
-
339
- if (buffer.length > metadata.frameSize * 10) {
340
- this.worker.logger.warn(`Buffer growing: ${buffer.length} bytes (${(buffer.length / metadata.frameSize).toFixed(2)} frames)`);
341
- }
342
-
343
- if (!firstChunkReceived) {
344
- this.worker.logger.trace('First chunk received');
345
- firstChunkReceived = true;
346
- }
347
-
348
- buffer = Buffer.concat([buffer, chunk]);
349
-
350
- while (buffer.length >= metadata.frameSize) {
351
- const frameData = buffer.subarray(0, metadata.frameSize);
352
- buffer = buffer.subarray(metadata.frameSize);
353
-
354
- if (lastBufferSize === buffer.length && buffer.length > 0) {
355
- this.worker.logger.warn(`Possible issue: Buffer size not changing: ${buffer.length} bytes`);
356
- // buffer = Buffer.alloc(0);
357
- break;
358
- }
359
-
360
- lastBufferSize = buffer.length;
361
-
362
- if (!firstFrameReceived) {
363
- this.worker.logger.trace('First frame received');
364
- firstFrameReceived = true;
365
- }
366
-
367
- this.addFrameToQueue(frameData, this.metadata);
368
- }
369
- }
370
- } catch (error) {
371
- this.worker.logger.error('Error in frame processing:', error);
372
- } finally {
373
- this.frameProcessingActive = false;
374
- }
375
- }
376
-
377
- private addFrameToQueue(frameData: Buffer, metadata: FrameMetadata): void {
378
- const timestamp = Date.now();
379
- this.lastFrameTimestamp = timestamp;
380
-
381
- const newFrame: Frame = {
382
- data: frameData,
383
- timestamp,
384
- metadata,
385
- };
386
-
387
- this.frameBuffer.push(newFrame);
388
- this.lastFrame = newFrame;
389
- this.cleanupOldFrames();
390
-
391
- // Notify all consumers that a new frame is available
392
- for (const consumer of this.queueConsumers) {
393
- consumer.notifyNewFrame();
394
- }
395
- }
396
-
397
- private cleanupOldFrames(): void {
398
- const currentTime = Date.now();
399
- const bufferThreshold = currentTime - this.bufferDurationMs;
400
-
401
- while (this.frameBuffer.length > 1 && this.frameBuffer[0].timestamp < bufferThreshold) {
402
- this.frameBuffer.shift();
403
- }
404
- }
405
-
406
- private async extractMetadata(): Promise<FrameMetadata> {
407
- return new Promise((resolve, reject) => {
408
- const timeout = setTimeout(() => {
409
- cleanup();
410
- reject(new Error('FFmpeg stream start timeout'));
411
- }, this.streamStartTimeout);
412
-
413
- const onData = (data: Buffer) => {
414
- const metadata = this.parseMetadataFromStderr(data);
415
- if (metadata) {
416
- this.worker.logger.debug('Metadata received:', metadata);
417
- cleanup();
418
- resolve(metadata);
419
- }
420
- };
421
-
422
- const cleanup = () => {
423
- clearTimeout(timeout);
424
- this.ffmpegProcess?.stderr?.removeListener('data', onData);
425
- };
426
-
427
- this.ffmpegProcess?.stderr?.on('data', onData);
428
- });
429
- }
430
-
431
- private calculateReconnectDelay(): number {
432
- if (this.reconnectCount === 10) {
433
- return 60000;
434
- } else {
435
- return 10000;
436
- }
437
- }
438
-
439
- private parseMetadataFromStderr(data: Buffer): FrameMetadata | undefined {
440
- const stderrText = data.toString();
441
- if (!stderrText) {
442
- return;
443
- }
444
-
445
- const match = METADATA_REGEX.exec(stderrText);
446
- if (!match?.[1]) {
447
- return;
448
- }
449
-
450
- const [originalWidth, originalHeight] = match[1].split('x').map((v) => parseInt(v, 10));
451
- const frameDataSize = this.width * this.height * this.bytesPerPixel;
452
-
453
- const metadata: FrameMetadata = {
454
- format: this.worker.imageUtils.decoder === 'gpu' ? 'nv12' : 'yuv420p',
455
- frameSize: frameDataSize,
456
- width: this.width,
457
- height: this.height,
458
- origHeight: originalHeight,
459
- origWidth: originalWidth,
460
- };
461
-
462
- return metadata;
463
- }
464
-
465
- private async prepareFfmpegArguments(serverUrl: string): Promise<string[]> {
466
- if (!this.ffmpegHwOptions) {
467
- const coreManager = await this.coreManagerProxy();
468
- this.ffmpegHwOptions = (
469
- await coreManager.getHwaccelInfo({
470
- targetCodec: 'h264',
471
- keepOnHardware: true,
472
- pixelFormat: this.pixelFormat,
473
- scale: {
474
- width: this.width,
475
- height: this.height,
476
- },
477
- })
478
- )[0];
479
- }
480
-
481
- const filterChain: string[] = ['showinfo=checksum=0', ...this.ffmpegHwOptions.hwaccelFilters];
482
- if (this.worker.config.fps > 0) {
483
- filterChain.push(`fps=fps=${this.worker.config.fps}`);
484
- }
485
-
486
- return [
487
- '-hide_banner',
488
- ...this.ffmpegHwOptions.hwaccelArgs,
489
- '-fflags',
490
- '+discardcorrupt+flush_packets+nobuffer',
491
- '-flags',
492
- 'low_delay',
493
- '-analyzeduration',
494
- '0',
495
- '-probesize',
496
- '500000',
497
- '-reorder_queue_size',
498
- '0',
499
- '-user_agent',
500
- 'camera.ui/frameworker',
501
- '-timeout',
502
- '5000000',
503
- '-rtsp_transport',
504
- 'tcp',
505
- '-re',
506
- '-i',
507
- this.worker.config.cameraSource,
508
- ...this.ffmpegHwOptions.hwDeviceArgs,
509
- '-fps_mode',
510
- 'cfr',
511
- '-vf',
512
- filterChain.join(','),
513
- '-an',
514
- '-dn',
515
- '-sn',
516
- '-f',
517
- 'rawvideo',
518
- `${serverUrl}?tcp_nodelay=1`,
519
- ];
520
- }
521
-
522
- private cleanupResources(): void {
523
- this.streamActive = false;
524
- this.metadata = undefined;
525
- this.frameProcessingActive = false;
526
-
527
- clearInterval(this.healthCheckInterval);
528
- this.healthCheckInterval = undefined;
529
-
530
- this.server?.terminate();
531
- this.server = undefined;
532
-
533
- this.ffmpegProcess?.stderr?.removeAllListeners();
534
- this.ffmpegProcess?.stderr?.destroy();
535
- this.ffmpegProcess?.removeAllListeners();
536
- this.ffmpegProcess?.kill('SIGKILL');
537
- this.ffmpegProcess = undefined;
538
- }
539
-
540
- private async coreManagerProxy(): Promise<Promisify<CoreManagerInterface>> {
541
- return await this.worker.createRPCProxy<CoreManagerInterface>(this.worker.namespaces.coreManagerRpc);
542
- }
543
- }
544
-
545
- class FrameConsumer {
546
- private lastFrameTimestamp = 0;
547
- private resolveNewFrame: (() => void) | null = null;
548
-
549
- constructor(
550
- public readonly id: number,
551
- private stream: FFmpegStream,
552
- ) {}
553
-
554
- public notifyNewFrame(): void {
555
- if (this.resolveNewFrame) {
556
- const resolve = this.resolveNewFrame;
557
- this.resolveNewFrame = null;
558
- resolve();
559
- }
560
- }
561
-
562
- public waitForNewFrame(): Promise<void> {
563
- return new Promise<void>((resolve) => {
564
- this.resolveNewFrame = resolve;
565
- });
566
- }
567
-
568
- public [Symbol.asyncIterator](): AsyncIterator<Frame> {
569
- return {
570
- next: async (): Promise<IteratorResult<Frame>> => {
571
- while (true) {
572
- const frame = this.stream.getNextFrame(this.lastFrameTimestamp);
573
-
574
- if (frame) {
575
- this.lastFrameTimestamp = frame.timestamp;
576
- return { value: frame, done: false };
577
- }
578
-
579
- if (!this.stream.streamActive) {
580
- return { value: undefined as any, done: true };
581
- }
582
-
583
- // Wait for notification of new frame
584
- await this.waitForNewFrame();
585
- }
586
- },
587
- };
588
- }
589
- }
590
-
591
- class FrameWorkerChild extends ClientInstance implements FrameWorkerInterface {
592
- public readonly config: BaseFrameWorkerConfig;
593
- public readonly namespaces: FrameWorkerNamespaces & CoreManagerNamespaces;
594
- public readonly logger: Logger;
595
- public readonly imageUtils: ImageUtils;
596
-
597
- private signalHandler: SignalHandler;
598
- private ffmpegStream: FFmpegStream;
599
-
600
- private stopped = false;
601
-
602
- constructor() {
603
- super('service', {
604
- endpoints: process.env.PROXY_ENDPOINTS!.split(','),
605
- auth: {
606
- user: process.env.PROXY_USER!,
607
- password: process.env.PROXY_PASSWORD!,
608
- },
609
- tls: {
610
- cert: process.env.PROXY_CERT!,
611
- key: process.env.PROXY_KEY!,
612
- ca: process.env.PROXY_CA!,
613
- },
614
- metadata: {
615
- id: NamespaceManager.frameWorkerNamespaces(process.env.CAMERA_ID!).frameWorkerChild,
616
- name: 'Frame Worker',
617
- },
618
- connect: {
619
- waitForServer: true,
620
- },
621
- reconnect: {
622
- enabled: true,
623
- },
624
- bundledConnection: false,
625
- });
626
-
627
- this.namespaces = {
628
- ...NamespaceManager.frameWorkerNamespaces(process.env.CAMERA_ID!),
629
- ...NamespaceManager.coreManagerNamespaces(),
630
- };
631
-
632
- this.config = {
633
- cameraId: process.env.CAMERA_ID!,
634
- cameraName: process.env.CAMERA_NAME!,
635
- cameraSource: process.env.CAMERA_SOURCE!,
636
- ffmpegPath: process.env.FFMPEG_PATH!,
637
- auth: { user: process.env.PROXY_USER!, password: process.env.PROXY_PASSWORD! },
638
- proxyEndpoints: process.env.PROXY_ENDPOINTS!.split(','),
639
- fps: parseInt(process.env.FPS!),
640
- resolution: process.env.RESOLUTION! as CameraFrameWorkerResolution,
641
- decoder: process.env.DECODER! as CameraFrameWorkerDecoder,
642
- };
643
-
644
- delete process.env.PROXY_USER;
645
- delete process.env.PROXY_PASSWORD;
646
- delete process.env.PROXY_ENDPOINTS;
647
- delete process.env.PROXY_CERT;
648
- delete process.env.PROXY_KEY;
649
- delete process.env.PROXY_CA;
650
-
651
- const loggerOptions: LoggerOptions = {
652
- prefix: 'Frame Worker',
653
- suffix: this.config.cameraName,
654
- disableTimestamps: process.env.LOGGER_DISABLE_TIMESTAMPS === '1',
655
- debugEnabled: process.env.LOGGER_LEVEL === 'debug' || process.env.LOGGER_LEVEL === 'trace',
656
- traceEnabled: process.env.LOGGER_LEVEL === 'trace',
657
- };
658
-
659
- this.logger = new Logger(loggerOptions);
660
- this.imageUtils = new ImageUtils(this.config.decoder, this.logger);
661
- this.ffmpegStream = new FFmpegStream(this);
662
- this.signalHandler = new SignalHandler({
663
- displayName: '[Signal]',
664
- timeoutDuration: 1000,
665
- logger: this.logger,
666
- closeFunction: this.close.bind(this),
667
- });
668
-
669
- this.start();
670
- }
671
-
672
- protected async onStart(): Promise<void> {
673
- await this.imageUtils.initiate();
674
- await this.registerRPCHandler(this.namespaces.frameWorkerChildRpc, this);
675
- this.sendMessage({ message: 'started', data: {} });
676
- }
677
-
678
- protected onBeforeStop(): Promise<void> {
679
- return this.close();
680
- }
681
-
682
- protected async onStop(): Promise<void> {}
683
-
684
- @rpc({ public: true })
685
- public async *generateFrames(options?: ImageOptions): AsyncGenerator<FrameData> {
686
- let consumer: FrameConsumer | undefined;
687
-
688
- try {
689
- consumer = this.ffmpegStream.registerViewer();
690
- await this.ffmpegStream.initialize();
691
-
692
- if (!this.ffmpegStream.metadata) {
693
- throw new Error('Stream metadata not available');
694
- }
695
-
696
- const metadata = this.ffmpegStream.metadata;
697
-
698
- // Use the async iterator from the consumer to get frames
699
- for await (const { data: frameData, timestamp } of consumer) {
700
- options = this.validateOptions(metadata, options);
701
-
702
- if (options) {
703
- const processedFrame = await this.processFrame(frameData, metadata.width, metadata.height, metadata.format, options);
704
- yield {
705
- data: processedFrame.image,
706
- metadata,
707
- timestamp,
708
- info: processedFrame.info,
709
- };
710
- } else {
711
- const info = this.getImageInformation(metadata.width, metadata.height, metadata.format);
712
- yield {
713
- data: frameData,
714
- metadata,
715
- timestamp,
716
- info,
717
- };
718
- }
719
- }
720
- } catch (error) {
721
- this.logger.error('Error in frame generation:', error);
722
- } finally {
723
- if (consumer) {
724
- this.ffmpegStream.unregisterViewer(consumer);
725
- }
726
- }
727
- }
728
-
729
- @rpc({ public: true })
730
- public async getPrebufferedFrame(timestamp: number, options?: ImageOptions, maxDifference = 500): Promise<FrameData | undefined> {
731
- const prebufferedFrame = this.ffmpegStream.getFrameByTimestamp(timestamp, maxDifference);
732
- if (!prebufferedFrame) {
733
- this.logger.debug(`No prebuffered frame found for timestamp ${timestamp}`);
734
- return;
735
- }
736
-
737
- const validatedOptions = options && this.validateOptions(prebufferedFrame.metadata, options);
738
-
739
- if (validatedOptions) {
740
- const processedFrame = await this.processFrame(
741
- prebufferedFrame.data,
742
- prebufferedFrame.metadata.width,
743
- prebufferedFrame.metadata.height,
744
- prebufferedFrame.metadata.format,
745
- validatedOptions,
746
- );
747
- return { data: processedFrame.image, metadata: prebufferedFrame.metadata, timestamp: prebufferedFrame.timestamp, info: processedFrame.info };
748
- } else {
749
- const info = this.getImageInformation(prebufferedFrame.metadata.width, prebufferedFrame.metadata.height, prebufferedFrame.metadata.format);
750
- return { data: prebufferedFrame.data, metadata: prebufferedFrame.metadata, timestamp: prebufferedFrame.timestamp, info };
751
- }
752
- }
753
-
754
- @rpc({ public: true })
755
- public async processFrame(
756
- frame: Buffer | Uint8Array,
757
- width: number,
758
- height: number,
759
- format: DecoderFormat | 'rgba' | 'gray',
760
- options: ImageOptions,
761
- ): Promise<FrameBuffer> {
762
- const newFrame = Buffer.isBuffer(frame) ? new Uint8Array(frame, frame.byteOffset, frame.byteLength) : frame;
763
- const info = this.getImageInformation(width, height, format, options);
764
-
765
- const image = await this.imageUtils.processImage(newFrame, width, height, format, options);
766
-
767
- return {
768
- image,
769
- info,
770
- };
771
- }
772
-
773
- private validateOptions(metadata: FrameMetadata, options: ImageOptions = {}): ImageOptions | undefined {
774
- const validated: ImageOptions = {};
775
-
776
- // Format conversion
777
- const metadataFormat = metadata.format === 'rgb24' ? 'rgb' : metadata.format;
778
- if (options.format?.to && options.format.to !== metadataFormat) {
779
- validated.format = options.format;
780
- }
781
-
782
- // Cropping
783
- if (options.crop) {
784
- const left = options.crop.left || 0;
785
- const top = options.crop.top || 0;
786
-
787
- // Validate crop parameters
788
- if (left >= metadata.width || top >= metadata.height) {
789
- return undefined;
790
- }
791
-
792
- const width = Math.min(options.crop.width ?? metadata.width, metadata.width - left);
793
- const height = Math.min(options.crop.height ?? metadata.height, metadata.height - top);
794
-
795
- if (width <= 0 || height <= 0) {
796
- return undefined;
797
- }
798
-
799
- // Skip full frame "crops"
800
- if (left === 0 && top === 0 && width === metadata.width && height === metadata.height) {
801
- // No need to include this crop as it's the full frame
802
- } else {
803
- validated.crop = {
804
- left,
805
- top,
806
- width,
807
- height,
808
- };
809
- }
810
- }
811
-
812
- // Resizing
813
- if (options.resize) {
814
- let targetWidth = options.resize.width;
815
- let targetHeight = options.resize.height;
816
-
817
- // Handle negative values (which mean "use original")
818
- if (targetWidth < 0) targetWidth = metadata.width;
819
- if (targetHeight < 0) targetHeight = metadata.height;
820
-
821
- // Calculate missing dimension if only one is provided
822
- if (targetWidth > 0 && targetHeight === 0) {
823
- targetHeight = Math.round((targetWidth * metadata.height) / metadata.width);
824
- } else if (targetHeight > 0 && targetWidth === 0) {
825
- targetWidth = Math.round((targetHeight * metadata.width) / metadata.height);
826
- }
827
-
828
- // Skip if no resize needed
829
- if ((targetWidth === 0 && targetHeight === 0) || (targetWidth === metadata.width && targetHeight === metadata.height)) {
830
- // Skip as it's the same as original
831
- } else {
832
- validated.resize = {
833
- width: targetWidth,
834
- height: targetHeight,
835
- };
836
- }
837
- }
838
-
839
- // Return undefined if no transformations are needed
840
- return Object.keys(validated).length > 0 ? validated : undefined;
841
- }
842
-
843
- private getImageInformation(inputWidth: number, inputHeight: number, inputFormat: DecoderFormat | 'rgba' | 'gray', options?: ImageOptions): ImageInformation {
844
- // Calculate output width
845
- const width = options?.resize?.width ?? (options?.crop ? Math.min(options.crop.width + (options.crop.left || 0), inputWidth - (options.crop.left || 0)) : inputWidth);
846
-
847
- // Calculate output height
848
- const height =
849
- options?.resize?.height ?? (options?.crop ? Math.min(options.crop.height + (options.crop.top || 0), inputHeight - (options.crop.top || 0)) : inputHeight);
850
-
851
- // Determine output format
852
- let format = options?.format?.to ?? inputFormat;
853
- format = format === 'rgb24' ? 'rgb' : format;
854
-
855
- // Calculate channels based on format
856
- const channels = format === 'rgba' ? 4 : format === 'rgb' ? 3 : format === 'gray' ? 1 : 1.5;
857
-
858
- return {
859
- width,
860
- height,
861
- channels,
862
- format,
863
- };
864
- }
865
-
866
- private sendMessage(message: WorkerToMainMessage): void {
867
- this.sendToServer<WorkerToMainMessage>(message);
868
- }
869
-
870
- private async close(): Promise<void> {
871
- if (this.stopped) {
872
- return;
873
- }
874
-
875
- this.stopped = true;
876
- this.ffmpegStream.cleanup();
877
- await this.stop();
878
- }
879
- }
880
-
881
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
882
- new FrameWorkerChild();
883
- }