camstreamerlib 4.0.0-beta.3 → 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/CamOverlayDrawingAPI.js +6 -3
- package/cjs/CamOverlayPainter/Painter.d.ts +14 -3
- package/cjs/CamOverlayPainter/Painter.js +4 -1
- package/cjs/CamOverlayPainter/ResourceManager.js +6 -10
- package/cjs/CamScripterAPICameraEventsGenerator.js +6 -3
- package/cjs/CamSwitcherAPI.js +16 -20
- package/cjs/VapixAPI.d.ts +9 -9
- package/cjs/VapixAPI.js +20 -16
- package/cjs/VapixEvents.js +3 -3
- package/cjs/internal/Digest.js +6 -6
- package/cjs/node/DefaultClient.js +1 -1
- package/cjs/node/HttpServer.js +1 -1
- package/cjs/types/VapixAPI.d.ts +40 -61
- package/cjs/types/VapixAPI.js +10 -12
- package/esm/CamOverlayDrawingAPI.js +6 -3
- package/esm/CamOverlayPainter/Painter.d.ts +14 -3
- package/esm/CamOverlayPainter/Painter.js +4 -1
- package/esm/CamOverlayPainter/ResourceManager.js +6 -10
- package/esm/CamScripterAPICameraEventsGenerator.js +6 -3
- package/esm/CamSwitcherAPI.js +16 -20
- package/esm/VapixAPI.d.ts +9 -9
- package/esm/VapixAPI.js +20 -16
- package/esm/VapixEvents.js +3 -3
- package/esm/internal/Digest.js +6 -6
- package/esm/node/DefaultClient.js +1 -1
- package/esm/node/HttpServer.js +1 -1
- package/esm/types/VapixAPI.d.ts +40 -61
- package/esm/types/VapixAPI.js +10 -12
- package/package.json +3 -2
- package/README.md +0 -99
|
@@ -121,10 +121,10 @@ export class CamOverlayDrawingAPI extends EventEmitter {
|
|
|
121
121
|
}
|
|
122
122
|
if (dataJSON.call_id !== undefined) {
|
|
123
123
|
if (errorResponse !== undefined) {
|
|
124
|
-
this.sendMessages[dataJSON.call_id]
|
|
124
|
+
this.sendMessages[dataJSON.call_id]?.reject(new Error(errorResponse.error));
|
|
125
125
|
}
|
|
126
126
|
else {
|
|
127
|
-
this.sendMessages[dataJSON.call_id]
|
|
127
|
+
this.sendMessages[dataJSON.call_id]?.resolve(dataJSON);
|
|
128
128
|
}
|
|
129
129
|
delete this.sendMessages[dataJSON.call_id];
|
|
130
130
|
}
|
|
@@ -194,6 +194,9 @@ export class CamOverlayDrawingAPI extends EventEmitter {
|
|
|
194
194
|
const now = Date.now();
|
|
195
195
|
for (const callId in this.sendMessages) {
|
|
196
196
|
const msg = this.sendMessages[callId];
|
|
197
|
+
if (!msg) {
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
197
200
|
if (now - msg.sentTimestamp > 10000) {
|
|
198
201
|
reconnect = true;
|
|
199
202
|
msg.reject(new Error('Message timeout'));
|
|
@@ -220,7 +223,7 @@ export class CamOverlayDrawingAPI extends EventEmitter {
|
|
|
220
223
|
}
|
|
221
224
|
reportClose() {
|
|
222
225
|
for (const callId in this.sendMessages) {
|
|
223
|
-
this.sendMessages[callId]
|
|
226
|
+
this.sendMessages[callId]?.reject(new Error('Connection lost'));
|
|
224
227
|
}
|
|
225
228
|
this.sendMessages = {};
|
|
226
229
|
this.emit('close');
|
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
import { CamOverlayDrawingAPI, CamOverlayDrawingOptions } from '../CamOverlayDrawingAPI';
|
|
2
2
|
import ResourceManager from './ResourceManager';
|
|
3
3
|
import { Frame, TFrameOptions } from './Frame';
|
|
4
|
-
export declare const COORD:
|
|
4
|
+
export declare const COORD: {
|
|
5
|
+
readonly top_left: readonly [-1, -1];
|
|
6
|
+
readonly center_left: readonly [-1, 0];
|
|
7
|
+
readonly bottom_left: readonly [-1, 1];
|
|
8
|
+
readonly top_center: readonly [0, -1];
|
|
9
|
+
readonly center: readonly [0, 0];
|
|
10
|
+
readonly bottom_center: readonly [0, 1];
|
|
11
|
+
readonly top_right: readonly [1, -1];
|
|
12
|
+
readonly center_right: readonly [1, 0];
|
|
13
|
+
readonly bottom_right: readonly [1, 1];
|
|
14
|
+
};
|
|
15
|
+
type TCoAlignment = keyof typeof COORD;
|
|
5
16
|
export type TPainterOptions = TFrameOptions & {
|
|
6
17
|
screenWidth: number;
|
|
7
18
|
screenHeight: number;
|
|
8
|
-
coAlignment:
|
|
19
|
+
coAlignment: TCoAlignment;
|
|
9
20
|
};
|
|
10
21
|
export declare class Painter extends Frame {
|
|
11
22
|
private screenWidth;
|
|
@@ -24,7 +35,7 @@ export declare class Painter extends Frame {
|
|
|
24
35
|
registerImage(moniker: string, fileName: string): void;
|
|
25
36
|
registerFont(moniker: string, fileName: string): void;
|
|
26
37
|
setScreenSize(sw: number, sh: number): void;
|
|
27
|
-
setCoAlignment(coAlignment:
|
|
38
|
+
setCoAlignment(coAlignment: TCoAlignment): void;
|
|
28
39
|
protected layoutChanged(): void;
|
|
29
40
|
display(scale?: number): Promise<void>;
|
|
30
41
|
hide(): Promise<void>;
|
|
@@ -82,6 +82,9 @@ export class Painter extends Frame {
|
|
|
82
82
|
let lastCachedLayer;
|
|
83
83
|
for (let i = 0; i < this.layers.length; i++) {
|
|
84
84
|
const layer = this.layers[i];
|
|
85
|
+
if (layer === undefined) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
85
88
|
if (layer.cairoCache !== undefined &&
|
|
86
89
|
layer.surfaceCache !== undefined &&
|
|
87
90
|
surface === undefined &&
|
|
@@ -115,7 +118,7 @@ export class Painter extends Frame {
|
|
|
115
118
|
}
|
|
116
119
|
for (let i = layerIdx; i < this.layers.length; i++) {
|
|
117
120
|
const currentLayer = this.layers[i];
|
|
118
|
-
if (currentLayer
|
|
121
|
+
if (currentLayer?.surfaceCache !== undefined && currentLayer.cairoCache !== undefined) {
|
|
119
122
|
await this.cleanupSurface(currentLayer.surfaceCache, currentLayer.cairoCache);
|
|
120
123
|
currentLayer.surfaceCache = undefined;
|
|
121
124
|
currentLayer.cairoCache = undefined;
|
|
@@ -15,30 +15,26 @@ export default class ResourceManager {
|
|
|
15
15
|
this.fontFileNames[moniker] = process.env.INSTALL_PATH + '/fonts/' + fileName;
|
|
16
16
|
}
|
|
17
17
|
async image(moniker) {
|
|
18
|
-
if (moniker
|
|
18
|
+
if (this.images[moniker] !== undefined) {
|
|
19
19
|
return this.images[moniker];
|
|
20
20
|
}
|
|
21
|
-
|
|
21
|
+
if (this.imgFileNames[moniker] !== undefined) {
|
|
22
22
|
const imgData = await fs.readFile(this.imgFileNames[moniker]);
|
|
23
23
|
this.images[moniker] = await this.co.uploadImageData(imgData);
|
|
24
24
|
return this.images[moniker];
|
|
25
25
|
}
|
|
26
|
-
|
|
27
|
-
throw new Error('Error! Unknown image requested!');
|
|
28
|
-
}
|
|
26
|
+
throw new Error('Error! Unknown image requested!');
|
|
29
27
|
}
|
|
30
28
|
async font(moniker) {
|
|
31
|
-
if (moniker
|
|
29
|
+
if (this.fonts[moniker] !== undefined) {
|
|
32
30
|
return this.fonts[moniker];
|
|
33
31
|
}
|
|
34
|
-
|
|
32
|
+
if (this.fontFileNames[moniker] !== undefined) {
|
|
35
33
|
const fontData = await fs.readFile(this.fontFileNames[moniker]);
|
|
36
34
|
this.fonts[moniker] = await this.co.uploadFontData(fontData);
|
|
37
35
|
return this.fonts[moniker];
|
|
38
36
|
}
|
|
39
|
-
|
|
40
|
-
throw new Error('Error! Unknown font requested!');
|
|
41
|
-
}
|
|
37
|
+
throw new Error('Error! Unknown font requested!');
|
|
42
38
|
}
|
|
43
39
|
clear() {
|
|
44
40
|
this.images = {};
|
|
@@ -88,10 +88,10 @@ export class CamScripterAPICameraEventsGenerator extends EventEmitter {
|
|
|
88
88
|
}
|
|
89
89
|
if (dataJSON.call_id !== undefined) {
|
|
90
90
|
if (errorResponse !== undefined) {
|
|
91
|
-
this.sendMessages[dataJSON.call_id]
|
|
91
|
+
this.sendMessages[dataJSON.call_id]?.reject(new Error(errorResponse.error));
|
|
92
92
|
}
|
|
93
93
|
else {
|
|
94
|
-
this.sendMessages[dataJSON.call_id]
|
|
94
|
+
this.sendMessages[dataJSON.call_id]?.resolve(dataJSON);
|
|
95
95
|
}
|
|
96
96
|
delete this.sendMessages[dataJSON.call_id];
|
|
97
97
|
}
|
|
@@ -124,6 +124,9 @@ export class CamScripterAPICameraEventsGenerator extends EventEmitter {
|
|
|
124
124
|
const now = Date.now();
|
|
125
125
|
for (const callId in this.sendMessages) {
|
|
126
126
|
const msg = this.sendMessages[callId];
|
|
127
|
+
if (!msg) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
127
130
|
if (now - msg.sentTimestamp > 10000) {
|
|
128
131
|
reconnect = true;
|
|
129
132
|
msg.reject(new Error('Message timeout'));
|
|
@@ -147,7 +150,7 @@ export class CamScripterAPICameraEventsGenerator extends EventEmitter {
|
|
|
147
150
|
}
|
|
148
151
|
reportClose() {
|
|
149
152
|
for (const callId in this.sendMessages) {
|
|
150
|
-
this.sendMessages[callId]
|
|
153
|
+
this.sendMessages[callId]?.reject(new Error('Connection lost'));
|
|
151
154
|
}
|
|
152
155
|
this.sendMessages = {};
|
|
153
156
|
this.emit('close');
|
package/esm/CamSwitcherAPI.js
CHANGED
|
@@ -292,16 +292,12 @@ const parseBitrateOptionsToBitrateVapixParams = (firmWareVersion, bitrateMode, c
|
|
|
292
292
|
if (bitrateMode === null) {
|
|
293
293
|
return '';
|
|
294
294
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (bitrateMode === 'ABR') {
|
|
302
|
-
return `videobitratemode=abr&videoabrtargetbitrate=${cameraOptions.maximumBitRate}&videoabrretentiontime=${cameraOptions.retentionTime}&videoabrmaxbitrate=${cameraOptions.bitRateLimit}`;
|
|
303
|
-
}
|
|
304
|
-
throw new Error('Unknown bitrateMode param in getVapixParams method.');
|
|
295
|
+
const data = {
|
|
296
|
+
VBR: 'videobitratemode=vbr',
|
|
297
|
+
MBR: `videobitratemode=mbr&videomaxbitrate=${cameraOptions.maximumBitRate}`,
|
|
298
|
+
ABR: `videobitratemode=abr&videoabrtargetbitrate=${cameraOptions.maximumBitRate}&videoabrretentiontime=${cameraOptions.retentionTime}&videoabrmaxbitrate=${cameraOptions.bitRateLimit}`,
|
|
299
|
+
};
|
|
300
|
+
return data[bitrateMode];
|
|
305
301
|
};
|
|
306
302
|
const parseVapixParamsToBitrateOptions = (bitrateVapixParams) => {
|
|
307
303
|
const params = {};
|
|
@@ -312,7 +308,7 @@ const parseVapixParamsToBitrateOptions = (bitrateVapixParams) => {
|
|
|
312
308
|
const bitrateMode = params['videobitratemode'] !== undefined ? params['videobitratemode'].toUpperCase() : undefined;
|
|
313
309
|
const hasLowerFw = bitrateMode === undefined && params['videomaxbitrate'] !== undefined;
|
|
314
310
|
if (hasLowerFw) {
|
|
315
|
-
const maximumBitRate = parseInt(params['videomaxbitrate'], 10);
|
|
311
|
+
const maximumBitRate = parseInt(params['videomaxbitrate'] ?? '0', 10);
|
|
316
312
|
return {
|
|
317
313
|
bitrateMode: 'MBR',
|
|
318
314
|
maximumBitRate: maximumBitRate,
|
|
@@ -321,19 +317,19 @@ const parseVapixParamsToBitrateOptions = (bitrateVapixParams) => {
|
|
|
321
317
|
};
|
|
322
318
|
}
|
|
323
319
|
if (bitrateMode === 'ABR') {
|
|
324
|
-
const maximumBitRate = parseInt(params['videoabrtargetbitrate'], 10);
|
|
325
|
-
const retentionTime = parseInt(params['videoabrretentiontime'], 10);
|
|
326
|
-
const
|
|
320
|
+
const maximumBitRate = parseInt(params['videoabrtargetbitrate'] ?? '0', 10);
|
|
321
|
+
const retentionTime = parseInt(params['videoabrretentiontime'] ?? '0', 10);
|
|
322
|
+
const bitRateLimit = parseInt(params['videoabrmaxbitrate'] ?? '0', 10);
|
|
327
323
|
return {
|
|
328
|
-
bitrateMode
|
|
329
|
-
maximumBitRate
|
|
330
|
-
retentionTime
|
|
331
|
-
bitRateLimit
|
|
324
|
+
bitrateMode,
|
|
325
|
+
maximumBitRate,
|
|
326
|
+
retentionTime,
|
|
327
|
+
bitRateLimit,
|
|
332
328
|
};
|
|
333
329
|
}
|
|
334
330
|
else if (bitrateMode === 'MBR') {
|
|
335
|
-
const maximumBitRate = parseInt(params['videomaxbitrate'], 10);
|
|
336
|
-
const oldMaximumBitrateParamValue = parseInt(params['videombrmaxbitrate'], 10);
|
|
331
|
+
const maximumBitRate = params['videomaxbitrate'] !== undefined ? parseInt(params['videomaxbitrate'], 10) : null;
|
|
332
|
+
const oldMaximumBitrateParamValue = parseInt(params['videombrmaxbitrate'] ?? '0', 10);
|
|
337
333
|
return {
|
|
338
334
|
bitrateMode: bitrateMode,
|
|
339
335
|
maximumBitRate: maximumBitRate ?? oldMaximumBitrateParamValue,
|
package/esm/VapixAPI.d.ts
CHANGED
|
@@ -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/esm/VapixAPI.js
CHANGED
|
@@ -11,7 +11,7 @@ export class VapixAPI {
|
|
|
11
11
|
constructor(client, getProxyUrl) {
|
|
12
12
|
this.client = new ProxyClient(client, getProxyUrl);
|
|
13
13
|
}
|
|
14
|
-
async getUrlEncoded(proxy
|
|
14
|
+
async getUrlEncoded(proxy, path, parameters, headers = {}) {
|
|
15
15
|
const data = paramToUrl(parameters);
|
|
16
16
|
const head = { ...headers, 'Content-Type': 'application/x-www-form-urlencoded' };
|
|
17
17
|
const res = await this.client.post(proxy, path, data, {}, head);
|
|
@@ -20,7 +20,7 @@ export class VapixAPI {
|
|
|
20
20
|
}
|
|
21
21
|
return res;
|
|
22
22
|
}
|
|
23
|
-
async postJson(proxy
|
|
23
|
+
async postJson(proxy, path, jsonData, headers = {}) {
|
|
24
24
|
const data = JSON.stringify(jsonData);
|
|
25
25
|
const head = { ...headers, 'Content-Type': 'application/json' };
|
|
26
26
|
const res = await this.client.post(proxy, path, data, {}, head);
|
|
@@ -231,9 +231,9 @@ export class VapixAPI {
|
|
|
231
231
|
const gTour = {
|
|
232
232
|
id: gTourBaseName,
|
|
233
233
|
camNbr: response[gTourBaseName + '.CamNbr'],
|
|
234
|
-
name: response[gTourBaseName + '.Name'],
|
|
234
|
+
name: response[gTourBaseName + '.Name'] ?? 'Guard Tour ' + (i + 1),
|
|
235
235
|
randomEnabled: response[gTourBaseName + '.RandomEnabled'],
|
|
236
|
-
running: response[gTourBaseName + '.Running'],
|
|
236
|
+
running: response[gTourBaseName + '.Running'] ?? 'no',
|
|
237
237
|
timeBetweenSequences: response[gTourBaseName + '.TimeBetweenSequences'],
|
|
238
238
|
tour: [],
|
|
239
239
|
};
|
|
@@ -298,8 +298,12 @@ export class VapixAPI {
|
|
|
298
298
|
});
|
|
299
299
|
const data = parseCameraPtzResponse(await response.text());
|
|
300
300
|
const res = {};
|
|
301
|
-
Object.keys(data)
|
|
302
|
-
|
|
301
|
+
Object.keys(data)
|
|
302
|
+
.map(Number)
|
|
303
|
+
.forEach((camera) => {
|
|
304
|
+
if (data[camera] !== undefined) {
|
|
305
|
+
res[camera - 1] = data[camera]?.map(({ data: itemData, ...d }) => d);
|
|
306
|
+
}
|
|
303
307
|
});
|
|
304
308
|
return res;
|
|
305
309
|
}
|
|
@@ -323,7 +327,7 @@ export class VapixAPI {
|
|
|
323
327
|
}
|
|
324
328
|
async getInputState(port, proxy = null) {
|
|
325
329
|
const response = await (await this.getUrlEncoded(proxy, '/axis-cgi/io/port.cgi', { checkactive: port.toString() })).text();
|
|
326
|
-
return response.split('=')[1]
|
|
330
|
+
return response.split('=')[1]?.indexOf('active') === 0;
|
|
327
331
|
}
|
|
328
332
|
async setOutputState(port, active, proxy = null) {
|
|
329
333
|
return this.getUrlEncoded(proxy, '/axis-cgi/io/port.cgi', { action: active ? `${port}:/` : `${port}:\\` });
|
|
@@ -333,10 +337,10 @@ export class VapixAPI {
|
|
|
333
337
|
const xml = await res.text();
|
|
334
338
|
const result = (await parseStringPromise(xml));
|
|
335
339
|
const apps = [];
|
|
336
|
-
for (
|
|
340
|
+
for (const app of result.reply.application) {
|
|
337
341
|
apps.push({
|
|
338
|
-
...
|
|
339
|
-
appId: APP_IDS.find((id) => id.toLowerCase() ===
|
|
342
|
+
...app.$,
|
|
343
|
+
appId: APP_IDS.find((id) => id.toLowerCase() === app.$.Name.toLowerCase()) ?? null,
|
|
340
344
|
});
|
|
341
345
|
}
|
|
342
346
|
return apps;
|
|
@@ -389,14 +393,14 @@ export class VapixAPI {
|
|
|
389
393
|
const parseParameters = (response) => {
|
|
390
394
|
const params = {};
|
|
391
395
|
const lines = response.split(/[\r\n]/);
|
|
392
|
-
for (
|
|
393
|
-
if (
|
|
396
|
+
for (const line of lines) {
|
|
397
|
+
if (line.length === 0 || line.substring(0, 7) === '# Error') {
|
|
394
398
|
continue;
|
|
395
399
|
}
|
|
396
|
-
const delimiterPos =
|
|
400
|
+
const delimiterPos = line.indexOf('=');
|
|
397
401
|
if (delimiterPos !== -1) {
|
|
398
|
-
const paramName =
|
|
399
|
-
const paramValue =
|
|
402
|
+
const paramName = line.substring(0, delimiterPos);
|
|
403
|
+
const paramValue = line.substring(delimiterPos + 1);
|
|
400
404
|
params[paramName] = paramValue;
|
|
401
405
|
}
|
|
402
406
|
}
|
|
@@ -442,7 +446,7 @@ const parsePtz = (parsed) => {
|
|
|
442
446
|
};
|
|
443
447
|
res.push({
|
|
444
448
|
id,
|
|
445
|
-
name: data[0],
|
|
449
|
+
name: data[0] ?? 'Preset ' + id,
|
|
446
450
|
data: {
|
|
447
451
|
pan: getValue('pan'),
|
|
448
452
|
tilt: getValue('tilt'),
|
package/esm/VapixEvents.js
CHANGED
|
@@ -39,10 +39,10 @@ export class VapixEvents extends EventEmitter {
|
|
|
39
39
|
this.ws.on('open', () => {
|
|
40
40
|
const topics = [];
|
|
41
41
|
const eventNames = this.eventNames();
|
|
42
|
-
for (
|
|
43
|
-
if (!this.isReservedEventName(
|
|
42
|
+
for (const eventName of eventNames) {
|
|
43
|
+
if (!this.isReservedEventName(eventName)) {
|
|
44
44
|
const topic = {
|
|
45
|
-
topicFilter:
|
|
45
|
+
topicFilter: eventName,
|
|
46
46
|
};
|
|
47
47
|
topics.push(topic);
|
|
48
48
|
}
|
package/esm/internal/Digest.js
CHANGED
|
@@ -4,17 +4,17 @@ export class Digest {
|
|
|
4
4
|
getAuthHeader(user, pass, method, uri, wwwAuthenticateHeader) {
|
|
5
5
|
const digestItems = {};
|
|
6
6
|
const digestArr = wwwAuthenticateHeader.substring(wwwAuthenticateHeader.indexOf('Digest') + 6).split(',');
|
|
7
|
-
for (
|
|
8
|
-
const pos =
|
|
9
|
-
const key =
|
|
10
|
-
const value =
|
|
7
|
+
for (const arg of digestArr) {
|
|
8
|
+
const pos = arg.indexOf('=');
|
|
9
|
+
const key = arg.substring(0, pos).trim();
|
|
10
|
+
const value = arg.substring(pos + 1).trim();
|
|
11
11
|
digestItems[key] = value.replace(/"/g, '');
|
|
12
12
|
}
|
|
13
13
|
const HA1 = crypto.createHash('md5').update(`${user}:${digestItems['realm']}:${pass}`).digest('hex');
|
|
14
14
|
const HA2 = crypto.createHash('md5').update(`${method}:${uri}`).digest('hex');
|
|
15
15
|
const ncValue = ('00000000' + this.nonceCount.toString(16)).slice(-8);
|
|
16
16
|
let response;
|
|
17
|
-
if (digestItems['qop']) {
|
|
17
|
+
if (digestItems['qop'] !== undefined) {
|
|
18
18
|
response = crypto
|
|
19
19
|
.createHash('md5')
|
|
20
20
|
.update(`${HA1}:${digestItems['nonce']}:${ncValue}:162d50aa594e9648:auth:${HA2}`)
|
|
@@ -29,7 +29,7 @@ export class Digest {
|
|
|
29
29
|
`nonce="${digestItems['nonce']}",` +
|
|
30
30
|
`uri="${uri}",` +
|
|
31
31
|
`response="${response}"`;
|
|
32
|
-
if (digestItems['qop']) {
|
|
32
|
+
if (digestItems['qop'] !== undefined) {
|
|
33
33
|
header += `,qop=auth,nc=${ncValue},cnonce="162d50aa594e9648"`;
|
|
34
34
|
}
|
|
35
35
|
this.nonceCount++;
|
|
@@ -36,7 +36,7 @@ export class DefaultClient {
|
|
|
36
36
|
return this.httpRequestSender.sendRequest(options, data);
|
|
37
37
|
}
|
|
38
38
|
getBaseConnectionParams(method, path, params) {
|
|
39
|
-
|
|
39
|
+
const pathName = addParametersToPath(path, params);
|
|
40
40
|
return {
|
|
41
41
|
method: method,
|
|
42
42
|
protocol: this.tls ? 'https:' : 'http:',
|
package/esm/node/HttpServer.js
CHANGED
package/esm/types/VapixAPI.d.ts
CHANGED
|
@@ -1509,7 +1509,7 @@ export declare const audioDeviceRequestSchema: z.ZodObject<{
|
|
|
1509
1509
|
}>;
|
|
1510
1510
|
export type TAudioDeviceFromRequest = z.infer<typeof audioDeviceFromRequestSchema>;
|
|
1511
1511
|
export declare const maxFpsResponseSchema: z.ZodObject<{
|
|
1512
|
-
data: z.ZodArray<z.ZodObject<{
|
|
1512
|
+
data: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1513
1513
|
channel: z.ZodNumber;
|
|
1514
1514
|
captureMode: z.ZodArray<z.ZodObject<{
|
|
1515
1515
|
enabled: z.ZodBoolean;
|
|
@@ -1533,23 +1533,23 @@ export declare const maxFpsResponseSchema: z.ZodObject<{
|
|
|
1533
1533
|
enabled: boolean;
|
|
1534
1534
|
maxFPS?: number | undefined;
|
|
1535
1535
|
}[];
|
|
1536
|
-
}>, "many"
|
|
1536
|
+
}>, "many">>;
|
|
1537
1537
|
}, "strip", z.ZodTypeAny, {
|
|
1538
|
-
data
|
|
1538
|
+
data?: {
|
|
1539
1539
|
channel: number;
|
|
1540
1540
|
captureMode: {
|
|
1541
1541
|
enabled: boolean;
|
|
1542
1542
|
maxFPS?: number | undefined;
|
|
1543
1543
|
}[];
|
|
1544
|
-
}[];
|
|
1544
|
+
}[] | undefined;
|
|
1545
1545
|
}, {
|
|
1546
|
-
data
|
|
1546
|
+
data?: {
|
|
1547
1547
|
channel: number;
|
|
1548
1548
|
captureMode: {
|
|
1549
1549
|
enabled: boolean;
|
|
1550
1550
|
maxFPS?: number | undefined;
|
|
1551
1551
|
}[];
|
|
1552
|
-
}[];
|
|
1552
|
+
}[] | undefined;
|
|
1553
1553
|
}>;
|
|
1554
1554
|
export declare const dateTimeinfoSchema: z.ZodObject<{
|
|
1555
1555
|
data: z.ZodObject<{
|
|
@@ -1590,8 +1590,8 @@ export declare const dateTimeinfoSchema: z.ZodObject<{
|
|
|
1590
1590
|
}>;
|
|
1591
1591
|
export declare const audioSampleRatesResponseSchema: z.ZodObject<{
|
|
1592
1592
|
data: z.ZodObject<{
|
|
1593
|
-
encoders: z.
|
|
1594
|
-
aac: z.ZodArray<z.ZodObject<{
|
|
1593
|
+
encoders: z.ZodObject<{
|
|
1594
|
+
aac: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1595
1595
|
sample_rate: z.ZodNumber;
|
|
1596
1596
|
bit_rates: z.ZodArray<z.ZodNumber, "many">;
|
|
1597
1597
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -1600,22 +1600,8 @@ export declare const audioSampleRatesResponseSchema: z.ZodObject<{
|
|
|
1600
1600
|
}, {
|
|
1601
1601
|
sample_rate: number;
|
|
1602
1602
|
bit_rates: number[];
|
|
1603
|
-
}>, "many"
|
|
1604
|
-
AAC: z.
|
|
1605
|
-
}, "strip", z.ZodTypeAny, {
|
|
1606
|
-
aac: {
|
|
1607
|
-
sample_rate: number;
|
|
1608
|
-
bit_rates: number[];
|
|
1609
|
-
}[];
|
|
1610
|
-
AAC?: undefined;
|
|
1611
|
-
}, {
|
|
1612
|
-
aac: {
|
|
1613
|
-
sample_rate: number;
|
|
1614
|
-
bit_rates: number[];
|
|
1615
|
-
}[];
|
|
1616
|
-
AAC?: undefined;
|
|
1617
|
-
}>, z.ZodObject<{
|
|
1618
|
-
AAC: z.ZodArray<z.ZodObject<{
|
|
1603
|
+
}>, "many">>;
|
|
1604
|
+
AAC: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1619
1605
|
sample_rate: z.ZodNumber;
|
|
1620
1606
|
bit_rates: z.ZodArray<z.ZodNumber, "many">;
|
|
1621
1607
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -1624,80 +1610,73 @@ export declare const audioSampleRatesResponseSchema: z.ZodObject<{
|
|
|
1624
1610
|
}, {
|
|
1625
1611
|
sample_rate: number;
|
|
1626
1612
|
bit_rates: number[];
|
|
1627
|
-
}>, "many"
|
|
1628
|
-
aac: z.ZodUndefined;
|
|
1613
|
+
}>, "many">>;
|
|
1629
1614
|
}, "strip", z.ZodTypeAny, {
|
|
1630
|
-
|
|
1615
|
+
aac?: {
|
|
1631
1616
|
sample_rate: number;
|
|
1632
1617
|
bit_rates: number[];
|
|
1633
|
-
}[];
|
|
1634
|
-
|
|
1618
|
+
}[] | undefined;
|
|
1619
|
+
AAC?: {
|
|
1620
|
+
sample_rate: number;
|
|
1621
|
+
bit_rates: number[];
|
|
1622
|
+
}[] | undefined;
|
|
1635
1623
|
}, {
|
|
1636
|
-
|
|
1624
|
+
aac?: {
|
|
1637
1625
|
sample_rate: number;
|
|
1638
1626
|
bit_rates: number[];
|
|
1639
|
-
}[];
|
|
1640
|
-
|
|
1641
|
-
|
|
1627
|
+
}[] | undefined;
|
|
1628
|
+
AAC?: {
|
|
1629
|
+
sample_rate: number;
|
|
1630
|
+
bit_rates: number[];
|
|
1631
|
+
}[] | undefined;
|
|
1632
|
+
}>;
|
|
1642
1633
|
}, "strip", z.ZodTypeAny, {
|
|
1643
1634
|
encoders: {
|
|
1644
|
-
aac
|
|
1635
|
+
aac?: {
|
|
1645
1636
|
sample_rate: number;
|
|
1646
1637
|
bit_rates: number[];
|
|
1647
|
-
}[];
|
|
1648
|
-
AAC?:
|
|
1649
|
-
} | {
|
|
1650
|
-
AAC: {
|
|
1638
|
+
}[] | undefined;
|
|
1639
|
+
AAC?: {
|
|
1651
1640
|
sample_rate: number;
|
|
1652
1641
|
bit_rates: number[];
|
|
1653
|
-
}[];
|
|
1654
|
-
aac?: undefined;
|
|
1642
|
+
}[] | undefined;
|
|
1655
1643
|
};
|
|
1656
1644
|
}, {
|
|
1657
1645
|
encoders: {
|
|
1658
|
-
aac
|
|
1646
|
+
aac?: {
|
|
1659
1647
|
sample_rate: number;
|
|
1660
1648
|
bit_rates: number[];
|
|
1661
|
-
}[];
|
|
1662
|
-
AAC?:
|
|
1663
|
-
} | {
|
|
1664
|
-
AAC: {
|
|
1649
|
+
}[] | undefined;
|
|
1650
|
+
AAC?: {
|
|
1665
1651
|
sample_rate: number;
|
|
1666
1652
|
bit_rates: number[];
|
|
1667
|
-
}[];
|
|
1668
|
-
aac?: undefined;
|
|
1653
|
+
}[] | undefined;
|
|
1669
1654
|
};
|
|
1670
1655
|
}>;
|
|
1671
1656
|
}, "strip", z.ZodTypeAny, {
|
|
1672
1657
|
data: {
|
|
1673
1658
|
encoders: {
|
|
1674
|
-
aac
|
|
1659
|
+
aac?: {
|
|
1675
1660
|
sample_rate: number;
|
|
1676
1661
|
bit_rates: number[];
|
|
1677
|
-
}[];
|
|
1678
|
-
AAC?:
|
|
1679
|
-
} | {
|
|
1680
|
-
AAC: {
|
|
1662
|
+
}[] | undefined;
|
|
1663
|
+
AAC?: {
|
|
1681
1664
|
sample_rate: number;
|
|
1682
1665
|
bit_rates: number[];
|
|
1683
|
-
}[];
|
|
1684
|
-
aac?: undefined;
|
|
1666
|
+
}[] | undefined;
|
|
1685
1667
|
};
|
|
1686
1668
|
};
|
|
1687
1669
|
}, {
|
|
1688
1670
|
data: {
|
|
1689
1671
|
encoders: {
|
|
1690
|
-
aac
|
|
1672
|
+
aac?: {
|
|
1691
1673
|
sample_rate: number;
|
|
1692
1674
|
bit_rates: number[];
|
|
1693
|
-
}[];
|
|
1694
|
-
AAC?:
|
|
1695
|
-
} | {
|
|
1696
|
-
AAC: {
|
|
1675
|
+
}[] | undefined;
|
|
1676
|
+
AAC?: {
|
|
1697
1677
|
sample_rate: number;
|
|
1698
1678
|
bit_rates: number[];
|
|
1699
|
-
}[];
|
|
1700
|
-
aac?: undefined;
|
|
1679
|
+
}[] | undefined;
|
|
1701
1680
|
};
|
|
1702
1681
|
};
|
|
1703
1682
|
}>;
|
package/esm/types/VapixAPI.js
CHANGED
|
@@ -96,13 +96,15 @@ const audioDeviceFromRequestSchema = z.object({
|
|
|
96
96
|
});
|
|
97
97
|
export const audioDeviceRequestSchema = z.object({ devices: z.array(audioDeviceFromRequestSchema) });
|
|
98
98
|
export const maxFpsResponseSchema = z.object({
|
|
99
|
-
data: z
|
|
99
|
+
data: z
|
|
100
|
+
.array(z.object({
|
|
100
101
|
channel: z.number(),
|
|
101
102
|
captureMode: z.array(z.object({
|
|
102
103
|
enabled: z.boolean(),
|
|
103
104
|
maxFPS: z.number().optional(),
|
|
104
105
|
})),
|
|
105
|
-
}))
|
|
106
|
+
}))
|
|
107
|
+
.optional(),
|
|
106
108
|
});
|
|
107
109
|
export const dateTimeinfoSchema = z.object({
|
|
108
110
|
data: z.object({
|
|
@@ -115,15 +117,11 @@ export const dateTimeinfoSchema = z.object({
|
|
|
115
117
|
});
|
|
116
118
|
export const audioSampleRatesResponseSchema = z.object({
|
|
117
119
|
data: z.object({
|
|
118
|
-
encoders: z
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
AAC: z.array(audioSampleRatesSchema),
|
|
125
|
-
aac: z.undefined(),
|
|
126
|
-
}),
|
|
127
|
-
]),
|
|
120
|
+
encoders: z
|
|
121
|
+
.object({
|
|
122
|
+
aac: z.array(audioSampleRatesSchema),
|
|
123
|
+
AAC: z.array(audioSampleRatesSchema),
|
|
124
|
+
})
|
|
125
|
+
.partial(),
|
|
128
126
|
}),
|
|
129
127
|
});
|