camstreamerlib 4.0.0-beta.4 → 4.0.0-beta.40

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 (239) hide show
  1. package/README.md +112 -0
  2. package/cjs/CamOverlayAPI.js +135 -92
  3. package/cjs/CamScripterAPI.js +52 -42
  4. package/cjs/CamStreamerAPI.js +83 -39
  5. package/cjs/CamSwitcherAPI.js +141 -123
  6. package/cjs/CamSwitcherEvents.js +4 -60
  7. package/cjs/PlaneTrackerAPI.js +200 -0
  8. package/cjs/VapixAPI.js +323 -233
  9. package/cjs/{CreatePackage.js → bin/CreatePackage.js} +22 -19
  10. package/cjs/errors/errors.js +64 -1
  11. package/cjs/index.js +17 -4
  12. package/cjs/internal/ProxyClient.js +28 -32
  13. package/cjs/internal/WsEvents.js +72 -0
  14. package/cjs/internal/types.js +2 -0
  15. package/cjs/internal/utils.js +22 -3
  16. package/cjs/{CamOverlayDrawingAPI.js → node/CamOverlayDrawingAPI.js} +7 -4
  17. package/cjs/{CamOverlayPainter → node/CamOverlayPainter}/Frame.js +33 -0
  18. package/cjs/{CamOverlayPainter → node/CamOverlayPainter}/Painter.js +5 -17
  19. package/cjs/node/CamOverlayPainter/ResourceManager.js +72 -0
  20. package/cjs/{CamScripterAPICameraEventsGenerator.js → node/CamScripterAPICameraEventsGenerator.js} +7 -4
  21. package/cjs/node/DefaultClient.js +10 -12
  22. package/cjs/{internal → node}/Digest.js +8 -5
  23. package/cjs/node/HttpRequestSender.js +14 -4
  24. package/cjs/node/HttpServer.js +15 -12
  25. package/cjs/{VapixEvents.js → node/VapixEvents.js} +1 -1
  26. package/cjs/node/WsClient.js +12 -9
  27. package/cjs/node/events/AxisCameraStationEvents.js +53 -0
  28. package/cjs/node/events/GenetecAgent.js +123 -0
  29. package/cjs/node/index.js +38 -5
  30. package/cjs/types/CamOverlayAPI/CamOverlayAPI.js +92 -0
  31. package/cjs/types/CamOverlayAPI/accuweatherSchema.js +47 -0
  32. package/cjs/types/CamOverlayAPI/customGraphicsSchema.js +72 -0
  33. package/cjs/types/CamOverlayAPI/imagesSchema.js +9 -0
  34. package/cjs/types/CamOverlayAPI/index.js +27 -0
  35. package/cjs/types/CamOverlayAPI/infotickerSchema.js +26 -0
  36. package/cjs/types/CamOverlayAPI/pipSchema.js +39 -0
  37. package/cjs/types/CamOverlayAPI/ptzCompassSchema.js +25 -0
  38. package/cjs/types/CamOverlayAPI/ptzSchema.js +12 -0
  39. package/cjs/types/CamOverlayAPI/scoreBoardSchema.js +132 -0
  40. package/cjs/types/CamOverlayAPI/screenSharingSchema.js +8 -0
  41. package/cjs/types/CamOverlayAPI/serviceCommonTypes.js +91 -0
  42. package/cjs/types/CamOverlayAPI/webCameraSharingSchema.js +8 -0
  43. package/cjs/types/CamOverlayDrawingAPI.js +2 -0
  44. package/cjs/types/CamOverlayPainter.js +14 -0
  45. package/cjs/types/CamScripterAPI.js +22 -7
  46. package/cjs/types/CamScripterAPICameraEventsGenerator.js +2 -0
  47. package/cjs/types/CamStreamerAPI.js +34 -3
  48. package/cjs/types/CamSwitcherAPI.js +38 -1
  49. package/cjs/types/CamSwitcherEvents.js +8 -0
  50. package/cjs/types/GenetecAgent.js +31 -0
  51. package/cjs/types/PlaneTrackerAPI.js +281 -0
  52. package/cjs/types/VapixAPI.js +71 -13
  53. package/cjs/types/VapixEvents.js +2 -0
  54. package/cjs/web/DefaultClient.js +22 -10
  55. package/cjs/web/WsClient.js +3 -3
  56. package/esm/CamOverlayAPI.js +131 -88
  57. package/esm/CamScripterAPI.js +48 -38
  58. package/esm/CamStreamerAPI.js +81 -38
  59. package/esm/CamSwitcherAPI.js +137 -119
  60. package/esm/CamSwitcherEvents.js +5 -61
  61. package/esm/PlaneTrackerAPI.js +196 -0
  62. package/esm/VapixAPI.js +315 -225
  63. package/esm/{CreatePackage.js → bin/CreatePackage.js} +3 -3
  64. package/esm/errors/errors.js +54 -0
  65. package/esm/index.js +12 -3
  66. package/esm/internal/ProxyClient.js +28 -32
  67. package/esm/internal/WsEvents.js +68 -0
  68. package/esm/internal/utils.js +17 -1
  69. package/esm/{CamOverlayDrawingAPI.js → node/CamOverlayDrawingAPI.js} +2 -2
  70. package/esm/{CamOverlayPainter → node/CamOverlayPainter}/Frame.js +33 -0
  71. package/esm/{CamOverlayPainter → node/CamOverlayPainter}/Painter.js +2 -13
  72. package/esm/{CamOverlayPainter → node/CamOverlayPainter}/ResourceManager.js +7 -5
  73. package/esm/{CamScripterAPICameraEventsGenerator.js → node/CamScripterAPICameraEventsGenerator.js} +2 -2
  74. package/esm/node/DefaultClient.js +10 -12
  75. package/esm/{internal → node}/Digest.js +1 -1
  76. package/esm/node/HttpRequestSender.js +14 -4
  77. package/esm/node/HttpServer.js +5 -5
  78. package/esm/{VapixEvents.js → node/VapixEvents.js} +1 -1
  79. package/esm/node/WsClient.js +3 -3
  80. package/esm/{events → node/events}/AxisCameraStationEvents.js +18 -13
  81. package/esm/node/events/GenetecAgent.js +119 -0
  82. package/esm/node/index.js +17 -2
  83. package/esm/types/CamOverlayAPI/CamOverlayAPI.js +76 -0
  84. package/esm/types/CamOverlayAPI/accuweatherSchema.js +44 -0
  85. package/esm/types/CamOverlayAPI/customGraphicsSchema.js +69 -0
  86. package/esm/types/CamOverlayAPI/imagesSchema.js +6 -0
  87. package/esm/types/CamOverlayAPI/index.js +11 -0
  88. package/esm/types/CamOverlayAPI/infotickerSchema.js +23 -0
  89. package/esm/types/CamOverlayAPI/pipSchema.js +36 -0
  90. package/esm/types/CamOverlayAPI/ptzCompassSchema.js +22 -0
  91. package/esm/types/CamOverlayAPI/ptzSchema.js +9 -0
  92. package/esm/types/CamOverlayAPI/scoreBoardSchema.js +129 -0
  93. package/esm/types/CamOverlayAPI/screenSharingSchema.js +5 -0
  94. package/esm/types/CamOverlayAPI/serviceCommonTypes.js +88 -0
  95. package/esm/types/CamOverlayAPI/webCameraSharingSchema.js +5 -0
  96. package/esm/types/CamOverlayPainter.js +11 -0
  97. package/esm/types/CamScripterAPI.js +21 -6
  98. package/esm/types/CamScripterAPICameraEventsGenerator.js +1 -0
  99. package/esm/types/CamStreamerAPI.js +33 -2
  100. package/esm/types/CamSwitcherAPI.js +38 -1
  101. package/esm/types/CamSwitcherEvents.js +8 -0
  102. package/esm/types/GenetecAgent.js +28 -0
  103. package/esm/types/PlaneTrackerAPI.js +278 -0
  104. package/esm/types/VapixAPI.js +70 -12
  105. package/esm/types/VapixEvents.js +1 -0
  106. package/esm/web/DefaultClient.js +22 -10
  107. package/esm/web/WsClient.js +3 -3
  108. package/package.json +30 -12
  109. package/types/CamOverlayAPI.d.ts +865 -0
  110. package/types/CamScripterAPI.d.ts +47 -0
  111. package/types/CamStreamerAPI.d.ts +64 -0
  112. package/types/CamSwitcherAPI.d.ts +167 -0
  113. package/types/CamSwitcherEvents.d.ts +8 -0
  114. package/types/PlaneTrackerAPI.d.ts +226 -0
  115. package/types/VapixAPI.d.ts +118 -0
  116. package/types/bin/CreatePackage.d.ts +1 -0
  117. package/{esm → types}/errors/errors.d.ts +28 -1
  118. package/types/index.d.ts +20 -0
  119. package/types/internal/ProxyClient.d.ts +10 -0
  120. package/types/internal/WsEvents.d.ts +41 -0
  121. package/types/internal/types.d.ts +45 -0
  122. package/{cjs → types}/internal/utils.d.ts +4 -1
  123. package/{cjs → types}/internal/versionCompare.d.ts +2 -2
  124. package/types/node/CamOverlayDrawingAPI.d.ts +41 -0
  125. package/{esm → types/node}/CamOverlayPainter/Frame.d.ts +8 -37
  126. package/{cjs → types/node}/CamOverlayPainter/Painter.d.ts +5 -21
  127. package/types/node/CamOverlayPainter/ResourceManager.d.ts +15 -0
  128. package/types/node/CamScripterAPICameraEventsGenerator.d.ts +31 -0
  129. package/types/node/DefaultClient.d.ts +16 -0
  130. package/{esm → types}/node/HttpRequestSender.d.ts +1 -0
  131. package/{cjs → types}/node/HttpServer.d.ts +2 -2
  132. package/types/node/VapixEvents.d.ts +16 -0
  133. package/{cjs → types}/node/WsClient.d.ts +3 -2
  134. package/types/node/events/AxisCameraStationEvents.d.ts +12 -0
  135. package/types/node/events/GenetecAgent.d.ts +16 -0
  136. package/types/node/index.d.ts +17 -0
  137. package/types/types/CamOverlayAPI/CamOverlayAPI.d.ts +4321 -0
  138. package/types/types/CamOverlayAPI/accuweatherSchema.d.ts +84 -0
  139. package/types/types/CamOverlayAPI/customGraphicsSchema.d.ts +700 -0
  140. package/types/types/CamOverlayAPI/imagesSchema.d.ts +95 -0
  141. package/types/types/CamOverlayAPI/index.d.ts +11 -0
  142. package/types/types/CamOverlayAPI/infotickerSchema.d.ts +96 -0
  143. package/types/types/CamOverlayAPI/pipSchema.d.ts +125 -0
  144. package/types/types/CamOverlayAPI/ptzCompassSchema.d.ts +93 -0
  145. package/types/types/CamOverlayAPI/ptzSchema.d.ts +118 -0
  146. package/types/types/CamOverlayAPI/scoreBoardSchema.d.ts +357 -0
  147. package/types/types/CamOverlayAPI/screenSharingSchema.d.ts +58 -0
  148. package/types/types/CamOverlayAPI/serviceCommonTypes.d.ts +145 -0
  149. package/types/types/CamOverlayAPI/webCameraSharingSchema.d.ts +58 -0
  150. package/types/types/CamOverlayDrawingAPI.d.ts +48 -0
  151. package/types/types/CamOverlayPainter.d.ts +76 -0
  152. package/types/types/CamScripterAPI.d.ts +130 -0
  153. package/types/types/CamScripterAPICameraEventsGenerator.d.ts +45 -0
  154. package/types/types/CamStreamerAPI.d.ts +272 -0
  155. package/{esm → types}/types/CamSwitcherAPI.d.ts +115 -36
  156. package/{cjs → types}/types/CamSwitcherEvents.d.ts +77 -0
  157. package/{esm/events → types/types}/GenetecAgent.d.ts +47 -47
  158. package/types/types/PlaneTrackerAPI.d.ts +877 -0
  159. package/{cjs → types}/types/VapixAPI.d.ts +647 -465
  160. package/types/types/VapixEvents.d.ts +15 -0
  161. package/{esm → types}/types/common.d.ts +15 -5
  162. package/types/web/DefaultClient.d.ts +6 -0
  163. package/cjs/CamOverlayAPI.d.ts +0 -31
  164. package/cjs/CamOverlayDrawingAPI.d.ts +0 -86
  165. package/cjs/CamOverlayPainter/Frame.d.ts +0 -96
  166. package/cjs/CamOverlayPainter/ResourceManager.d.ts +0 -14
  167. package/cjs/CamOverlayPainter/ResourceManager.js +0 -46
  168. package/cjs/CamScripterAPI.d.ts +0 -19
  169. package/cjs/CamScripterAPICameraEventsGenerator.d.ts +0 -74
  170. package/cjs/CamStreamerAPI.d.ts +0 -16
  171. package/cjs/CamSwitcherAPI.d.ts +0 -48
  172. package/cjs/CamSwitcherEvents.d.ts +0 -18
  173. package/cjs/VapixAPI.d.ts +0 -66
  174. package/cjs/VapixEvents.d.ts +0 -43
  175. package/cjs/errors/errors.d.ts +0 -34
  176. package/cjs/events/AxisCameraStationEvents.d.ts +0 -9
  177. package/cjs/events/AxisCameraStationEvents.js +0 -48
  178. package/cjs/events/GenetecAgent.d.ts +0 -174
  179. package/cjs/events/GenetecAgent.js +0 -123
  180. package/cjs/index.d.ts +0 -11
  181. package/cjs/internal/ProxyClient.d.ts +0 -11
  182. package/cjs/internal/common.d.ts +0 -39
  183. package/cjs/internal/common.js +0 -27
  184. package/cjs/node/DefaultClient.d.ts +0 -15
  185. package/cjs/node/HttpRequestSender.d.ts +0 -28
  186. package/cjs/node/WsEventClient.d.ts +0 -13
  187. package/cjs/node/WsEventClient.js +0 -22
  188. package/cjs/types/CamOverlayAPI.d.ts +0 -188
  189. package/cjs/types/CamOverlayAPI.js +0 -47
  190. package/cjs/types/CamScripterAPI.d.ts +0 -67
  191. package/cjs/types/CamStreamerAPI.d.ts +0 -139
  192. package/cjs/types/CamSwitcherAPI.d.ts +0 -814
  193. package/cjs/types/common.d.ts +0 -37
  194. package/cjs/web/DefaultClient.d.ts +0 -6
  195. package/cjs/web/index.d.ts +0 -2
  196. package/esm/CamOverlayAPI.d.ts +0 -31
  197. package/esm/CamOverlayDrawingAPI.d.ts +0 -86
  198. package/esm/CamOverlayPainter/Painter.d.ts +0 -48
  199. package/esm/CamOverlayPainter/ResourceManager.d.ts +0 -14
  200. package/esm/CamScripterAPI.d.ts +0 -19
  201. package/esm/CamScripterAPICameraEventsGenerator.d.ts +0 -74
  202. package/esm/CamStreamerAPI.d.ts +0 -16
  203. package/esm/CamSwitcherAPI.d.ts +0 -48
  204. package/esm/CamSwitcherEvents.d.ts +0 -18
  205. package/esm/VapixAPI.d.ts +0 -66
  206. package/esm/VapixEvents.d.ts +0 -43
  207. package/esm/events/AxisCameraStationEvents.d.ts +0 -9
  208. package/esm/events/GenetecAgent.js +0 -119
  209. package/esm/index.d.ts +0 -11
  210. package/esm/internal/Digest.d.ts +0 -4
  211. package/esm/internal/ProxyClient.d.ts +0 -11
  212. package/esm/internal/common.d.ts +0 -39
  213. package/esm/internal/common.js +0 -20
  214. package/esm/internal/constants.d.ts +0 -1
  215. package/esm/internal/transformers.d.ts +0 -5
  216. package/esm/internal/utils.d.ts +0 -11
  217. package/esm/internal/versionCompare.d.ts +0 -6
  218. package/esm/node/DefaultClient.d.ts +0 -15
  219. package/esm/node/HttpServer.d.ts +0 -21
  220. package/esm/node/WsClient.d.ts +0 -39
  221. package/esm/node/WsEventClient.d.ts +0 -13
  222. package/esm/node/WsEventClient.js +0 -18
  223. package/esm/node/index.d.ts +0 -2
  224. package/esm/types/CamOverlayAPI.d.ts +0 -188
  225. package/esm/types/CamOverlayAPI.js +0 -44
  226. package/esm/types/CamScripterAPI.d.ts +0 -67
  227. package/esm/types/CamStreamerAPI.d.ts +0 -139
  228. package/esm/types/CamSwitcherEvents.d.ts +0 -491
  229. package/esm/types/VapixAPI.d.ts +0 -1683
  230. package/esm/web/DefaultClient.d.ts +0 -6
  231. package/esm/web/WsClient.d.ts +0 -13
  232. package/esm/web/index.d.ts +0 -2
  233. /package/{cjs/CreatePackage.d.ts → esm/internal/types.js} +0 -0
  234. /package/esm/{CreatePackage.d.ts → types/CamOverlayDrawingAPI.js} +0 -0
  235. /package/{cjs → types}/internal/constants.d.ts +0 -0
  236. /package/{cjs → types}/internal/transformers.d.ts +0 -0
  237. /package/{cjs/internal → types/node}/Digest.d.ts +0 -0
  238. /package/{cjs → types}/web/WsClient.d.ts +0 -0
  239. /package/{cjs/node → types/web}/index.d.ts +0 -0
