camstreamerlib 3.2.2 → 3.2.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/CamOverlayAPI.d.ts +25 -14
- package/CamOverlayAPI.js +107 -29
- package/CamOverlayDrawingAPI.d.ts +10 -0
- package/CamOverlayDrawingAPI.js +1 -1
- package/CamScripterAPICameraEventsGenerator.d.ts +8 -0
- package/CamStreamerAPI.d.ts +4 -1
- package/CamStreamerAPI.js +31 -3
- package/CamSwitcherAPI.d.ts +37 -8
- package/CamSwitcherAPI.js +59 -18
- package/CamSwitcherEvents.d.ts +17 -0
- package/CamSwitcherEvents.js +18 -5
- package/CameraVapix.d.ts +46 -8
- package/CameraVapix.js +340 -48
- package/VapixEvents.d.ts +26 -0
- package/internal/HttpRequestSender.js +4 -5
- package/internal/WsClient.d.ts +10 -0
- package/internal/common.d.ts +1 -0
- package/internal/common.js +19 -1
- package/package.json +1 -1
package/CamOverlayAPI.d.ts
CHANGED
|
@@ -6,32 +6,43 @@ export type TField = {
|
|
|
6
6
|
text: string;
|
|
7
7
|
color?: string;
|
|
8
8
|
};
|
|
9
|
-
export type TService =
|
|
10
|
-
id: number;
|
|
11
|
-
enabled: number;
|
|
12
|
-
schedule: string;
|
|
13
|
-
name: string;
|
|
14
|
-
identifier: string;
|
|
15
|
-
cameraList: number[];
|
|
16
|
-
};
|
|
9
|
+
export type TService = Record<string, any>;
|
|
17
10
|
export type TServiceList = {
|
|
18
11
|
services: TService[];
|
|
19
12
|
};
|
|
13
|
+
export type TNetworkCameraList = {
|
|
14
|
+
name: string;
|
|
15
|
+
ip: string;
|
|
16
|
+
}[];
|
|
17
|
+
export type TImage = {
|
|
18
|
+
name: string;
|
|
19
|
+
path: string;
|
|
20
|
+
storage: string;
|
|
21
|
+
};
|
|
20
22
|
export declare enum ImageType {
|
|
21
23
|
PNG = 0,
|
|
22
24
|
JPEG = 1
|
|
23
25
|
}
|
|
26
|
+
export type TCoordinates = 'top_left' | 'top_right' | 'top' | 'bottom_left' | 'bottom_right' | 'bottom' | 'left' | 'right' | 'center' | '';
|
|
24
27
|
export declare class CamOverlayAPI {
|
|
25
28
|
private client;
|
|
26
29
|
constructor(options?: CamOverlayOptions | IClient);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
checkCameraTime(): Promise<boolean>;
|
|
31
|
+
listImages(): Promise<TImage[]>;
|
|
32
|
+
uploadImage(file: Buffer, fileName: string): Promise<void>;
|
|
33
|
+
getNetworkCameraList(): Promise<TNetworkCameraList>;
|
|
30
34
|
updateInfoticker(serviceID: number, text: string): Promise<void>;
|
|
31
35
|
setEnabled(serviceID: number, enabled: boolean): Promise<void>;
|
|
32
36
|
isEnabled(serviceID: number): Promise<boolean>;
|
|
37
|
+
getSingleService(serviceId: number): Promise<TService>;
|
|
38
|
+
getServices(): Promise<TService[]>;
|
|
39
|
+
updateSingleService(serviceId: number, serviceJson: TService): Promise<void>;
|
|
33
40
|
updateServices(servicesJson: TServiceList): Promise<void>;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
updateCGText(serviceID: number, fields: TField[]): Promise<void>;
|
|
42
|
+
updateCGImagePos(serviceID: number, coordinates?: TCoordinates, x?: number, y?: number): Promise<void>;
|
|
43
|
+
updateCGImage(serviceID: number, path: string, coordinates?: TCoordinates, x?: number, y?: number): Promise<void>;
|
|
44
|
+
updateCGImageFromData(serviceID: number, imageType: ImageType, imageData: Buffer, coordinates?: TCoordinates, x?: number, y?: number): Promise<void>;
|
|
45
|
+
private promiseCGUpdate;
|
|
46
|
+
private get;
|
|
47
|
+
private post;
|
|
37
48
|
}
|
package/CamOverlayAPI.js
CHANGED
|
@@ -26,32 +26,39 @@ class CamOverlayAPI {
|
|
|
26
26
|
this.client = new DefaultAgent_1.DefaultAgent(options);
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (field.color !== undefined) {
|
|
35
|
-
field_specs += `&${name}_color=${field.color}`;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return this.promiseCGUpdate(serviceID, 'update_text', field_specs);
|
|
29
|
+
checkCameraTime() {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const cameraTime = yield this.get('/local/camoverlay/api/camera_time.cgi');
|
|
32
|
+
return cameraTime.state;
|
|
33
|
+
});
|
|
39
34
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
35
|
+
listImages() {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const images = yield this.get('/local/camoverlay/api/upload_image.cgi?action=list');
|
|
38
|
+
return images.list;
|
|
39
|
+
});
|
|
43
40
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
41
|
+
uploadImage(file, fileName) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
const formData = new FormData();
|
|
44
|
+
formData.append('target', 'SD0');
|
|
45
|
+
formData.append('uploadedFile[]', file, fileName);
|
|
46
|
+
const path = '/local/camoverlay/api/upload_image.cgi?action=upload';
|
|
47
|
+
yield this.post(path, formData);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
getNetworkCameraList() {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
const response = yield this.get('/local/camoverlay/api/network_camera_list.cgi');
|
|
53
|
+
return response.camera_list;
|
|
54
|
+
});
|
|
48
55
|
}
|
|
49
56
|
updateInfoticker(serviceID, text) {
|
|
50
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
58
|
const path = `/local/camoverlay/api/infoticker.cgi?service_id=${serviceID}&text=${text}`;
|
|
52
59
|
const res = yield this.client.get(path);
|
|
53
60
|
if (!res.ok) {
|
|
54
|
-
throw new Error(
|
|
61
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
55
62
|
}
|
|
56
63
|
});
|
|
57
64
|
}
|
|
@@ -60,7 +67,7 @@ class CamOverlayAPI {
|
|
|
60
67
|
const path = `/local/camoverlay/api/enabled.cgi?id_${serviceID}=${enabled ? 1 : 0}`;
|
|
61
68
|
const res = yield this.client.post(path, '');
|
|
62
69
|
if (!res.ok) {
|
|
63
|
-
throw new Error(
|
|
70
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
64
71
|
}
|
|
65
72
|
});
|
|
66
73
|
}
|
|
@@ -78,39 +85,110 @@ class CamOverlayAPI {
|
|
|
78
85
|
throw new Error('Service not found.');
|
|
79
86
|
}
|
|
80
87
|
else {
|
|
81
|
-
throw new Error(
|
|
88
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
82
89
|
}
|
|
83
90
|
});
|
|
84
91
|
}
|
|
92
|
+
getSingleService(serviceId) {
|
|
93
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
return this.get('/local/camoverlay/api/services.cgi', { action: 'get', service_id: serviceId.toString() });
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
getServices() {
|
|
98
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
+
const serviceList = yield this.get('/local/camoverlay/api/services.cgi?action=get');
|
|
100
|
+
return serviceList.services;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
updateSingleService(serviceId, serviceJson) {
|
|
104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
+
const path = '/local/camoverlay/api/services.cgi';
|
|
106
|
+
yield this.post(path, JSON.stringify(serviceJson), {
|
|
107
|
+
action: 'set',
|
|
108
|
+
service_id: serviceId.toString(),
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
}
|
|
85
112
|
updateServices(servicesJson) {
|
|
86
113
|
return __awaiter(this, void 0, void 0, function* () {
|
|
87
114
|
const path = '/local/camoverlay/api/services.cgi?action=set';
|
|
88
115
|
const res = yield this.client.post(path, JSON.stringify(servicesJson));
|
|
89
116
|
if (!res.ok) {
|
|
90
|
-
throw new Error(
|
|
117
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
91
118
|
}
|
|
92
119
|
});
|
|
93
120
|
}
|
|
121
|
+
updateCGText(serviceID, fields) {
|
|
122
|
+
const params = {};
|
|
123
|
+
for (const field of fields) {
|
|
124
|
+
const name = field.field_name;
|
|
125
|
+
params[name] = field.text;
|
|
126
|
+
if (field.color !== undefined) {
|
|
127
|
+
params[`${name}_color`] = field.color;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return this.promiseCGUpdate(serviceID, 'update_text', params);
|
|
131
|
+
}
|
|
132
|
+
updateCGImagePos(serviceID, coordinates = '', x = 0, y = 0) {
|
|
133
|
+
const params = {
|
|
134
|
+
coord_system: coordinates,
|
|
135
|
+
pos_x: x,
|
|
136
|
+
pos_y: y,
|
|
137
|
+
};
|
|
138
|
+
return this.promiseCGUpdate(serviceID, 'update_image', params);
|
|
139
|
+
}
|
|
140
|
+
updateCGImage(serviceID, path, coordinates = '', x = 0, y = 0) {
|
|
141
|
+
const params = {
|
|
142
|
+
coord_system: coordinates,
|
|
143
|
+
pos_x: x,
|
|
144
|
+
pos_y: y,
|
|
145
|
+
image: path,
|
|
146
|
+
};
|
|
147
|
+
return this.promiseCGUpdate(serviceID, 'update_image', params);
|
|
148
|
+
}
|
|
94
149
|
updateCGImageFromData(serviceID, imageType, imageData, coordinates = '', x = 0, y = 0) {
|
|
95
|
-
const coord = this.formCoordinates(coordinates, x, y);
|
|
96
150
|
const contentType = imageType === ImageType.PNG ? 'image/png' : 'image/jpeg';
|
|
97
|
-
|
|
151
|
+
const params = {
|
|
152
|
+
coord_system: coordinates,
|
|
153
|
+
pos_x: x,
|
|
154
|
+
pos_y: y,
|
|
155
|
+
};
|
|
156
|
+
return this.promiseCGUpdate(serviceID, 'update_image', params, contentType, imageData);
|
|
98
157
|
}
|
|
99
|
-
promiseCGUpdate(serviceID, action, params, contentType, data) {
|
|
158
|
+
promiseCGUpdate(serviceID, action, params = {}, contentType, data) {
|
|
100
159
|
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
-
const path = `/local/camoverlay/api/customGraphics.cgi
|
|
160
|
+
const path = `/local/camoverlay/api/customGraphics.cgi`;
|
|
102
161
|
let headers = {};
|
|
103
162
|
if (contentType !== undefined && data) {
|
|
104
163
|
headers = { 'Content-Type': contentType };
|
|
105
164
|
}
|
|
106
|
-
const res = yield this.client.post(path, data !== null && data !== void 0 ? data : '', {}, headers);
|
|
165
|
+
const res = yield this.client.post(path, data !== null && data !== void 0 ? data : '', Object.assign({ action: action, service_id: serviceID.toString() }, params), headers);
|
|
107
166
|
if (!res.ok) {
|
|
108
|
-
throw new Error(
|
|
167
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
109
168
|
}
|
|
110
169
|
});
|
|
111
170
|
}
|
|
112
|
-
|
|
113
|
-
return
|
|
171
|
+
get(path, params) {
|
|
172
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
173
|
+
const res = yield this.client.get(path, params);
|
|
174
|
+
if (res.ok) {
|
|
175
|
+
return yield res.json();
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
post(path, data, params) {
|
|
183
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
184
|
+
const res = yield this.client.post(path, data, params);
|
|
185
|
+
if (res.ok) {
|
|
186
|
+
return yield res.json();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
190
|
+
}
|
|
191
|
+
});
|
|
114
192
|
}
|
|
115
193
|
}
|
|
116
194
|
exports.CamOverlayAPI = CamOverlayAPI;
|
|
@@ -34,6 +34,16 @@ export type TServiceList = {
|
|
|
34
34
|
export type TAlign = 'A_RIGHT' | 'A_LEFT' | 'A_CENTER';
|
|
35
35
|
export type TextFit = 'TFM_SCALE' | 'TFM_TRUNCATE' | 'TFM_OVERFLOW';
|
|
36
36
|
export type TWriteTextParams = [string, string, number, number, number, number, TAlign, TextFit?];
|
|
37
|
+
export interface CamOverlayDrawingAPI {
|
|
38
|
+
on(event: 'open', listener: () => void): this;
|
|
39
|
+
on(event: 'close', listener: () => void): this;
|
|
40
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
41
|
+
on(event: 'message', listener: (msg: string) => void): this;
|
|
42
|
+
emit(event: 'open'): boolean;
|
|
43
|
+
emit(event: 'close'): boolean;
|
|
44
|
+
emit(event: 'error', err: Error): boolean;
|
|
45
|
+
emit(event: 'message', msg: string): boolean;
|
|
46
|
+
}
|
|
37
47
|
export declare class CamOverlayDrawingAPI extends EventEmitter {
|
|
38
48
|
private tls;
|
|
39
49
|
private tlsInsecure;
|
package/CamOverlayDrawingAPI.js
CHANGED
|
@@ -73,7 +73,7 @@ class CamOverlayDrawingAPI extends EventEmitter {
|
|
|
73
73
|
});
|
|
74
74
|
}
|
|
75
75
|
removeImage() {
|
|
76
|
-
return this.sendMessage({ command: 'remove_image_v2' });
|
|
76
|
+
return this.sendMessage({ command: 'remove_image_v2', params: [] });
|
|
77
77
|
}
|
|
78
78
|
createWsClient() {
|
|
79
79
|
const options = {
|
|
@@ -35,6 +35,14 @@ export type TResponse = {
|
|
|
35
35
|
call_id: number;
|
|
36
36
|
message: string;
|
|
37
37
|
};
|
|
38
|
+
export interface CamScripterAPICameraEventsGenerator {
|
|
39
|
+
on(event: 'open', listener: () => void): this;
|
|
40
|
+
on(event: 'close', listener: () => void): this;
|
|
41
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
42
|
+
emit(event: 'open'): boolean;
|
|
43
|
+
emit(event: 'close'): boolean;
|
|
44
|
+
emit(event: 'error', err: Error): boolean;
|
|
45
|
+
}
|
|
38
46
|
export declare class CamScripterAPICameraEventsGenerator extends EventEmitter {
|
|
39
47
|
private tls;
|
|
40
48
|
private tlsInsecure;
|
package/CamStreamerAPI.d.ts
CHANGED
|
@@ -28,8 +28,11 @@ export declare class CamStreamerAPI {
|
|
|
28
28
|
private client;
|
|
29
29
|
constructor(options?: CamStreamerAPIOptions | IClient);
|
|
30
30
|
getStreamList(): Promise<TStreamList>;
|
|
31
|
+
getStream(streamID: string): Promise<TStreamAttributes>;
|
|
31
32
|
getStreamParameter(streamID: string, paramName: string): Promise<string>;
|
|
33
|
+
setStream(streamID: string, params: TStreamAttributes): Promise<void>;
|
|
32
34
|
setStreamParameter(streamID: string, paramName: string, value: string): Promise<void>;
|
|
33
35
|
isStreaming(streamID: string): Promise<boolean>;
|
|
34
|
-
|
|
36
|
+
deleteStream(streamID: string): Promise<void>;
|
|
37
|
+
private get;
|
|
35
38
|
}
|
package/CamStreamerAPI.js
CHANGED
|
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
11
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
23
|
exports.CamStreamerAPI = void 0;
|
|
13
24
|
const common_1 = require("./internal/common");
|
|
@@ -27,12 +38,24 @@ class CamStreamerAPI {
|
|
|
27
38
|
return streamListRes.data;
|
|
28
39
|
});
|
|
29
40
|
}
|
|
41
|
+
getStream(streamID) {
|
|
42
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
43
|
+
const stream = yield this.get(`/local/camstreamer/stream/get.cgi?stream_id=${streamID}`);
|
|
44
|
+
return stream.data;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
30
47
|
getStreamParameter(streamID, paramName) {
|
|
31
48
|
return __awaiter(this, void 0, void 0, function* () {
|
|
32
49
|
const stream = yield this.get(`/local/camstreamer/stream/get.cgi?stream_id=${streamID}`);
|
|
33
50
|
return stream.data[paramName];
|
|
34
51
|
});
|
|
35
52
|
}
|
|
53
|
+
setStream(streamID, params) {
|
|
54
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
55
|
+
const { streamDelay, startTime, stopTime } = params, rest = __rest(params, ["streamDelay", "startTime", "stopTime"]);
|
|
56
|
+
yield this.get('/local/camstreamer/stream/set.cgi', Object.assign({ stream_id: streamID, streamDelay: streamDelay !== null && streamDelay !== void 0 ? streamDelay : '', startTime: startTime !== null && startTime !== void 0 ? startTime : 'null', stopTime: stopTime !== null && stopTime !== void 0 ? stopTime : 'null' }, rest));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
36
59
|
setStreamParameter(streamID, paramName, value) {
|
|
37
60
|
return __awaiter(this, void 0, void 0, function* () {
|
|
38
61
|
yield this.get(`/local/camstreamer/stream/set.cgi?stream_id=${streamID}&${paramName}=${value}`);
|
|
@@ -44,14 +67,19 @@ class CamStreamerAPI {
|
|
|
44
67
|
return response.data.is_streaming === 1;
|
|
45
68
|
});
|
|
46
69
|
}
|
|
47
|
-
|
|
70
|
+
deleteStream(streamID) {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
yield this.get('/local/camstreamer/stream/remove.cgi', { stream_id: streamID });
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
get(path, parameters) {
|
|
48
76
|
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
-
const res = yield this.client.get(path);
|
|
77
|
+
const res = yield this.client.get(path, parameters);
|
|
50
78
|
if (res.ok) {
|
|
51
79
|
return yield res.json();
|
|
52
80
|
}
|
|
53
81
|
else {
|
|
54
|
-
throw new Error(
|
|
82
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
55
83
|
}
|
|
56
84
|
});
|
|
57
85
|
}
|
package/CamSwitcherAPI.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import * as EventEmitter from 'events';
|
|
3
2
|
import { HttpOptions, IClient } from './internal/common';
|
|
4
3
|
export type CamSwitcherAPIOptions = HttpOptions;
|
|
5
4
|
export type TStreamInfo = {
|
|
@@ -21,14 +20,16 @@ export type TPlaylistInfo = {
|
|
|
21
20
|
sortIndexOverview: number;
|
|
22
21
|
stream_list: TStreamInfo[];
|
|
23
22
|
};
|
|
23
|
+
export type TPlaylistList = Record<string, TPlaylistInfo>;
|
|
24
24
|
export type TClipInfo = {
|
|
25
25
|
niceName: string;
|
|
26
26
|
channel: string;
|
|
27
27
|
keyboard: object;
|
|
28
28
|
sortIndexOverview: number;
|
|
29
29
|
};
|
|
30
|
-
export type TPlaylistList = Record<string, TPlaylistInfo>;
|
|
31
30
|
export type TClipList = Record<string, TClipInfo>;
|
|
31
|
+
export type TApiClipType = 'audio' | 'video';
|
|
32
|
+
export type TClipStorage = 'SD_DISK' | 'FLASH';
|
|
32
33
|
export type TPlaylistQueue = {
|
|
33
34
|
playlist_queue_list: string[];
|
|
34
35
|
};
|
|
@@ -37,16 +38,44 @@ export type TOutputInfo = {
|
|
|
37
38
|
ws: string;
|
|
38
39
|
ws_initial_message: string;
|
|
39
40
|
};
|
|
40
|
-
export
|
|
41
|
+
export type TSilenceChannel = 'mono' | 'stereo';
|
|
42
|
+
export type TAvailableCameraList = {
|
|
43
|
+
camera_list: {
|
|
44
|
+
name: string;
|
|
45
|
+
ip: string;
|
|
46
|
+
}[];
|
|
47
|
+
};
|
|
48
|
+
export type TStorageInfo = {
|
|
49
|
+
storage: TClipStorage;
|
|
50
|
+
writable: boolean;
|
|
51
|
+
size: number;
|
|
52
|
+
available: number;
|
|
53
|
+
};
|
|
54
|
+
declare const cgiNames: {
|
|
55
|
+
camera: string;
|
|
56
|
+
audio: string;
|
|
57
|
+
playlist: string;
|
|
58
|
+
clip: string;
|
|
59
|
+
tracker: string;
|
|
60
|
+
};
|
|
61
|
+
export type TSourceType = keyof typeof cgiNames;
|
|
62
|
+
export declare class CamSwitcherAPI {
|
|
41
63
|
private client;
|
|
42
64
|
constructor(options?: CamSwitcherAPIOptions | IClient);
|
|
65
|
+
generateSilence(sampleRate: number, channels: TSilenceChannel): Promise<void>;
|
|
66
|
+
getIpListFromNetworkCheck(): Promise<TAvailableCameraList>;
|
|
67
|
+
getMaxFps(source: number): Promise<number>;
|
|
68
|
+
getStorageInfo(): Promise<TStorageInfo[]>;
|
|
69
|
+
getOutputInfo(): Promise<TOutputInfo>;
|
|
43
70
|
getPlaylistList(): Promise<TPlaylistList>;
|
|
44
|
-
getClipList(): Promise<TClipList>;
|
|
45
71
|
playlistSwitch(playlistName: string): Promise<void>;
|
|
46
|
-
playlistQueueList(): Promise<TPlaylistQueue>;
|
|
47
|
-
playlistQueueClear(): Promise<void>;
|
|
48
72
|
playlistQueuePush(playlistName: string): Promise<void>;
|
|
73
|
+
playlistQueueClear(): Promise<void>;
|
|
74
|
+
playlistQueueList(): Promise<TPlaylistQueue>;
|
|
49
75
|
playlistQueuePlayNext(): Promise<void>;
|
|
50
|
-
|
|
51
|
-
|
|
76
|
+
getClipList(): Promise<TClipList>;
|
|
77
|
+
addNewClip(file: Buffer, clipType: TApiClipType, storage: TClipStorage, id: string, fileName: string): Promise<void>;
|
|
78
|
+
removeClip(id: string, storage: TClipStorage): Promise<{}>;
|
|
79
|
+
private get;
|
|
52
80
|
}
|
|
81
|
+
export {};
|
package/CamSwitcherAPI.js
CHANGED
|
@@ -10,60 +10,101 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.CamSwitcherAPI = void 0;
|
|
13
|
-
const EventEmitter = require("events");
|
|
14
13
|
const DefaultAgent_1 = require("./DefaultAgent");
|
|
15
14
|
const common_1 = require("./internal/common");
|
|
16
|
-
|
|
15
|
+
const cgiNames = {
|
|
16
|
+
camera: 'streams',
|
|
17
|
+
audio: 'audios',
|
|
18
|
+
playlist: 'playlists',
|
|
19
|
+
clip: 'clips',
|
|
20
|
+
tracker: 'trackers',
|
|
21
|
+
};
|
|
22
|
+
class CamSwitcherAPI {
|
|
17
23
|
constructor(options = {}) {
|
|
18
|
-
super();
|
|
19
24
|
if ((0, common_1.isClient)(options)) {
|
|
20
25
|
this.client = options;
|
|
21
26
|
}
|
|
22
27
|
else {
|
|
23
28
|
this.client = new DefaultAgent_1.DefaultAgent(options);
|
|
24
29
|
}
|
|
25
|
-
|
|
30
|
+
}
|
|
31
|
+
generateSilence(sampleRate, channels) {
|
|
32
|
+
return this.get('/local/camswitcher/generate_silence.cgi', { sample_rate: sampleRate.toString(), channels });
|
|
33
|
+
}
|
|
34
|
+
getIpListFromNetworkCheck() {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
return (yield this.get('/local/camswitcher/network_camera_list.cgi')).data;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
getMaxFps(source) {
|
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
return (yield this.get('/local/camswitcher/get_max_framerate.cgi', { video_source: source.toString() })).data;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
getStorageInfo() {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
return (yield this.get('/local/camswitcher/get_storage.cgi')).data;
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
getOutputInfo() {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
return (yield this.get('/local/camswitcher/output_info.cgi')).data;
|
|
52
|
+
});
|
|
26
53
|
}
|
|
27
54
|
getPlaylistList() {
|
|
28
55
|
return this.get('/local/camswitcher/playlists.cgi?action=get');
|
|
29
56
|
}
|
|
30
|
-
getClipList() {
|
|
31
|
-
return this.get('/local/camswitcher/clips.cgi?action=get');
|
|
32
|
-
}
|
|
33
57
|
playlistSwitch(playlistName) {
|
|
34
58
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
59
|
yield this.get(`/local/camswitcher/playlist_switch.cgi?playlist_name=${playlistName}`);
|
|
36
60
|
});
|
|
37
61
|
}
|
|
38
|
-
|
|
39
|
-
return this
|
|
62
|
+
playlistQueuePush(playlistName) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
yield this.get(`/local/camswitcher/playlist_queue_push.cgi?playlist_name=${playlistName}`);
|
|
65
|
+
});
|
|
40
66
|
}
|
|
41
67
|
playlistQueueClear() {
|
|
42
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
43
69
|
yield this.get('/local/camswitcher/playlist_queue_clear.cgi');
|
|
44
70
|
});
|
|
45
71
|
}
|
|
46
|
-
|
|
47
|
-
return
|
|
48
|
-
yield this.get(`/local/camswitcher/playlist_queue_push.cgi?playlist_name=${playlistName}`);
|
|
49
|
-
});
|
|
72
|
+
playlistQueueList() {
|
|
73
|
+
return this.get('/local/camswitcher/playlist_queue_list.cgi');
|
|
50
74
|
}
|
|
51
75
|
playlistQueuePlayNext() {
|
|
52
76
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53
77
|
yield this.get('/local/camswitcher/playlist_queue_play_next.cgi');
|
|
54
78
|
});
|
|
55
79
|
}
|
|
56
|
-
|
|
57
|
-
return this.get('/local/camswitcher/
|
|
80
|
+
getClipList() {
|
|
81
|
+
return this.get('/local/camswitcher/clips.cgi?action=get');
|
|
82
|
+
}
|
|
83
|
+
addNewClip(file, clipType, storage, id, fileName) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
const formData = new FormData();
|
|
86
|
+
formData.append('clip_name', id);
|
|
87
|
+
formData.append('clip_type', clipType);
|
|
88
|
+
formData.append('file', file, fileName);
|
|
89
|
+
const path = `/local/camswitcher/clip_upload.cgi?storage=${storage}`;
|
|
90
|
+
const res = yield this.client.post(path, formData);
|
|
91
|
+
const output = (yield res.json());
|
|
92
|
+
if (output.status !== 200) {
|
|
93
|
+
throw new Error('Error on camera: ' + output.message);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
removeClip(id, storage) {
|
|
98
|
+
return this.get(`/local/camswitcher/clip_remove.cgi`, { clip_name: id, storage });
|
|
58
99
|
}
|
|
59
|
-
get(path) {
|
|
100
|
+
get(path, parameters = {}) {
|
|
60
101
|
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
-
const res = yield this.client.get(path);
|
|
102
|
+
const res = yield this.client.get(path, parameters);
|
|
62
103
|
if (res.ok) {
|
|
63
104
|
return yield res.json();
|
|
64
105
|
}
|
|
65
106
|
else {
|
|
66
|
-
throw new Error(
|
|
107
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
67
108
|
}
|
|
68
109
|
});
|
|
69
110
|
}
|
package/CamSwitcherEvents.d.ts
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
import * as EventEmitter from 'events';
|
|
3
3
|
import { HttpOptions } from './internal/common';
|
|
4
4
|
export type CamSwitcherEventsOptions = HttpOptions;
|
|
5
|
+
export type TEvent = {
|
|
6
|
+
type: string;
|
|
7
|
+
date: Record<string, string | number | boolean> & {
|
|
8
|
+
type: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export interface CamSwitcherEvents {
|
|
12
|
+
on(event: 'open', listener: () => void): this;
|
|
13
|
+
on(event: 'close', listener: () => void): this;
|
|
14
|
+
on(event: 'event', listener: (data: TEvent) => void): this;
|
|
15
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
16
|
+
emit(event: 'open'): boolean;
|
|
17
|
+
emit(event: 'close'): boolean;
|
|
18
|
+
emit(event: 'event', data: TEvent): boolean;
|
|
19
|
+
emit(event: 'error', err: Error): boolean;
|
|
20
|
+
}
|
|
5
21
|
export declare class CamSwitcherEvents extends EventEmitter {
|
|
6
22
|
private tls;
|
|
7
23
|
private tlsInsecure;
|
|
@@ -14,6 +30,7 @@ export declare class CamSwitcherEvents extends EventEmitter {
|
|
|
14
30
|
constructor(options?: CamSwitcherEventsOptions);
|
|
15
31
|
connect(): void;
|
|
16
32
|
disconnect(): void;
|
|
33
|
+
resendInitData(): void;
|
|
17
34
|
private createWsClient;
|
|
18
35
|
private get;
|
|
19
36
|
}
|
package/CamSwitcherEvents.js
CHANGED
|
@@ -33,6 +33,12 @@ class CamSwitcherEvents extends EventEmitter {
|
|
|
33
33
|
disconnect() {
|
|
34
34
|
this.ws.close();
|
|
35
35
|
}
|
|
36
|
+
resendInitData() {
|
|
37
|
+
const request = {
|
|
38
|
+
command: 'sendInitData',
|
|
39
|
+
};
|
|
40
|
+
this.ws.send(JSON.stringify(request));
|
|
41
|
+
}
|
|
36
42
|
createWsClient() {
|
|
37
43
|
const options = {
|
|
38
44
|
ip: this.ip,
|
|
@@ -49,21 +55,28 @@ class CamSwitcherEvents extends EventEmitter {
|
|
|
49
55
|
try {
|
|
50
56
|
const token = yield this.get('/local/camswitcher/ws_authorization.cgi');
|
|
51
57
|
this.ws.send(JSON.stringify({ authorization: token }));
|
|
52
|
-
this.emit('open');
|
|
53
58
|
}
|
|
54
59
|
catch (err) {
|
|
55
60
|
this.emit('error', err);
|
|
56
|
-
this.ws.close();
|
|
57
|
-
this.ws.open();
|
|
58
61
|
}
|
|
59
62
|
}));
|
|
60
63
|
this.ws.on('message', (data) => {
|
|
61
64
|
try {
|
|
62
65
|
const parsedData = JSON.parse(data.toString());
|
|
63
|
-
|
|
66
|
+
if (parsedData.type === 'authorization') {
|
|
67
|
+
if (parsedData.state === 'OK') {
|
|
68
|
+
this.emit('open');
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.emit('error', new Error(data.toString()));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.emit('event', parsedData);
|
|
76
|
+
}
|
|
64
77
|
}
|
|
65
78
|
catch (err) {
|
|
66
|
-
|
|
79
|
+
this.emit('error', err);
|
|
67
80
|
}
|
|
68
81
|
});
|
|
69
82
|
this.ws.on('error', (err) => {
|
package/CameraVapix.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
|
+
/// <reference types="node" />
|
|
3
4
|
import { WritableStream } from 'node:stream/web';
|
|
4
|
-
import { EventEmitter2 as EventEmitter } from 'eventemitter2';
|
|
5
5
|
import { HttpOptions, IClient } from './internal/common';
|
|
6
6
|
export type CameraVapixOptions = HttpOptions;
|
|
7
7
|
export type TApplicationList = {
|
|
@@ -41,20 +41,58 @@ export type TGuardTour = {
|
|
|
41
41
|
waitTimeViewType: unknown;
|
|
42
42
|
}[];
|
|
43
43
|
};
|
|
44
|
-
export
|
|
44
|
+
export type TAudioSampleRates = {
|
|
45
|
+
sampleRate: number;
|
|
46
|
+
bitRates: number[];
|
|
47
|
+
};
|
|
48
|
+
export type TSDCardInfo = {
|
|
49
|
+
available: boolean;
|
|
50
|
+
totalSize: number;
|
|
51
|
+
freeSize: number;
|
|
52
|
+
};
|
|
53
|
+
export type TPtzOverview = Record<number, {
|
|
54
|
+
id: number;
|
|
55
|
+
name: string;
|
|
56
|
+
}[]>;
|
|
57
|
+
export type TCameraPTZItem = {
|
|
58
|
+
name: string;
|
|
59
|
+
id: number;
|
|
60
|
+
data: TCameraPTZItemData;
|
|
61
|
+
};
|
|
62
|
+
export type TCameraPTZItemData = {
|
|
63
|
+
pan?: number;
|
|
64
|
+
tilt?: number;
|
|
65
|
+
zoom?: number;
|
|
66
|
+
};
|
|
67
|
+
export declare class CameraVapix {
|
|
45
68
|
private client;
|
|
46
69
|
constructor(options?: CameraVapixOptions | IClient);
|
|
47
|
-
vapixGet(path: string): Promise<Response>;
|
|
48
|
-
vapixPost(path: string, data: string, contentType?: string): Promise<Response>;
|
|
70
|
+
vapixGet(path: string, parameters?: Record<string, string>): Promise<Response>;
|
|
71
|
+
vapixPost(path: string, data: string | Buffer | FormData, contentType?: string): Promise<Response>;
|
|
72
|
+
getCameraImage(camera: string, compression: string, resolution: string, outputStream: WritableStream): Promise<WritableStream<any>>;
|
|
73
|
+
getEventDeclarations(): Promise<string>;
|
|
74
|
+
getSupportedAudioSampleRate(): Promise<TAudioSampleRates[]>;
|
|
75
|
+
checkSdCard(): Promise<TSDCardInfo>;
|
|
76
|
+
downloadCameraReport(): Promise<Response>;
|
|
77
|
+
getMaxFps(channel: number): Promise<number>;
|
|
78
|
+
getTimezone(): Promise<string>;
|
|
79
|
+
getHeaders(): Promise<Record<string, string>>;
|
|
80
|
+
setHeaders(headers: Record<string, string>): Promise<Response>;
|
|
81
|
+
private parseGetParametrs;
|
|
49
82
|
getParameterGroup(groupNames: string): Promise<Record<string, string>>;
|
|
50
83
|
setParameter(params: Record<string, string>): Promise<Response>;
|
|
51
|
-
getPTZPresetList(channel: string): Promise<string[]>;
|
|
52
|
-
goToPreset(channel: number, presetName: string): Promise<Response>;
|
|
53
84
|
getGuardTourList(): Promise<TGuardTour[]>;
|
|
54
85
|
setGuardTourEnabled(gourTourID: string, enable: boolean): Promise<Response>;
|
|
86
|
+
private parsePtz;
|
|
87
|
+
private parseCameraPtzFromReq;
|
|
88
|
+
getPTZPresetList(channel: number): Promise<string[]>;
|
|
89
|
+
listPtzVideoSourceOverview(): Promise<TPtzOverview>;
|
|
90
|
+
goToPreset(channel: number, presetName: string): Promise<Response>;
|
|
91
|
+
getPtzPosition(camera: number): Promise<TCameraPTZItemData>;
|
|
55
92
|
getInputState(port: number): Promise<boolean>;
|
|
56
93
|
setOutputState(port: number, active: boolean): Promise<Response>;
|
|
57
94
|
getApplicationList(): Promise<TApplication[]>;
|
|
58
|
-
|
|
59
|
-
|
|
95
|
+
startApplication(applicationID: string): Promise<void>;
|
|
96
|
+
restartApplication(applicationID: string): Promise<void>;
|
|
97
|
+
stopApplication(applicationID: string): Promise<void>;
|
|
60
98
|
}
|
package/CameraVapix.js
CHANGED
|
@@ -8,16 +8,25 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
12
|
+
var t = {};
|
|
13
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
14
|
+
t[p] = s[p];
|
|
15
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
16
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
17
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
18
|
+
t[p[i]] = s[p[i]];
|
|
19
|
+
}
|
|
20
|
+
return t;
|
|
21
|
+
};
|
|
11
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
23
|
exports.CameraVapix = void 0;
|
|
13
24
|
const prettifyXml = require("prettify-xml");
|
|
14
25
|
const xml2js_1 = require("xml2js");
|
|
15
|
-
const eventemitter2_1 = require("eventemitter2");
|
|
16
26
|
const common_1 = require("./internal/common");
|
|
17
27
|
const DefaultAgent_1 = require("./DefaultAgent");
|
|
18
|
-
class CameraVapix
|
|
28
|
+
class CameraVapix {
|
|
19
29
|
constructor(options = {}) {
|
|
20
|
-
super();
|
|
21
30
|
if ((0, common_1.isClient)(options)) {
|
|
22
31
|
this.client = options;
|
|
23
32
|
}
|
|
@@ -25,8 +34,8 @@ class CameraVapix extends eventemitter2_1.EventEmitter2 {
|
|
|
25
34
|
this.client = new DefaultAgent_1.DefaultAgent(options);
|
|
26
35
|
}
|
|
27
36
|
}
|
|
28
|
-
vapixGet(path) {
|
|
29
|
-
return this.client.get(path);
|
|
37
|
+
vapixGet(path, parameters) {
|
|
38
|
+
return this.client.get(path, parameters);
|
|
30
39
|
}
|
|
31
40
|
vapixPost(path, data, contentType) {
|
|
32
41
|
let headers = {};
|
|
@@ -35,17 +44,174 @@ class CameraVapix extends eventemitter2_1.EventEmitter2 {
|
|
|
35
44
|
}
|
|
36
45
|
return this.client.post(path, data, {}, headers);
|
|
37
46
|
}
|
|
47
|
+
getCameraImage(camera, compression, resolution, outputStream) {
|
|
48
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
49
|
+
const path = `/axis-cgi/jpg/image.cgi?resolution=${resolution}&compression=${compression}&camera=${camera}`;
|
|
50
|
+
const res = yield this.vapixGet(path);
|
|
51
|
+
if (res.body) {
|
|
52
|
+
void res.body.pipeTo(outputStream);
|
|
53
|
+
}
|
|
54
|
+
return outputStream;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
getEventDeclarations() {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
const data = '<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">' +
|
|
60
|
+
'<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
|
|
61
|
+
'xmlns:xsd="http://www.w3.org/2001/XMLSchema">' +
|
|
62
|
+
'<GetEventInstances xmlns="http://www.axis.com/vapix/ws/event1"/>' +
|
|
63
|
+
'</s:Body>' +
|
|
64
|
+
'</s:Envelope>';
|
|
65
|
+
const declarations = yield (yield this.vapixPost('/vapix/services', data, 'application/soap+xml')).text();
|
|
66
|
+
return prettifyXml(declarations);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
getSupportedAudioSampleRate() {
|
|
70
|
+
var _a, _b;
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
const url = '/axis-cgi/audio/streamingcapabilities.cgi';
|
|
73
|
+
const formData = { apiVersion: '1.0', method: 'list' };
|
|
74
|
+
const res = yield this.vapixPost(url, JSON.stringify(formData));
|
|
75
|
+
try {
|
|
76
|
+
const encoders = (yield res.json()).data.encoders;
|
|
77
|
+
const data = (_b = (_a = encoders.aac) !== null && _a !== void 0 ? _a : encoders.AAC) !== null && _b !== void 0 ? _b : [];
|
|
78
|
+
return data.map((item) => {
|
|
79
|
+
return {
|
|
80
|
+
sampleRate: item.sample_rate,
|
|
81
|
+
bitRates: item.bit_rates,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (err) {
|
|
86
|
+
return [];
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
checkSdCard() {
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
const res = yield this.vapixGet('/axis-cgi/disks/list.cgi', {
|
|
93
|
+
diskid: 'SD_DISK',
|
|
94
|
+
});
|
|
95
|
+
const result = yield (0, xml2js_1.parseStringPromise)(yield res.text(), {
|
|
96
|
+
ignoreAttrs: false,
|
|
97
|
+
mergeAttrs: true,
|
|
98
|
+
explicitArray: false,
|
|
99
|
+
});
|
|
100
|
+
const data = result.root.disks.disk;
|
|
101
|
+
return {
|
|
102
|
+
available: data.status === 'OK',
|
|
103
|
+
totalSize: parseInt(data.totalsize),
|
|
104
|
+
freeSize: parseInt(data.freesize),
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
downloadCameraReport() {
|
|
109
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
const res = yield this.vapixGet('/axis-cgi/serverreport.cgi', { mode: 'text' });
|
|
111
|
+
if (res.ok) {
|
|
112
|
+
return res;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
getMaxFps(channel) {
|
|
120
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
+
const data = JSON.stringify({ apiVersion: '1.0', method: 'getCaptureModes' });
|
|
122
|
+
const res = yield this.vapixPost('/axis-cgi/capturemode.cgi', data);
|
|
123
|
+
if (!res.ok) {
|
|
124
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
125
|
+
}
|
|
126
|
+
const response = (yield res.json());
|
|
127
|
+
const channels = response.data;
|
|
128
|
+
if (channels === undefined) {
|
|
129
|
+
throw new Error(`Malformed reply from camera`);
|
|
130
|
+
}
|
|
131
|
+
const channelData = channels.find((x) => x.channel === channel);
|
|
132
|
+
if (channelData === undefined) {
|
|
133
|
+
throw new Error(`Video channel '${channel}' not found`);
|
|
134
|
+
}
|
|
135
|
+
const captureModes = channelData.captureMode;
|
|
136
|
+
const captureMode = captureModes.find((x) => x.enabled === true);
|
|
137
|
+
if (captureMode === undefined) {
|
|
138
|
+
throw new Error(`No enabled capture mode found.`);
|
|
139
|
+
}
|
|
140
|
+
const maxFps = parseInt(captureMode.maxFPS, 10);
|
|
141
|
+
if (isNaN(maxFps)) {
|
|
142
|
+
throw new Error(`Max fps not specified for given capture mode.`);
|
|
143
|
+
}
|
|
144
|
+
return maxFps;
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
getTimezone() {
|
|
148
|
+
var _a, _b;
|
|
149
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
150
|
+
const data = JSON.stringify({ apiVersion: '1.0', method: 'getDateTimeInfo' });
|
|
151
|
+
const res = yield this.vapixPost('/axis-cgi/time.cgi', data);
|
|
152
|
+
if (res.ok) {
|
|
153
|
+
return (_b = (_a = ((yield res.json()))) === null || _a === void 0 ? void 0 : _a.timeZone) !== null && _b !== void 0 ? _b : 'Europe/Prague';
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
getHeaders() {
|
|
161
|
+
var _a;
|
|
162
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
163
|
+
try {
|
|
164
|
+
const data = JSON.stringify({ apiVersion: '1.0', method: 'list' });
|
|
165
|
+
const res = yield this.vapixPost('/axis-cgi/customhttpheader.cgi', data);
|
|
166
|
+
if (res.ok) {
|
|
167
|
+
return (_a = (yield res.json()).data) !== null && _a !== void 0 ? _a : {};
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
return {};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (e) {
|
|
174
|
+
return {};
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
setHeaders(headers) {
|
|
179
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
180
|
+
const data = JSON.stringify({ apiVersion: '1.0', method: 'set', params: headers });
|
|
181
|
+
return this.vapixPost('/axis-cgi/customhttpheader.cgi', data);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
parseGetParametrs(response) {
|
|
185
|
+
const params = {};
|
|
186
|
+
const lines = response.split(/[\r\n]/);
|
|
187
|
+
for (let i = 0; i < lines.length; i++) {
|
|
188
|
+
if (lines[i].substring(0, 7) === '# Error') {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (lines[i].length) {
|
|
192
|
+
const p = lines[i].split(/=(.+)/);
|
|
193
|
+
if (p.length >= 2) {
|
|
194
|
+
const paramName = p[0].replace('root.', '');
|
|
195
|
+
params[paramName] = String(p[1]);
|
|
196
|
+
}
|
|
197
|
+
else if (p[0].substring(0, 7) !== '# Error') {
|
|
198
|
+
params[p[0].slice(0, -1)] = '';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return params;
|
|
203
|
+
}
|
|
38
204
|
getParameterGroup(groupNames) {
|
|
39
205
|
return __awaiter(this, void 0, void 0, function* () {
|
|
40
206
|
const response = yield (yield this.vapixGet(`/axis-cgi/param.cgi?action=list&group=${encodeURIComponent(groupNames)}`)).text();
|
|
41
207
|
const params = {};
|
|
42
208
|
const lines = response.split(/[\r\n]/);
|
|
43
|
-
for (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
209
|
+
for (let i = 0; i < lines.length; i++) {
|
|
210
|
+
if (lines[i].length) {
|
|
211
|
+
const p = lines[i].split('=');
|
|
212
|
+
if (p.length >= 2) {
|
|
213
|
+
params[p[0]] = p[1];
|
|
214
|
+
}
|
|
49
215
|
}
|
|
50
216
|
}
|
|
51
217
|
return params;
|
|
@@ -59,26 +225,6 @@ class CameraVapix extends eventemitter2_1.EventEmitter2 {
|
|
|
59
225
|
postData = postData.slice(0, postData.length - 1);
|
|
60
226
|
return this.vapixPost('/axis-cgi/param.cgi', postData);
|
|
61
227
|
}
|
|
62
|
-
getPTZPresetList(channel) {
|
|
63
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
const response = yield (yield this.vapixGet(`/axis-cgi/com/ptz.cgi?query=presetposcam&camera=${encodeURIComponent(channel)}`)).text();
|
|
65
|
-
const positions = [];
|
|
66
|
-
const lines = response.split(/[\r\n]/);
|
|
67
|
-
for (const line of lines) {
|
|
68
|
-
if (line.indexOf('presetposno') !== -1) {
|
|
69
|
-
const delimiterPos = line.indexOf('=');
|
|
70
|
-
if (delimiterPos !== -1) {
|
|
71
|
-
const value = line.substring(delimiterPos + 1);
|
|
72
|
-
positions.push(value);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return positions;
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
goToPreset(channel, presetName) {
|
|
80
|
-
return this.vapixPost('/axis-cgi/com/ptz.cgi', `camera=${encodeURIComponent(channel)}&gotoserverpresetname=${encodeURIComponent(presetName)}`);
|
|
81
|
-
}
|
|
82
228
|
getGuardTourList() {
|
|
83
229
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
230
|
const gTourList = new Array();
|
|
@@ -122,6 +268,121 @@ class CameraVapix extends eventemitter2_1.EventEmitter2 {
|
|
|
122
268
|
options[gourTourID + '.Running'] = enable ? 'yes' : 'no';
|
|
123
269
|
return this.setParameter(options);
|
|
124
270
|
}
|
|
271
|
+
parsePtz(parsed) {
|
|
272
|
+
const res = [];
|
|
273
|
+
parsed.forEach((value) => {
|
|
274
|
+
const valueData = value.split('=');
|
|
275
|
+
if (valueData.length < 2) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (!valueData[0].startsWith('presetposno')) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const id = Number(valueData[0].replace('presetposno', ''));
|
|
282
|
+
if (Number.isNaN(id)) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const data = valueData[1].split(':');
|
|
286
|
+
const getValue = (valueName) => {
|
|
287
|
+
for (const d of data) {
|
|
288
|
+
const p = d.split('=');
|
|
289
|
+
if (p[0] === valueName) {
|
|
290
|
+
return Number(p[1]);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return 0;
|
|
294
|
+
};
|
|
295
|
+
res.push({
|
|
296
|
+
id,
|
|
297
|
+
name: data[0],
|
|
298
|
+
data: {
|
|
299
|
+
pan: getValue('pan'),
|
|
300
|
+
tilt: getValue('tilt'),
|
|
301
|
+
zoom: getValue('zoom'),
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
return res;
|
|
306
|
+
}
|
|
307
|
+
parseCameraPtzFromReq(response) {
|
|
308
|
+
const json = JSON.parse(response);
|
|
309
|
+
const parsed = {};
|
|
310
|
+
Object.keys(json).forEach((key) => {
|
|
311
|
+
if (!key.startsWith('Camera ')) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
const camera = Number(key.replace('Camera ', ''));
|
|
315
|
+
if (json[key].presets !== undefined) {
|
|
316
|
+
parsed[camera] = this.parsePtz(json[key].presets);
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
return parsed;
|
|
320
|
+
}
|
|
321
|
+
getPTZPresetList(channel) {
|
|
322
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
323
|
+
const response = yield (yield this.vapixGet(`/axis-cgi/com/ptz.cgi?query=presetposcam&camera=${encodeURIComponent(channel)}`)).text();
|
|
324
|
+
const positions = [];
|
|
325
|
+
const lines = response.split(/[\r\n]/);
|
|
326
|
+
for (const line of lines) {
|
|
327
|
+
if (line.indexOf('presetposno') !== -1) {
|
|
328
|
+
const delimiterPos = line.indexOf('=');
|
|
329
|
+
if (delimiterPos !== -1) {
|
|
330
|
+
const value = line.substring(delimiterPos + 1);
|
|
331
|
+
positions.push(value);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
return positions;
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
listPtzVideoSourceOverview() {
|
|
339
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
340
|
+
try {
|
|
341
|
+
const response = yield this.vapixGet(`/axis-cgi/com/ptz.cgi`, {
|
|
342
|
+
query: 'presetposall',
|
|
343
|
+
format: 'json',
|
|
344
|
+
});
|
|
345
|
+
const data = this.parseCameraPtzFromReq(yield response.text());
|
|
346
|
+
const res = {};
|
|
347
|
+
Object.keys(data).forEach((camera) => {
|
|
348
|
+
res[Number(camera) - 1] = data[Number(camera)].map((_a) => {
|
|
349
|
+
var { data } = _a, d = __rest(_a, ["data"]);
|
|
350
|
+
return d;
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
return res;
|
|
354
|
+
}
|
|
355
|
+
catch (err) {
|
|
356
|
+
return [];
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
goToPreset(channel, presetName) {
|
|
361
|
+
return this.vapixPost('/axis-cgi/com/ptz.cgi', `camera=${encodeURIComponent(channel)}&gotoserverpresetname=${encodeURIComponent(presetName)}`);
|
|
362
|
+
}
|
|
363
|
+
getPtzPosition(camera) {
|
|
364
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
365
|
+
try {
|
|
366
|
+
const res = yield this.vapixGet(`/axis-cgi/com/ptz.cgi`, {
|
|
367
|
+
query: 'position',
|
|
368
|
+
camera: camera.toString(),
|
|
369
|
+
});
|
|
370
|
+
const data = this.parseGetParametrs(yield res.text());
|
|
371
|
+
return {
|
|
372
|
+
pan: Number(data.pan),
|
|
373
|
+
tilt: Number(data.tilt),
|
|
374
|
+
zoom: Number(data.zoom),
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
catch (err) {
|
|
378
|
+
return {
|
|
379
|
+
pan: 0,
|
|
380
|
+
tilt: 0,
|
|
381
|
+
zoom: 0,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
}
|
|
125
386
|
getInputState(port) {
|
|
126
387
|
return __awaiter(this, void 0, void 0, function* () {
|
|
127
388
|
const response = yield (yield this.vapixPost('/axis-cgi/io/port.cgi', `checkactive=${encodeURIComponent(port)}`)).text();
|
|
@@ -129,11 +390,13 @@ class CameraVapix extends eventemitter2_1.EventEmitter2 {
|
|
|
129
390
|
});
|
|
130
391
|
}
|
|
131
392
|
setOutputState(port, active) {
|
|
132
|
-
return this
|
|
393
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
394
|
+
return this.vapixPost('/axis-cgi/io/port.cgi', `action=${encodeURIComponent(port)}:${active ? '/' : '\\'}`);
|
|
395
|
+
});
|
|
133
396
|
}
|
|
134
397
|
getApplicationList() {
|
|
135
398
|
return __awaiter(this, void 0, void 0, function* () {
|
|
136
|
-
const xml = yield this.vapixGet('/axis-cgi/applications/list.cgi');
|
|
399
|
+
const xml = yield (yield this.vapixGet('/axis-cgi/applications/list.cgi')).text();
|
|
137
400
|
const result = (yield (0, xml2js_1.parseStringPromise)(xml));
|
|
138
401
|
const apps = [];
|
|
139
402
|
for (let i = 0; i < result.reply.application.length; i++) {
|
|
@@ -142,26 +405,55 @@ class CameraVapix extends eventemitter2_1.EventEmitter2 {
|
|
|
142
405
|
return apps;
|
|
143
406
|
});
|
|
144
407
|
}
|
|
145
|
-
|
|
408
|
+
startApplication(applicationID) {
|
|
146
409
|
return __awaiter(this, void 0, void 0, function* () {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
410
|
+
const res = yield this.vapixGet('/axis-cgi/applications/control.cgi', {
|
|
411
|
+
package: applicationID.toLowerCase(),
|
|
412
|
+
action: 'start',
|
|
413
|
+
});
|
|
414
|
+
const text = (yield res.text()).trim().toLowerCase();
|
|
415
|
+
if (res.ok && text === 'ok') {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
else if (text.startsWith('error:') && text.substring(7) === '6') {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
151
423
|
}
|
|
152
|
-
return outputStream;
|
|
153
424
|
});
|
|
154
425
|
}
|
|
155
|
-
|
|
426
|
+
restartApplication(applicationID) {
|
|
156
427
|
return __awaiter(this, void 0, void 0, function* () {
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
428
|
+
const res = yield this.vapixGet('/axis-cgi/applications/control.cgi', {
|
|
429
|
+
package: applicationID.toLowerCase(),
|
|
430
|
+
action: 'restart',
|
|
431
|
+
});
|
|
432
|
+
const text = (yield res.text()).trim().toLowerCase();
|
|
433
|
+
if (res.ok && text === 'ok') {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
else {
|
|
437
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
stopApplication(applicationID) {
|
|
442
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
443
|
+
const res = yield this.vapixGet('/axis-cgi/applications/control.cgi', {
|
|
444
|
+
package: applicationID.toLowerCase(),
|
|
445
|
+
action: 'stop',
|
|
446
|
+
});
|
|
447
|
+
const text = (yield res.text()).trim().toLowerCase();
|
|
448
|
+
if (res.ok && text === 'ok') {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
else if (text.startsWith('error:') && text.substring(7) === '6') {
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
throw new Error(yield (0, common_1.responseStringify)(res));
|
|
456
|
+
}
|
|
165
457
|
});
|
|
166
458
|
}
|
|
167
459
|
}
|
package/VapixEvents.d.ts
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
import { EventEmitter2 as EventEmitter } from 'eventemitter2';
|
|
2
2
|
import { WsOptions } from './internal/common';
|
|
3
3
|
export type VapixEventsOptions = WsOptions;
|
|
4
|
+
type TEventMessage = {
|
|
5
|
+
apiVersion: string;
|
|
6
|
+
method: string;
|
|
7
|
+
params: {
|
|
8
|
+
notification: {
|
|
9
|
+
timestamp: number;
|
|
10
|
+
topic: string;
|
|
11
|
+
message: {
|
|
12
|
+
source: Record<string, string>;
|
|
13
|
+
data: Record<string, string>;
|
|
14
|
+
key: Record<string, string>;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export interface VapixEvents {
|
|
20
|
+
on(event: 'open', listener: () => void): this;
|
|
21
|
+
on(event: 'close', listener: () => void): this;
|
|
22
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
23
|
+
on(event: string, listener: (data: TEventMessage) => void): this;
|
|
24
|
+
emit(event: 'open'): boolean;
|
|
25
|
+
emit(event: 'close'): boolean;
|
|
26
|
+
emit(event: 'error', err: Error): boolean;
|
|
27
|
+
emit(event: string, msg: TEventMessage): boolean;
|
|
28
|
+
}
|
|
4
29
|
export declare class VapixEvents extends EventEmitter {
|
|
5
30
|
private tls;
|
|
6
31
|
private tlsInsecure;
|
|
@@ -15,3 +40,4 @@ export declare class VapixEvents extends EventEmitter {
|
|
|
15
40
|
private createWsClient;
|
|
16
41
|
private isReservedEventName;
|
|
17
42
|
}
|
|
43
|
+
export {};
|
|
@@ -30,16 +30,15 @@ class HttpRequestSender {
|
|
|
30
30
|
return this.sendRequestWithAuth(options, postData);
|
|
31
31
|
}
|
|
32
32
|
sendRequestWithAuth(options, postData, wwwAuthenticateHeader) {
|
|
33
|
-
var _a;
|
|
33
|
+
var _a, _b;
|
|
34
34
|
return __awaiter(this, void 0, void 0, function* () {
|
|
35
|
+
(_a = options.timeout) !== null && _a !== void 0 ? _a : (options.timeout = 10000);
|
|
35
36
|
const url = HttpRequestSender.getURL(options);
|
|
36
37
|
const controller = new AbortController();
|
|
37
|
-
|
|
38
|
-
setTimeout(() => controller.abort(new Error('Request timeout')), options.timeout);
|
|
39
|
-
}
|
|
38
|
+
setTimeout(() => controller.abort(new Error('Request timeout')), options.timeout);
|
|
40
39
|
const authorization = this.getAuthorization(options, wwwAuthenticateHeader);
|
|
41
40
|
if (authorization !== undefined) {
|
|
42
|
-
(
|
|
41
|
+
(_b = options.headers) !== null && _b !== void 0 ? _b : (options.headers = {});
|
|
43
42
|
options.headers['Authorization'] = authorization;
|
|
44
43
|
}
|
|
45
44
|
let res;
|
package/internal/WsClient.d.ts
CHANGED
|
@@ -8,6 +8,16 @@ export type WsClientOptions = WsOptions & {
|
|
|
8
8
|
pingInterval?: number;
|
|
9
9
|
protocol?: string;
|
|
10
10
|
};
|
|
11
|
+
export interface WsClient {
|
|
12
|
+
on(event: 'open', listener: () => void): this;
|
|
13
|
+
on(event: 'close', listener: () => void): this;
|
|
14
|
+
on(event: 'message', listener: (data: Buffer) => void): this;
|
|
15
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
16
|
+
emit(event: 'open'): boolean;
|
|
17
|
+
emit(event: 'close'): boolean;
|
|
18
|
+
emit(event: 'message', data: Buffer): boolean;
|
|
19
|
+
emit(event: 'error', err: Error): boolean;
|
|
20
|
+
}
|
|
11
21
|
export declare class WsClient extends EventEmitter {
|
|
12
22
|
private user;
|
|
13
23
|
private pass;
|
package/internal/common.d.ts
CHANGED
package/internal/common.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isBrowserEnvironment = exports.isClient = void 0;
|
|
12
|
+
exports.responseStringify = exports.isBrowserEnvironment = exports.isClient = void 0;
|
|
4
13
|
function isClient(arg = {}) {
|
|
5
14
|
return 'get' in arg && 'post' in arg;
|
|
6
15
|
}
|
|
@@ -9,3 +18,12 @@ function isBrowserEnvironment() {
|
|
|
9
18
|
return typeof process === 'undefined' || process.versions === null || process.versions.node === null;
|
|
10
19
|
}
|
|
11
20
|
exports.isBrowserEnvironment = isBrowserEnvironment;
|
|
21
|
+
function responseStringify(res) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
return JSON.stringify({
|
|
24
|
+
status: res.status,
|
|
25
|
+
body: yield res.text(),
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
exports.responseStringify = responseStringify;
|