camstreamerlib 1.8.7 → 1.9.0

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.
@@ -0,0 +1,59 @@
1
+ /// <reference types="node" />
2
+ import * as EventEmitter from 'events';
3
+ export declare type CamScripterOptions = {
4
+ tls?: boolean;
5
+ tlsInsecure?: boolean;
6
+ ip?: string;
7
+ port?: number;
8
+ auth?: string;
9
+ };
10
+ export declare type Declaration = {
11
+ type?: '' | 'SOURCE' | 'DATA';
12
+ namespace: string;
13
+ key: string;
14
+ value: string | boolean | number;
15
+ value_type: 'STRING' | 'INT' | 'BOOL' | 'DOUBLE';
16
+ key_nice_name?: string;
17
+ value_nice_name?: string;
18
+ };
19
+ export declare type EventDeclaration = {
20
+ declaration_id: string;
21
+ stateless: boolean;
22
+ declaration: Declaration[];
23
+ };
24
+ export declare type EventUndeclaration = {
25
+ declaration_id: string;
26
+ };
27
+ export declare type EventData = {
28
+ namespace: string;
29
+ key: string;
30
+ value: string | boolean | number;
31
+ value_type: 'STRING' | 'INT' | 'BOOL' | 'DOUBLE';
32
+ };
33
+ export declare type Event = {
34
+ declaration_id: string;
35
+ event_data: EventData[];
36
+ };
37
+ export declare type Response = {
38
+ call_id: number;
39
+ message: string;
40
+ };
41
+ export declare class CamScripterAPICameraEventsGenerator extends EventEmitter {
42
+ private tls;
43
+ private tlsInsecure;
44
+ private ip;
45
+ private port;
46
+ private auth;
47
+ private callId;
48
+ private sendMessages;
49
+ private ws;
50
+ constructor(options?: CamScripterOptions);
51
+ connect(): Promise<void>;
52
+ private openWebsocket;
53
+ declareEvent(eventDeclaration: EventDeclaration): Promise<Response>;
54
+ undeclareEvent(eventUndeclaration: EventUndeclaration): Promise<Response>;
55
+ sendEvent(event: Event): Promise<Response>;
56
+ private sendMessage;
57
+ private reportErr;
58
+ private reportClose;
59
+ }
@@ -0,0 +1,148 @@
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
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.CamScripterAPICameraEventsGenerator = void 0;
13
+ const WebSocket = require("ws");
14
+ const EventEmitter = require("events");
15
+ const Digest_1 = require("./Digest");
16
+ class CamScripterAPICameraEventsGenerator extends EventEmitter {
17
+ constructor(options) {
18
+ var _a, _b, _c, _d, _e;
19
+ super();
20
+ this.ws = null;
21
+ this.tls = (_a = options === null || options === void 0 ? void 0 : options.tls) !== null && _a !== void 0 ? _a : false;
22
+ this.tlsInsecure = (_b = options === null || options === void 0 ? void 0 : options.tlsInsecure) !== null && _b !== void 0 ? _b : false;
23
+ this.ip = (_c = options === null || options === void 0 ? void 0 : options.ip) !== null && _c !== void 0 ? _c : '127.0.0.1';
24
+ this.port = (_d = options === null || options === void 0 ? void 0 : options.port) !== null && _d !== void 0 ? _d : (this.tls ? 443 : 80);
25
+ this.auth = (_e = options === null || options === void 0 ? void 0 : options.auth) !== null && _e !== void 0 ? _e : '';
26
+ this.callId = 0;
27
+ this.sendMessages = {};
28
+ EventEmitter.call(this);
29
+ }
30
+ connect() {
31
+ return __awaiter(this, void 0, void 0, function* () {
32
+ try {
33
+ yield this.openWebsocket();
34
+ this.emit('open');
35
+ }
36
+ catch (err) {
37
+ this.reportErr(err);
38
+ }
39
+ });
40
+ }
41
+ openWebsocket(digestHeader) {
42
+ return new Promise((resolve, reject) => {
43
+ const userPass = this.auth.split(':');
44
+ const protocol = this.tls ? 'wss' : 'ws';
45
+ const addr = `${protocol}://${this.ip}:${this.port}/local/camscripter/ws`;
46
+ const options = {
47
+ auth: this.auth,
48
+ rejectUnauthorized: !this.tlsInsecure,
49
+ headers: {},
50
+ };
51
+ if (digestHeader !== undefined) {
52
+ options.headers['Authorization'] = Digest_1.Digest.getAuthHeader(userPass[0], userPass[1], 'GET', '/local/camscripter/ws', digestHeader);
53
+ }
54
+ this.ws = new WebSocket(addr, 'camera-events', options);
55
+ this.ws.binaryType = 'arraybuffer';
56
+ this.ws.isAlive = true;
57
+ const pingTimer = setInterval(() => {
58
+ if (this.ws.readyState !== this.ws.OPEN || this.ws.isAlive === false) {
59
+ return this.ws.terminate();
60
+ }
61
+ this.ws.isAlive = false;
62
+ this.ws.ping();
63
+ }, 30000);
64
+ this.ws.on('open', () => {
65
+ resolve();
66
+ });
67
+ this.ws.on('pong', () => {
68
+ this.ws.isAlive = true;
69
+ });
70
+ this.ws.on('message', (data) => {
71
+ const dataJSON = JSON.parse(data);
72
+ if (dataJSON.hasOwnProperty('call_id') && dataJSON['call_id'] in this.sendMessages) {
73
+ if (dataJSON.hasOwnProperty('error')) {
74
+ this.sendMessages[dataJSON['call_id']].reject(new Error(dataJSON.error));
75
+ }
76
+ else {
77
+ this.sendMessages[dataJSON['call_id']].resolve(dataJSON);
78
+ }
79
+ delete this.sendMessages[dataJSON['call_id']];
80
+ }
81
+ if (dataJSON.hasOwnProperty('error')) {
82
+ this.reportErr(new Error(dataJSON.error));
83
+ }
84
+ });
85
+ this.ws.on('unexpected-response', (req, res) => __awaiter(this, void 0, void 0, function* () {
86
+ if (res.statusCode === 401 && res.headers['www-authenticate'] !== undefined)
87
+ this.openWebsocket(res.headers['www-authenticate']).then(resolve, reject);
88
+ else {
89
+ reject('Error: status code: ' + res.statusCode + ', ' + res.data);
90
+ }
91
+ }));
92
+ this.ws.on('error', (error) => {
93
+ this.reportErr(error);
94
+ reject(error);
95
+ });
96
+ this.ws.on('close', () => {
97
+ clearInterval(pingTimer);
98
+ this.reportClose();
99
+ });
100
+ });
101
+ }
102
+ declareEvent(eventDeclaration) {
103
+ return this.sendMessage({
104
+ call_id: 0,
105
+ command: 'declare_event',
106
+ data: eventDeclaration,
107
+ });
108
+ }
109
+ undeclareEvent(eventUndeclaration) {
110
+ return this.sendMessage({
111
+ call_id: 0,
112
+ command: 'undeclare_event',
113
+ data: eventUndeclaration,
114
+ });
115
+ }
116
+ sendEvent(event) {
117
+ return this.sendMessage({
118
+ call_id: 0,
119
+ command: 'send_event',
120
+ data: event,
121
+ });
122
+ }
123
+ sendMessage(msgJson) {
124
+ return new Promise((resolve, reject) => {
125
+ try {
126
+ this.sendMessages[this.callId] = { resolve, reject };
127
+ msgJson.call_id = this.callId++;
128
+ this.ws.send(JSON.stringify(msgJson));
129
+ }
130
+ catch (err) {
131
+ this.reportErr(new Error(`Send message error: ${err}`));
132
+ }
133
+ });
134
+ }
135
+ reportErr(err) {
136
+ var _a;
137
+ (_a = this.ws) === null || _a === void 0 ? void 0 : _a.terminate();
138
+ this.emit('error', err);
139
+ }
140
+ reportClose() {
141
+ for (const callId in this.sendMessages) {
142
+ this.sendMessages[callId].reject(new Error('Connection lost'));
143
+ }
144
+ this.sendMessages = {};
145
+ this.emit('close');
146
+ }
147
+ }
148
+ exports.CamScripterAPICameraEventsGenerator = CamScripterAPICameraEventsGenerator;
package/CreatePackage.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const fs = require("fs");
4
- const Path = require("path");
5
3
  const AdmZip = require("adm-zip");
