node-libcamera 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +36 -84
- package/dist/index.d.ts +3 -1
- package/dist/node-libcamera.cjs.development.js +31 -109
- package/dist/node-libcamera.cjs.development.js.map +1 -1
- package/dist/node-libcamera.cjs.production.min.js +1 -1
- package/dist/node-libcamera.cjs.production.min.js.map +1 -1
- package/dist/node-libcamera.esm.js +29 -99
- package/dist/node-libcamera.esm.js.map +1 -1
- package/dist/options.d.ts +121 -11
- package/dist/utils.d.ts +1 -1
- package/package.json +8 -3
- package/src/index.ts +21 -2
- package/src/options.ts +132 -96
- package/src/utils.ts +5 -8
package/README.md
CHANGED
@@ -1,103 +1,55 @@
|
|
1
|
-
#
|
1
|
+
# node-libcamera 📷
|
2
2
|
|
3
|
-
|
3
|
+
A set of wrapper functions for the native [Raspberry Pi `libcamera` API](https://www.raspberrypi.com/documentation/accessories/camera.html).
|
4
4
|
|
5
|
-
|
5
|
+
_Open to any and all contributions!_
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
## Commands
|
10
|
-
|
11
|
-
TSDX scaffolds your new library inside `/src`.
|
12
|
-
|
13
|
-
To run TSDX, use:
|
7
|
+
## Installation
|
14
8
|
|
15
9
|
```bash
|
16
|
-
npm
|
10
|
+
npm install node-libcamera
|
17
11
|
```
|
18
12
|
|
19
|
-
|
20
|
-
|
21
|
-
To do a one-off build, use `npm run build` or `yarn build`.
|
22
|
-
|
23
|
-
To run tests, use `npm test` or `yarn test`.
|
24
|
-
|
25
|
-
## Configuration
|
26
|
-
|
27
|
-
Code quality is set up for you with `prettier`, `husky`, and `lint-staged`. Adjust the respective fields in `package.json` accordingly.
|
28
|
-
|
29
|
-
### Jest
|
13
|
+
## Usage
|
30
14
|
|
31
|
-
|
15
|
+
### [`libcamera-still`](https://www.raspberrypi.com/documentation/accessories/camera.html#libcamera-still)
|
32
16
|
|
33
|
-
|
17
|
+
Capture an image!
|
34
18
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
19
|
+
```js
|
20
|
+
const { still } = require('node-libcamera')
|
21
|
+
|
22
|
+
// basic example
|
23
|
+
still({ output: 'test.jpg' })
|
24
|
+
.then((result) => /* 📸 */ )
|
25
|
+
.catch((error) => /* 🐛 */ )
|
26
|
+
|
27
|
+
// example with options
|
28
|
+
still({
|
29
|
+
output: 'images/test.jpg', // output file path
|
30
|
+
timeout: 2000, // timeout before taking the picture
|
31
|
+
width: 640, // image width
|
32
|
+
height: 480, // image height
|
33
|
+
})
|
34
|
+
.then((result) => /* 📸 */ )
|
35
|
+
.catch((error) => /* 🐛 */ )
|
50
36
|
```
|
51
37
|
|
52
|
-
###
|
53
|
-
|
54
|
-
TSDX uses [Rollup](https://rollupjs.org) as a bundler and generates multiple rollup configs for various module formats and build settings. See [Optimizations](#optimizations) for details.
|
55
|
-
|
56
|
-
### TypeScript
|
57
|
-
|
58
|
-
`tsconfig.json` is set up to interpret `dom` and `esnext` types, as well as `react` for `jsx`. Adjust according to your needs.
|
59
|
-
|
60
|
-
## Continuous Integration
|
38
|
+
### [`libcamera-vid`](https://www.raspberrypi.com/documentation/accessories/camera.html#libcamera-vid)
|
61
39
|
|
62
|
-
|
63
|
-
|
64
|
-
Two actions are added by default:
|
65
|
-
|
66
|
-
- `main` which installs deps w/ cache, lints, tests, and builds on all pushes against a Node and OS matrix
|
67
|
-
- `size` which comments cost comparison of your library on every pull request using [`size-limit`](https://github.com/ai/size-limit)
|
68
|
-
|
69
|
-
## Optimizations
|
70
|
-
|
71
|
-
Please see the main `tsdx` [optimizations docs](https://github.com/palmerhq/tsdx#optimizations). In particular, know that you can take advantage of development-only optimizations:
|
40
|
+
Record a video!
|
72
41
|
|
73
42
|
```js
|
74
|
-
|
75
|
-
declare var __DEV__: boolean;
|
43
|
+
const { vid } = require('node-libcamera')
|
76
44
|
|
77
|
-
//
|
78
|
-
|
79
|
-
|
80
|
-
|
45
|
+
// record a 10s video
|
46
|
+
vid({ output: 'test.h264', timeout: 10000, 'save-pts': 'timestamps.txt' })
|
47
|
+
.then((result) => /* 🎥 */ )
|
48
|
+
.catch((error) => /* 🐛 */ )
|
81
49
|
```
|
82
50
|
|
83
|
-
|
84
|
-
|
85
|
-
## Module Formats
|
86
|
-
|
87
|
-
CJS, ESModules, and UMD module formats are supported.
|
88
|
-
|
89
|
-
The appropriate paths are configured in `package.json` and `dist/index.js` accordingly. Please report if any issues are found.
|
90
|
-
|
91
|
-
## Named Exports
|
51
|
+
Note: this will result in an unpackaged video bistream, it is not wrapped in any kind of container format (such as an mp4 file). The `save-pts` option can be used to output frame timestamps so that the bitstream can subsequently be converted into an appropriate format using a tool like `mkvmerge`.
|
92
52
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
There are many ways to ship styles, including with CSS-in-JS. TSDX has no opinion on this, configure how you like.
|
98
|
-
|
99
|
-
For vanilla CSS, you can include it at the root directory and add it to the `files` section in your `package.json`, so that it can be imported separately by your users and run through their bundler's loader.
|
100
|
-
|
101
|
-
## Publishing to NPM
|
102
|
-
|
103
|
-
We recommend using [np](https://github.com/sindresorhus/np).
|
53
|
+
```bash
|
54
|
+
mkvmerge -o test.mkv --timecodes 0:timestamps.txt test.h264
|
55
|
+
```
|
package/dist/index.d.ts
CHANGED
@@ -1,2 +1,4 @@
|
|
1
1
|
import { LibCamera } from './options';
|
2
|
-
export declare function
|
2
|
+
export declare function jpeg(options: Partial<LibCamera.OptionsObject>): string | Promise<unknown>;
|
3
|
+
export declare function still(options: Partial<LibCamera.OptionsObject>): string | Promise<unknown>;
|
4
|
+
export declare function vid(options: Partial<LibCamera.OptionsObject>): string | Promise<unknown>;
|
@@ -2,96 +2,11 @@
|
|
2
2
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
4
4
|
|
5
|
-
|
5
|
+
require('child_process');
|
6
6
|
|
7
|
-
var
|
8
|
-
|
9
|
-
"
|
10
|
-
desc: 'Print help information for the application'
|
11
|
-
},
|
12
|
-
version: {
|
13
|
-
desc: 'Print help information for the application'
|
14
|
-
},
|
15
|
-
timeout: {
|
16
|
-
"short": 't',
|
17
|
-
desc: 'Delay before application stops automatically <milliseconds>',
|
18
|
-
validator: function validator(val) {
|
19
|
-
return typeof val === 'number';
|
20
|
-
},
|
21
|
-
convert: function convert(val) {
|
22
|
-
return val.toString();
|
23
|
-
}
|
24
|
-
},
|
25
|
-
preview: {
|
26
|
-
"short": 'p',
|
27
|
-
desc: 'Preview window settings <x,y,w,h>',
|
28
|
-
validator: function validator(val) {
|
29
|
-
return typeof val === 'object' && Boolean((val == null ? void 0 : val.x) && (val == null ? void 0 : val.y) && (val == null ? void 0 : val.width) && (val == null ? void 0 : val.height));
|
30
|
-
},
|
31
|
-
convert: function convert(val) {
|
32
|
-
return val.x + "," + val.y + "," + val.width + "," + val.height;
|
33
|
-
}
|
34
|
-
},
|
35
|
-
fullscreen: {
|
36
|
-
"short": 'f',
|
37
|
-
desc: 'Fullscreen preview mode'
|
38
|
-
},
|
39
|
-
'qt-preview': {
|
40
|
-
desc: 'Use Qt-based preview window'
|
41
|
-
},
|
42
|
-
nopreview: {
|
43
|
-
"short": 'n',
|
44
|
-
desc: 'Do not display a preview window'
|
45
|
-
},
|
46
|
-
'info-text': {
|
47
|
-
desc: 'Set window title bar text <string>',
|
48
|
-
validator: function validator(val) {
|
49
|
-
return typeof val === 'string';
|
50
|
-
}
|
51
|
-
},
|
52
|
-
width: {
|
53
|
-
desc: 'Capture image width <width>',
|
54
|
-
validator: function validator(val) {
|
55
|
-
return typeof val === 'number';
|
56
|
-
},
|
57
|
-
convert: function convert(val) {
|
58
|
-
return val.toString();
|
59
|
-
}
|
60
|
-
},
|
61
|
-
height: {
|
62
|
-
desc: 'Capture image height <height>',
|
63
|
-
validator: function validator(val) {
|
64
|
-
return typeof val === 'number';
|
65
|
-
},
|
66
|
-
convert: function convert(val) {
|
67
|
-
return val.toString();
|
68
|
-
}
|
69
|
-
},
|
70
|
-
'viewfinder-width': {
|
71
|
-
desc: 'Capture image width <width>',
|
72
|
-
validator: function validator(val) {
|
73
|
-
return typeof val === 'number';
|
74
|
-
},
|
75
|
-
convert: function convert(val) {
|
76
|
-
return val.toString();
|
77
|
-
}
|
78
|
-
},
|
79
|
-
'viewfinder-height': {
|
80
|
-
desc: 'Capture image height <height>',
|
81
|
-
validator: function validator(val) {
|
82
|
-
return typeof val === 'number';
|
83
|
-
},
|
84
|
-
convert: function convert(val) {
|
85
|
-
return val.toString();
|
86
|
-
}
|
87
|
-
},
|
88
|
-
// ...
|
89
|
-
output: {
|
90
|
-
"short": 'o',
|
91
|
-
desc: 'Output file name <string>',
|
92
|
-
validator: function validator(val) {
|
93
|
-
return typeof val === 'string';
|
94
|
-
}
|
7
|
+
var optionConverterMap = {
|
8
|
+
preview: function preview(val) {
|
9
|
+
return val.x + "," + val.y + "," + val.width + "," + val.height;
|
95
10
|
}
|
96
11
|
};
|
97
12
|
|
@@ -99,37 +14,44 @@ function cmd(base, args) {
|
|
99
14
|
if (base && !args) return base;
|
100
15
|
return base + " " + (args == null ? void 0 : args.join(' '));
|
101
16
|
}
|
102
|
-
function run(command, options) {
|
103
|
-
return new Promise(function (resolve, reject) {
|
104
|
-
child_process.exec(command, options, function (error, stdout, stderr) {
|
105
|
-
if (stderr || error) reject(stderr || error);
|
106
|
-
resolve(stdout);
|
107
|
-
});
|
108
|
-
});
|
109
|
-
}
|
110
17
|
function convertOptionsToCmdArgs(options) {
|
111
18
|
var args = [];
|
112
19
|
Object.entries(options).forEach(function (_ref) {
|
113
20
|
var key = _ref[0],
|
114
21
|
val = _ref[1];
|
115
|
-
var
|
116
|
-
|
117
|
-
if (typeof opt.validator === 'function' && !opt.validator(val)) {
|
118
|
-
throw new Error("Invalid value for option \"" + key + "\"");
|
119
|
-
}
|
120
|
-
|
121
|
-
var value = typeof opt.convert === 'function' ? opt.convert(val) : val;
|
22
|
+
var converter = optionConverterMap[key];
|
23
|
+
var value = typeof converter === 'function' ? converter(val) : val;
|
122
24
|
if (value) args.push("--" + key);
|
123
|
-
if (value !== true) args.push(value);
|
25
|
+
if (value !== true && value != null && value.toString()) args.push(value == null ? void 0 : value.toString());
|
124
26
|
}, true);
|
125
27
|
return args;
|
126
28
|
}
|
127
29
|
|
128
|
-
function
|
30
|
+
function runLibCamera(bin, options) {
|
31
|
+
if (bin === void 0) {
|
32
|
+
bin = 'libcamera-still';
|
33
|
+
}
|
34
|
+
|
129
35
|
var args = convertOptionsToCmdArgs(options);
|
130
|
-
var command = cmd(
|
131
|
-
|
36
|
+
var command = cmd(bin, args);
|
37
|
+
|
38
|
+
{
|
39
|
+
console.log(command);
|
40
|
+
return command;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
function jpeg(options) {
|
45
|
+
return runLibCamera('libcamera-jpeg', options);
|
46
|
+
}
|
47
|
+
function still(options) {
|
48
|
+
return runLibCamera('libcamera-still', options);
|
49
|
+
}
|
50
|
+
function vid(options) {
|
51
|
+
return runLibCamera('libcamera-vid', options);
|
132
52
|
}
|
133
53
|
|
134
|
-
exports.
|
54
|
+
exports.jpeg = jpeg;
|
55
|
+
exports.still = still;
|
56
|
+
exports.vid = vid;
|
135
57
|
//# sourceMappingURL=node-libcamera.cjs.development.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"node-libcamera.cjs.development.js","sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["export namespace LibCamera {\n export
|
1
|
+
{"version":3,"file":"node-libcamera.cjs.development.js","sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["export namespace LibCamera {\n export interface CommandLineOptions {\n /**\n * Print help information for the application\n *\n * The `--help` option causes every application to print its full set of command line options with a brief synopsis of each, and then quit.\n **/\n help: boolean\n /**\n * Print out a software version number\n *\n * All `libcamera-apps` will, when they see the `--version` option, print out a version string both for `libcamera` and `libcamera-apps` and then quit.\n */\n version: boolean\n /**\n * Delay before application stops automatically <milliseconds>\n *\n * The `--timeout` option specifies how long the application runs before it stops, whether it is recording a video or showing a preview. In the case of still image capture, the application will show the preview window for this long before capturing the output image.\n *\n * If unspecified, the default value is 5000 (5 seconds). The value zero causes the application to run indefinitely.\n */\n timeout: number\n }\n\n export interface PreviewWindowOptions {\n /**\n * Preview window settings\n *\n * Sets the size and location of the preview window (both X Windows and DRM versions). It does not affect the resolution or aspect ratio of images being requested from the camera. The camera images will be scaled to the size of the preview window for display, and will be pillar/letter-boxed to fit.\n *\n * Example:\n * ```json\n * { \"x\": 100, \"y\": 100, \"width\": 500, \"height\": 500 }\n * ```\n */\n preview: PreviewOption\n /**\n * Fullscreen preview mode\n *\n * Forces the preview window to use the whole screen, and the window will have no border or title bar. Again the image may be pillar/letter-boxed.\n */\n fullscreen: boolean\n /**\n * Use Qt-based preview window\n *\n * The preview window is switched to use the Qt-based implementation. This option is not normally recommended because it no longer uses zero-copy buffer sharing nor GPU acceleration and is therefore very expensive, however, it does support X forwarding (which the other preview implementations do not).\n *\n * The Qt preview window does not support the `--fullscreen` option. Generally it is advised to try and keep the preview window small.\n */\n 'qt-preview': boolean\n /**\n * Do not display a preview window\n *\n * The preview window is suppressed entirely.\n */\n nopreview: boolean\n /**\n * Set window title bar text <string>\n *\n * The supplied string is set as the title of the preview window (when running under X Windows). Additionally the string may contain a number of `%` directives which are substituted with information from the image metadata. The permitted directives are:\n *\n * | Directive | Substitution |\n * | :--------------- | :------------------ |\n * | `%frame` | The sequence number of the frame |\n * | `%fps` | The instantaneous frame rate |\n * | `%exp` | The shutter speed used to capture the image, in microseconds |\n * | `%ag` | The analogue gain applied to the image in the sensor |\n * | `%dg` | The digital gain applied to the image by the ISP |\n * | `%rg` | The gain applied to the red component of each pixel |\n * | `%bg` | The gain applied to the blue component of each pixel |\n * | `%focus` | The focus metric for the image, where a larger value implies a sharper image |\n *\n * When not provided, the `--info-text` string defaults to `\"#%frame (%fps fps) exp %exp ag %ag dg %dg\"`.\n */\n 'info-text': string\n }\n\n export interface CameraResolutionOptions {\n /**\n * Capture image width <width>\n *\n * This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.\n *\n * For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.\n *\n * For libcamera-hello these parameters have no effect.\n */\n width: number\n /**\n * Capture image height <height>\n *\n * This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.\n *\n * For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.\n *\n * For libcamera-hello these parameters have no effect.\n */\n height: number\n }\n\n export interface OutputFileOptions {\n /**\n * Output file name <string>\n *\n * `--output` sets the name of the output file to which the output image or video is written. Besides regular file names, this may take the following special values:\n *\n * `-` - write to stdout\n *\n * `udp://` - a string starting with this is taken as a network address for streaming\n *\n * `tcp://` - a string starting with this is taken as a network address for streaming\n *\n * a string containing a `%d` directive is taken as a file name where the format directive is replaced with a count that increments for each file that is opened. Standard C format directive modifiers are permitted.\n */\n output: string\n }\n\n export interface VideoOptions {\n /**\n * Saves timestamp information to the specified file. Useful as an input file to `mkvmerge`.\n */\n 'save-pts': string\n }\n\n export type OptionsObject = CommandLineOptions &\n PreviewWindowOptions &\n CameraResolutionOptions &\n OutputFileOptions &\n VideoOptions\n\n export type OptionKeys = keyof OptionsObject\n export type OptionConverter = (val: any) => string\n\n export interface PreviewOption {\n x: number\n y: number\n width: number\n height: number\n }\n}\n\nexport const optionConverterMap: Partial<Record<\n LibCamera.OptionKeys,\n LibCamera.OptionConverter\n>> = {\n preview(val: LibCamera.PreviewOption) {\n return `${val.x},${val.y},${val.width},${val.height}`\n },\n} as const\n","import { exec, ExecOptionsWithBufferEncoding } from 'child_process'\nimport { optionConverterMap, LibCamera } from './options'\n\nexport function cmd(base: string, args?: string[]): string {\n if (base && !args) return base\n return `${base} ${args?.join(' ')}`\n}\n\nexport function run(command: string, options?: ExecOptionsWithBufferEncoding) {\n return new Promise((resolve, reject) => {\n exec(command, options, (error, stdout, stderr) => {\n if (stderr || error) reject(stderr || error)\n resolve(stdout)\n })\n })\n}\n\nexport function convertOptionsToCmdArgs(\n options: Partial<LibCamera.OptionsObject>\n): string[] {\n const args: string[] = []\n Object.entries(options).forEach(([key, val]) => {\n const converter = optionConverterMap[key as LibCamera.OptionKeys]\n const value = typeof converter === 'function' ? converter(val) : val\n if (value) args.push(`--${key}`)\n if (value !== true && value?.toString()) args.push(value?.toString())\n }, true)\n return args\n}\n","import { LibCamera } from './options'\nimport { run, cmd, convertOptionsToCmdArgs } from './utils'\n\nfunction runLibCamera(\n bin: string = 'libcamera-still',\n options: Partial<LibCamera.OptionsObject>\n) {\n const args = convertOptionsToCmdArgs(options)\n const command = cmd(bin, args)\n if (__DEV__) {\n console.log(command)\n return command\n }\n return run(command)\n}\n\nexport function jpeg(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-jpeg', options)\n}\n\nexport function still(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-still', options)\n}\n\nexport function vid(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-vid', options)\n}\n"],"names":["optionConverterMap","preview","val","x","y","width","height","cmd","base","args","join","convertOptionsToCmdArgs","options","Object","entries","forEach","key","converter","value","push","toString","runLibCamera","bin","command","console","log","jpeg","still","vid"],"mappings":";;;;;;AA6IO,IAAMA,kBAAkB,GAG1B;AACHC,EAAAA,OADG,mBACKC,GADL;AAED,WAAUA,GAAG,CAACC,CAAd,SAAmBD,GAAG,CAACE,CAAvB,SAA4BF,GAAG,CAACG,KAAhC,SAAyCH,GAAG,CAACI,MAA7C;AACD;AAHE,CAHE;;SC1ISC,IAAIC,MAAcC;AAChC,MAAID,IAAI,IAAI,CAACC,IAAb,EAAmB,OAAOD,IAAP;AACnB,SAAUA,IAAV,UAAkBC,IAAlB,oBAAkBA,IAAI,CAAEC,IAAN,CAAW,GAAX,CAAlB;AACD;AAED,SASgBC,wBACdC;AAEA,MAAMH,IAAI,GAAa,EAAvB;AACAI,EAAAA,MAAM,CAACC,OAAP,CAAeF,OAAf,EAAwBG,OAAxB,CAAgC;QAAEC;QAAKd;AACrC,QAAMe,SAAS,GAAGjB,kBAAkB,CAACgB,GAAD,CAApC;AACA,QAAME,KAAK,GAAG,OAAOD,SAAP,KAAqB,UAArB,GAAkCA,SAAS,CAACf,GAAD,CAA3C,GAAmDA,GAAjE;AACA,QAAIgB,KAAJ,EAAWT,IAAI,CAACU,IAAL,QAAeH,GAAf;AACX,QAAIE,KAAK,KAAK,IAAV,IAAkBA,KAAlB,YAAkBA,KAAK,CAAEE,QAAP,EAAtB,EAAyCX,IAAI,CAACU,IAAL,CAAUD,KAAV,oBAAUA,KAAK,CAAEE,QAAP,EAAV;AAC1C,GALD,EAKG,IALH;AAMA,SAAOX,IAAP;AACD;;ACzBD,SAASY,YAAT,CACEC,GADF,EAEEV,OAFF;MACEU;AAAAA,IAAAA,MAAc;;;AAGd,MAAMb,IAAI,GAAGE,uBAAuB,CAACC,OAAD,CAApC;AACA,MAAMW,OAAO,GAAGhB,GAAG,CAACe,GAAD,EAAMb,IAAN,CAAnB;;AACA,EAAa;AACXe,IAAAA,OAAO,CAACC,GAAR,CAAYF,OAAZ;AACA,WAAOA,OAAP;AACD;AAEF;;AAED,SAAgBG,KAAKd;AACnB,SAAOS,YAAY,CAAC,gBAAD,EAAmBT,OAAnB,CAAnB;AACD;AAED,SAAgBe,MAAMf;AACpB,SAAOS,YAAY,CAAC,iBAAD,EAAoBT,OAApB,CAAnB;AACD;AAED,SAAgBgB,IAAIhB;AAClB,SAAOS,YAAY,CAAC,eAAD,EAAkBT,OAAlB,CAAnB;AACD;;;;;;"}
|
@@ -1,2 +1,2 @@
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("child_process"),n={preview:function(e){return e.x+","+e.y+","+e.width+","+e.height}};function r(r,t){return void 0===r&&(r="libcamera-still"),i=function(e,n){return e&&!n?e:e+" "+(null==n?void 0:n.join(" "))}(r,function(e){var r=[];return Object.entries(e).forEach((function(e){var t=e[0],i=e[1],o=n[t],u="function"==typeof o?o(i):i;u&&r.push("--"+t),!0!==u&&null!=u&&u.toString()&&r.push(null==u?void 0:u.toString())}),!0),r}(t)),new Promise((function(n,r){e.exec(i,void 0,(function(e,t,i){(i||e)&&r(i||e),n(t)}))}));var i}exports.jpeg=function(e){return r("libcamera-jpeg",e)},exports.still=function(e){return r("libcamera-still",e)},exports.vid=function(e){return r("libcamera-vid",e)};
|
2
2
|
//# sourceMappingURL=node-libcamera.cjs.production.min.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"node-libcamera.cjs.production.min.js","sources":["../src/options.ts","../src/index.ts","../src/utils.ts"],"sourcesContent":["export namespace LibCamera {\n export
|
1
|
+
{"version":3,"file":"node-libcamera.cjs.production.min.js","sources":["../src/options.ts","../src/index.ts","../src/utils.ts"],"sourcesContent":["export namespace LibCamera {\n export interface CommandLineOptions {\n /**\n * Print help information for the application\n *\n * The `--help` option causes every application to print its full set of command line options with a brief synopsis of each, and then quit.\n **/\n help: boolean\n /**\n * Print out a software version number\n *\n * All `libcamera-apps` will, when they see the `--version` option, print out a version string both for `libcamera` and `libcamera-apps` and then quit.\n */\n version: boolean\n /**\n * Delay before application stops automatically <milliseconds>\n *\n * The `--timeout` option specifies how long the application runs before it stops, whether it is recording a video or showing a preview. In the case of still image capture, the application will show the preview window for this long before capturing the output image.\n *\n * If unspecified, the default value is 5000 (5 seconds). The value zero causes the application to run indefinitely.\n */\n timeout: number\n }\n\n export interface PreviewWindowOptions {\n /**\n * Preview window settings\n *\n * Sets the size and location of the preview window (both X Windows and DRM versions). It does not affect the resolution or aspect ratio of images being requested from the camera. The camera images will be scaled to the size of the preview window for display, and will be pillar/letter-boxed to fit.\n *\n * Example:\n * ```json\n * { \"x\": 100, \"y\": 100, \"width\": 500, \"height\": 500 }\n * ```\n */\n preview: PreviewOption\n /**\n * Fullscreen preview mode\n *\n * Forces the preview window to use the whole screen, and the window will have no border or title bar. Again the image may be pillar/letter-boxed.\n */\n fullscreen: boolean\n /**\n * Use Qt-based preview window\n *\n * The preview window is switched to use the Qt-based implementation. This option is not normally recommended because it no longer uses zero-copy buffer sharing nor GPU acceleration and is therefore very expensive, however, it does support X forwarding (which the other preview implementations do not).\n *\n * The Qt preview window does not support the `--fullscreen` option. Generally it is advised to try and keep the preview window small.\n */\n 'qt-preview': boolean\n /**\n * Do not display a preview window\n *\n * The preview window is suppressed entirely.\n */\n nopreview: boolean\n /**\n * Set window title bar text <string>\n *\n * The supplied string is set as the title of the preview window (when running under X Windows). Additionally the string may contain a number of `%` directives which are substituted with information from the image metadata. The permitted directives are:\n *\n * | Directive | Substitution |\n * | :--------------- | :------------------ |\n * | `%frame` | The sequence number of the frame |\n * | `%fps` | The instantaneous frame rate |\n * | `%exp` | The shutter speed used to capture the image, in microseconds |\n * | `%ag` | The analogue gain applied to the image in the sensor |\n * | `%dg` | The digital gain applied to the image by the ISP |\n * | `%rg` | The gain applied to the red component of each pixel |\n * | `%bg` | The gain applied to the blue component of each pixel |\n * | `%focus` | The focus metric for the image, where a larger value implies a sharper image |\n *\n * When not provided, the `--info-text` string defaults to `\"#%frame (%fps fps) exp %exp ag %ag dg %dg\"`.\n */\n 'info-text': string\n }\n\n export interface CameraResolutionOptions {\n /**\n * Capture image width <width>\n *\n * This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.\n *\n * For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.\n *\n * For libcamera-hello these parameters have no effect.\n */\n width: number\n /**\n * Capture image height <height>\n *\n * This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.\n *\n * For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.\n *\n * For libcamera-hello these parameters have no effect.\n */\n height: number\n }\n\n export interface OutputFileOptions {\n /**\n * Output file name <string>\n *\n * `--output` sets the name of the output file to which the output image or video is written. Besides regular file names, this may take the following special values:\n *\n * `-` - write to stdout\n *\n * `udp://` - a string starting with this is taken as a network address for streaming\n *\n * `tcp://` - a string starting with this is taken as a network address for streaming\n *\n * a string containing a `%d` directive is taken as a file name where the format directive is replaced with a count that increments for each file that is opened. Standard C format directive modifiers are permitted.\n */\n output: string\n }\n\n export interface VideoOptions {\n /**\n * Saves timestamp information to the specified file. Useful as an input file to `mkvmerge`.\n */\n 'save-pts': string\n }\n\n export type OptionsObject = CommandLineOptions &\n PreviewWindowOptions &\n CameraResolutionOptions &\n OutputFileOptions &\n VideoOptions\n\n export type OptionKeys = keyof OptionsObject\n export type OptionConverter = (val: any) => string\n\n export interface PreviewOption {\n x: number\n y: number\n width: number\n height: number\n }\n}\n\nexport const optionConverterMap: Partial<Record<\n LibCamera.OptionKeys,\n LibCamera.OptionConverter\n>> = {\n preview(val: LibCamera.PreviewOption) {\n return `${val.x},${val.y},${val.width},${val.height}`\n },\n} as const\n","import { LibCamera } from './options'\nimport { run, cmd, convertOptionsToCmdArgs } from './utils'\n\nfunction runLibCamera(\n bin: string = 'libcamera-still',\n options: Partial<LibCamera.OptionsObject>\n) {\n const args = convertOptionsToCmdArgs(options)\n const command = cmd(bin, args)\n if (__DEV__) {\n console.log(command)\n return command\n }\n return run(command)\n}\n\nexport function jpeg(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-jpeg', options)\n}\n\nexport function still(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-still', options)\n}\n\nexport function vid(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-vid', options)\n}\n","import { exec, ExecOptionsWithBufferEncoding } from 'child_process'\nimport { optionConverterMap, LibCamera } from './options'\n\nexport function cmd(base: string, args?: string[]): string {\n if (base && !args) return base\n return `${base} ${args?.join(' ')}`\n}\n\nexport function run(command: string, options?: ExecOptionsWithBufferEncoding) {\n return new Promise((resolve, reject) => {\n exec(command, options, (error, stdout, stderr) => {\n if (stderr || error) reject(stderr || error)\n resolve(stdout)\n })\n })\n}\n\nexport function convertOptionsToCmdArgs(\n options: Partial<LibCamera.OptionsObject>\n): string[] {\n const args: string[] = []\n Object.entries(options).forEach(([key, val]) => {\n const converter = optionConverterMap[key as LibCamera.OptionKeys]\n const value = typeof converter === 'function' ? converter(val) : val\n if (value) args.push(`--${key}`)\n if (value !== true && value?.toString()) args.push(value?.toString())\n }, true)\n return args\n}\n"],"names":["optionConverterMap","preview","val","x","y","width","height","runLibCamera","bin","options","command","base","args","join","cmd","Object","entries","forEach","key","converter","value","push","toString","convertOptionsToCmdArgs","Promise","resolve","reject","exec","run","error","stdout","stderr"],"mappings":"mGA6IaA,EAGR,CACHC,iBAAQC,UACIA,EAAIC,MAAKD,EAAIE,MAAKF,EAAIG,UAASH,EAAII,SC/IjD,SAASC,EACPC,EACAC,mBADAD,IAAAA,EAAc,mBCIIE,WALAC,EAAcC,UAC5BD,IAASC,EAAaD,EAChBA,aAAQC,SAAAA,EAAMC,KAAK,MDGbC,CAAIN,WCUpBC,OAEMG,EAAiB,UACvBG,OAAOC,QAAQP,GAASQ,SAAQ,gBAAEC,OAAKhB,OAC/BiB,EAAYnB,EAAmBkB,GAC/BE,EAA6B,mBAAdD,EAA2BA,EAAUjB,GAAOA,EAC7DkB,GAAOR,EAAKS,UAAUH,IACZ,IAAVE,SAAkBA,GAAAA,EAAOE,YAAYV,EAAKS,WAAKD,SAAAA,EAAOE,eACzD,GACIV,EDpBMW,CAAwBd,ICE9B,IAAIe,SAAQ,SAACC,EAASC,GAC3BC,OAAKjB,ODGAkB,GCHkB,SAACC,EAAOC,EAAQC,IACjCA,GAAUF,IAAOH,EAAOK,GAAUF,GACtCJ,EAAQK,aAJMpB,wBDQCD,UACZF,EAAa,iBAAkBE,2BAGlBA,UACbF,EAAa,kBAAmBE,yBAGrBA,UACXF,EAAa,gBAAiBE"}
|
@@ -1,93 +1,8 @@
|
|
1
1
|
import { exec } from 'child_process';
|
2
2
|
|
3
|
-
var
|
4
|
-
|
5
|
-
"
|
6
|
-
desc: 'Print help information for the application'
|
7
|
-
},
|
8
|
-
version: {
|
9
|
-
desc: 'Print help information for the application'
|
10
|
-
},
|
11
|
-
timeout: {
|
12
|
-
"short": 't',
|
13
|
-
desc: 'Delay before application stops automatically <milliseconds>',
|
14
|
-
validator: function validator(val) {
|
15
|
-
return typeof val === 'number';
|
16
|
-
},
|
17
|
-
convert: function convert(val) {
|
18
|
-
return val.toString();
|
19
|
-
}
|
20
|
-
},
|
21
|
-
preview: {
|
22
|
-
"short": 'p',
|
23
|
-
desc: 'Preview window settings <x,y,w,h>',
|
24
|
-
validator: function validator(val) {
|
25
|
-
return typeof val === 'object' && Boolean((val == null ? void 0 : val.x) && (val == null ? void 0 : val.y) && (val == null ? void 0 : val.width) && (val == null ? void 0 : val.height));
|
26
|
-
},
|
27
|
-
convert: function convert(val) {
|
28
|
-
return val.x + "," + val.y + "," + val.width + "," + val.height;
|
29
|
-
}
|
30
|
-
},
|
31
|
-
fullscreen: {
|
32
|
-
"short": 'f',
|
33
|
-
desc: 'Fullscreen preview mode'
|
34
|
-
},
|
35
|
-
'qt-preview': {
|
36
|
-
desc: 'Use Qt-based preview window'
|
37
|
-
},
|
38
|
-
nopreview: {
|
39
|
-
"short": 'n',
|
40
|
-
desc: 'Do not display a preview window'
|
41
|
-
},
|
42
|
-
'info-text': {
|
43
|
-
desc: 'Set window title bar text <string>',
|
44
|
-
validator: function validator(val) {
|
45
|
-
return typeof val === 'string';
|
46
|
-
}
|
47
|
-
},
|
48
|
-
width: {
|
49
|
-
desc: 'Capture image width <width>',
|
50
|
-
validator: function validator(val) {
|
51
|
-
return typeof val === 'number';
|
52
|
-
},
|
53
|
-
convert: function convert(val) {
|
54
|
-
return val.toString();
|
55
|
-
}
|
56
|
-
},
|
57
|
-
height: {
|
58
|
-
desc: 'Capture image height <height>',
|
59
|
-
validator: function validator(val) {
|
60
|
-
return typeof val === 'number';
|
61
|
-
},
|
62
|
-
convert: function convert(val) {
|
63
|
-
return val.toString();
|
64
|
-
}
|
65
|
-
},
|
66
|
-
'viewfinder-width': {
|
67
|
-
desc: 'Capture image width <width>',
|
68
|
-
validator: function validator(val) {
|
69
|
-
return typeof val === 'number';
|
70
|
-
},
|
71
|
-
convert: function convert(val) {
|
72
|
-
return val.toString();
|
73
|
-
}
|
74
|
-
},
|
75
|
-
'viewfinder-height': {
|
76
|
-
desc: 'Capture image height <height>',
|
77
|
-
validator: function validator(val) {
|
78
|
-
return typeof val === 'number';
|
79
|
-
},
|
80
|
-
convert: function convert(val) {
|
81
|
-
return val.toString();
|
82
|
-
}
|
83
|
-
},
|
84
|
-
// ...
|
85
|
-
output: {
|
86
|
-
"short": 'o',
|
87
|
-
desc: 'Output file name <string>',
|
88
|
-
validator: function validator(val) {
|
89
|
-
return typeof val === 'string';
|
90
|
-
}
|
3
|
+
var optionConverterMap = {
|
4
|
+
preview: function preview(val) {
|
5
|
+
return val.x + "," + val.y + "," + val.width + "," + val.height;
|
91
6
|
}
|
92
7
|
};
|
93
8
|
|
@@ -108,24 +23,39 @@ function convertOptionsToCmdArgs(options) {
|
|
108
23
|
Object.entries(options).forEach(function (_ref) {
|
109
24
|
var key = _ref[0],
|
110
25
|
val = _ref[1];
|
111
|
-
var
|
112
|
-
|
113
|
-
if (typeof opt.validator === 'function' && !opt.validator(val)) {
|
114
|
-
throw new Error("Invalid value for option \"" + key + "\"");
|
115
|
-
}
|
116
|
-
|
117
|
-
var value = typeof opt.convert === 'function' ? opt.convert(val) : val;
|
26
|
+
var converter = optionConverterMap[key];
|
27
|
+
var value = typeof converter === 'function' ? converter(val) : val;
|
118
28
|
if (value) args.push("--" + key);
|
119
|
-
if (value !== true) args.push(value);
|
29
|
+
if (value !== true && value != null && value.toString()) args.push(value == null ? void 0 : value.toString());
|
120
30
|
}, true);
|
121
31
|
return args;
|
122
32
|
}
|
123
33
|
|
124
|
-
function
|
34
|
+
function runLibCamera(bin, options) {
|
35
|
+
if (bin === void 0) {
|
36
|
+
bin = 'libcamera-still';
|
37
|
+
}
|
38
|
+
|
125
39
|
var args = convertOptionsToCmdArgs(options);
|
126
|
-
var command = cmd(
|
40
|
+
var command = cmd(bin, args);
|
41
|
+
|
42
|
+
if (process.env.NODE_ENV !== "production") {
|
43
|
+
console.log(command);
|
44
|
+
return command;
|
45
|
+
}
|
46
|
+
|
127
47
|
return run(command);
|
128
48
|
}
|
129
49
|
|
130
|
-
|
50
|
+
function jpeg(options) {
|
51
|
+
return runLibCamera('libcamera-jpeg', options);
|
52
|
+
}
|
53
|
+
function still(options) {
|
54
|
+
return runLibCamera('libcamera-still', options);
|
55
|
+
}
|
56
|
+
function vid(options) {
|
57
|
+
return runLibCamera('libcamera-vid', options);
|
58
|
+
}
|
59
|
+
|
60
|
+
export { jpeg, still, vid };
|
131
61
|
//# sourceMappingURL=node-libcamera.esm.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"node-libcamera.esm.js","sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["export namespace LibCamera {\n export type OptionKeys = typeof OPTION_KEYS[number]\n\n export interface OptionDefinition {\n short?: string\n desc?: string\n validator?: (val: any) => boolean\n convert?: (val: any) => string\n }\n\n export type OptionsObject = {\n [key in OptionKeys]?: any\n }\n\n export interface PreviewOption {\n x: number\n y: number\n width: number\n height: number\n }\n}\n\nexport const OPTION_KEYS = [\n 'help',\n 'version',\n 'timeout',\n 'preview',\n 'fullscreen',\n 'qt-preview',\n 'nopreview',\n 'info-text',\n 'width',\n 'height',\n 'viewfinder-width',\n 'viewfinder-height',\n // ...\n 'output',\n] as const\n\nexport const OPTIONS: Record<\n LibCamera.OptionKeys,\n LibCamera.OptionDefinition\n> = {\n help: {\n short: 'h',\n desc: 'Print help information for the application',\n },\n version: {\n desc: 'Print help information for the application',\n },\n timeout: {\n short: 't',\n desc: 'Delay before application stops automatically <milliseconds>',\n validator: (val: number) => typeof val === 'number',\n convert: (val: number) => val.toString(),\n },\n preview: {\n short: 'p',\n desc: 'Preview window settings <x,y,w,h>',\n validator(val: LibCamera.PreviewOption) {\n return (\n typeof val === 'object' &&\n Boolean(val?.x && val?.y && val?.width && val?.height)\n )\n },\n convert(val: LibCamera.PreviewOption) {\n return `${val.x},${val.y},${val.width},${val.height}`\n },\n },\n fullscreen: {\n short: 'f',\n desc: 'Fullscreen preview mode',\n },\n 'qt-preview': {\n desc: 'Use Qt-based preview window',\n },\n nopreview: {\n short: 'n',\n desc: 'Do not display a preview window',\n },\n 'info-text': {\n desc: 'Set window title bar text <string>',\n validator: (val: string) => typeof val === 'string',\n },\n width: {\n desc: 'Capture image width <width>',\n validator: (val: number) => typeof val === 'number',\n convert: (val: number) => val.toString(),\n },\n height: {\n desc: 'Capture image height <height>',\n validator: (val: number) => typeof val === 'number',\n convert: (val: number) => val.toString(),\n },\n 'viewfinder-width': {\n desc: 'Capture image width <width>',\n validator: (val: number) => typeof val === 'number',\n convert: (val: number) => val.toString(),\n },\n 'viewfinder-height': {\n desc: 'Capture image height <height>',\n validator: (val: number) => typeof val === 'number',\n convert: (val: number) => val.toString(),\n },\n\n // ...\n\n output: {\n short: 'o',\n desc: 'Output file name <string>',\n validator: (val: string) => typeof val === 'string',\n },\n} as const\n","import { exec, ExecOptionsWithBufferEncoding } from 'child_process'\nimport { OPTIONS, LibCamera } from './options'\n\nexport function cmd(base: string, args?: string[]): string {\n if (base && !args) return base\n return `${base} ${args?.join(' ')}`\n}\n\nexport function run(command: string, options?: ExecOptionsWithBufferEncoding) {\n return new Promise((resolve, reject) => {\n exec(command, options, (error, stdout, stderr) => {\n if (stderr || error) reject(stderr || error)\n resolve(stdout)\n })\n })\n}\n\nexport function convertOptionsToCmdArgs(\n options: LibCamera.OptionsObject\n): string[] {\n const args: string[] = []\n Object.entries(options).forEach(([key, val]) => {\n const opt = OPTIONS[key as LibCamera.OptionKeys]\n if (typeof opt.validator === 'function' && !opt.validator(val)) {\n throw new Error(`Invalid value for option \"${key}\"`)\n }\n const value = typeof opt.convert === 'function' ? opt.convert(val) : val\n if (value) args.push(`--${key}`)\n if (value !== true) args.push(value)\n }, true)\n return args\n}\n","import { LibCamera } from './options'\nimport { run, cmd, convertOptionsToCmdArgs } from './utils'\n\nexport function snap(options: LibCamera.OptionsObject) {\n const args = convertOptionsToCmdArgs(options)\n const command = cmd('libcamera-still', args)\n return run(command)\n}\n"],"names":["OPTIONS","help","desc","version","timeout","validator","val","convert","toString","preview","Boolean","x","y","width","height","fullscreen","nopreview","output","cmd","base","args","join","run","command","options","Promise","resolve","reject","exec","error","stdout","stderr","convertOptionsToCmdArgs","Object","entries","forEach","key","opt","Error","value","push","snap"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"node-libcamera.esm.js","sources":["../src/options.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["export namespace LibCamera {\n export interface CommandLineOptions {\n /**\n * Print help information for the application\n *\n * The `--help` option causes every application to print its full set of command line options with a brief synopsis of each, and then quit.\n **/\n help: boolean\n /**\n * Print out a software version number\n *\n * All `libcamera-apps` will, when they see the `--version` option, print out a version string both for `libcamera` and `libcamera-apps` and then quit.\n */\n version: boolean\n /**\n * Delay before application stops automatically <milliseconds>\n *\n * The `--timeout` option specifies how long the application runs before it stops, whether it is recording a video or showing a preview. In the case of still image capture, the application will show the preview window for this long before capturing the output image.\n *\n * If unspecified, the default value is 5000 (5 seconds). The value zero causes the application to run indefinitely.\n */\n timeout: number\n }\n\n export interface PreviewWindowOptions {\n /**\n * Preview window settings\n *\n * Sets the size and location of the preview window (both X Windows and DRM versions). It does not affect the resolution or aspect ratio of images being requested from the camera. The camera images will be scaled to the size of the preview window for display, and will be pillar/letter-boxed to fit.\n *\n * Example:\n * ```json\n * { \"x\": 100, \"y\": 100, \"width\": 500, \"height\": 500 }\n * ```\n */\n preview: PreviewOption\n /**\n * Fullscreen preview mode\n *\n * Forces the preview window to use the whole screen, and the window will have no border or title bar. Again the image may be pillar/letter-boxed.\n */\n fullscreen: boolean\n /**\n * Use Qt-based preview window\n *\n * The preview window is switched to use the Qt-based implementation. This option is not normally recommended because it no longer uses zero-copy buffer sharing nor GPU acceleration and is therefore very expensive, however, it does support X forwarding (which the other preview implementations do not).\n *\n * The Qt preview window does not support the `--fullscreen` option. Generally it is advised to try and keep the preview window small.\n */\n 'qt-preview': boolean\n /**\n * Do not display a preview window\n *\n * The preview window is suppressed entirely.\n */\n nopreview: boolean\n /**\n * Set window title bar text <string>\n *\n * The supplied string is set as the title of the preview window (when running under X Windows). Additionally the string may contain a number of `%` directives which are substituted with information from the image metadata. The permitted directives are:\n *\n * | Directive | Substitution |\n * | :--------------- | :------------------ |\n * | `%frame` | The sequence number of the frame |\n * | `%fps` | The instantaneous frame rate |\n * | `%exp` | The shutter speed used to capture the image, in microseconds |\n * | `%ag` | The analogue gain applied to the image in the sensor |\n * | `%dg` | The digital gain applied to the image by the ISP |\n * | `%rg` | The gain applied to the red component of each pixel |\n * | `%bg` | The gain applied to the blue component of each pixel |\n * | `%focus` | The focus metric for the image, where a larger value implies a sharper image |\n *\n * When not provided, the `--info-text` string defaults to `\"#%frame (%fps fps) exp %exp ag %ag dg %dg\"`.\n */\n 'info-text': string\n }\n\n export interface CameraResolutionOptions {\n /**\n * Capture image width <width>\n *\n * This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.\n *\n * For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.\n *\n * For libcamera-hello these parameters have no effect.\n */\n width: number\n /**\n * Capture image height <height>\n *\n * This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.\n *\n * For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.\n *\n * For libcamera-hello these parameters have no effect.\n */\n height: number\n }\n\n export interface OutputFileOptions {\n /**\n * Output file name <string>\n *\n * `--output` sets the name of the output file to which the output image or video is written. Besides regular file names, this may take the following special values:\n *\n * `-` - write to stdout\n *\n * `udp://` - a string starting with this is taken as a network address for streaming\n *\n * `tcp://` - a string starting with this is taken as a network address for streaming\n *\n * a string containing a `%d` directive is taken as a file name where the format directive is replaced with a count that increments for each file that is opened. Standard C format directive modifiers are permitted.\n */\n output: string\n }\n\n export interface VideoOptions {\n /**\n * Saves timestamp information to the specified file. Useful as an input file to `mkvmerge`.\n */\n 'save-pts': string\n }\n\n export type OptionsObject = CommandLineOptions &\n PreviewWindowOptions &\n CameraResolutionOptions &\n OutputFileOptions &\n VideoOptions\n\n export type OptionKeys = keyof OptionsObject\n export type OptionConverter = (val: any) => string\n\n export interface PreviewOption {\n x: number\n y: number\n width: number\n height: number\n }\n}\n\nexport const optionConverterMap: Partial<Record<\n LibCamera.OptionKeys,\n LibCamera.OptionConverter\n>> = {\n preview(val: LibCamera.PreviewOption) {\n return `${val.x},${val.y},${val.width},${val.height}`\n },\n} as const\n","import { exec, ExecOptionsWithBufferEncoding } from 'child_process'\nimport { optionConverterMap, LibCamera } from './options'\n\nexport function cmd(base: string, args?: string[]): string {\n if (base && !args) return base\n return `${base} ${args?.join(' ')}`\n}\n\nexport function run(command: string, options?: ExecOptionsWithBufferEncoding) {\n return new Promise((resolve, reject) => {\n exec(command, options, (error, stdout, stderr) => {\n if (stderr || error) reject(stderr || error)\n resolve(stdout)\n })\n })\n}\n\nexport function convertOptionsToCmdArgs(\n options: Partial<LibCamera.OptionsObject>\n): string[] {\n const args: string[] = []\n Object.entries(options).forEach(([key, val]) => {\n const converter = optionConverterMap[key as LibCamera.OptionKeys]\n const value = typeof converter === 'function' ? converter(val) : val\n if (value) args.push(`--${key}`)\n if (value !== true && value?.toString()) args.push(value?.toString())\n }, true)\n return args\n}\n","import { LibCamera } from './options'\nimport { run, cmd, convertOptionsToCmdArgs } from './utils'\n\nfunction runLibCamera(\n bin: string = 'libcamera-still',\n options: Partial<LibCamera.OptionsObject>\n) {\n const args = convertOptionsToCmdArgs(options)\n const command = cmd(bin, args)\n if (__DEV__) {\n console.log(command)\n return command\n }\n return run(command)\n}\n\nexport function jpeg(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-jpeg', options)\n}\n\nexport function still(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-still', options)\n}\n\nexport function vid(options: Partial<LibCamera.OptionsObject>) {\n return runLibCamera('libcamera-vid', options)\n}\n"],"names":["optionConverterMap","preview","val","x","y","width","height","cmd","base","args","join","run","command","options","Promise","resolve","reject","exec","error","stdout","stderr","convertOptionsToCmdArgs","Object","entries","forEach","key","converter","value","push","toString","runLibCamera","bin","console","log","jpeg","still","vid"],"mappings":";;AA6IO,IAAMA,kBAAkB,GAG1B;AACHC,EAAAA,OADG,mBACKC,GADL;AAED,WAAUA,GAAG,CAACC,CAAd,SAAmBD,GAAG,CAACE,CAAvB,SAA4BF,GAAG,CAACG,KAAhC,SAAyCH,GAAG,CAACI,MAA7C;AACD;AAHE,CAHE;;SC1ISC,IAAIC,MAAcC;AAChC,MAAID,IAAI,IAAI,CAACC,IAAb,EAAmB,OAAOD,IAAP;AACnB,SAAUA,IAAV,UAAkBC,IAAlB,oBAAkBA,IAAI,CAAEC,IAAN,CAAW,GAAX,CAAlB;AACD;AAED,SAAgBC,IAAIC,SAAiBC;AACnC,SAAO,IAAIC,OAAJ,CAAY,UAACC,OAAD,EAAUC,MAAV;AACjBC,IAAAA,IAAI,CAACL,OAAD,EAAUC,OAAV,EAAmB,UAACK,KAAD,EAAQC,MAAR,EAAgBC,MAAhB;AACrB,UAAIA,MAAM,IAAIF,KAAd,EAAqBF,MAAM,CAACI,MAAM,IAAIF,KAAX,CAAN;AACrBH,MAAAA,OAAO,CAACI,MAAD,CAAP;AACD,KAHG,CAAJ;AAID,GALM,CAAP;AAMD;AAED,SAAgBE,wBACdR;AAEA,MAAMJ,IAAI,GAAa,EAAvB;AACAa,EAAAA,MAAM,CAACC,OAAP,CAAeV,OAAf,EAAwBW,OAAxB,CAAgC;QAAEC;QAAKvB;AACrC,QAAMwB,SAAS,GAAG1B,kBAAkB,CAACyB,GAAD,CAApC;AACA,QAAME,KAAK,GAAG,OAAOD,SAAP,KAAqB,UAArB,GAAkCA,SAAS,CAACxB,GAAD,CAA3C,GAAmDA,GAAjE;AACA,QAAIyB,KAAJ,EAAWlB,IAAI,CAACmB,IAAL,QAAeH,GAAf;AACX,QAAIE,KAAK,KAAK,IAAV,IAAkBA,KAAlB,YAAkBA,KAAK,CAAEE,QAAP,EAAtB,EAAyCpB,IAAI,CAACmB,IAAL,CAAUD,KAAV,oBAAUA,KAAK,CAAEE,QAAP,EAAV;AAC1C,GALD,EAKG,IALH;AAMA,SAAOpB,IAAP;AACD;;ACzBD,SAASqB,YAAT,CACEC,GADF,EAEElB,OAFF;MACEkB;AAAAA,IAAAA,MAAc;;;AAGd,MAAMtB,IAAI,GAAGY,uBAAuB,CAACR,OAAD,CAApC;AACA,MAAMD,OAAO,GAAGL,GAAG,CAACwB,GAAD,EAAMtB,IAAN,CAAnB;;AACA,6CAAa;AACXuB,IAAAA,OAAO,CAACC,GAAR,CAAYrB,OAAZ;AACA,WAAOA,OAAP;AACD;;AACD,SAAOD,GAAG,CAACC,OAAD,CAAV;AACD;;AAED,SAAgBsB,KAAKrB;AACnB,SAAOiB,YAAY,CAAC,gBAAD,EAAmBjB,OAAnB,CAAnB;AACD;AAED,SAAgBsB,MAAMtB;AACpB,SAAOiB,YAAY,CAAC,iBAAD,EAAoBjB,OAApB,CAAnB;AACD;AAED,SAAgBuB,IAAIvB;AAClB,SAAOiB,YAAY,CAAC,eAAD,EAAkBjB,OAAlB,CAAnB;AACD;;;;"}
|
package/dist/options.d.ts
CHANGED
@@ -1,14 +1,125 @@
|
|
1
1
|
export declare namespace LibCamera {
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
interface CommandLineOptions {
|
3
|
+
/**
|
4
|
+
* Print help information for the application
|
5
|
+
*
|
6
|
+
* The `--help` option causes every application to print its full set of command line options with a brief synopsis of each, and then quit.
|
7
|
+
**/
|
8
|
+
help: boolean;
|
9
|
+
/**
|
10
|
+
* Print out a software version number
|
11
|
+
*
|
12
|
+
* All `libcamera-apps` will, when they see the `--version` option, print out a version string both for `libcamera` and `libcamera-apps` and then quit.
|
13
|
+
*/
|
14
|
+
version: boolean;
|
15
|
+
/**
|
16
|
+
* Delay before application stops automatically <milliseconds>
|
17
|
+
*
|
18
|
+
* The `--timeout` option specifies how long the application runs before it stops, whether it is recording a video or showing a preview. In the case of still image capture, the application will show the preview window for this long before capturing the output image.
|
19
|
+
*
|
20
|
+
* If unspecified, the default value is 5000 (5 seconds). The value zero causes the application to run indefinitely.
|
21
|
+
*/
|
22
|
+
timeout: number;
|
8
23
|
}
|
9
|
-
|
10
|
-
|
11
|
-
|
24
|
+
interface PreviewWindowOptions {
|
25
|
+
/**
|
26
|
+
* Preview window settings
|
27
|
+
*
|
28
|
+
* Sets the size and location of the preview window (both X Windows and DRM versions). It does not affect the resolution or aspect ratio of images being requested from the camera. The camera images will be scaled to the size of the preview window for display, and will be pillar/letter-boxed to fit.
|
29
|
+
*
|
30
|
+
* Example:
|
31
|
+
* ```json
|
32
|
+
* { "x": 100, "y": 100, "width": 500, "height": 500 }
|
33
|
+
* ```
|
34
|
+
*/
|
35
|
+
preview: PreviewOption;
|
36
|
+
/**
|
37
|
+
* Fullscreen preview mode
|
38
|
+
*
|
39
|
+
* Forces the preview window to use the whole screen, and the window will have no border or title bar. Again the image may be pillar/letter-boxed.
|
40
|
+
*/
|
41
|
+
fullscreen: boolean;
|
42
|
+
/**
|
43
|
+
* Use Qt-based preview window
|
44
|
+
*
|
45
|
+
* The preview window is switched to use the Qt-based implementation. This option is not normally recommended because it no longer uses zero-copy buffer sharing nor GPU acceleration and is therefore very expensive, however, it does support X forwarding (which the other preview implementations do not).
|
46
|
+
*
|
47
|
+
* The Qt preview window does not support the `--fullscreen` option. Generally it is advised to try and keep the preview window small.
|
48
|
+
*/
|
49
|
+
'qt-preview': boolean;
|
50
|
+
/**
|
51
|
+
* Do not display a preview window
|
52
|
+
*
|
53
|
+
* The preview window is suppressed entirely.
|
54
|
+
*/
|
55
|
+
nopreview: boolean;
|
56
|
+
/**
|
57
|
+
* Set window title bar text <string>
|
58
|
+
*
|
59
|
+
* The supplied string is set as the title of the preview window (when running under X Windows). Additionally the string may contain a number of `%` directives which are substituted with information from the image metadata. The permitted directives are:
|
60
|
+
*
|
61
|
+
* | Directive | Substitution |
|
62
|
+
* | :--------------- | :------------------ |
|
63
|
+
* | `%frame` | The sequence number of the frame |
|
64
|
+
* | `%fps` | The instantaneous frame rate |
|
65
|
+
* | `%exp` | The shutter speed used to capture the image, in microseconds |
|
66
|
+
* | `%ag` | The analogue gain applied to the image in the sensor |
|
67
|
+
* | `%dg` | The digital gain applied to the image by the ISP |
|
68
|
+
* | `%rg` | The gain applied to the red component of each pixel |
|
69
|
+
* | `%bg` | The gain applied to the blue component of each pixel |
|
70
|
+
* | `%focus` | The focus metric for the image, where a larger value implies a sharper image |
|
71
|
+
*
|
72
|
+
* When not provided, the `--info-text` string defaults to `"#%frame (%fps fps) exp %exp ag %ag dg %dg"`.
|
73
|
+
*/
|
74
|
+
'info-text': string;
|
75
|
+
}
|
76
|
+
interface CameraResolutionOptions {
|
77
|
+
/**
|
78
|
+
* Capture image width <width>
|
79
|
+
*
|
80
|
+
* This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.
|
81
|
+
*
|
82
|
+
* For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.
|
83
|
+
*
|
84
|
+
* For libcamera-hello these parameters have no effect.
|
85
|
+
*/
|
86
|
+
width: number;
|
87
|
+
/**
|
88
|
+
* Capture image height <height>
|
89
|
+
*
|
90
|
+
* This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.
|
91
|
+
*
|
92
|
+
* For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.
|
93
|
+
*
|
94
|
+
* For libcamera-hello these parameters have no effect.
|
95
|
+
*/
|
96
|
+
height: number;
|
97
|
+
}
|
98
|
+
interface OutputFileOptions {
|
99
|
+
/**
|
100
|
+
* Output file name <string>
|
101
|
+
*
|
102
|
+
* `--output` sets the name of the output file to which the output image or video is written. Besides regular file names, this may take the following special values:
|
103
|
+
*
|
104
|
+
* `-` - write to stdout
|
105
|
+
*
|
106
|
+
* `udp://` - a string starting with this is taken as a network address for streaming
|
107
|
+
*
|
108
|
+
* `tcp://` - a string starting with this is taken as a network address for streaming
|
109
|
+
*
|
110
|
+
* a string containing a `%d` directive is taken as a file name where the format directive is replaced with a count that increments for each file that is opened. Standard C format directive modifiers are permitted.
|
111
|
+
*/
|
112
|
+
output: string;
|
113
|
+
}
|
114
|
+
interface VideoOptions {
|
115
|
+
/**
|
116
|
+
* Saves timestamp information to the specified file. Useful as an input file to `mkvmerge`.
|
117
|
+
*/
|
118
|
+
'save-pts': string;
|
119
|
+
}
|
120
|
+
type OptionsObject = CommandLineOptions & PreviewWindowOptions & CameraResolutionOptions & OutputFileOptions & VideoOptions;
|
121
|
+
type OptionKeys = keyof OptionsObject;
|
122
|
+
type OptionConverter = (val: any) => string;
|
12
123
|
interface PreviewOption {
|
13
124
|
x: number;
|
14
125
|
y: number;
|
@@ -16,5 +127,4 @@ export declare namespace LibCamera {
|
|
16
127
|
height: number;
|
17
128
|
}
|
18
129
|
}
|
19
|
-
export declare const
|
20
|
-
export declare const OPTIONS: Record<LibCamera.OptionKeys, LibCamera.OptionDefinition>;
|
130
|
+
export declare const optionConverterMap: Partial<Record<LibCamera.OptionKeys, LibCamera.OptionConverter>>;
|
package/dist/utils.d.ts
CHANGED
@@ -3,4 +3,4 @@ import { ExecOptionsWithBufferEncoding } from 'child_process';
|
|
3
3
|
import { LibCamera } from './options';
|
4
4
|
export declare function cmd(base: string, args?: string[]): string;
|
5
5
|
export declare function run(command: string, options?: ExecOptionsWithBufferEncoding): Promise<unknown>;
|
6
|
-
export declare function convertOptionsToCmdArgs(options: LibCamera.OptionsObject): string[];
|
6
|
+
export declare function convertOptionsToCmdArgs(options: Partial<LibCamera.OptionsObject>): string[];
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "node-libcamera",
|
3
3
|
"author": "Hussain Abbas",
|
4
|
-
"version": "0.1.
|
4
|
+
"version": "0.1.1",
|
5
5
|
"license": "MIT",
|
6
6
|
"main": "dist/index.js",
|
7
7
|
"typings": "dist/index.d.ts",
|
@@ -16,7 +16,7 @@
|
|
16
16
|
"scripts": {
|
17
17
|
"start": "tsdx watch",
|
18
18
|
"build": "tsdx build",
|
19
|
-
"test": "tsdx test",
|
19
|
+
"test": "tsdx test --no-cache",
|
20
20
|
"lint": "tsdx lint",
|
21
21
|
"prepare": "tsdx build",
|
22
22
|
"size": "size-limit",
|
@@ -51,5 +51,10 @@
|
|
51
51
|
"path": "dist/node-libcamera.esm.js",
|
52
52
|
"limit": "10 KB"
|
53
53
|
}
|
54
|
-
]
|
54
|
+
],
|
55
|
+
"jest": {
|
56
|
+
"globals": {
|
57
|
+
"__DEV__": true
|
58
|
+
}
|
59
|
+
}
|
55
60
|
}
|
package/src/index.ts
CHANGED
@@ -1,8 +1,27 @@
|
|
1
1
|
import { LibCamera } from './options'
|
2
2
|
import { run, cmd, convertOptionsToCmdArgs } from './utils'
|
3
3
|
|
4
|
-
|
4
|
+
function runLibCamera(
|
5
|
+
bin: string = 'libcamera-still',
|
6
|
+
options: Partial<LibCamera.OptionsObject>
|
7
|
+
) {
|
5
8
|
const args = convertOptionsToCmdArgs(options)
|
6
|
-
const command = cmd(
|
9
|
+
const command = cmd(bin, args)
|
10
|
+
if (__DEV__) {
|
11
|
+
console.log(command)
|
12
|
+
return command
|
13
|
+
}
|
7
14
|
return run(command)
|
8
15
|
}
|
16
|
+
|
17
|
+
export function jpeg(options: Partial<LibCamera.OptionsObject>) {
|
18
|
+
return runLibCamera('libcamera-jpeg', options)
|
19
|
+
}
|
20
|
+
|
21
|
+
export function still(options: Partial<LibCamera.OptionsObject>) {
|
22
|
+
return runLibCamera('libcamera-still', options)
|
23
|
+
}
|
24
|
+
|
25
|
+
export function vid(options: Partial<LibCamera.OptionsObject>) {
|
26
|
+
return runLibCamera('libcamera-vid', options)
|
27
|
+
}
|
package/src/options.ts
CHANGED
@@ -1,17 +1,136 @@
|
|
1
1
|
export namespace LibCamera {
|
2
|
-
export
|
2
|
+
export interface CommandLineOptions {
|
3
|
+
/**
|
4
|
+
* Print help information for the application
|
5
|
+
*
|
6
|
+
* The `--help` option causes every application to print its full set of command line options with a brief synopsis of each, and then quit.
|
7
|
+
**/
|
8
|
+
help: boolean
|
9
|
+
/**
|
10
|
+
* Print out a software version number
|
11
|
+
*
|
12
|
+
* All `libcamera-apps` will, when they see the `--version` option, print out a version string both for `libcamera` and `libcamera-apps` and then quit.
|
13
|
+
*/
|
14
|
+
version: boolean
|
15
|
+
/**
|
16
|
+
* Delay before application stops automatically <milliseconds>
|
17
|
+
*
|
18
|
+
* The `--timeout` option specifies how long the application runs before it stops, whether it is recording a video or showing a preview. In the case of still image capture, the application will show the preview window for this long before capturing the output image.
|
19
|
+
*
|
20
|
+
* If unspecified, the default value is 5000 (5 seconds). The value zero causes the application to run indefinitely.
|
21
|
+
*/
|
22
|
+
timeout: number
|
23
|
+
}
|
24
|
+
|
25
|
+
export interface PreviewWindowOptions {
|
26
|
+
/**
|
27
|
+
* Preview window settings
|
28
|
+
*
|
29
|
+
* Sets the size and location of the preview window (both X Windows and DRM versions). It does not affect the resolution or aspect ratio of images being requested from the camera. The camera images will be scaled to the size of the preview window for display, and will be pillar/letter-boxed to fit.
|
30
|
+
*
|
31
|
+
* Example:
|
32
|
+
* ```json
|
33
|
+
* { "x": 100, "y": 100, "width": 500, "height": 500 }
|
34
|
+
* ```
|
35
|
+
*/
|
36
|
+
preview: PreviewOption
|
37
|
+
/**
|
38
|
+
* Fullscreen preview mode
|
39
|
+
*
|
40
|
+
* Forces the preview window to use the whole screen, and the window will have no border or title bar. Again the image may be pillar/letter-boxed.
|
41
|
+
*/
|
42
|
+
fullscreen: boolean
|
43
|
+
/**
|
44
|
+
* Use Qt-based preview window
|
45
|
+
*
|
46
|
+
* The preview window is switched to use the Qt-based implementation. This option is not normally recommended because it no longer uses zero-copy buffer sharing nor GPU acceleration and is therefore very expensive, however, it does support X forwarding (which the other preview implementations do not).
|
47
|
+
*
|
48
|
+
* The Qt preview window does not support the `--fullscreen` option. Generally it is advised to try and keep the preview window small.
|
49
|
+
*/
|
50
|
+
'qt-preview': boolean
|
51
|
+
/**
|
52
|
+
* Do not display a preview window
|
53
|
+
*
|
54
|
+
* The preview window is suppressed entirely.
|
55
|
+
*/
|
56
|
+
nopreview: boolean
|
57
|
+
/**
|
58
|
+
* Set window title bar text <string>
|
59
|
+
*
|
60
|
+
* The supplied string is set as the title of the preview window (when running under X Windows). Additionally the string may contain a number of `%` directives which are substituted with information from the image metadata. The permitted directives are:
|
61
|
+
*
|
62
|
+
* | Directive | Substitution |
|
63
|
+
* | :--------------- | :------------------ |
|
64
|
+
* | `%frame` | The sequence number of the frame |
|
65
|
+
* | `%fps` | The instantaneous frame rate |
|
66
|
+
* | `%exp` | The shutter speed used to capture the image, in microseconds |
|
67
|
+
* | `%ag` | The analogue gain applied to the image in the sensor |
|
68
|
+
* | `%dg` | The digital gain applied to the image by the ISP |
|
69
|
+
* | `%rg` | The gain applied to the red component of each pixel |
|
70
|
+
* | `%bg` | The gain applied to the blue component of each pixel |
|
71
|
+
* | `%focus` | The focus metric for the image, where a larger value implies a sharper image |
|
72
|
+
*
|
73
|
+
* When not provided, the `--info-text` string defaults to `"#%frame (%fps fps) exp %exp ag %ag dg %dg"`.
|
74
|
+
*/
|
75
|
+
'info-text': string
|
76
|
+
}
|
77
|
+
|
78
|
+
export interface CameraResolutionOptions {
|
79
|
+
/**
|
80
|
+
* Capture image width <width>
|
81
|
+
*
|
82
|
+
* This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.
|
83
|
+
*
|
84
|
+
* For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.
|
85
|
+
*
|
86
|
+
* For libcamera-hello these parameters have no effect.
|
87
|
+
*/
|
88
|
+
width: number
|
89
|
+
/**
|
90
|
+
* Capture image height <height>
|
91
|
+
*
|
92
|
+
* This number specifies the output resolution of the camera images captured by libcamera-still, libcamera-jpeg and libcamera-vid.
|
93
|
+
*
|
94
|
+
* For libcamera-raw, it affects the size of the raw frames captured. Where a camera has a 2x2 binned readout mode, specifying a resolution not larger than this binned mode will result in the capture of 2x2 binned raw frames.
|
95
|
+
*
|
96
|
+
* For libcamera-hello these parameters have no effect.
|
97
|
+
*/
|
98
|
+
height: number
|
99
|
+
}
|
3
100
|
|
4
|
-
export interface
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
101
|
+
export interface OutputFileOptions {
|
102
|
+
/**
|
103
|
+
* Output file name <string>
|
104
|
+
*
|
105
|
+
* `--output` sets the name of the output file to which the output image or video is written. Besides regular file names, this may take the following special values:
|
106
|
+
*
|
107
|
+
* `-` - write to stdout
|
108
|
+
*
|
109
|
+
* `udp://` - a string starting with this is taken as a network address for streaming
|
110
|
+
*
|
111
|
+
* `tcp://` - a string starting with this is taken as a network address for streaming
|
112
|
+
*
|
113
|
+
* a string containing a `%d` directive is taken as a file name where the format directive is replaced with a count that increments for each file that is opened. Standard C format directive modifiers are permitted.
|
114
|
+
*/
|
115
|
+
output: string
|
9
116
|
}
|
10
117
|
|
11
|
-
export
|
12
|
-
|
118
|
+
export interface VideoOptions {
|
119
|
+
/**
|
120
|
+
* Saves timestamp information to the specified file. Useful as an input file to `mkvmerge`.
|
121
|
+
*/
|
122
|
+
'save-pts': string
|
13
123
|
}
|
14
124
|
|
125
|
+
export type OptionsObject = CommandLineOptions &
|
126
|
+
PreviewWindowOptions &
|
127
|
+
CameraResolutionOptions &
|
128
|
+
OutputFileOptions &
|
129
|
+
VideoOptions
|
130
|
+
|
131
|
+
export type OptionKeys = keyof OptionsObject
|
132
|
+
export type OptionConverter = (val: any) => string
|
133
|
+
|
15
134
|
export interface PreviewOption {
|
16
135
|
x: number
|
17
136
|
y: number
|
@@ -20,94 +139,11 @@ export namespace LibCamera {
|
|
20
139
|
}
|
21
140
|
}
|
22
141
|
|
23
|
-
export const
|
24
|
-
'help',
|
25
|
-
'version',
|
26
|
-
'timeout',
|
27
|
-
'preview',
|
28
|
-
'fullscreen',
|
29
|
-
'qt-preview',
|
30
|
-
'nopreview',
|
31
|
-
'info-text',
|
32
|
-
'width',
|
33
|
-
'height',
|
34
|
-
'viewfinder-width',
|
35
|
-
'viewfinder-height',
|
36
|
-
// ...
|
37
|
-
'output',
|
38
|
-
] as const
|
39
|
-
|
40
|
-
export const OPTIONS: Record<
|
142
|
+
export const optionConverterMap: Partial<Record<
|
41
143
|
LibCamera.OptionKeys,
|
42
|
-
LibCamera.
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
desc: 'Print help information for the application',
|
47
|
-
},
|
48
|
-
version: {
|
49
|
-
desc: 'Print help information for the application',
|
50
|
-
},
|
51
|
-
timeout: {
|
52
|
-
short: 't',
|
53
|
-
desc: 'Delay before application stops automatically <milliseconds>',
|
54
|
-
validator: (val: number) => typeof val === 'number',
|
55
|
-
convert: (val: number) => val.toString(),
|
56
|
-
},
|
57
|
-
preview: {
|
58
|
-
short: 'p',
|
59
|
-
desc: 'Preview window settings <x,y,w,h>',
|
60
|
-
validator(val: LibCamera.PreviewOption) {
|
61
|
-
return (
|
62
|
-
typeof val === 'object' &&
|
63
|
-
Boolean(val?.x && val?.y && val?.width && val?.height)
|
64
|
-
)
|
65
|
-
},
|
66
|
-
convert(val: LibCamera.PreviewOption) {
|
67
|
-
return `${val.x},${val.y},${val.width},${val.height}`
|
68
|
-
},
|
69
|
-
},
|
70
|
-
fullscreen: {
|
71
|
-
short: 'f',
|
72
|
-
desc: 'Fullscreen preview mode',
|
73
|
-
},
|
74
|
-
'qt-preview': {
|
75
|
-
desc: 'Use Qt-based preview window',
|
76
|
-
},
|
77
|
-
nopreview: {
|
78
|
-
short: 'n',
|
79
|
-
desc: 'Do not display a preview window',
|
80
|
-
},
|
81
|
-
'info-text': {
|
82
|
-
desc: 'Set window title bar text <string>',
|
83
|
-
validator: (val: string) => typeof val === 'string',
|
84
|
-
},
|
85
|
-
width: {
|
86
|
-
desc: 'Capture image width <width>',
|
87
|
-
validator: (val: number) => typeof val === 'number',
|
88
|
-
convert: (val: number) => val.toString(),
|
89
|
-
},
|
90
|
-
height: {
|
91
|
-
desc: 'Capture image height <height>',
|
92
|
-
validator: (val: number) => typeof val === 'number',
|
93
|
-
convert: (val: number) => val.toString(),
|
94
|
-
},
|
95
|
-
'viewfinder-width': {
|
96
|
-
desc: 'Capture image width <width>',
|
97
|
-
validator: (val: number) => typeof val === 'number',
|
98
|
-
convert: (val: number) => val.toString(),
|
99
|
-
},
|
100
|
-
'viewfinder-height': {
|
101
|
-
desc: 'Capture image height <height>',
|
102
|
-
validator: (val: number) => typeof val === 'number',
|
103
|
-
convert: (val: number) => val.toString(),
|
104
|
-
},
|
105
|
-
|
106
|
-
// ...
|
107
|
-
|
108
|
-
output: {
|
109
|
-
short: 'o',
|
110
|
-
desc: 'Output file name <string>',
|
111
|
-
validator: (val: string) => typeof val === 'string',
|
144
|
+
LibCamera.OptionConverter
|
145
|
+
>> = {
|
146
|
+
preview(val: LibCamera.PreviewOption) {
|
147
|
+
return `${val.x},${val.y},${val.width},${val.height}`
|
112
148
|
},
|
113
149
|
} as const
|
package/src/utils.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { exec, ExecOptionsWithBufferEncoding } from 'child_process'
|
2
|
-
import {
|
2
|
+
import { optionConverterMap, LibCamera } from './options'
|
3
3
|
|
4
4
|
export function cmd(base: string, args?: string[]): string {
|
5
5
|
if (base && !args) return base
|
@@ -16,17 +16,14 @@ export function run(command: string, options?: ExecOptionsWithBufferEncoding) {
|
|
16
16
|
}
|
17
17
|
|
18
18
|
export function convertOptionsToCmdArgs(
|
19
|
-
options: LibCamera.OptionsObject
|
19
|
+
options: Partial<LibCamera.OptionsObject>
|
20
20
|
): string[] {
|
21
21
|
const args: string[] = []
|
22
22
|
Object.entries(options).forEach(([key, val]) => {
|
23
|
-
const
|
24
|
-
|
25
|
-
throw new Error(`Invalid value for option "${key}"`)
|
26
|
-
}
|
27
|
-
const value = typeof opt.convert === 'function' ? opt.convert(val) : val
|
23
|
+
const converter = optionConverterMap[key as LibCamera.OptionKeys]
|
24
|
+
const value = typeof converter === 'function' ? converter(val) : val
|
28
25
|
if (value) args.push(`--${key}`)
|
29
|
-
if (value !== true) args.push(value)
|
26
|
+
if (value !== true && value?.toString()) args.push(value?.toString())
|
30
27
|
}, true)
|
31
28
|
return args
|
32
29
|
}
|