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