4
+ const Path = require("path");
5
+ const fs = require("fs");
6
6
  function isDirectory(path) {
7
7
  const stat = fs.statSync(path);
8
8
  return stat.isDirectory();
@@ -26,7 +26,8 @@ function createZipArchive(zip, folder, options) {
26
26
  if (file[0] === '.' ||
27
27
  zipFileRegex.test(file) ||
28
28
  (file === 'node_modules' && !options.includeNodeModules) ||
29
- (file === 'src' && options.typeScriptPackage)) {
29
+ (file === 'src' && options.typeScriptPackage) ||
30
+ options.excludedFileNames.includes(file)) {
30
31
  continue;
31
32
  }
32
33
  else if (file === 'dist' && options.typeScriptPackage) {
@@ -44,11 +45,15 @@ function main(args) {
44
45
  const options = {
45
46
  includeNodeModules: false,
46
47
  typeScriptPackage: false,
48
+ excludedFileNames: [],
47
49
  };
48
50
  for (let arg of args) {
49
51
  if (arg === '-i' || arg === '-includeNodeModules') {
50
52
  options.includeNodeModules = true;
51
53
  }
54
+ if (arg.startsWith('-e=') || arg.startsWith('-exclude=')) {
55
+ options.excludedFileNames = arg.substring(arg.indexOf('=') + 1).split(',');
56
+ }
52
57
  }
53
58
  if (fs.existsSync('dist')) {
54
59
  options.typeScriptPackage = true;
package/README.md CHANGED
@@ -1,350 +1,56 @@
1
1
  # CamStreamerLib
2
+
2
3
  Node.js helper library for CamStreamer ACAP applications.
3
4
 
4
5
  The library is primarily developed for CamScripter Acap application running directly in Axis cameras.
5
6
  Examples of CamScripter packages can be found at https://github.com/CamStreamer/CamScripterApp_examples
6
7
 
7
8
  ## Installation
9
+
8
10
  ```
9
11
  npm install camstreamerlib
10
12
  ```
11
13
 
12
14
  # Documentation for Node.js modules
13
15
 
14
- ## HttpServer
15
- HttpServer is a module for processing HTTP requests in your scripts. It also automatically serves up the content from html directory or you can register paths which you can proccess by your own (e.g. http://$CAMERA_IP/local/camscripter/proxy/$MY_PACKAGE_NAME/control.cgi).
16
-
17
- ### methods
18
- #### onRequest(path, callback)
19
- It registers callback for access to specified path. Callback has attributes - request and response.
20
-
21
- #### close()
22
- Closes httpServer service and frees up the occupied port.
23
-
24
- ##### example
25
- ```javascript
26
- httpServer.onRequest('/settings.cgi', function(req, res) {
27
- res.statusCode = 200;
28
- res.setHeader('Content-type', 'application/json');
29
- res.setHeader('Access-Control-Allow-Origin', '*');
30
- res.end('{"enabled": true}');
31
- });
32
- ```
33
-
34
- ### events
35
- #### access(msg)
36
- The Event is emitted for all HTTP requests to this server
37
- #### error(err)
38
- An error occurs
39
-
40
-
41
- ## CameraVapix
42
- Access to Axis camera VAPIX interface. For more details see documentation for Axis camera VAPIX library.
43
-
44
- ### methods
45
- #### CameraVapix(options)
46
- ```javascript
47
- options = {
48
- 'protocol': 'http',
49
- 'ip': '127.0.0.1',
50
- 'port': 80,
51
- 'auth': 'root:pass'
52
- }
53
- ```
54
-
55
- #### vapixGet(groupNames)
56
- Universal method for HTTP GET requests to camera VAPIX API.
57
- ##### example
58
- ```javascript
59
- vapixGet('/axis-cgi/param.cgi?action=list&group=camscripter')
60
- ```
61
-
62
- #### vapixPost(groupNames)
63
- Universal method for HTTP POST requests to camera VAPIX API.
64
- ##### example
65
- ```javascript
66
- vapixPost('/axis-cgi/param.cgi', 'action=update&camscripter.enabled=1')
67
- ```
68
-
69
- #### getParameterGroup(groupNames)
70
- Get parameters from the camera.
71
- ##### example
72
- ```javascript
73
- getParameterGroup('camscripter','camoverlay')
74
- ```
75
-
76
- #### setParameter(params)
77
- Set parameters to the camera.
78
- ##### example
79
- ```javascript
80
- setParameter('{"root.camscripter.Enabled": "1"}')
81
- ```
82
-
83
- #### getPTZPresetList(channel)
84
- Get a list of PTZ presets for the specified channel. Channels are numbered from 1.
85
- ##### example
86
- ```javascript
87
- getPTZPresetList(1)
88
- ```
89
-
90
- #### goToPreset(channel, presetName)
91
- Move the camera channel to the PTZ preset.
92
- ##### example
93
- ```javascript
94
- goToPreset(1, 'home')
95
- ```
96
-
97
- #### getGuardTourList()
98
- Get the list of guard tours.
99
- ##### example
100
- ```javascript
101
- getGuardTourList()
102
- ```
103
-
104
- #### setGuardTourEnabled(gourTourID, enable)
105
- Enable or disable the guard tour.
106
- ##### example
107
- ```javascript
108
- setGuardTourEnabled('root.GuardTour.G0', true)
109
- ```
110
-
111
- #### getInputState(port)
112
- Get the camera input state for the specified port number.
113
- ##### example
114
- ```javascript
115
- getInputState(2)
116
- ```
117
-
118
- #### setOutputState(port, active)
119
- Set the state of the camera output port.
120
- ##### example
121
- ```javascript
122
- setOutputState(2, true)
123
- ```
124
-
125
- #### getApplicationList()
126
- Get the list of installed Acap applications.
127
- ##### example
128
- ```javascript
129
- getApplicationList()
130
- ```
131
-
132
- #### getEventDeclarations()
133
- Get all the available camera events in JSON format.
134
- ##### example
135
- ```javascript
136
- getEventDeclarations()
137
- ```
138
-
139
- ### events
140
- #### eventsConnect
141
- Events connection is ready
142
- #### eventsDisconnect(err)
143
- Events connection error
144
- #### *
145
- You can listen for events from camera by registrating the appropriate topic
146
- ##### example
147
- ```javascript
148
- on('axis:CameraApplicationPlatform/VMD/Camera1Profile1/.', function(event) {})
149
- ```
150
-
151
-
152
- ## CamStreamerAPI
153
- Module for easy control of streaming in CamStreamer Acap application.
154
-
155
- ### methods
156
- #### CameraVapix(options)
157
- ```javascript
158
- options = {
159
- 'protocol': 'http',
160
- 'ip': '127.0.0.1',
161
- 'port': 80,
162
- 'auth': 'root:pass'
163
- }
164
- ```
165
-
166
- #### getStreamList()
167
- Get info about CamStreamer streams in JSON format.
168
- ##### example
169
- ```javascript
170
- getStreamList()
171
- ```
172
-
173
- #### getStreamParameter(streamID, paramName)
174
- Get a single parameter of the stream with specified ID.
175
- ##### example
176
- ```javascript
177
- getStreamParameter('1234', 'enabled')
178
- ```
179
-
180
- #### setStreamParameter(streamID, paramName, value)
181
- Set value of stream parameter.
182
- ##### example
183
- ```javascript
184
- setStreamParameter('1234', 'enabled', '1')
185
- ```
186
-
187
- #### isStreaming(streamID)
188
- Return the state of streaming.
189
- ##### example
190
- ```javascript
191
- isStreaming('1234')
192
- ```
193
-
194
-
195
- ## CamOverlayAPI
196
- Module for easy control of CamOverlay drawing API. For more details on supported drawing functions see https://camstreamer.com/camoverlay-api1
197
-
198
- ### methods
199
- #### CameraVapix(options)
200
- Options parameter contains access to the camera, service name, service ID and camera. If service ID is not specified, service is automatically created/selected based on serviceName. Specify video channel using parameter camera (in which View Area overlay will be shown). If you need to specify multiple video channels, you can use an array: `camera=[0,1]`. If omitted the default value `camera=0` is used.
201
- ```javascript
202
- options = {
203
- 'ip': '127.0.0.1',
204
- 'port': 80,
205
- 'auth': 'root:pass',
206
- 'serviceName': 'Drawing Test',
207
- 'serviceID': -1,
208
- 'camera': 0
209
- }
210
- ```
211
-
212
- #### connect()
213
- Connect to CamOverlay WebSocket drawing API.
214
- ##### example
215
- ```javascript
216
- connect()
217
- ```
218
-
219
- #### cairo(command, args...)
220
- Call a function from Cairo library. See https://cairographics.org/manual/
221
- ##### example
222
- ```javascript
223
- cairo('cairo_image_surface_create', 'CAIRO_FORMAT_ARGB32', 200, 200) // https://cairographics.org/manual/cairo-Image-Surfaces.html#cairo-image-surface-create
224
- ```
225
-
226
- #### writeText(cairoContext, text, posX, posY, width, height, align, textFitMethod)
227
- Write aligned text to the box specified by x, y coordinates, width and height. Alignment options: A_RIGHT, A_LEFT, A_CENTER.
228
-
229
- TextFitMethod options:
230
- - TFM_SCALE - Text size is adjusted to width and height of the box.
231
- - TFM_TRUNCATE - Text size truncated to the width of the box.
232
- - TFM_OVERFLOW - Text overflows the box.
233
-
234
- ##### example
235
- ```javascript
236
- writeText('cairo0', 'Hello World', 5, 100, 190, 15, 'A_RIGHT', 'TFM_TRUNCATE');
237
- ```
238
-
239
- #### uploadImageData(imgBuffer)
240
- Upload .jpg or .png image to the CamOverlay application. Function returns variable name and dimensions of the image.
241
- ##### example
242
- ```javascript
243
- uploadImageData(fs.readFileSync('image.png'))
244
- ```
245
-
246
- #### uploadFontData(fontBuffer)
247
- Upload .ttf font to the CamOverlay application.
248
- ##### example
249
- ```javascript
250
- uploadFontData(fs.readFileSync('font.ttf'))
251
- ```
252
-
253
- #### showCairoImage(cairoImage, posX, posY)
254
- Show image in video stream from the camera. Position is in coordinates -1.0, -1.0 (upper left) / 1.0, 1.0 (bootom right).
255
- ##### example
256
- ```javascript
257
- showCairoImage('surface0', -1.0, -1.0)
258
- ```
259
-
260
- #### showCairoImageAbsolute(cairoImage, posX, posY, width, height)
261
- Show image in video stream from the camera. Position is absolute in pixels, stream resolution is required, because it can be called once there is no video stream running yet.
262
- ##### example
263
- ```javascript
264
- showCairoImage('surface0', 100, 100, 1920, 1080)
265
- ```
266
-
267
- #### removeImage()
268
- Remove image from the camera stream.
269
- ##### example
270
- ```javascript
271
- removeImage()
272
- ```
273
-
274
- #### updateCGText(fields)
275
- Updates text fields listed in parameter fields.
276
- One field is defined as follows:
277
- ```json
278
- {
279
- "field_name": "NAME_OF_YOUR_FIELD",
280
- "text": "UPDATED_TEXT",
281
- "color": "COLOR"
282
- }
283
- ```
284
- Parameter "color" is optional.
285
-
286
- #### updateCGImagePos(coordinates, x, y)
287
- Changes position of Custom Graphics.
288
- Coordinates have these values
289
- ```json
290
- [
291
- "top_left",
292
- "top_center",
293
- "top_right",
294
- "center_...",
295
- "...",
296
- "bottom_...",
297
- "..."
298
- ]
299
- ```
16
+ - [HttpServer](doc/HttpServer.md) is a module for processing HTTP requests in your scripts. It also automatically serves up the content from html directory or you can register paths which you can process by your own (e.g. http://$CAMERA_IP/local/camscripter/proxy/$MY_PACKAGE_NAME/control.cgi).
17
+ - [CameraVapix](doc/CameraVapix.md) is a module to access Axis camera VAPIX interface.
18
+ - [CamStreamerAPI](doc/CamStreamerAPI.md) is a module for easy control of video streaming in the CamStreamer ACAP application (RTMP, HLS, SRT and MPEG-TS protocols).
19
+ - [CamOverlayAPI](doc/CamOverlayAPI.md) is a module for easy control of CamOverlay drawing API. For more details on supported video overlay drawing functions see https://camstreamer.com/camoverlay-api1
20
+ - [CamScripterAPICameraEventsGenerator](doc/CamScripterAPICameraEventsGenerator.md) is a module which allows generating events on an Axis camera. These events can be used for triggers in the Axis camera rule engine (events/actions). It is also an easy way how to integrate events and metadata in VMS systems which support Axis camera events.
300
21
 
301
- #### updateCGImage(path, [coordinates, x, y])
302
- Updates Custom Graphics background to an image with specified path on the camera.
303
- If no coordinates are specified, the service will use positioning from the last update.
22
+ ## For Developers
304
23
 
305
- #### updateInfoticker(text)
306
- Updates text in Infoticker service, if any is running.
24
+ ### Publishing to npm repository
307
25
 
308
- #### setEnabled(enabled)
309
- Enables/disables the bound CO service.
26
+ 1. Update version in package.json and push it
27
+ 2. Create git tag e.g. v1.2.4
310
28
 
311
- #### isEnabled()
312
- Returns whether the bound CO service is enabled (true) or disabled (false).
29
+ - `git tag v1.2.4`
30
+ - `git push --tags`
313
31
 
314
- ### events
315
- #### msg(msg)
316
- WebSocket message received
317
- #### error(err)
318
- An error occurs
319
- #### close
320
- WebSocket closed
32
+ 3. Publish new version to npm
321
33
 
322
- ## For Developers
323
- ### Publishing with npm
324
- First log in to the npm service with valid Username, Password and E-mail:
325
- ```bash
326
- npm login
327
- ```
328
- The program will prompt you for your information.
34
+ - `npm publish ./dist`
329
35
 
330
- For publishing itself use np tool. You will find it on this site: https://github.com/sindresorhus/np
331
- After login, enter your Git repository and run the following command:
332
- ```bash
333
- np
334
- ```
335
- The utility will ask you for the prefered version raise and if you are lucky, everything will run just fine.
336
- Finally, edit GitHub release form.
36
+ 4. Edit GitHub release form.
337
37
 
338
38
  ### Preparing a package to upload to CamScripter
39
+
339
40
  If you want to create your own package and upload it to CamScripter App, you can use the script CreatePackage. It creates a zip file which contains all required files and directories in your package folder. The script accepts source code written either in JavaScript or TypeScript if the package has the correct structure (more information in https://github.com/CamStreamer/CamScripterApp_examples/#readme). To include this script in your package add the following lines in the file package.json:
41
+
340
42
  ```json
341
43
  "scripts": {
342
44
  "create-package": "node node_modules/camstreamerlib/CreatePackage.js"
343
45
  }
344
46
  ```
345
- By default, the zipped package does not contain node_modules directory. If you want to include it (required when uploading to CamScripter App on Axis camera), add this:
47
+
48
+ By default, the zipped package does not contain node_modules directory. If you want to include it (required when uploading to CamScripter App on Axis camera), add `-includeNodeModules` or `-i` parameter.
49
+
50
+ If you need to exclude a file or directory add `-exlude` or `-e` parameter with comma separated list.
51
+
346
52
  ```json
347
53
  "scripts": {
348
- "create-package": "node node_modules/camstreamerlib/CreatePackage.js -includeNodeModules"
349
- }
54
+ "create-package": "node node_modules/camstreamerlib/CreatePackage.js -i -e=react"
55
+ }
350
56
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "camstreamerlib",
3
- "version": "1.8.7",
3
+ "version": "1.9.0",
4
4
  "description": "Helper library for CamStreamer ACAP applications.",
5
5
  "prettier": "@camstreamer/prettier-config",
6
6
  "dependencies": {