camstreamerlib 4.0.0-beta.37 → 4.0.0-beta.39

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 (79) hide show
  1. package/README.md +38 -27
  2. package/cjs/CamOverlayAPI.js +42 -75
  3. package/cjs/CamScripterAPI.js +30 -24
  4. package/cjs/CamStreamerAPI.js +30 -33
  5. package/cjs/CamSwitcherAPI.js +57 -52
  6. package/cjs/PlaneTrackerAPI.js +55 -66
  7. package/cjs/VapixAPI.js +23 -22
  8. package/cjs/{CamOverlayDrawingAPI.js → node/CamOverlayDrawingAPI.js} +1 -1
  9. package/cjs/{CamOverlayPainter → node/CamOverlayPainter}/Painter.js +4 -14
  10. package/cjs/{CamScripterAPICameraEventsGenerator.js → node/CamScripterAPICameraEventsGenerator.js} +1 -1
  11. package/cjs/{VapixEvents.js → node/VapixEvents.js} +1 -1
  12. package/cjs/node/events/GenetecAgent.js +5 -27
  13. package/cjs/node/index.js +17 -0
  14. package/cjs/types/CamOverlayAPI/CamOverlayAPI.js +2 -2
  15. package/cjs/types/CamOverlayAPI/scoreBoardSchema.js +6 -1
  16. package/cjs/types/CamOverlayPainter.js +12 -0
  17. package/cjs/types/CamScripterAPICameraEventsGenerator.js +2 -0
  18. package/cjs/types/CamSwitcherAPI.js +38 -1
  19. package/cjs/types/GenetecAgent.js +31 -0
  20. package/cjs/types/PlaneTrackerAPI.js +277 -0
  21. package/cjs/types/VapixAPI.js +20 -2
  22. package/cjs/types/VapixEvents.js +2 -0
  23. package/esm/CamOverlayAPI.js +43 -76
  24. package/esm/CamScripterAPI.js +30 -24
  25. package/esm/CamStreamerAPI.js +30 -30
  26. package/esm/CamSwitcherAPI.js +58 -53
  27. package/esm/PlaneTrackerAPI.js +56 -67
  28. package/esm/VapixAPI.js +24 -23
  29. package/esm/{CamOverlayDrawingAPI.js → node/CamOverlayDrawingAPI.js} +1 -1
  30. package/esm/{CamOverlayPainter → node/CamOverlayPainter}/Painter.js +1 -11
  31. package/esm/{CamScripterAPICameraEventsGenerator.js → node/CamScripterAPICameraEventsGenerator.js} +1 -1
  32. package/esm/{VapixEvents.js → node/VapixEvents.js} +1 -1
  33. package/esm/node/events/GenetecAgent.js +1 -23
  34. package/esm/node/index.js +10 -0
  35. package/esm/types/CamOverlayAPI/CamOverlayAPI.js +1 -1
  36. package/esm/types/CamOverlayAPI/scoreBoardSchema.js +6 -1
  37. package/esm/types/CamOverlayPainter.js +11 -1
  38. package/esm/types/CamSwitcherAPI.js +38 -1
  39. package/esm/types/GenetecAgent.js +28 -0
  40. package/esm/types/PlaneTrackerAPI.js +276 -1
  41. package/esm/types/VapixAPI.js +19 -1
  42. package/esm/types/VapixEvents.js +1 -0
  43. package/package.json +1 -1
  44. package/types/CamOverlayAPI.d.ts +24 -14
  45. package/types/CamScripterAPI.d.ts +34 -9
  46. package/types/CamStreamerAPI.d.ts +27 -5
  47. package/types/CamSwitcherAPI.d.ts +136 -23
  48. package/types/PlaneTrackerAPI.d.ts +201 -20
  49. package/types/VapixAPI.d.ts +46 -12
  50. package/types/bin/CreatePackage.d.ts +1 -0
  51. package/types/{CamOverlayDrawingAPI.d.ts → node/CamOverlayDrawingAPI.d.ts} +1 -1
  52. package/types/{CamOverlayPainter → node/CamOverlayPainter}/Frame.d.ts +2 -2
  53. package/types/{CamOverlayPainter → node/CamOverlayPainter}/Painter.d.ts +2 -13
  54. package/types/{CamOverlayPainter → node/CamOverlayPainter}/ResourceManager.d.ts +1 -1
  55. package/types/node/CamScripterAPICameraEventsGenerator.d.ts +31 -0
  56. package/types/node/VapixEvents.d.ts +16 -0
  57. package/types/node/events/GenetecAgent.d.ts +1 -144
  58. package/types/node/index.d.ts +10 -0
  59. package/types/types/CamOverlayAPI/CamOverlayAPI.d.ts +38 -38
  60. package/types/types/CamOverlayAPI/scoreBoardSchema.d.ts +13 -13
  61. package/types/types/CamOverlayDrawingAPI.d.ts +3 -13
  62. package/types/types/CamOverlayPainter.d.ts +12 -10
  63. package/types/types/CamScripterAPICameraEventsGenerator.d.ts +45 -0
  64. package/types/types/CamStreamerAPI.d.ts +2 -2
  65. package/types/types/CamSwitcherAPI.d.ts +111 -30
  66. package/types/types/GenetecAgent.d.ts +174 -0
  67. package/types/types/PlaneTrackerAPI.d.ts +859 -0
  68. package/types/types/VapixAPI.d.ts +54 -8
  69. package/types/types/VapixEvents.d.ts +15 -0
  70. package/types/types/common.d.ts +1 -0
  71. package/types/CamScripterAPICameraEventsGenerator.d.ts +0 -74
  72. package/types/VapixEvents.d.ts +0 -43
  73. /package/cjs/{CreatePackage.js → bin/CreatePackage.js} +0 -0
  74. /package/cjs/{CamOverlayPainter → node/CamOverlayPainter}/Frame.js +0 -0
  75. /package/cjs/{CamOverlayPainter → node/CamOverlayPainter}/ResourceManager.js +0 -0
  76. /package/esm/{CreatePackage.js → bin/CreatePackage.js} +0 -0
  77. /package/esm/{CamOverlayPainter → node/CamOverlayPainter}/Frame.js +0 -0
  78. /package/esm/{CamOverlayPainter → node/CamOverlayPainter}/ResourceManager.js +0 -0
  79. /package/{types/CreatePackage.d.ts → esm/types/CamScripterAPICameraEventsGenerator.js} +0 -0