package/cjs/VapixAPI.js CHANGED
@@ -1,58 +1,72 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VapixAPI = void 0;
4
- const prettifyXml = require("prettify-xml");
5
- const xml2js_1 = require("xml2js");
6
- const common_1 = require("./internal/common");
4
+ const utils_1 = require("./internal/utils");
7
5
  const VapixAPI_1 = require("./types/VapixAPI");
8
6
  const errors_1 = require("./errors/errors");
9
7
  const ProxyClient_1 = require("./internal/ProxyClient");
10
- const utils_1 = require("./internal/utils");
11
8
  const zod_1 = require("zod");
9
+ const fast_xml_parser_1 = require("fast-xml-parser");
12
10
  class VapixAPI {
13
11
  client;
14
- constructor(client, getProxyUrl) {
15
- this.client = new ProxyClient_1.ProxyClient(client, getProxyUrl);
12
+ CustomFormData;
13
+ constructor(client, CustomFormData = FormData) {
14
+ this.client = client;
15
+ this.CustomFormData = CustomFormData;
16
+ }
17
+ getClient(proxyParams) {
18
+ return proxyParams ? new ProxyClient_1.ProxyClient(this.client, proxyParams) : this.client;
16
19
  }
17
- async getUrlEncoded(proxy, path, parameters, headers = {}) {
20
+ async postUrlEncoded(path, parameters, headers, options) {
18
21
  const data = (0, utils_1.paramToUrl)(parameters);
19
22
  const head = { ...headers, 'Content-Type': 'application/x-www-form-urlencoded' };
20
- const res = await this.client.post(proxy, path, data, {}, head);
23
+ const agent = this.getClient(options?.proxyParams);
24
+ const res = await agent.post({ path, data, headers: head, timeout: options?.timeout });
21
25
  if (!res.ok) {
22
- throw new Error(await (0, common_1.responseStringify)(res));
26
+ throw new Error(await (0, utils_1.responseStringify)(res));
23
27
  }
24
28
  return res;
25
29
  }
26
- async postJson(proxy, path, jsonData, headers = {}) {
30
+ async postJson(path, jsonData, headers, options) {
27
31
  const data = JSON.stringify(jsonData);
28
32
  const head = { ...headers, 'Content-Type': 'application/json' };
29
- const res = await this.client.post(proxy, path, data, {}, head);
33
+ const agent = this.getClient(options?.proxyParams);
34
+ const res = await agent.post({ path, data, headers: head, timeout: options?.timeout });
30
35
  if (!res.ok) {
31
- throw new Error(await (0, common_1.responseStringify)(res));
36
+ throw new Error(await (0, utils_1.responseStringify)(res));
32
37
  }
33
38
  return res;
34
39
  }
35
- async getCameraImage(params, proxy = null) {
36
- return await this.client.get(proxy, '/axis-cgi/jpg/image.cgi', params);
40
+ async getCameraImage(parameters, options) {
41
+ const agent = this.getClient(options?.proxyParams);
42
+ return (await agent.get({
43
+ path: '/axis-cgi/jpg/image.cgi',
44
+ parameters,
45
+ timeout: options?.timeout,
46
+ }));
37
47
  }
38
- async getEventDeclarations(proxy = null) {
48
+ async getEventDeclarations(options) {
39
49
  const data = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
40
50
  '<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
41
51
  'xmlns:xsd="http://www.w3.org/2001/XMLSchema">' +
42
52
  '<GetEventInstances xmlns="http://www.axis.com/vapix/ws/event1"/>' +
43
53
  '</s:Body>' +
44
54
  '</s:Envelope>';
45
- const res = await this.client.post(proxy, '/vapix/services', data, { 'Content-Type': 'application/soap+xml' });
55
+ const agent = this.getClient(options?.proxyParams);
56
+ const res = await agent.post({
57
+ path: '/vapix/services',
58
+ data,
59
+ headers: { 'Content-Type': 'application/soap+xml' },
60
+ });
46
61
  if (!res.ok) {
47
- throw new Error(await (0, common_1.responseStringify)(res));
62
+ throw new Error(await (0, utils_1.responseStringify)(res));
48
63
  }
49
- const declarations = await res.text();
50
- return prettifyXml(declarations);
64
+ return await res.text();
51
65
  }
52
- async getSupportedAudioSampleRate(proxy = null) {
53
- const url = '/axis-cgi/audio/streamingcapabilities.cgi';
54
- const formData = { apiVersion: '1.0', method: 'list' };
55
- const res = await this.postJson(proxy, url, formData);
66
+ async getSupportedAudioSampleRate(options) {
67
+ const path = '/axis-cgi/audio/streamingcapabilities.cgi';
68
+ const jsonData = { apiVersion: '1.0', method: 'list' };
69
+ const res = await this.postJson(path, jsonData, undefined, options);
56
70
  const encoders = VapixAPI_1.audioSampleRatesResponseSchema.parse(await res.json()).data.encoders;
57
71
  const data = encoders.aac ?? encoders.AAC ?? [];
58
72
  return data.map((item) => {
@@ -62,7 +76,7 @@ class VapixAPI {
62
76
  };
63
77
  });
64
78
  }
65
- async performAutofocus(proxy = null) {
79
+ async performAutofocus(options) {
66
80
  try {
67
81
  const data = {
68
82
  apiVersion: '1',
@@ -75,78 +89,83 @@ class VapixAPI {
75
89
  ],
76
90
  },
77
91
  };
78
- await this.postJson(proxy, '/axis-cgi/opticscontrol.cgi', data);
92
+ await this.postJson('/axis-cgi/opticscontrol.cgi', data, undefined, options);
79
93
  }
80
94
  catch (err) {
81
- await this.postJson(proxy, '/axis-cgi/opticssetup.cgi', {
95
+ await this.postUrlEncoded('/axis-cgi/opticssetup.cgi', {
82
96
  autofocus: 'perform',
83
97
  source: '1',
84
- });
98
+ }, undefined, options);
85
99
  }
86
100
  }
87
- async checkSDCard(proxy = null) {
88
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/disks/list.cgi', {
101
+ async checkSDCard(options) {
102
+ const res = await this.postUrlEncoded('/axis-cgi/disks/list.cgi', {
89
103
  diskid: 'SD_DISK',
104
+ }, undefined, options);
105
+ const xmlText = await res.text();
106
+ const parser = new fast_xml_parser_1.XMLParser({
107
+ ignoreAttributes: false,
108
+ attributeNamePrefix: '',
109
+ allowBooleanAttributes: true,
90
110
  });
91
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
92
- ignoreAttrs: false,
93
- mergeAttrs: true,
94
- explicitArray: false,
95
- });
111
+ const result = parser.parse(xmlText);
96
112
  const data = result.root.disks.disk;
97
- return {
113
+ return VapixAPI_1.sdCardInfoSchema.parse({
98
114
  totalSize: parseInt(data.totalsize),
99
115
  freeSize: parseInt(data.freesize),
100
116
  status: VapixAPI_1.sdCardWatchedStatuses.includes(data.status) ? data.status : 'disconnected',
101
- };
117
+ });
102
118
  }
103
- mountSDCard(proxy = null) {
104
- return this._doSDCardMountAction('MOUNT', proxy);
119
+ mountSDCard(options) {
120
+ return this._doSDCardMountAction('MOUNT', options);
105
121
  }
106
- unmountSDCard(proxy = null) {
107
- return this._doSDCardMountAction('UNMOUNT', proxy);
122
+ unmountSDCard(options) {
123
+ return this._doSDCardMountAction('UNMOUNT', options);
108
124
  }
109
- async _doSDCardMountAction(action, proxy = null) {
110
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/disks/mount.cgi', {
125
+ async _doSDCardMountAction(action, options) {
126
+ const res = await this.postUrlEncoded('/axis-cgi/disks/mount.cgi', {
111
127
  action: action,
112
128
  diskid: 'SD_DISK',
129
+ }, undefined, options);
130
+ const textXml = await res.text();
131
+ const parser = new fast_xml_parser_1.XMLParser({
132
+ ignoreAttributes: false,
133
+ attributeNamePrefix: '',
134
+ allowBooleanAttributes: true,
113
135
  });
114
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
115
- ignoreAttrs: false,
116
- mergeAttrs: true,
117
- explicitArray: false,
118
- });
136
+ const result = parser.parse(textXml);
119
137
  const job = result.root.job;
120
138
  if (job.result !== 'OK') {
121
- throw new errors_1.SDCardActionError(action, await (0, common_1.responseStringify)(res));
139
+ throw new errors_1.SDCardActionError(action, await (0, utils_1.responseStringify)(res));
122
140
  }
123
141
  return Number(job.jobid);
124
142
  }
125
- async fetchSDCardJobProgress(jobId, proxy = null) {
126
- const res = await this.getUrlEncoded(proxy, '/disks/job.cgi', {
143
+ async fetchSDCardJobProgress(jobId, options) {
144
+ const res = await this.postUrlEncoded('/disks/job.cgi', {
127
145
  jobid: String(jobId),
128
146
  diskid: 'SD_DISK',
147
+ }, undefined, options);
148
+ const textXml = await res.text();
149
+ const parser = new fast_xml_parser_1.XMLParser({
150
+ ignoreAttributes: false,
151
+ attributeNamePrefix: '',
152
+ allowBooleanAttributes: true,
129
153
  });
130
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
131
- ignoreAttrs: false,
132
- mergeAttrs: true,
133
- explicitArray: false,
134
- });
135
- const job = result.root.job;
154
+ const job = parser.parse(textXml).root.job;
136
155
  if (job.result !== 'OK') {
137
156
  throw new errors_1.SDCardJobError();
138
157
  }
139
158
  return Number(job.progress);
140
159
  }
141
- downloadCameraReport(proxy = null) {
142
- return this.getUrlEncoded(proxy, '/axis-cgi/serverreport.cgi', { mode: 'text' });
160
+ downloadCameraReport(options) {
161
+ return this.postUrlEncoded('/axis-cgi/serverreport.cgi', { mode: 'text' }, undefined, options);
143
162
  }
144
- getSystemLog(proxy = null) {
145
- return this.getUrlEncoded(proxy, '/axis-cgi/admin/systemlog.cgi');
163
+ getSystemLog(options) {
164
+ return this.postUrlEncoded('/axis-cgi/admin/systemlog.cgi', undefined, undefined, options);
146
165
  }
147
- async getMaxFps(channel, proxy = null) {
166
+ async getMaxFps(channel, options) {
148
167
  const data = { apiVersion: '1.0', method: 'getCaptureModes' };
149
- const res = await this.postJson(proxy, '/axis-cgi/capturemode.cgi', data);
168
+ const res = await this.postJson('/axis-cgi/capturemode.cgi', data, undefined, options);
150
169
  const response = VapixAPI_1.maxFpsResponseSchema.parse(await res.json());
151
170
  const channels = response.data;
152
171
  if (channels === undefined) {
@@ -161,75 +180,89 @@ class VapixAPI {
161
180
  if (captureMode === undefined) {
162
181
  throw new errors_1.MaxFPSError('CAPTURE_MODE_NOT_FOUND');
163
182
  }
164
- if ((0, common_1.isNullish)(captureMode.maxFPS)) {
183
+ if ((0, utils_1.isNullish)(captureMode.maxFPS)) {
165
184
  throw new errors_1.MaxFPSError('FPS_NOT_SPECIFIED');
166
185
  }
167
- return captureMode.maxFPS;
186
+ return zod_1.z.number().parse(captureMode.maxFPS);
168
187
  }
169
- async getTimezone(proxy = null) {
170
- const data = { apiVersion: '1.0', method: 'getDateTimeInfo' };
171
- const res = await this.postJson(proxy, '/axis-cgi/time.cgi', data);
172
- return (await res.json())?.timeZone ?? 'Europe/Prague';
188
+ async getTimezone(options) {
189
+ try {
190
+ const agent = this.getClient(options?.proxyParams);
191
+ const resV2 = await agent.get({ path: '/config/rest/time/v2/timeZone', timeout: options?.timeout });
192
+ if (!resV2.ok) {
193
+ throw new Error(await (0, utils_1.responseStringify)(resV2));
194
+ }
195
+ const json = await resV2.json();
196
+ const data = VapixAPI_1.timeZoneSchema.parse(json);
197
+ if (data.status === 'error') {
198
+ throw new errors_1.TimezoneFetchError(data.error.message);
199
+ }
200
+ return data.data.activeTimeZone;
201
+ }
202
+ catch (error) {
203
+ console.warn('Failed to fetch time zone data from time API v2:', error instanceof Error ? error.message : JSON.stringify(error));
204
+ console.warn('Falling back to deprecated time API v1');
205
+ }
206
+ const data = await this.getDateTimeInfo(options);
207
+ if (data.data.timeZone === undefined) {
208
+ throw new errors_1.TimezoneNotSetupError();
209
+ }
210
+ return zod_1.z.string().parse(data.data.timeZone);
173
211
  }
174
- async getDateTimeInfo(proxy = null) {
212
+ async getDateTimeInfo(options) {
175
213
  const data = { apiVersion: '1.0', method: 'getDateTimeInfo' };
176
- const res = await this.postJson(proxy, '/axis-cgi/time.cgi', data);
214
+ const res = await this.postJson('/axis-cgi/time.cgi', data, undefined, options);
177
215
  return VapixAPI_1.dateTimeinfoSchema.parse(await res.json());
178
216
  }
179
- async getDevicesSettings(proxy = null) {
217
+ async getDevicesSettings(options) {
180
218
  const data = { apiVersion: '1.0', method: 'getDevicesSettings' };
181
- const res = await this.postJson(proxy, '/axis-cgi/audiodevicecontrol.cgi', data);
219
+ const res = await this.postJson('/axis-cgi/audiodevicecontrol.cgi', data, undefined, options);
182
220
  const result = VapixAPI_1.audioDeviceRequestSchema.parse(await res.json());
183
- return result.devices.map((device) => ({
221
+ return result.data.devices.map((device) => ({
184
222
  ...device,
185
223
  inputs: (device.inputs || []).sort((a, b) => a.id.localeCompare(b.id)),
186
224
  outputs: (device.outputs || []).sort((a, b) => a.id.localeCompare(b.id)),
187
225
  }));
188
226
  }
189
- async fetchRemoteDeviceInfo(payload, proxy = null) {
190
- const res = await this.postJson(proxy, '/axis-cgi/basicdeviceinfo.cgi', payload);
191
- const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
192
- ignoreAttrs: false,
193
- mergeAttrs: true,
194
- explicitArray: false,
195
- });
196
- if ((0, common_1.isNullish)(result.body.data)) {
227
+ async fetchRemoteDeviceInfo(payload, options) {
228
+ const res = await this.postJson('/axis-cgi/basicdeviceinfo.cgi', payload, undefined, options);
229
+ const json = await res.json();
230
+ if ((0, utils_1.isNullish)(json.data)) {
197
231
  throw new errors_1.NoDeviceInfoError();
198
232
  }
199
- return result.data;
233
+ return json.data;
200
234
  }
201
- async getHeaders(proxy = null) {
235
+ async getHeaders(options) {
202
236
  const data = { apiVersion: '1.0', method: 'list' };
203
- const res = await this.postJson(proxy, '/axis-cgi/customhttpheader.cgi', data);
237
+ const res = await this.postJson('/axis-cgi/customhttpheader.cgi', data, undefined, options);
204
238
  return zod_1.z.object({ data: zod_1.z.record(zod_1.z.string()) }).parse(await res.json()).data;
205
239
  }
206
- async setHeaders(headers, proxy = null) {
240
+ async setHeaders(headers, options) {
207
241
  const data = { apiVersion: '1.0', method: 'set', params: headers };
208
- return this.postJson(proxy, '/axis-cgi/customhttpheader.cgi', data);
242
+ return this.postJson('/axis-cgi/customhttpheader.cgi', data, undefined, options);
209
243
  }
210
- async getParameter(paramNames, proxy = null) {
211
- const response = await this.getUrlEncoded(proxy, '/axis-cgi/param.cgi', {
244
+ async getParameter(paramNames, options) {
245
+ const response = await this.postUrlEncoded('/axis-cgi/param.cgi', {
212
246
  action: 'list',
213
247
  group: (0, utils_1.arrayToUrl)(paramNames),
214
- });
215
- return parseParameters(await response.text());
248
+ }, undefined, options);
249
+ return VapixAPI.parseParameters(await response.text());
216
250
  }
217
- async setParameter(params, proxy = null) {
218
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/param.cgi', {
251
+ async setParameter(params, options) {
252
+ const res = await this.postUrlEncoded('/axis-cgi/param.cgi', {
219
253
  ...params,
220
254
  action: 'update',
221
- });
255
+ }, undefined, options);
222
256
  const responseText = await res.text();
223
257
  if (responseText.startsWith('# Error')) {
224
- throw new Error(responseText);
258
+ throw new errors_1.SettingParameterError(responseText);
225
259
  }
226
- return true;
227
260
  }
228
- async getGuardTourList(proxy = null) {
261
+ async getGuardTourList(options) {
229
262
  const gTourList = new Array();
230
- const response = await this.getParameter('GuardTour', proxy);
263
+ const response = await this.getParameter('GuardTour', options);
231
264
  for (let i = 0; i < 20; i++) {
232
- const gTourBaseName = 'root.GuardTour.G' + i;
265
+ const gTourBaseName = 'GuardTour.G' + i;
233
266
  if (gTourBaseName + '.CamNbr' in response) {
234
267
  const gTour = {
235
268
  id: gTourBaseName,
@@ -241,7 +274,7 @@ class VapixAPI {
241
274
  tour: [],
242
275
  };
243
276
  for (let j = 0; j < 100; j++) {
244
- const tourBaseName = 'root.GuardTour.G' + i + '.Tour.T' + j;
277
+ const tourBaseName = 'GuardTour.G' + i + '.Tour.T' + j;
245
278
  if (tourBaseName + '.MoveSpeed' in response) {
246
279
  const tour = {
247
280
  moveSpeed: response[tourBaseName + '.MoveSpeed'],
@@ -259,18 +292,18 @@ class VapixAPI {
259
292
  break;
260
293
  }
261
294
  }
262
- return gTourList;
295
+ return VapixAPI_1.guardTourSchema.parse(gTourList);
263
296
  }
264
- setGuardTourEnabled(guardTourID, enable, proxy = null) {
265
- const options = {};
266
- options[guardTourID + '.Running'] = enable ? 'yes' : 'no';
267
- return this.setParameter(options, proxy);
297
+ setGuardTourEnabled(guardTourId, enable, options) {
298
+ const params = {};
299
+ params[guardTourId + '.Running'] = enable ? 'yes' : 'no';
300
+ return this.setParameter(params, options);
268
301
  }
269
- async getPTZPresetList(channel, proxy = null) {
270
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
302
+ async getPTZPresetList(channel, options) {
303
+ const res = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
271
304
  query: 'presetposcam',
272
- camera: channel.toString(),
273
- });
305
+ camera: channel,
306
+ }, undefined, options);
274
307
  const text = await res.text();
275
308
  const lines = text.split(/[\r\n]/);
276
309
  const positions = [];
@@ -283,180 +316,237 @@ class VapixAPI {
283
316
  }
284
317
  }
285
318
  }
286
- return positions;
319
+ return zod_1.z.array(zod_1.z.string()).parse(positions);
287
320
  }
288
- async listPTZ(camera, proxy = null) {
321
+ async listPTZ(camera, options) {
289
322
  const url = `/axis-cgi/com/ptz.cgi`;
290
- const response = await this.getUrlEncoded(proxy, url, {
323
+ const response = await this.postUrlEncoded(url, {
291
324
  camera,
292
325
  query: 'presetposcamdata',
293
326
  format: 'json',
294
- });
295
- return parseCameraPtzResponse(await response.text())[camera] ?? [];
327
+ }, undefined, options);
328
+ const text = await response.text();
329
+ if (text === '') {
330
+ throw new errors_1.PtzNotSupportedError();
331
+ }
332
+ return VapixAPI.parseCameraPtzResponse(text)[camera] ?? [];
296
333
  }
297
- async listPtzVideoSourceOverview(proxy = null) {
298
- const response = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
334
+ async listPtzVideoSourceOverview(options) {
335
+ const response = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
299
336
  query: 'presetposall',
300
337
  format: 'json',
301
- });
302
- const data = parseCameraPtzResponse(await response.text());
338
+ }, undefined, options);
339
+ const text = await response.text();
340
+ if (text === '') {
341
+ throw new errors_1.PtzNotSupportedError();
342
+ }
343
+ const data = VapixAPI.parseCameraPtzResponse(text);
303
344
  const res = {};
304
345
  Object.keys(data)
305
346
  .map(Number)
306
347
  .forEach((camera) => {
307
- if (data[camera] !== undefined) {
308
- res[camera - 1] = data[camera]?.map(({ data: itemData, ...d }) => d);
348
+ const item = data[camera];
349
+ if (item !== undefined) {
350
+ res[camera - 1] = item.map(({ data: itemData, ...d }) => d);
309
351
  }
310
352
  });
311
- return res;
353
+ return VapixAPI_1.ptzOverviewSchema.parse(res);
312
354
  }
313
- goToPreset(channel, presetName, proxy = null) {
314
- return this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
355
+ goToPreset(channel, presetName, options) {
356
+ return this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
315
357
  camera: channel.toString(),
316
358
  gotoserverpresetname: presetName,
317
- });
359
+ }, undefined, options);
318
360
  }
319
- async getPtzPosition(camera, proxy = null) {
320
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
361
+ async getPtzPosition(camera, options) {
362
+ const res = await this.postUrlEncoded('/axis-cgi/com/ptz.cgi', {
321
363
  query: 'position',
322
364
  camera: camera.toString(),
323
- });
324
- const params = parseParameters(await res.text());
325
- return {
365
+ }, undefined, options);
366
+ const params = VapixAPI.parseParameters(await res.text());
367
+ return VapixAPI_1.cameraPTZItemDataSchema.parse({
326
368
  pan: Number(params.pan),
327
369
  tilt: Number(params.tilt),
328
370
  zoom: Number(params.zoom),
329
- };
330
- }
331
- async getInputState(port, proxy = null) {
332
- const response = await (await this.getUrlEncoded(proxy, '/axis-cgi/io/port.cgi', { checkactive: port.toString() })).text();
333
- return response.split('=')[1]?.indexOf('active') === 0;
334
- }
335
- async setOutputState(port, active, proxy = null) {
336
- return this.getUrlEncoded(proxy, '/axis-cgi/io/port.cgi', { action: active ? `${port}:/` : `${port}:\\` });
371
+ });
337
372
  }
338
- async getApplicationList(proxy = null) {
339
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/list.cgi');
373
+ async getPorts(options) {
374
+ const res = await this.postJson('/axis-cgi/io/portmanagement.cgi', {
375
+ apiVersion: '1.0',
376
+ context: '',
377
+ method: 'getPorts',
378
+ }, undefined, options);
379
+ const portResponseParsed = VapixAPI_1.getPortsResponseSchema.parse(await res.json());
380
+ return portResponseParsed.data.items;
381
+ }
382
+ async setPorts(ports, options) {
383
+ await this.postJson('/axis-cgi/io/portmanagement.cgi', {
384
+ apiVersion: '1.0',
385
+ context: '',
386
+ method: 'setPorts',
387
+ params: { ports },
388
+ }, undefined, options);
389
+ }
390
+ async setPortStateSequence(port, sequence, options) {
391
+ await this.postJson('/axis-cgi/io/portmanagement.cgi', {
392
+ apiVersion: '1.0',
393
+ context: '',
394
+ method: 'setStateSequence',
395
+ params: { port, sequence },
396
+ }, undefined, options);
397
+ }
398
+ async getApplicationList(options) {
399
+ const agent = this.getClient(options?.proxyParams);
400
+ const res = await agent.get({ path: '/axis-cgi/applications/list.cgi', timeout: options?.timeout });
340
401
  const xml = await res.text();
341
- const result = (await (0, xml2js_1.parseStringPromise)(xml));
342
- const apps = [];
343
- for (const app of result.reply.application) {
344
- apps.push({
345
- ...app.$,
346
- appId: VapixAPI_1.APP_IDS.find((id) => id.toLowerCase() === app.$.Name.toLowerCase()) ?? null,
347
- });
402
+ const parser = new fast_xml_parser_1.XMLParser({
403
+ ignoreAttributes: false,
404
+ attributeNamePrefix: '',
405
+ allowBooleanAttributes: true,
406
+ });
407
+ const result = parser.parse(xml);
408
+ let apps = result.reply.application ?? [];
409
+ if (!Array.isArray(apps)) {
410
+ apps = [apps];
348
411
  }
349
- return apps;
350
- }
351
- async startApplication(applicationID, proxy = null) {
352
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/control.cgi', {
353
- package: applicationID.toLowerCase(),
354
- action: 'start',
412
+ const appList = apps.map((app) => {
413
+ return {
414
+ ...app,
415
+ appId: VapixAPI_1.APP_IDS.find((id) => id.toLowerCase() === app.Name.toLowerCase()) ?? null,
416
+ };
417
+ });
418
+ return VapixAPI_1.applicationListSchema.parse(appList);
419
+ }
420
+ async startApplication(applicationId, options) {
421
+ const agent = this.getClient(options?.proxyParams);
422
+ const res = await agent.get({
423
+ path: '/axis-cgi/applications/control.cgi',
424
+ parameters: {
425
+ package: applicationId.toLowerCase(),
426
+ action: 'start',
427
+ },
428
+ timeout: options?.timeout,
355
429
  });
356
430
  const text = (await res.text()).trim().toLowerCase();
357
431
  if (text !== 'ok' && !(text.startsWith('error:') && text.substring(7) === '6')) {
358
- throw new errors_1.ApplicationAPIError('START', await (0, common_1.responseStringify)(res));
432
+ throw new errors_1.ApplicationAPIError('START', await (0, utils_1.responseStringify)(res));
359
433
  }
360
434
  }
361
- async restartApplication(applicationID, proxy = null) {
362
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/control.cgi', {
363
- package: applicationID.toLowerCase(),
364
- action: 'restart',
435
+ async restartApplication(applicationId, options) {
436
+ const agent = this.getClient(options?.proxyParams);
437
+ const res = await agent.get({
438
+ path: '/axis-cgi/applications/control.cgi',
439
+ parameters: {
440
+ package: applicationId.toLowerCase(),
441
+ action: 'restart',
442
+ },
443
+ timeout: options?.timeout,
365
444
  });
366
445
  const text = (await res.text()).trim().toLowerCase();
367
446
  if (text !== 'ok') {
368
- throw new errors_1.ApplicationAPIError('RESTART', await (0, common_1.responseStringify)(res));
447
+ throw new errors_1.ApplicationAPIError('RESTART', await (0, utils_1.responseStringify)(res));
369
448
  }
370
449
  }
371
- async stopApplication(applicationID, proxy = null) {
372
- const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/control.cgi', {
373
- package: applicationID.toLowerCase(),
374
- action: 'stop',
450
+ async stopApplication(applicationId, options) {
451
+ const agent = this.getClient(options?.proxyParams);
452
+ const res = await agent.get({
453
+ path: '/axis-cgi/applications/control.cgi',
454
+ parameters: {
455
+ package: applicationId.toLowerCase(),
456
+ action: 'stop',
457
+ },
458
+ timeout: options?.timeout,
375
459
  });
376
460
  const text = (await res.text()).trim().toLowerCase();
377
461
  if (text !== 'ok' && !(text.startsWith('error:') && text.substring(7) === '6')) {
378
- throw new errors_1.ApplicationAPIError('STOP', await (0, common_1.responseStringify)(res));
462
+ throw new errors_1.ApplicationAPIError('STOP', await (0, utils_1.responseStringify)(res));
379
463
  }
380
464
  }
381
- async installApplication(data, fileName) {
382
- const formData = new FormData();
465
+ async installApplication(data, fileName, options) {
466
+ const formData = new this.CustomFormData();
383
467
  formData.append('packfil', data, fileName);
384
- const res = await this.client.post(null, '/axis-cgi/applications/upload.cgi', formData, {}, {
385
- contentType: 'application/octet-stream',
468
+ const agent = this.getClient(options?.proxyParams);
469
+ const res = await agent.post({
470
+ path: '/axis-cgi/applications/upload.cgi',
471
+ data: formData,
472
+ headers: {
473
+ contentType: 'application/octet-stream',
474
+ },
475
+ timeout: options?.timeout ?? 120000,
386
476
  });
387
477
  if (!res.ok) {
388
- throw new Error(await (0, common_1.responseStringify)(res));
478
+ throw new Error(await (0, utils_1.responseStringify)(res));
389
479
  }
390
480
  const text = await res.text();
391
481
  if (text.length > 5) {
392
- throw new Error('installing error: ' + text);
393
- }
394
- }
395
- }
396
- exports.VapixAPI = VapixAPI;
397
- const parseParameters = (response) => {
398
- const params = {};
399
- const lines = response.split(/[\r\n]/);
400
- for (const line of lines) {
401
- if (line.length === 0 || line.substring(0, 7) === '# Error') {
402
- continue;
403
- }
404
- const delimiterPos = line.indexOf('=');
405
- if (delimiterPos !== -1) {
406
- const paramName = line.substring(0, delimiterPos);
407
- const paramValue = line.substring(delimiterPos + 1);
408
- params[paramName] = paramValue;
482
+ throw new errors_1.ApplicationAPIError('INSTALL', text);
409
483
  }
410
484
  }
411
- return params;
412
- };
413
- const parseCameraPtzResponse = (response) => {
414
- const json = JSON.parse(response);
415
- const parsed = {};
416
- Object.keys(json).forEach((key) => {
417
- if (!key.startsWith('Camera ')) {
418
- return;
419
- }
420
- const camera = Number(key.replace('Camera ', ''));
421
- if (json[key].presets !== undefined) {
422
- parsed[camera] = parsePtz(json[key].presets);
423
- }
424
- });
425
- return parsed;
426
- };
427
- const parsePtz = (parsed) => {
428
- const res = [];
429
- parsed.forEach((value) => {
430
- const delimiterPos = value.indexOf('=');
431
- if (delimiterPos === -1) {
432
- return;
433
- }
434
- if (!value.startsWith('presetposno')) {
435
- return;
436
- }
437
- const id = Number(value.substring(11, delimiterPos));
438
- if (Number.isNaN(id)) {
439
- return;
485
+ static parseParameters = (response) => {
486
+ const params = {};
487
+ const lines = response.split(/[\r\n]/);
488
+ for (const line of lines) {
489
+ if (line.length === 0 || line.substring(0, 7) === '# Error') {
490
+ continue;
491
+ }
492
+ const delimiterPos = line.indexOf('=');
493
+ if (delimiterPos !== -1) {
494
+ const paramName = line.substring(0, delimiterPos).replace('root.', '');
495
+ const paramValue = line.substring(delimiterPos + 1);
496
+ params[paramName] = paramValue;
497
+ }
440
498
  }
441
- const data = value.substring(delimiterPos + 1).split(':');
442
- const getValue = (valueName) => {
443
- for (const d of data) {
444
- const p = d.split('=');
445
- if (p[0] === valueName) {
446
- return Number(p[1]);
447
- }
499
+ return params;
500
+ };
501
+ static parseCameraPtzResponse = (response) => {
502
+ const json = JSON.parse(response);
503
+ const parsed = {};
504
+ Object.keys(json).forEach((key) => {
505
+ if (!key.startsWith('Camera ')) {
506
+ return;
507
+ }
508
+ const camera = Number(key.replace('Camera ', ''));
509
+ if (json[key].presets !== undefined) {
510
+ parsed[camera] = VapixAPI.parsePtz(json[key].presets);
448
511
  }
449
- return 0;
450
- };
451
- res.push({
452
- id,
453
- name: data[0] ?? 'Preset ' + id,
454
- data: {
455
- pan: getValue('pan'),
456
- tilt: getValue('tilt'),
457
- zoom: getValue('zoom'),
458
- },
459
512
  });
460
- });
461
- return res;
462
- };
513
+ return parsed;
514
+ };
515
+ static parsePtz = (parsed) => {
516
+ const res = [];
517
+ parsed.forEach((value) => {
518
+ const delimiterPos = value.indexOf('=');
519
+ if (delimiterPos === -1) {
520
+ return;
521
+ }
522
+ if (!value.startsWith('presetposno')) {
523
+ return;
524
+ }
525
+ const id = Number(value.substring(11, delimiterPos));
526
+ if (Number.isNaN(id)) {
527
+ return;
528
+ }
529
+ const data = value.substring(delimiterPos + 1).split(':');
530
+ const getValue = (valueName) => {
531
+ for (const d of data) {
532
+ const p = d.split('=');
533
+ if (p[0] === valueName) {
534
+ return Number(p[1]);
535
+ }
536
+ }
537
+ return 0;
538
+ };
539
+ res.push({
540
+ id,
541
+ name: data[0] ?? 'Preset ' + id,
542
+ data: {
543
+ pan: getValue('pan'),
544
+ tilt: getValue('tilt'),
545
+ zoom: getValue('zoom'),
546
+ },
547
+ });
548
+ });
549
+ return res;
550
+ };
551
+ }
552
+ exports.VapixAPI = VapixAPI;