camstreamerlib 4.0.0-beta.2 → 4.0.0-beta.4
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/cjs/CamOverlayAPI.js +176 -0
- package/cjs/CamOverlayDrawingAPI.js +235 -0
- package/cjs/CamOverlayPainter/Frame.js +301 -0
- package/{CamOverlayPainter → cjs/CamOverlayPainter}/Painter.d.ts +14 -3
- package/cjs/CamOverlayPainter/Painter.js +171 -0
- package/cjs/CamOverlayPainter/ResourceManager.js +46 -0
- package/cjs/CamScripterAPI.js +70 -0
- package/cjs/CamScripterAPICameraEventsGenerator.js +162 -0
- package/cjs/CamStreamerAPI.js +65 -0
- package/{CamSwitcherAPI.d.ts → cjs/CamSwitcherAPI.d.ts} +3 -3
- package/cjs/CamSwitcherAPI.js +350 -0
- package/{CamSwitcherEvents.d.ts → cjs/CamSwitcherEvents.d.ts} +1 -1
- package/cjs/CamSwitcherEvents.js +67 -0
- package/cjs/CreatePackage.js +106 -0
- package/{VapixAPI.d.ts → cjs/VapixAPI.d.ts} +9 -9
- package/cjs/VapixAPI.js +462 -0
- package/cjs/VapixEvents.js +88 -0
- package/cjs/errors/errors.js +79 -0
- package/cjs/events/AxisCameraStationEvents.js +48 -0
- package/cjs/events/GenetecAgent.js +123 -0
- package/cjs/index.d.ts +11 -0
- package/cjs/index.js +31 -0
- package/cjs/internal/Digest.js +42 -0
- package/cjs/internal/ProxyClient.js +44 -0
- package/{internal → cjs/internal}/common.d.ts +0 -1
- package/cjs/internal/common.js +27 -0
- package/cjs/internal/constants.js +4 -0
- package/cjs/internal/transformers.js +32 -0
- package/cjs/internal/utils.js +46 -0
- package/cjs/internal/versionCompare.js +53 -0
- package/cjs/node/DefaultClient.js +54 -0
- package/cjs/node/HttpRequestSender.js +89 -0
- package/cjs/node/HttpServer.js +96 -0
- package/cjs/node/WsClient.js +149 -0
- package/cjs/node/WsEventClient.js +22 -0
- package/cjs/node/index.d.ts +2 -0
- package/cjs/node/index.js +7 -0
- package/cjs/types/CamOverlayAPI.js +47 -0
- package/cjs/types/CamScripterAPI.js +20 -0
- package/cjs/types/CamStreamerAPI.js +28 -0
- package/cjs/types/CamSwitcherAPI.js +137 -0
- package/cjs/types/CamSwitcherEvents.js +62 -0
- package/{types → cjs/types}/VapixAPI.d.ts +40 -61
- package/cjs/types/VapixAPI.js +130 -0
- package/cjs/types/common.js +14 -0
- package/cjs/web/DefaultClient.js +20 -0
- package/cjs/web/WsClient.js +62 -0
- package/cjs/web/index.d.ts +2 -0
- package/cjs/web/index.js +7 -0
- package/esm/CamOverlayAPI.d.ts +31 -0
- package/esm/CamOverlayDrawingAPI.d.ts +86 -0
- package/{CamOverlayDrawingAPI.js → esm/CamOverlayDrawingAPI.js} +6 -3
- package/esm/CamOverlayPainter/Frame.d.ts +96 -0
- package/esm/CamOverlayPainter/Painter.d.ts +48 -0
- package/{CamOverlayPainter → esm/CamOverlayPainter}/Painter.js +4 -1
- package/esm/CamOverlayPainter/ResourceManager.d.ts +14 -0
- package/{CamOverlayPainter → esm/CamOverlayPainter}/ResourceManager.js +6 -10
- package/esm/CamScripterAPI.d.ts +19 -0
- package/esm/CamScripterAPICameraEventsGenerator.d.ts +74 -0
- package/{CamScripterAPICameraEventsGenerator.js → esm/CamScripterAPICameraEventsGenerator.js} +6 -3
- package/esm/CamStreamerAPI.d.ts +16 -0
- package/esm/CamSwitcherAPI.d.ts +48 -0
- package/{CamSwitcherAPI.js → esm/CamSwitcherAPI.js} +19 -23
- package/esm/CamSwitcherEvents.d.ts +18 -0
- package/{CamSwitcherEvents.js → esm/CamSwitcherEvents.js} +1 -1
- package/esm/CreatePackage.d.ts +1 -0
- package/esm/VapixAPI.d.ts +66 -0
- package/{VapixAPI.js → esm/VapixAPI.js} +20 -16
- package/esm/VapixEvents.d.ts +43 -0
- package/{VapixEvents.js → esm/VapixEvents.js} +3 -3
- package/esm/errors/errors.d.ts +34 -0
- package/esm/events/AxisCameraStationEvents.d.ts +9 -0
- package/esm/events/GenetecAgent.d.ts +174 -0
- package/esm/index.d.ts +11 -0
- package/esm/index.js +11 -0
- package/esm/internal/Digest.d.ts +4 -0
- package/{internal → esm/internal}/Digest.js +6 -6
- package/esm/internal/ProxyClient.d.ts +11 -0
- package/esm/internal/common.d.ts +39 -0
- package/{internal → esm/internal}/common.js +0 -3
- package/esm/internal/constants.d.ts +1 -0
- package/esm/internal/transformers.d.ts +5 -0
- package/esm/internal/utils.d.ts +11 -0
- package/esm/internal/versionCompare.d.ts +6 -0
- package/esm/node/DefaultClient.d.ts +15 -0
- package/{node → esm/node}/DefaultClient.js +1 -1
- package/esm/node/HttpRequestSender.d.ts +28 -0
- package/esm/node/HttpServer.d.ts +21 -0
- package/{node → esm/node}/HttpServer.js +1 -1
- package/esm/node/WsClient.d.ts +39 -0
- package/esm/node/WsEventClient.d.ts +13 -0
- package/esm/node/index.d.ts +2 -0
- package/esm/node/index.js +2 -0
- package/esm/types/CamOverlayAPI.d.ts +188 -0
- package/esm/types/CamScripterAPI.d.ts +67 -0
- package/esm/types/CamStreamerAPI.d.ts +139 -0
- package/esm/types/CamSwitcherAPI.d.ts +814 -0
- package/esm/types/CamSwitcherEvents.d.ts +491 -0
- package/esm/types/VapixAPI.d.ts +1683 -0
- package/{types → esm/types}/VapixAPI.js +10 -12
- package/esm/types/common.d.ts +37 -0
- package/esm/web/DefaultClient.d.ts +6 -0
- package/esm/web/WsClient.d.ts +13 -0
- package/esm/web/index.d.ts +2 -0
- package/esm/web/index.js +2 -0
- package/package.json +6 -5
- package/README.md +0 -97
- /package/{CamOverlayAPI.d.ts → cjs/CamOverlayAPI.d.ts} +0 -0
- /package/{CamOverlayDrawingAPI.d.ts → cjs/CamOverlayDrawingAPI.d.ts} +0 -0
- /package/{CamOverlayPainter → cjs/CamOverlayPainter}/Frame.d.ts +0 -0
- /package/{CamOverlayPainter → cjs/CamOverlayPainter}/ResourceManager.d.ts +0 -0
- /package/{CamScripterAPI.d.ts → cjs/CamScripterAPI.d.ts} +0 -0
- /package/{CamScripterAPICameraEventsGenerator.d.ts → cjs/CamScripterAPICameraEventsGenerator.d.ts} +0 -0
- /package/{CamStreamerAPI.d.ts → cjs/CamStreamerAPI.d.ts} +0 -0
- /package/{CreatePackage.d.ts → cjs/CreatePackage.d.ts} +0 -0
- /package/{VapixEvents.d.ts → cjs/VapixEvents.d.ts} +0 -0
- /package/{errors → cjs/errors}/errors.d.ts +0 -0
- /package/{events → cjs/events}/AxisCameraStationEvents.d.ts +0 -0
- /package/{events → cjs/events}/GenetecAgent.d.ts +0 -0
- /package/{internal → cjs/internal}/Digest.d.ts +0 -0
- /package/{internal → cjs/internal}/ProxyClient.d.ts +0 -0
- /package/{internal → cjs/internal}/constants.d.ts +0 -0
- /package/{internal → cjs/internal}/transformers.d.ts +0 -0
- /package/{internal → cjs/internal}/utils.d.ts +0 -0
- /package/{internal → cjs/internal}/versionCompare.d.ts +0 -0
- /package/{node → cjs/node}/DefaultClient.d.ts +0 -0
- /package/{node → cjs/node}/HttpRequestSender.d.ts +0 -0
- /package/{node → cjs/node}/HttpServer.d.ts +0 -0
- /package/{node → cjs/node}/WsClient.d.ts +0 -0
- /package/{node → cjs/node}/WsEventClient.d.ts +0 -0
- /package/{types → cjs/types}/CamOverlayAPI.d.ts +0 -0
- /package/{types → cjs/types}/CamScripterAPI.d.ts +0 -0
- /package/{types → cjs/types}/CamStreamerAPI.d.ts +0 -0
- /package/{types → cjs/types}/CamSwitcherAPI.d.ts +0 -0
- /package/{types/CamswitcherEvents.d.ts → cjs/types/CamSwitcherEvents.d.ts} +0 -0
- /package/{types → cjs/types}/common.d.ts +0 -0
- /package/{web → cjs/web}/DefaultClient.d.ts +0 -0
- /package/{web → cjs/web}/WsClient.d.ts +0 -0
- /package/{CamOverlayAPI.js → esm/CamOverlayAPI.js} +0 -0
- /package/{CamOverlayPainter → esm/CamOverlayPainter}/Frame.js +0 -0
- /package/{CamScripterAPI.js → esm/CamScripterAPI.js} +0 -0
- /package/{CamStreamerAPI.js → esm/CamStreamerAPI.js} +0 -0
- /package/{CreatePackage.js → esm/CreatePackage.js} +0 -0
- /package/{errors → esm/errors}/errors.js +0 -0
- /package/{events → esm/events}/AxisCameraStationEvents.js +0 -0
- /package/{events → esm/events}/GenetecAgent.js +0 -0
- /package/{internal → esm/internal}/ProxyClient.js +0 -0
- /package/{internal → esm/internal}/constants.js +0 -0
- /package/{internal → esm/internal}/transformers.js +0 -0
- /package/{internal → esm/internal}/utils.js +0 -0
- /package/{internal → esm/internal}/versionCompare.js +0 -0
- /package/{node → esm/node}/HttpRequestSender.js +0 -0
- /package/{node → esm/node}/WsClient.js +0 -0
- /package/{node → esm/node}/WsEventClient.js +0 -0
- /package/{types → esm/types}/CamOverlayAPI.js +0 -0
- /package/{types → esm/types}/CamScripterAPI.js +0 -0
- /package/{types → esm/types}/CamStreamerAPI.js +0 -0
- /package/{types → esm/types}/CamSwitcherAPI.js +0 -0
- /package/{types/CamswitcherEvents.js → esm/types/CamSwitcherEvents.js} +0 -0
- /package/{types → esm/types}/common.js +0 -0
- /package/{web → esm/web}/DefaultClient.js +0 -0
- /package/{web → esm/web}/WsClient.js +0 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const AdmZip = require("adm-zip");
|
|
4
|
+
const Path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
const child_process_1 = require("child_process");
|
|
7
|
+
const productionModulesFolder = 'production_modules';
|
|
8
|
+
function isDirectory(path) {
|
|
9
|
+
const stat = fs.statSync(path);
|
|
10
|
+
return stat.isDirectory();
|
|
11
|
+
}
|
|
12
|
+
function getPackageInfo(folder) {
|
|
13
|
+
try {
|
|
14
|
+
const manifest = fs.readFileSync(Path.join(folder, 'manifest.json'));
|
|
15
|
+
const manifestParsed = JSON.parse(manifest.toString());
|
|
16
|
+
return {
|
|
17
|
+
packageName: manifestParsed.package_name,
|
|
18
|
+
packageVersion: manifestParsed.package_version.replace(/\./g, '_'),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
console.error('Get package version:', err);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function createZipArchive(zip, folder, options) {
|
|
26
|
+
const zipFileRegex = new RegExp(`${Path.basename(folder)}(_[0-9]){3}\\.zip`);
|
|
27
|
+
const files = fs.readdirSync(folder);
|
|
28
|
+
for (const file of files) {
|
|
29
|
+
const path = Path.join(folder, file);
|
|
30
|
+
const isDir = isDirectory(path);
|
|
31
|
+
if (file[0] === '.' ||
|
|
32
|
+
zipFileRegex.test(file) ||
|
|
33
|
+
file === 'node_modules' ||
|
|
34
|
+
(file === 'src' && options.typeScriptPackage) ||
|
|
35
|
+
options.excludedFileNames.includes(file)) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
else if (file === 'dist' && options.typeScriptPackage) {
|
|
39
|
+
zip.addLocalFolder(path);
|
|
40
|
+
}
|
|
41
|
+
else if (file === productionModulesFolder && options.includeNodeModules) {
|
|
42
|
+
zip.addLocalFolder(Path.join(productionModulesFolder, 'node_modules'), 'node_modules');
|
|
43
|
+
}
|
|
44
|
+
else if (isDir) {
|
|
45
|
+
zip.addLocalFolder(path, file);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
zip.addLocalFile(path);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function installDependencies() {
|
|
53
|
+
if (!fs.existsSync(productionModulesFolder)) {
|
|
54
|
+
fs.mkdirSync(productionModulesFolder, {});
|
|
55
|
+
}
|
|
56
|
+
fs.cpSync('package.json', Path.join(productionModulesFolder, 'package.json'));
|
|
57
|
+
fs.cpSync('package-lock.json', Path.join(productionModulesFolder, 'package-lock.json'));
|
|
58
|
+
(0, child_process_1.execSync)(`npm ci --omit=dev`, {
|
|
59
|
+
cwd: Path.join(process.cwd(), productionModulesFolder),
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function main(args) {
|
|
63
|
+
const options = {
|
|
64
|
+
includeNodeModules: false,
|
|
65
|
+
typeScriptPackage: false,
|
|
66
|
+
outputFolder: '.',
|
|
67
|
+
excludedFileNames: [],
|
|
68
|
+
};
|
|
69
|
+
for (const arg of args) {
|
|
70
|
+
if (arg === '-i' || arg === '-includeNodeModules') {
|
|
71
|
+
options.includeNodeModules = true;
|
|
72
|
+
}
|
|
73
|
+
if (arg.startsWith('-w=') || arg.startsWith('-where=')) {
|
|
74
|
+
options.outputFolder = arg.substring(arg.indexOf('=') + 1);
|
|
75
|
+
}
|
|
76
|
+
if (arg.startsWith('-e=') || arg.startsWith('-exclude=')) {
|
|
77
|
+
options.excludedFileNames = arg.substring(arg.indexOf('=') + 1).split(',');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (options.includeNodeModules) {
|
|
81
|
+
installDependencies();
|
|
82
|
+
}
|
|
83
|
+
if (fs.existsSync('dist')) {
|
|
84
|
+
options.typeScriptPackage = true;
|
|
85
|
+
}
|
|
86
|
+
const folder = Path.resolve('.');
|
|
87
|
+
const packageInfo = getPackageInfo(folder);
|
|
88
|
+
if (packageInfo === undefined) {
|
|
89
|
+
console.error('Package info not found');
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const zipFile = `${options.outputFolder}/${packageInfo.packageName}_${packageInfo.packageVersion}.zip`;
|
|
93
|
+
if (fs.existsSync(zipFile)) {
|
|
94
|
+
try {
|
|
95
|
+
fs.unlinkSync(zipFile);
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
console.error('An error occured: ', error);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const zip = new AdmZip();
|
|
103
|
+
createZipArchive(zip, folder, options);
|
|
104
|
+
zip.writeZip(zipFile);
|
|
105
|
+
}
|
|
106
|
+
main(process.argv.slice(2));
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { IClient, TParameters
|
|
1
|
+
import { IClient, TParameters } from './internal/common';
|
|
2
2
|
import { TApplication, TAudioSampleRates, TSDCardInfo, TPtzOverview, TCameraPTZItem, TCameraPTZItemData, TAudioDevice } from './types/VapixAPI';
|
|
3
3
|
import { ProxyClient } from './internal/ProxyClient';
|
|
4
4
|
import { TCameraImageConfig, TProxyParam } from './types/common';
|
|
5
5
|
export declare class VapixAPI<Client extends IClient = IClient> {
|
|
6
6
|
client: ProxyClient<Client>;
|
|
7
7
|
constructor(client: Client, getProxyUrl: () => string);
|
|
8
|
-
getUrlEncoded(proxy: TProxyParam
|
|
9
|
-
postJson(proxy: TProxyParam
|
|
10
|
-
getCameraImage(params: TCameraImageConfig, proxy?: TProxyParam): Promise<TResponse>;
|
|
8
|
+
getUrlEncoded(proxy: TProxyParam, path: string, parameters?: TParameters, headers?: Record<string, string>): Promise<import("./internal/common").TResponse>;
|
|
9
|
+
postJson(proxy: TProxyParam, path: string, jsonData: Record<string, any>, headers?: Record<string, string>): Promise<import("./internal/common").TResponse>;
|
|
10
|
+
getCameraImage(params: TCameraImageConfig, proxy?: TProxyParam): Promise<import("./internal/common").TResponse>;
|
|
11
11
|
getEventDeclarations(proxy?: TProxyParam): Promise<string>;
|
|
12
12
|
getSupportedAudioSampleRate(proxy?: TProxyParam): Promise<TAudioSampleRates[]>;
|
|
13
13
|
performAutofocus(proxy?: TProxyParam): Promise<void>;
|
|
@@ -16,8 +16,8 @@ export declare class VapixAPI<Client extends IClient = IClient> {
|
|
|
16
16
|
unmountSDCard(proxy?: TProxyParam): Promise<number>;
|
|
17
17
|
private _doSDCardMountAction;
|
|
18
18
|
fetchSDCardJobProgress(jobId: number, proxy?: TProxyParam): Promise<number>;
|
|
19
|
-
downloadCameraReport(proxy?: TProxyParam): Promise<TResponse>;
|
|
20
|
-
getSystemLog(proxy?: TProxyParam): Promise<TResponse>;
|
|
19
|
+
downloadCameraReport(proxy?: TProxyParam): Promise<import("./internal/common").TResponse>;
|
|
20
|
+
getSystemLog(proxy?: TProxyParam): Promise<import("./internal/common").TResponse>;
|
|
21
21
|
getMaxFps(channel: number, proxy?: TProxyParam): Promise<number>;
|
|
22
22
|
getTimezone(proxy?: TProxyParam): Promise<string>;
|
|
23
23
|
getDateTimeInfo(proxy?: TProxyParam): Promise<{
|
|
@@ -32,7 +32,7 @@ export declare class VapixAPI<Client extends IClient = IClient> {
|
|
|
32
32
|
getDevicesSettings(proxy?: TProxyParam): Promise<TAudioDevice[]>;
|
|
33
33
|
fetchRemoteDeviceInfo<T extends Record<string, any>>(payload: T, proxy?: TProxyParam): Promise<any>;
|
|
34
34
|
getHeaders(proxy?: TProxyParam): Promise<Record<string, string>>;
|
|
35
|
-
setHeaders(headers: Record<string, string>, proxy?: TProxyParam): Promise<TResponse>;
|
|
35
|
+
setHeaders(headers: Record<string, string>, proxy?: TProxyParam): Promise<import("./internal/common").TResponse>;
|
|
36
36
|
getParameter(paramNames: string | string[], proxy?: TProxyParam): Promise<Record<string, string>>;
|
|
37
37
|
setParameter(params: Record<string, string | number | boolean>, proxy?: TProxyParam): Promise<boolean>;
|
|
38
38
|
getGuardTourList(proxy?: TProxyParam): Promise<{
|
|
@@ -54,10 +54,10 @@ export declare class VapixAPI<Client extends IClient = IClient> {
|
|
|
54
54
|
getPTZPresetList(channel: number, proxy?: TProxyParam): Promise<string[]>;
|
|
55
55
|
listPTZ(camera: number, proxy?: TProxyParam): Promise<TCameraPTZItem[]>;
|
|
56
56
|
listPtzVideoSourceOverview(proxy?: TProxyParam): Promise<TPtzOverview>;
|
|
57
|
-
goToPreset(channel: number, presetName: string, proxy?: TProxyParam): Promise<TResponse>;
|
|
57
|
+
goToPreset(channel: number, presetName: string, proxy?: TProxyParam): Promise<import("./internal/common").TResponse>;
|
|
58
58
|
getPtzPosition(camera: number, proxy?: TProxyParam): Promise<TCameraPTZItemData>;
|
|
59
59
|
getInputState(port: number, proxy?: TProxyParam): Promise<boolean>;
|
|
60
|
-
setOutputState(port: number, active: boolean, proxy?: TProxyParam): Promise<TResponse>;
|
|
60
|
+
setOutputState(port: number, active: boolean, proxy?: TProxyParam): Promise<import("./internal/common").TResponse>;
|
|
61
61
|
getApplicationList(proxy?: TProxyParam): Promise<TApplication[]>;
|
|
62
62
|
startApplication(applicationID: string, proxy?: TProxyParam): Promise<void>;
|
|
63
63
|
restartApplication(applicationID: string, proxy?: TProxyParam): Promise<void>;
|
package/cjs/VapixAPI.js
ADDED
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.VapixAPI = void 0;
|
|
4
|
+
const prettifyXml = require("prettify-xml");
|
|
5
|
+
const xml2js_1 = require("xml2js");
|
|
6
|
+
const common_1 = require("./internal/common");
|
|
7
|
+
const VapixAPI_1 = require("./types/VapixAPI");
|
|
8
|
+
const errors_1 = require("./errors/errors");
|
|
9
|
+
const ProxyClient_1 = require("./internal/ProxyClient");
|
|
10
|
+
const utils_1 = require("./internal/utils");
|
|
11
|
+
const zod_1 = require("zod");
|
|
12
|
+
class VapixAPI {
|
|
13
|
+
client;
|
|
14
|
+
constructor(client, getProxyUrl) {
|
|
15
|
+
this.client = new ProxyClient_1.ProxyClient(client, getProxyUrl);
|
|
16
|
+
}
|
|
17
|
+
async getUrlEncoded(proxy, path, parameters, headers = {}) {
|
|
18
|
+
const data = (0, utils_1.paramToUrl)(parameters);
|
|
19
|
+
const head = { ...headers, 'Content-Type': 'application/x-www-form-urlencoded' };
|
|
20
|
+
const res = await this.client.post(proxy, path, data, {}, head);
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
23
|
+
}
|
|
24
|
+
return res;
|
|
25
|
+
}
|
|
26
|
+
async postJson(proxy, path, jsonData, headers = {}) {
|
|
27
|
+
const data = JSON.stringify(jsonData);
|
|
28
|
+
const head = { ...headers, 'Content-Type': 'application/json' };
|
|
29
|
+
const res = await this.client.post(proxy, path, data, {}, head);
|
|
30
|
+
if (!res.ok) {
|
|
31
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
32
|
+
}
|
|
33
|
+
return res;
|
|
34
|
+
}
|
|
35
|
+
async getCameraImage(params, proxy = null) {
|
|
36
|
+
return await this.client.get(proxy, '/axis-cgi/jpg/image.cgi', params);
|
|
37
|
+
}
|
|
38
|
+
async getEventDeclarations(proxy = null) {
|
|
39
|
+
const data = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
|
|
40
|
+
'<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
|
|
41
|
+
'xmlns:xsd="http://www.w3.org/2001/XMLSchema">' +
|
|
42
|
+
'<GetEventInstances xmlns="http://www.axis.com/vapix/ws/event1"/>' +
|
|
43
|
+
'</s:Body>' +
|
|
44
|
+
'</s:Envelope>';
|
|
45
|
+
const res = await this.client.post(proxy, '/vapix/services', data, { 'Content-Type': 'application/soap+xml' });
|
|
46
|
+
if (!res.ok) {
|
|
47
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
48
|
+
}
|
|
49
|
+
const declarations = await res.text();
|
|
50
|
+
return prettifyXml(declarations);
|
|
51
|
+
}
|
|
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);
|
|
56
|
+
const encoders = VapixAPI_1.audioSampleRatesResponseSchema.parse(await res.json()).data.encoders;
|
|
57
|
+
const data = encoders.aac ?? encoders.AAC ?? [];
|
|
58
|
+
return data.map((item) => {
|
|
59
|
+
return {
|
|
60
|
+
sampleRate: item.sample_rate,
|
|
61
|
+
bitRates: item.bit_rates,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async performAutofocus(proxy = null) {
|
|
66
|
+
try {
|
|
67
|
+
const data = {
|
|
68
|
+
apiVersion: '1',
|
|
69
|
+
method: 'performAutofocus',
|
|
70
|
+
params: {
|
|
71
|
+
optics: [
|
|
72
|
+
{
|
|
73
|
+
opticsId: '0',
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
await this.postJson(proxy, '/axis-cgi/opticscontrol.cgi', data);
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
await this.postJson(proxy, '/axis-cgi/opticssetup.cgi', {
|
|
82
|
+
autofocus: 'perform',
|
|
83
|
+
source: '1',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async checkSDCard(proxy = null) {
|
|
88
|
+
const res = await this.getUrlEncoded(proxy, '/axis-cgi/disks/list.cgi', {
|
|
89
|
+
diskid: 'SD_DISK',
|
|
90
|
+
});
|
|
91
|
+
const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
|
|
92
|
+
ignoreAttrs: false,
|
|
93
|
+
mergeAttrs: true,
|
|
94
|
+
explicitArray: false,
|
|
95
|
+
});
|
|
96
|
+
const data = result.root.disks.disk;
|
|
97
|
+
return {
|
|
98
|
+
totalSize: parseInt(data.totalsize),
|
|
99
|
+
freeSize: parseInt(data.freesize),
|
|
100
|
+
status: VapixAPI_1.sdCardWatchedStatuses.includes(data.status) ? data.status : 'disconnected',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
mountSDCard(proxy = null) {
|
|
104
|
+
return this._doSDCardMountAction('MOUNT', proxy);
|
|
105
|
+
}
|
|
106
|
+
unmountSDCard(proxy = null) {
|
|
107
|
+
return this._doSDCardMountAction('UNMOUNT', proxy);
|
|
108
|
+
}
|
|
109
|
+
async _doSDCardMountAction(action, proxy = null) {
|
|
110
|
+
const res = await this.getUrlEncoded(proxy, '/axis-cgi/disks/mount.cgi', {
|
|
111
|
+
action: action,
|
|
112
|
+
diskid: 'SD_DISK',
|
|
113
|
+
});
|
|
114
|
+
const result = await (0, xml2js_1.parseStringPromise)(await res.text(), {
|
|
115
|
+
ignoreAttrs: false,
|
|
116
|
+
mergeAttrs: true,
|
|
117
|
+
explicitArray: false,
|
|
118
|
+
});
|
|
119
|
+
const job = result.root.job;
|
|
120
|
+
if (job.result !== 'OK') {
|
|
121
|
+
throw new errors_1.SDCardActionError(action, await (0, common_1.responseStringify)(res));
|
|
122
|
+
}
|
|
123
|
+
return Number(job.jobid);
|
|
124
|
+
}
|
|
125
|
+
async fetchSDCardJobProgress(jobId, proxy = null) {
|
|
126
|
+
const res = await this.getUrlEncoded(proxy, '/disks/job.cgi', {
|
|
127
|
+
jobid: String(jobId),
|
|
128
|
+
diskid: 'SD_DISK',
|
|
129
|
+
});
|
|
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;
|
|
136
|
+
if (job.result !== 'OK') {
|
|
137
|
+
throw new errors_1.SDCardJobError();
|
|
138
|
+
}
|
|
139
|
+
return Number(job.progress);
|
|
140
|
+
}
|
|
141
|
+
downloadCameraReport(proxy = null) {
|
|
142
|
+
return this.getUrlEncoded(proxy, '/axis-cgi/serverreport.cgi', { mode: 'text' });
|
|
143
|
+
}
|
|
144
|
+
getSystemLog(proxy = null) {
|
|
145
|
+
return this.getUrlEncoded(proxy, '/axis-cgi/admin/systemlog.cgi');
|
|
146
|
+
}
|
|
147
|
+
async getMaxFps(channel, proxy = null) {
|
|
148
|
+
const data = { apiVersion: '1.0', method: 'getCaptureModes' };
|
|
149
|
+
const res = await this.postJson(proxy, '/axis-cgi/capturemode.cgi', data);
|
|
150
|
+
const response = VapixAPI_1.maxFpsResponseSchema.parse(await res.json());
|
|
151
|
+
const channels = response.data;
|
|
152
|
+
if (channels === undefined) {
|
|
153
|
+
throw new errors_1.MaxFPSError('MALFORMED_REPLY');
|
|
154
|
+
}
|
|
155
|
+
const channelData = channels.find((x) => x.channel === channel);
|
|
156
|
+
if (channelData === undefined) {
|
|
157
|
+
throw new errors_1.MaxFPSError('CHANNEL_NOT_FOUND');
|
|
158
|
+
}
|
|
159
|
+
const captureModes = channelData.captureMode;
|
|
160
|
+
const captureMode = captureModes.find((x) => x.enabled === true);
|
|
161
|
+
if (captureMode === undefined) {
|
|
162
|
+
throw new errors_1.MaxFPSError('CAPTURE_MODE_NOT_FOUND');
|
|
163
|
+
}
|
|
164
|
+
if ((0, common_1.isNullish)(captureMode.maxFPS)) {
|
|
165
|
+
throw new errors_1.MaxFPSError('FPS_NOT_SPECIFIED');
|
|
166
|
+
}
|
|
167
|
+
return captureMode.maxFPS;
|
|
168
|
+
}
|
|
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';
|
|
173
|
+
}
|
|
174
|
+
async getDateTimeInfo(proxy = null) {
|
|
175
|
+
const data = { apiVersion: '1.0', method: 'getDateTimeInfo' };
|
|
176
|
+
const res = await this.postJson(proxy, '/axis-cgi/time.cgi', data);
|
|
177
|
+
return VapixAPI_1.dateTimeinfoSchema.parse(await res.json());
|
|
178
|
+
}
|
|
179
|
+
async getDevicesSettings(proxy = null) {
|
|
180
|
+
const data = { apiVersion: '1.0', method: 'getDevicesSettings' };
|
|
181
|
+
const res = await this.postJson(proxy, '/axis-cgi/audiodevicecontrol.cgi', data);
|
|
182
|
+
const result = VapixAPI_1.audioDeviceRequestSchema.parse(await res.json());
|
|
183
|
+
return result.devices.map((device) => ({
|
|
184
|
+
...device,
|
|
185
|
+
inputs: (device.inputs || []).sort((a, b) => a.id.localeCompare(b.id)),
|
|
186
|
+
outputs: (device.outputs || []).sort((a, b) => a.id.localeCompare(b.id)),
|
|
187
|
+
}));
|
|
188
|
+
}
|
|
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)) {
|
|
197
|
+
throw new errors_1.NoDeviceInfoError();
|
|
198
|
+
}
|
|
199
|
+
return result.data;
|
|
200
|
+
}
|
|
201
|
+
async getHeaders(proxy = null) {
|
|
202
|
+
const data = { apiVersion: '1.0', method: 'list' };
|
|
203
|
+
const res = await this.postJson(proxy, '/axis-cgi/customhttpheader.cgi', data);
|
|
204
|
+
return zod_1.z.object({ data: zod_1.z.record(zod_1.z.string()) }).parse(await res.json()).data;
|
|
205
|
+
}
|
|
206
|
+
async setHeaders(headers, proxy = null) {
|
|
207
|
+
const data = { apiVersion: '1.0', method: 'set', params: headers };
|
|
208
|
+
return this.postJson(proxy, '/axis-cgi/customhttpheader.cgi', data);
|
|
209
|
+
}
|
|
210
|
+
async getParameter(paramNames, proxy = null) {
|
|
211
|
+
const response = await this.getUrlEncoded(proxy, '/axis-cgi/param.cgi', {
|
|
212
|
+
action: 'list',
|
|
213
|
+
group: (0, utils_1.arrayToUrl)(paramNames),
|
|
214
|
+
});
|
|
215
|
+
return parseParameters(await response.text());
|
|
216
|
+
}
|
|
217
|
+
async setParameter(params, proxy = null) {
|
|
218
|
+
const res = await this.getUrlEncoded(proxy, '/axis-cgi/param.cgi', {
|
|
219
|
+
...params,
|
|
220
|
+
action: 'update',
|
|
221
|
+
});
|
|
222
|
+
const responseText = await res.text();
|
|
223
|
+
if (responseText.startsWith('# Error')) {
|
|
224
|
+
throw new Error(responseText);
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
async getGuardTourList(proxy = null) {
|
|
229
|
+
const gTourList = new Array();
|
|
230
|
+
const response = await this.getParameter('GuardTour', proxy);
|
|
231
|
+
for (let i = 0; i < 20; i++) {
|
|
232
|
+
const gTourBaseName = 'root.GuardTour.G' + i;
|
|
233
|
+
if (gTourBaseName + '.CamNbr' in response) {
|
|
234
|
+
const gTour = {
|
|
235
|
+
id: gTourBaseName,
|
|
236
|
+
camNbr: response[gTourBaseName + '.CamNbr'],
|
|
237
|
+
name: response[gTourBaseName + '.Name'] ?? 'Guard Tour ' + (i + 1),
|
|
238
|
+
randomEnabled: response[gTourBaseName + '.RandomEnabled'],
|
|
239
|
+
running: response[gTourBaseName + '.Running'] ?? 'no',
|
|
240
|
+
timeBetweenSequences: response[gTourBaseName + '.TimeBetweenSequences'],
|
|
241
|
+
tour: [],
|
|
242
|
+
};
|
|
243
|
+
for (let j = 0; j < 100; j++) {
|
|
244
|
+
const tourBaseName = 'root.GuardTour.G' + i + '.Tour.T' + j;
|
|
245
|
+
if (tourBaseName + '.MoveSpeed' in response) {
|
|
246
|
+
const tour = {
|
|
247
|
+
moveSpeed: response[tourBaseName + '.MoveSpeed'],
|
|
248
|
+
position: response[tourBaseName + '.Position'],
|
|
249
|
+
presetNbr: response[tourBaseName + '.PresetNbr'],
|
|
250
|
+
waitTime: response[tourBaseName + '.WaitTime'],
|
|
251
|
+
waitTimeViewType: response[tourBaseName + '.WaitTimeViewType'],
|
|
252
|
+
};
|
|
253
|
+
gTour.tour.push(tour);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
gTourList.push(gTour);
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return gTourList;
|
|
263
|
+
}
|
|
264
|
+
setGuardTourEnabled(guardTourID, enable, proxy = null) {
|
|
265
|
+
const options = {};
|
|
266
|
+
options[guardTourID + '.Running'] = enable ? 'yes' : 'no';
|
|
267
|
+
return this.setParameter(options, proxy);
|
|
268
|
+
}
|
|
269
|
+
async getPTZPresetList(channel, proxy = null) {
|
|
270
|
+
const res = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
|
|
271
|
+
query: 'presetposcam',
|
|
272
|
+
camera: channel.toString(),
|
|
273
|
+
});
|
|
274
|
+
const text = await res.text();
|
|
275
|
+
const lines = text.split(/[\r\n]/);
|
|
276
|
+
const positions = [];
|
|
277
|
+
for (const line of lines) {
|
|
278
|
+
if (line.indexOf('presetposno') !== -1) {
|
|
279
|
+
const delimiterPos = line.indexOf('=');
|
|
280
|
+
if (delimiterPos !== -1) {
|
|
281
|
+
const value = line.substring(delimiterPos + 1);
|
|
282
|
+
positions.push(value);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return positions;
|
|
287
|
+
}
|
|
288
|
+
async listPTZ(camera, proxy = null) {
|
|
289
|
+
const url = `/axis-cgi/com/ptz.cgi`;
|
|
290
|
+
const response = await this.getUrlEncoded(proxy, url, {
|
|
291
|
+
camera,
|
|
292
|
+
query: 'presetposcamdata',
|
|
293
|
+
format: 'json',
|
|
294
|
+
});
|
|
295
|
+
return parseCameraPtzResponse(await response.text())[camera] ?? [];
|
|
296
|
+
}
|
|
297
|
+
async listPtzVideoSourceOverview(proxy = null) {
|
|
298
|
+
const response = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
|
|
299
|
+
query: 'presetposall',
|
|
300
|
+
format: 'json',
|
|
301
|
+
});
|
|
302
|
+
const data = parseCameraPtzResponse(await response.text());
|
|
303
|
+
const res = {};
|
|
304
|
+
Object.keys(data)
|
|
305
|
+
.map(Number)
|
|
306
|
+
.forEach((camera) => {
|
|
307
|
+
if (data[camera] !== undefined) {
|
|
308
|
+
res[camera - 1] = data[camera]?.map(({ data: itemData, ...d }) => d);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
return res;
|
|
312
|
+
}
|
|
313
|
+
goToPreset(channel, presetName, proxy = null) {
|
|
314
|
+
return this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
|
|
315
|
+
camera: channel.toString(),
|
|
316
|
+
gotoserverpresetname: presetName,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
async getPtzPosition(camera, proxy = null) {
|
|
320
|
+
const res = await this.getUrlEncoded(proxy, '/axis-cgi/com/ptz.cgi', {
|
|
321
|
+
query: 'position',
|
|
322
|
+
camera: camera.toString(),
|
|
323
|
+
});
|
|
324
|
+
const params = parseParameters(await res.text());
|
|
325
|
+
return {
|
|
326
|
+
pan: Number(params.pan),
|
|
327
|
+
tilt: Number(params.tilt),
|
|
328
|
+
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}:\\` });
|
|
337
|
+
}
|
|
338
|
+
async getApplicationList(proxy = null) {
|
|
339
|
+
const res = await this.getUrlEncoded(proxy, '/axis-cgi/applications/list.cgi');
|
|
340
|
+
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
|
+
});
|
|
348
|
+
}
|
|
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',
|
|
355
|
+
});
|
|
356
|
+
const text = (await res.text()).trim().toLowerCase();
|
|
357
|
+
if (text !== 'ok' && !(text.startsWith('error:') && text.substring(7) === '6')) {
|
|
358
|
+
throw new errors_1.ApplicationAPIError('START', await (0, common_1.responseStringify)(res));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
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',
|
|
365
|
+
});
|
|
366
|
+
const text = (await res.text()).trim().toLowerCase();
|
|
367
|
+
if (text !== 'ok') {
|
|
368
|
+
throw new errors_1.ApplicationAPIError('RESTART', await (0, common_1.responseStringify)(res));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
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',
|
|
375
|
+
});
|
|
376
|
+
const text = (await res.text()).trim().toLowerCase();
|
|
377
|
+
if (text !== 'ok' && !(text.startsWith('error:') && text.substring(7) === '6')) {
|
|
378
|
+
throw new errors_1.ApplicationAPIError('STOP', await (0, common_1.responseStringify)(res));
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
async installApplication(data, fileName) {
|
|
382
|
+
const formData = new FormData();
|
|
383
|
+
formData.append('packfil', data, fileName);
|
|
384
|
+
const res = await this.client.post(null, '/axis-cgi/applications/upload.cgi', formData, {}, {
|
|
385
|
+
contentType: 'application/octet-stream',
|
|
386
|
+
});
|
|
387
|
+
if (!res.ok) {
|
|
388
|
+
throw new Error(await (0, common_1.responseStringify)(res));
|
|
389
|
+
}
|
|
390
|
+
const text = await res.text();
|
|
391
|
+
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;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
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;
|
|
440
|
+
}
|
|
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
|
+
}
|
|
448
|
+
}
|
|
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
|
+
});
|
|
460
|
+
});
|
|
461
|
+
return res;
|
|
462
|
+
};
|