@@ -3,7 +3,7 @@ import { ParsingBlobError, ServiceNotFoundError } from './errors/errors';
3
3
  import { networkCameraListSchema } from './types/common';
4
4
  import { z } from 'zod';
5
5
  import { ProxyClient } from './internal/ProxyClient';
6
- import { fileListSchema, ImageType, storageDataListSchema, serviceListSchema, servicesSchema, WSResponseSchema, } from './types/CamOverlayAPI';
6
+ import { fileListSchema, ImageType, storageDataListSchema, serviceListSchema, servicesSchema, wsResponseSchema, } from './types/CamOverlayAPI';
7
7
  const BASE_PATH = '/local/camoverlay/api';
8
8
  export class CamOverlayAPI {
9
9
  client;
@@ -17,68 +17,51 @@ export class CamOverlayAPI {
17
17
  return proxyParams ? new ProxyClient(this.client, proxyParams) : this.client;
18
18
  }
19
19
  async checkCameraTime(options) {
20
- const response = await this._get({ path: `${BASE_PATH}/camera_time.cgi` }, options);
21
- return z.boolean().parse(response.state);
20
+ const res = await this._getJson(`${BASE_PATH}/camera_time.cgi`, undefined, options);
21
+ return z.boolean().parse(res.state);
22
22
  }
23
23
  async getNetworkCameraList(options) {
24
- const response = await this._get({ path: `${BASE_PATH}/network_camera_list.cgi` }, options);
25
- return networkCameraListSchema.parse(response.camera_list);
24
+ const res = await this._getJson(`${BASE_PATH}/network_camera_list.cgi`, undefined, options);
25
+ return networkCameraListSchema.parse(res.camera_list);
26
26
  }
27
27
  async wsAuthorization(options) {
28
- const response = await this._get({ path: `${BASE_PATH}/ws_authorization.cgi` }, options);
29
- return WSResponseSchema.parse(response).message;
28
+ const res = await this._getJson(`${BASE_PATH}/ws_authorization.cgi`, undefined, options);
29
+ return wsResponseSchema.parse(res).message;
30
30
  }
31
31
  async getMjpegStreamImage(mjpegUrl, options) {
32
- return await this._getBlob({
33
- path: `${BASE_PATH}/fetch_mjpeg_image.cgi?mjpeg_url=${encodeURIComponent(decodeURIComponent(mjpegUrl))}`,
34
- }, options);
32
+ return await this._getBlob(`${BASE_PATH}/fetch_mjpeg_image.cgi`, { mjpeg_url: decodeURIComponent(mjpegUrl) }, options);
35
33
  }
36
34
  async listFiles(fileType, options) {
37
- const files = await this._get({
38
- path: `${BASE_PATH}/upload_${fileType}.cgi`,
39
- parameters: {
40
- action: 'list',
41
- },
42
- }, options);
43
- return fileListSchema.parse(files.list);
35
+ const res = await this._getJson(`${BASE_PATH}/upload_${fileType}.cgi`, { action: 'list' }, options);
36
+ return fileListSchema.parse(res.list);
44
37
  }
45
38
  async uploadFile(fileType, formData, storage, options) {
46
- await this._post({
47
- path: `${BASE_PATH}/upload_${fileType}.cgi`,
48
- data: formData,
49
- parameters: {
50
- action: 'upload',
51
- storage: storage,
52
- },
39
+ await this._post(`${BASE_PATH}/upload_${fileType}.cgi`, formData, {
40
+ action: 'upload',
41
+ storage: storage,
53
42
  }, options);
54
43
  }
55
44
  async removeFile(fileType, fileParams, options) {
56
- const path = `${BASE_PATH}/upload_${fileType}.cgi`;
57
- await this._postUrlEncoded(path, {
45
+ await this._postUrlEncoded(`${BASE_PATH}/upload_${fileType}.cgi`, {
58
46
  action: 'remove',
59
47
  ...fileParams,
60
- }, undefined, options);
48
+ }, options, undefined);
61
49
  }
62
50
  async getFileStorage(fileType, options) {
63
- const data = await this._get({
64
- path: `${BASE_PATH}/upload_${fileType}.cgi`,
65
- parameters: {
66
- action: 'get_storage',
67
- },
68
- }, options);
69
- if (data.code !== 200) {
51
+ const res = await this._getJson(`${BASE_PATH}/upload_${fileType}.cgi`, { action: 'get_storage' }, options);
52
+ if (res.code !== 200) {
70
53
  throw new Error('Error occured while fetching file storage data');
71
54
  }
72
- return storageDataListSchema.parse(data.list);
55
+ return storageDataListSchema.parse(res.list);
73
56
  }
74
57
  async getFilePreviewFromCamera(path, options) {
75
- return await this._getBlob({ path: CamOverlayAPI.getFilePreviewPath(path) }, options);
58
+ return await this._getBlob(CamOverlayAPI.getFilePreviewPath(path), undefined, options);
76
59
  }
77
60
  async updateInfoticker(serviceId, text, options) {
78
- await this._get({ path: `${BASE_PATH}/infoticker.cgi?service_id=${serviceId}&text=${text}` }, options);
61
+ await this._getJson(`${BASE_PATH}/infoticker.cgi`, { service_id: serviceId, text: text }, options);
79
62
  }
80
63
  async setEnabled(serviceId, enabled, options) {
81
- await this._post({ path: `${BASE_PATH}/enabled.cgi?id_${serviceId}=${enabled ? 1 : 0}`, data: '' }, options);
64
+ await this._post(`${BASE_PATH}/enabled.cgi`, '', { [`id_${serviceId}`]: enabled ? 1 : 0 }, options);
82
65
  }
83
66
  async isEnabled(serviceId, options) {
84
67
  const agent = this.getClient(options?.proxyParams);
@@ -97,43 +80,27 @@ export class CamOverlayAPI {
97
80
  }
98
81
  }
99
82
  async getSingleService(serviceId, options) {
100
- const data = await this._get({
101
- path: `${BASE_PATH}/services.cgi`,
102
- parameters: {
103
- action: 'get',
104
- service_id: serviceId.toString(),
105
- },
83
+ const res = await this._getJson(`${BASE_PATH}/services.cgi`, {
84
+ action: 'get',
85
+ service_id: serviceId,
106
86
  }, options);
107
- return servicesSchema.parse(data);
87
+ return servicesSchema.parse(res);
108
88
  }
109
89
  async getServices(options) {
110
- const serviceList = await this._get({
111
- path: `${BASE_PATH}/services.cgi`,
112
- parameters: {
113
- action: 'get',
114
- },
115
- }, options);
116
- const services = serviceListSchema.parse(serviceList).services;
117
- services.forEach((service) => {
118
- const parsedService = servicesSchema.safeParse(service);
119
- if (!parsedService.success) {
120
- console.warn(`[SERVICE SCHEMA MISMATCH]: Service ${service.name} (${service.id}) does not match the current schema, or is a hidden service.`);
121
- }
122
- });
90
+ const res = await this._getJson(`${BASE_PATH}/services.cgi`, { action: 'get' }, options);
91
+ const services = serviceListSchema.parse(res).services;
123
92
  return services;
124
93
  }
125
94
  async updateSingleService(service, options) {
126
- const path = `${BASE_PATH}/services.cgi`;
127
- await this._postJsonEncoded(path, JSON.stringify(service), {
95
+ await this._postJsonEncoded(`${BASE_PATH}/services.cgi`, JSON.stringify(service), {
128
96
  action: 'set',
129
- service_id: service.id.toString(),
130
- }, undefined, options);
97
+ service_id: service.id,
98
+ }, options, undefined);
131
99
  }
132
100
  async updateServices(services, options) {
133
- const path = `${BASE_PATH}/services.cgi`;
134
- await this._postJsonEncoded(path, JSON.stringify({ services: services }), {
101
+ await this._postJsonEncoded(`${BASE_PATH}/services.cgi`, JSON.stringify({ services: services }), {
135
102
  action: 'set',
136
- }, undefined, options);
103
+ }, options, undefined);
137
104
  }
138
105
  updateCGText(serviceId, fields, options) {
139
106
  const params = {};
@@ -194,9 +161,9 @@ export class CamOverlayAPI {
194
161
  throw new Error(await responseStringify(res));
195
162
  }
196
163
  }
197
- async _get(params, options) {
164
+ async _getJson(path, parameters, options) {
198
165
  const agent = this.getClient(options?.proxyParams);
199
- const res = await agent.get({ ...params, timeout: options?.timeout });
166
+ const res = await agent.get({ path, parameters, timeout: options?.timeout });
200
167
  if (res.ok) {
201
168
  return await res.json();
202
169
  }
@@ -204,9 +171,9 @@ export class CamOverlayAPI {
204
171
  throw new Error(await responseStringify(res));
205
172
  }
206
173
  }
207
- async _post(params, options) {
174
+ async _post(path, data, parameters, options, headers) {
208
175
  const agent = this.getClient(options?.proxyParams);
209
- const res = await agent.post({ ...params, timeout: options?.timeout });
176
+ const res = await agent.post({ path, data, parameters, headers, timeout: options?.timeout });
210
177
  if (res.ok) {
211
178
  return await res.json();
212
179
  }
@@ -214,9 +181,9 @@ export class CamOverlayAPI {
214
181
  throw new Error(await responseStringify(res));
215
182
  }
216
183
  }
217
- async _getBlob(params, options) {
184
+ async _getBlob(path, parameters, options) {
218
185
  const agent = this.getClient(options?.proxyParams);
219
- const res = await agent.get({ ...params, timeout: options?.timeout });
186
+ const res = await agent.get({ path, parameters, timeout: options?.timeout });
220
187
  if (res.ok) {
221
188
  return await this.parseBlobResponse(res);
222
189
  }
@@ -232,13 +199,13 @@ export class CamOverlayAPI {
232
199
  throw new ParsingBlobError(err);
233
200
  }
234
201
  }
235
- async _postUrlEncoded(path, params, headers, options) {
236
- const data = paramToUrl(params);
202
+ async _postUrlEncoded(path, parameters, options, headers) {
203
+ const data = paramToUrl(parameters);
237
204
  const baseHeaders = { 'Content-Type': 'application/x-www-form-urlencoded' };
238
- return this._post({ path, data, headers: { ...baseHeaders, ...headers } }, options);
205
+ return this._post(path, data, undefined, options, { ...baseHeaders, ...headers });
239
206
  }
240
- async _postJsonEncoded(path, data, parameters, headers, options) {
207
+ async _postJsonEncoded(path, data, parameters, options, headers) {
241
208
  const baseHeaders = { 'Accept': 'application/json', 'Content-Type': 'application/json' };
242
- return this._post({ path, data, parameters, headers: { ...baseHeaders, ...headers } }, options);
209
+ return this._post(path, data, parameters, options, { ...baseHeaders, ...headers });
243
210
  }
244
211
  }
@@ -8,51 +8,57 @@ export class CamScripterAPI {
8
8
  constructor(client) {
9
9
  this.client = client;
10
10
  }
11
- static getProxyUrlPath = () => `${BASE_PATH}/proxy.cgi`;
11
+ static getProxyPath = () => `${BASE_PATH}/proxy.cgi`;
12
12
  getClient(proxyParams) {
13
13
  return proxyParams ? new ProxyClient(this.client, proxyParams) : this.client;
14
14
  }
15
15
  async checkCameraTime(options) {
16
- const data = await this.get(`${BASE_PATH}/camera_time.cgi`, undefined, options);
17
- return cameraTimeResponseSchema.parse(data).state;
16
+ const res = await this._getJson(`${BASE_PATH}/camera_time.cgi`, undefined, options);
17
+ return cameraTimeResponseSchema.parse(res).state;
18
18
  }
19
19
  async getNetworkCameraList(options) {
20
- const data = await this.get(`${BASE_PATH}/network_camera_list.cgi`, undefined, options);
21
- return networkCameraListSchema.parse(data.camera_list);
20
+ const res = await this._getJson(`${BASE_PATH}/network_camera_list.cgi`, undefined, options);
21
+ return networkCameraListSchema.parse(res.camera_list);
22
22
  }
23
23
  async getStorageInfo(options) {
24
- const data = await this.get(`${BASE_PATH}/package/get_storage.cgi`, undefined, options);
25
- return storageSchema.parse(data);
24
+ const res = await this._getJson(`${BASE_PATH}/package/get_storage.cgi`, undefined, options);
25
+ return storageSchema.parse(res);
26
26
  }
27
27
  async getPackageList(options) {
28
- const data = await this.get(`${BASE_PATH}/package/list.cgi`, undefined, options);
29
- return packageInfoListSchema.parse(data);
28
+ const res = await this._getJson(`${BASE_PATH}/package/list.cgi`, undefined, options);
29
+ return packageInfoListSchema.parse(res);
30
30
  }
31
31
  async installPackages(formData, storage, options) {
32
- const data = await this.post(`${BASE_PATH}/package/install.cgi?storage=${storage}`, formData, undefined, options);
33
- return camscripterApiResponseSchema.parse(data);
32
+ const res = await this._post(`${BASE_PATH}/package/install.cgi`, formData, { storage: storage }, options);
33
+ return camscripterApiResponseSchema.parse(res);
34
34
  }
35
35
  async uninstallPackage(packageId, options) {
36
- const data = await this.get(`${BASE_PATH}/package/remove.cgi?package_name=${packageId}`, undefined, options);
37
- return camscripterApiResponseSchema.parse(data);
36
+ const res = await this._getJson(`${BASE_PATH}/package/remove.cgi`, { package_name: packageId }, options);
37
+ return camscripterApiResponseSchema.parse(res);
38
38
  }
39
39
  async importSettings(packageId, formData, options) {
40
- const data = await this.post(`${BASE_PATH}/package/data.cgi?action=IMPORT&package_name=${packageId}`, formData, undefined, options);
41
- return camscripterApiResponseSchema.parse(data);
40
+ const res = await this._post(`${BASE_PATH}/package/data.cgi`, formData, {
41
+ action: 'IMPORT',
42
+ package_name: packageId,
43
+ }, options);
44
+ return camscripterApiResponseSchema.parse(res);
42
45
  }
43
46
  async exportSettings(packageId, formData, options) {
44
- const data = await this.post(`${BASE_PATH}/package/data.cgi?action=EXPORT&package_name=${packageId}`, formData, undefined, options);
45
- return camscripterApiResponseSchema.parse(data);
47
+ const res = await this._post(`${BASE_PATH}/package/data.cgi`, formData, {
48
+ action: 'EXPORT',
49
+ package_name: packageId,
50
+ }, options);
51
+ return camscripterApiResponseSchema.parse(res);
46
52
  }
47
53
  async getNodejsStatus(options) {
48
- const data = await this.get(`${BASE_PATH}/diagnostics.cgi`, undefined, options);
49
- return nodeStateSchema.parse(data);
54
+ const res = await this._getJson(`${BASE_PATH}/diagnostics.cgi`, undefined, options);
55
+ return nodeStateSchema.parse(res);
50
56
  }
51
57
  async installNodejs(storage, options) {
52
- const data = await this.get(`${BASE_PATH}/node_update.cgi?storage=${storage}`, undefined, options);
53
- return camscripterApiResponseSchema.parse(data);
58
+ const res = await this._getJson(`${BASE_PATH}/node_update.cgi`, { storage: storage }, options);
59
+ return camscripterApiResponseSchema.parse(res);
54
60
  }
55
- async get(path, parameters, options) {
61
+ async _getJson(path, parameters, options) {
56
62
  const agent = this.getClient(options?.proxyParams);
57
63
  const res = await agent.get({ path, parameters, timeout: options?.timeout });
58
64
  if (res.ok) {
@@ -62,9 +68,9 @@ export class CamScripterAPI {
62
68
  throw new Error(await responseStringify(res));
63
69
  }
64
70
  }
65
- async post(path, data, parameters, options) {
71
+ async _post(path, data, parameters, options, headers) {
66
72
  const agent = this.getClient(options?.proxyParams);
67
- const res = await agent.post({ path, data, parameters, timeout: options?.timeout });
73
+ const res = await agent.post({ path, data, parameters, headers, timeout: options?.timeout });
68
74
  if (res.ok) {
69
75
  return await res.json();
70
76
  }
@@ -1,4 +1,4 @@
1
- import z from 'zod';
1
+ import { z } from 'zod';
2
2
  import { ProxyClient } from './internal/ProxyClient';
3
3
  import { responseStringify } from './internal/utils';
4
4
  import { cameraStreamSchema } from './types/CamStreamerAPI';
@@ -11,28 +11,42 @@ export class CamStreamerAPI {
11
11
  getClient(proxyParams) {
12
12
  return proxyParams ? new ProxyClient(this.client, proxyParams) : this.client;
13
13
  }
14
+ async wsAuthorization(options) {
15
+ const res = await this._getJson(`${BASE_PATH}/ws_authorization.cgi`, undefined, options);
16
+ if (res.status !== 200) {
17
+ throw new Error(`Server error on ws authorization: ${res.message}`);
18
+ }
19
+ return z.string().parse(res.data);
20
+ }
21
+ async getUtcTime(options) {
22
+ const res = await this._getJson(`${BASE_PATH}/get_utc_time.cgi`, undefined, options);
23
+ if (res.status !== 200) {
24
+ throw new Error(`Server error on get UTC time: ${res.message}`);
25
+ }
26
+ return z.number().parse(res.data);
27
+ }
14
28
  async getStreamList(options) {
15
- const streamListRes = await this.get(`${BASE_PATH}/stream/list.cgi`, undefined, options);
16
- const list = z.record(z.string(), cameraStreamSchema).parse(streamListRes.data);
17
- const res = {};
29
+ const res = await this._getJson(`${BASE_PATH}/stream/list.cgi`, undefined, options);
30
+ const list = z.record(z.string(), cameraStreamSchema).parse(res.data);
31
+ const streamList = {};
18
32
  for (const [key, data] of Object.entries(list)) {
19
33
  const streamId = parseInt(key);
20
- res[streamId] = parseCameraStreamResponse(data);
34
+ streamList[streamId] = parseCameraStreamResponse(data);
21
35
  }
22
- return res;
36
+ return streamList;
23
37
  }
24
38
  async getStream(streamId, options) {
25
- const stream = await this.get(`${BASE_PATH}/stream/get.cgi?stream_id=${streamId}`, undefined, options);
26
- const cameraData = cameraStreamSchema.parse(stream.data);
39
+ const res = await this._getJson(`${BASE_PATH}/stream/get.cgi`, { stream_id: streamId }, options);
40
+ const cameraData = cameraStreamSchema.parse(res.data);
27
41
  return parseCameraStreamResponse(cameraData);
28
42
  }
29
43
  async getStreamParameter(streamId, paramName, options) {
30
- const stream = await this.get(`${BASE_PATH}/stream/get.cgi?stream_id=${streamId}`, undefined, options);
31
- return stream.data[paramName];
44
+ const res = await this._getJson(`${BASE_PATH}/stream/get.cgi`, { stream_id: streamId }, options);
45
+ return z.string().parse(res.data[paramName]);
32
46
  }
33
47
  async setStream(streamId, params, options) {
34
48
  const { streamDelay, startTime, stopTime, ...rest } = params;
35
- return await this.get(`${BASE_PATH}/stream/set.cgi`, {
49
+ return await this._getJson(`${BASE_PATH}/stream/set.cgi`, {
36
50
  stream_id: streamId,
37
51
  streamDelay: streamDelay ?? '',
38
52
  startTime: startTime ?? null,
@@ -41,31 +55,17 @@ export class CamStreamerAPI {
41
55
  }, options);
42
56
  }
43
57
  async setStreamParameter(streamId, paramName, value, options) {
44
- return await this.get(`${BASE_PATH}/stream/set.cgi?stream_id=${streamId}&${paramName}=${value}`, undefined, options);
58
+ return await this._getJson(`${BASE_PATH}/stream/set.cgi`, { stream_id: streamId, [paramName]: value }, options);
45
59
  }
46
60
  async isStreaming(streamId, options) {
47
- const response = await this.get(`${BASE_PATH}/get_streamstat.cgi?stream_id=${streamId}`, undefined, options);
48
- return response.data.is_streaming === 1;
61
+ const res = await this._getJson(`${BASE_PATH}/get_streamstat.cgi`, { stream_id: streamId }, options);
62
+ return res.data.is_streaming === 1;
49
63
  }
50
64
  async deleteStream(streamId, options) {
51
- const res = await this.get(`${BASE_PATH}/stream/remove.cgi`, { stream_id: streamId }, options);
65
+ const res = await this._getJson(`${BASE_PATH}/stream/remove.cgi`, { stream_id: streamId }, options);
52
66
  return res.data.status === 200;
53
67
  }
54
- async getWsAuthorization(options) {
55
- const res = await this.get(`${BASE_PATH}/ws_authorization.cgi`, undefined, options);
56
- if (res.status !== 200) {
57
- throw new Error(`Server error on ws authorization: ${res.message}`);
58
- }
59
- return res.data;
60
- }
61
- async getUtcTime(options) {
62
- const res = await this.get(`${BASE_PATH}/get_utc_time.cgi`, undefined, options);
63
- if (res.status !== 200) {
64
- throw new Error(`Server error on get UTC time: ${res.message}`);
65
- }
66
- return res.data;
67
- }
68
- async get(path, parameters, options) {
68
+ async _getJson(path, parameters, options) {
69
69
  const agent = this.getClient(options?.proxyParams);
70
70
  const res = await agent.get({ path, parameters, timeout: options?.timeout });
71
71
  if (res.ok) {
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { AddNewClipError } from './errors/errors';
3
3
  import { isClip, isNullish, responseStringify } from './internal/utils';
4
- import { storageInfoListSchema, outputInfoSchema, audioPushInfoSchema, clipListSchema, playlistQueueSchema, streamSaveLoadSchema, clipSaveLoadSchema, playlistSaveLoadSchema, trackerSaveLoadSchema, } from './types/CamSwitcherAPI';
4
+ import { storageInfoListSchema, outputInfoSchema, audioPushInfoSchema, clipListSchema, playlistQueueSchema, streamSaveLoadSchema, clipSaveLoadSchema, playlistSaveLoadSchema, trackerSaveLoadSchema, secondaryAudioSettingsSchema, globalAudioSettingsSchema, } from './types/CamSwitcherAPI';
5
5
  import { networkCameraListSchema, } from './types/common';
6
6
  import { VapixAPI } from './VapixAPI';
7
7
  import { isFirmwareVersionAtLeast } from './internal/versionCompare';
@@ -17,9 +17,9 @@ export class CamSwitcherAPI {
17
17
  this.CustomFormData = CustomFormData;
18
18
  this.vapixAgent = new VapixAPI(client);
19
19
  }
20
- static getProxyUrlPath = () => `${BASE_PATH}/proxy.cgi`;
21
- static getWsEventsUrlPath = () => `/local/camswitcher/events`;
22
- static getClipPreviewUrlPath = (id, storage) => `${BASE_PATH}/clip_preview.cgi?clip_name=${id}&storage=${storage}`;
20
+ static getProxyPath = () => `${BASE_PATH}/proxy.cgi`;
21
+ static getWsEventsPath = () => `/local/camswitcher/events`;
22
+ static getClipPreviewPath = (id, storage) => `${BASE_PATH}/clip_preview.cgi?clip_name=${id}&storage=${storage}`;
23
23
  getClient(proxyParams) {
24
24
  return proxyParams ? new ProxyClient(this.client, proxyParams) : this.client;
25
25
  }
@@ -35,98 +35,105 @@ export class CamSwitcherAPI {
35
35
  });
36
36
  }
37
37
  async checkCameraTime(options) {
38
- const data = await this.get(`${BASE_PATH}/camera_time.cgi`, undefined, options);
39
- return z.boolean().parse(data);
38
+ const res = await this._getJson(`${BASE_PATH}/camera_time.cgi`, undefined, options);
39
+ return z.boolean().parse(res.data);
40
40
  }
41
41
  async getNetworkCameraList(options) {
42
- const data = await this.get(`${BASE_PATH}/network_camera_list.cgi`, undefined, options);
43
- return networkCameraListSchema.parse(data);
42
+ const res = await this._getJson(`${BASE_PATH}/network_camera_list.cgi`, undefined, options);
43
+ return networkCameraListSchema.parse(res.data);
44
44
  }
45
45
  async getMaxFps(source, options) {
46
- const data = await this.get(`${BASE_PATH}/get_max_framerate.cgi`, {
47
- video_source: source.toString(),
46
+ const res = await this._getJson(`${BASE_PATH}/get_max_framerate.cgi`, {
47
+ video_source: source,
48
48
  }, options);
49
- return z.number().parse(data);
49
+ return z.number().parse(res.data);
50
50
  }
51
51
  async getStorageInfo(options) {
52
- const data = await this.get(`${BASE_PATH}/get_storage.cgi`, undefined, options);
53
- return storageInfoListSchema.parse(data);
52
+ const res = await this._getJson(`${BASE_PATH}/get_storage.cgi`, undefined, options);
53
+ return storageInfoListSchema.parse(res.data);
54
54
  }
55
55
  async wsAuthorization(options) {
56
- const data = await this.get(`${BASE_PATH}/ws_authorization.cgi`, undefined, options);
57
- return z.string().parse(data);
56
+ const res = await this._getJson(`${BASE_PATH}/ws_authorization.cgi`, undefined, options);
57
+ return z.string().parse(res.data);
58
58
  }
59
59
  async getOutputInfo(options) {
60
- const data = await this.get(`${BASE_PATH}/output_info.cgi`, undefined, options);
61
- return outputInfoSchema.parse(data);
60
+ const res = await this._getJson(`${BASE_PATH}/output_info.cgi`, undefined, options);
61
+ return outputInfoSchema.parse(res.data);
62
62
  }
63
63
  async getAudioPushInfo(options) {
64
- const data = await this.get(`${BASE_PATH}/audio_push_info.cgi`, undefined, options);
65
- return audioPushInfoSchema.parse(data);
64
+ const res = await this._getJson(`${BASE_PATH}/audio_push_info.cgi`, undefined, options);
65
+ return audioPushInfoSchema.parse(res.data);
66
66
  }
67
67
  async getStreamSaveList(options) {
68
- const data = await this.get(`${BASE_PATH}/streams.cgi`, { action: 'get' }, options);
69
- return streamSaveLoadSchema.parse(data);
68
+ const res = await this._getJson(`${BASE_PATH}/streams.cgi`, { action: 'get' }, options);
69
+ return streamSaveLoadSchema.parse(res.data);
70
70
  }
71
71
  async getClipSaveList(options) {
72
- const data = await this.get(`${BASE_PATH}/clips.cgi`, { action: 'get' }, options);
73
- return clipSaveLoadSchema.parse(data);
72
+ const res = await this._getJson(`${BASE_PATH}/clips.cgi`, { action: 'get' }, options);
73
+ return clipSaveLoadSchema.parse(res.data);
74
74
  }
75
75
  async getPlaylistSaveList(options) {
76
- const data = await this.get(`${BASE_PATH}/playlists.cgi`, { action: 'get' }, options);
77
- return playlistSaveLoadSchema.parse(data);
76
+ const res = await this._getJson(`${BASE_PATH}/playlists.cgi`, { action: 'get' }, options);
77
+ return playlistSaveLoadSchema.parse(res.data);
78
78
  }
79
79
  async getTrackerSaveList(options) {
80
- const data = await this.get(`${BASE_PATH}/trackers.cgi`, { action: 'get' }, options);
81
- return trackerSaveLoadSchema.parse(data);
80
+ const res = await this._getJson(`${BASE_PATH}/trackers.cgi`, { action: 'get' }, options);
81
+ return trackerSaveLoadSchema.parse(res.data);
82
82
  }
83
83
  async setStreamSaveList(data, options) {
84
- return await this.set(`${BASE_PATH}/streams.cgi`, data, { action: 'set' }, options);
84
+ return await this._post(`${BASE_PATH}/streams.cgi`, data, { action: 'set' }, options);
85
85
  }
86
86
  async setClipSaveList(data, options) {
87
- return await this.set(`${BASE_PATH}/clips.cgi`, data, { action: 'set' }, options);
87
+ return await this._post(`${BASE_PATH}/clips.cgi`, data, { action: 'set' }, options);
88
88
  }
89
89
  async setPlaylistSaveList(data, options) {
90
- return await this.set(`${BASE_PATH}/playlists.cgi`, data, { action: 'set' }, options);
90
+ return await this._post(`${BASE_PATH}/playlists.cgi`, data, { action: 'set' }, options);
91
91
  }
92
92
  async setTrackerSaveList(data, options) {
93
- return await this.set(`${BASE_PATH}/trackers.cgi`, data, { action: 'set' }, options);
93
+ return await this._post(`${BASE_PATH}/trackers.cgi`, data, { action: 'set' }, options);
94
94
  }
95
95
  async playlistSwitch(playlistName, options) {
96
- await this.get(`${BASE_PATH}/playlist_switch.cgi`, { playlist_name: playlistName }, options);
96
+ await this._getJson(`${BASE_PATH}/playlist_switch.cgi`, { playlist_name: playlistName }, options);
97
97
  }
98
98
  async playlistQueuePush(playlistName, options) {
99
- await this.get(`${BASE_PATH}/playlist_queue_push.cgi`, { playlist_name: playlistName }, options);
99
+ await this._getJson(`${BASE_PATH}/playlist_queue_push.cgi`, { playlist_name: playlistName }, options);
100
100
  }
101
101
  async playlistQueueClear(options) {
102
- await this.get(`${BASE_PATH}/playlist_queue_clear.cgi`, undefined, options);
102
+ await this._getJson(`${BASE_PATH}/playlist_queue_clear.cgi`, undefined, options);
103
103
  }
104
104
  async playlistQueueList(options) {
105
- const data = await this.get(`${BASE_PATH}/playlist_queue_list.cgi`, undefined, options);
106
- return playlistQueueSchema.parse(data).playlistQueueList;
105
+ const res = await this._getJson(`${BASE_PATH}/playlist_queue_list.cgi`, undefined, options);
106
+ return playlistQueueSchema.parse(res.data).playlistQueueList;
107
107
  }
108
108
  async playlistQueuePlayNext(options) {
109
- await this.get(`${BASE_PATH}/playlist_queue_play_next.cgi`, undefined, options);
109
+ await this._getJson(`${BASE_PATH}/playlist_queue_play_next.cgi`, undefined, options);
110
110
  }
111
111
  async addNewClip(file, clipType, storage, clipId, fileName, options) {
112
- const path = `${BASE_PATH}/clip_upload.cgi?storage=${storage}`;
112
+ const path = `${BASE_PATH}/clip_upload.cgi`;
113
113
  const formData = new this.CustomFormData();
114
114
  formData.append('clip_name', clipId);
115
115
  formData.append('clip_type', clipType);
116
116
  formData.append('file', file, fileName);
117
117
  const agent = this.getClient(options?.proxyParams);
118
- const res = await agent.post({ path, data: formData, timeout: options?.timeout });
118
+ const res = await agent.post({
119
+ path,
120
+ data: formData,
121
+ parameters: {
122
+ storage: storage,
123
+ },
124
+ timeout: options?.timeout,
125
+ });
119
126
  const output = (await res.json());
120
127
  if (output.status !== 200) {
121
128
  throw new AddNewClipError(output.message);
122
129
  }
123
130
  }
124
131
  removeClip(clipId, storage, options) {
125
- return this.get(`${BASE_PATH}/clip_remove.cgi`, { clip_name: clipId, storage }, options);
132
+ return this._getJson(`${BASE_PATH}/clip_remove.cgi`, { clip_name: clipId, storage }, options);
126
133
  }
127
134
  async getClipList(options) {
128
- const data = await this.get(`${BASE_PATH}/clip_list.cgi`, undefined, options);
129
- return clipListSchema.parse(data).clip_list;
135
+ const res = await this._getJson(`${BASE_PATH}/clip_list.cgi`, undefined, options);
136
+ return clipListSchema.parse(res.data).clip_list;
130
137
  }
131
138
  setCamSwitchOptions(data, cameraFWVersion, options) {
132
139
  const bitrateVapixParams = parseBitrateOptionsToBitrateVapixParams(cameraFWVersion, data.bitrateMode, data);
@@ -227,7 +234,7 @@ export class CamSwitcherAPI {
227
234
  settings.source = res.clip_name;
228
235
  settings.storage = res.storage;
229
236
  }
230
- return settings;
237
+ return globalAudioSettingsSchema.parse(settings);
231
238
  }
232
239
  async getSecondaryAudioSettings(options) {
233
240
  const res = await this.getParamFromCameraAndJSONParse(CSW_PARAM_NAMES.SECONDARY_AUDIO, options);
@@ -239,30 +246,28 @@ export class CamSwitcherAPI {
239
246
  secondaryAudioLevel: res.secondary_audio_level ?? 1,
240
247
  masterAudioLevel: res.master_audio_level ?? 1,
241
248
  };
242
- return settings;
249
+ return secondaryAudioSettingsSchema.parse(settings);
243
250
  }
244
251
  async getPermanentRtspUrlToken(options) {
245
252
  const paramName = CSW_PARAM_NAMES.RTSP_TOKEN;
246
253
  const res = await this.vapixAgent.getParameter([paramName], options);
247
- return res[paramName] ?? '';
254
+ return z.string().parse(res[paramName] ?? '');
248
255
  }
249
- async get(path, parameters, options) {
256
+ async _getJson(path, parameters, options) {
250
257
  const agent = this.getClient(options?.proxyParams);
251
258
  const res = await agent.get({ path, parameters, timeout: options?.timeout });
252
259
  if (res.ok) {
253
- const d = await res.json();
254
- return d.data;
260
+ return await res.json();
255
261
  }
256
262
  else {
257
263
  throw new Error(await responseStringify(res));
258
264
  }
259
265
  }
260
- async set(path, data, parameters, options) {
266
+ async _post(path, data, parameters, options, headers) {
261
267
  const agent = this.getClient(options?.proxyParams);
262
- const res = await agent.post({ path, data: JSON.stringify(data), parameters, timeout: options?.timeout });
268
+ const res = await agent.post({ path, data, parameters, timeout: options?.timeout, headers });
263
269
  if (res.ok) {
264
- const parsed = await res.json();
265
- return parsed.message === 'OK';
270
+ return await res.json();
266
271
  }
267
272
  else {
268
273
  throw new Error(await responseStringify(res));
@@ -302,7 +307,7 @@ const parseBitrateOptionsToBitrateVapixParams = (firmWareVersion, bitrateMode, c
302
307
  if (!isFirmwareVersionAtLeast(firmWareVersion, FIRMWARE_WITH_BITRATE_MODES_SUPPORT)) {
303
308
  return `videomaxbitrate=${cameraOptions.maximumBitRate}`;
304
309
  }
305
- if (bitrateMode === null) {
310
+ if (bitrateMode === undefined) {
306
311
  return '';
307
312
  }
308
313
  const data = {