├── .gitignore
├── .prettierrc.json
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
├── lib
├── build
│ ├── Lame.js
│ ├── Lame.js.map
│ ├── LameOptions.js
│ ├── LameOptions.js.map
│ ├── LameTypings.js
│ └── LameTypings.js.map
└── src
│ ├── Lame.ts
│ ├── LameOptions.ts
│ └── LameTypings.ts
├── package-lock.json
├── package.json
├── temp
├── encoded
│ └── .keep
└── raw
│ └── .keep
├── test
├── .keep
├── example.mp3
├── example.wav
├── example.wav_LICENSE
├── notAWavFile.wav
├── notAnMp3File.mp3
├── testpic.jpg
└── tests.js
├── tsconfig.json
└── tslint.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | *.log
3 | npm-debug.log*
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # node-waf configuration
11 | .lock-wscript
12 |
13 | # Dependency directories
14 | node_modules
15 |
16 | # Lib dependencies
17 | bin/*
18 |
19 | # Optional npm cache directory
20 | .npm
21 |
22 | # Optional REPL history
23 | .node_repl_history
24 |
25 | # OS generated files
26 | .DS_Store*
27 | ehthumbs.db
28 | Icon?
29 | Thumbs.db
30 |
31 | # IDE
32 | .vscode/*
33 | .idea/*
34 |
35 | # Test
36 | test/encoded.mp3
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "tabWidth": 4
3 | }
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2017-2021, devowl.io GmbH and Jan Karres
2 |
3 | Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
4 |
5 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
6 |
7 | Source: http://opensource.org/licenses/ISC
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # node-lame
2 |
3 |
4 |
5 | LAME is an open-source encoder that encodes and decodes audio to the MP3 file format. For all MP3 needs a Node.js wrapper of the full [LAME](http://lame.sourceforge.net/) command line.
6 |
7 | The encoder reads WAV-, MP1-, MP2- and MP3-format and encodes it into an MP3 file. The decoder reads MP3-format and decodes it into WAV.
8 |
9 | ## Requirements
10 |
11 | - Linux or MacOS (This package is NOT tested on Windows)
12 | - Lame Installed (View instructions below)
13 | - Node 12.20.\* or newer
14 |
15 | ## Installation
16 |
17 | You can install it with `npm`:
18 |
19 | ```bash
20 | $ npm install node-lame
21 | ```
22 |
23 | If you have not installed [LAME](http://lame.sourceforge.net/) yet, please use the following instruction.
24 |
25 | ### Install on Debian
26 |
27 | ```bash
28 | $ sudo apt-get install lame
29 | ```
30 |
31 | ### Install on MacOS with brew
32 |
33 | ```bash
34 | $ brew install lame
35 | ```
36 |
37 | ### Install on Windows
38 |
39 | 1. Go to the the [Lame Download Page](https://lame.buanzo.org/#lamewindl) and download the EXE or ZIP file.
40 | 2. Navigate to the directory Lame was installed in (most commonly `C:\Program Files (x86)\Lame For Audacity`).
41 | 3. Add the directory to your [Environment Variables](https://www.java.com/en/download/help/path.xml).
42 |
43 | ## Examples
44 |
45 | ### Encode from file to file
46 |
47 | ```node
48 | const Lame = require("node-lame").Lame;
49 |
50 | const encoder = new Lame({
51 | output: "./audio-files/demo.mp3",
52 | bitrate: 192,
53 | }).setFile("./audio-files/demo.wav");
54 |
55 | encoder
56 | .encode()
57 | .then(() => {
58 | // Encoding finished
59 | })
60 | .catch((error) => {
61 | // Something went wrong
62 | });
63 | ```
64 |
65 | ### Encode from file to buffer
66 |
67 | ```node
68 | const Lame = require("node-lame").Lame;
69 |
70 | const encoder = new Lame({
71 | output: "buffer",
72 | bitrate: 192,
73 | }).setFile("./audio-files/demo.wav");
74 |
75 | encoder
76 | .encode()
77 | .then(() => {
78 | // Encoding finished
79 | const buffer = encoder.getBuffer();
80 | })
81 | .catch((error) => {
82 | // Something went wrong
83 | });
84 | ```
85 |
86 | ### Encode from buffer to file
87 |
88 | ```node
89 | [...]
90 |
91 | const Lame = require("node-lame").Lame;
92 |
93 | const encoder = new Lame({
94 | "output": "./audio-files/demo.mp3",
95 | "bitrate": 192
96 | }).setBuffer(audioFileBuffer);
97 |
98 | encoder.encode()
99 | .then(() => {
100 | // Encoding finished
101 | })
102 | .catch((error) => {
103 | // Something went wrong
104 | });
105 | ```
106 |
107 | ### Encode from buffer to buffer
108 |
109 | ```node
110 | [...]
111 |
112 | const Lame = require("node-lame").Lame;
113 |
114 | const encoder = new Lame({
115 | "output": "buffer",
116 | "bitrate": 192
117 | }).setBuffer(audioFileBuffer);
118 |
119 | encoder.encode()
120 | .then(() => {
121 | // Encoding finished
122 | const buffer = encoder.getBuffer();
123 | })
124 | .catch((error) => {
125 | // Something went wrong
126 | });
127 | ```
128 |
129 | ### Get status of encoder as object
130 |
131 | ```node
132 | const Lame = require("node-lame").Lame;
133 |
134 | const encoder = new Lame({
135 | output: "buffer",
136 | bitrate: 192,
137 | }).setFile("./audio-files/demo.wav");
138 |
139 | encoder
140 | .encode()
141 | .then(() => {
142 | // Encoding finished
143 | })
144 | .catch((error) => {
145 | // Something went wrong
146 | });
147 |
148 | const status = encoder.getStatus();
149 | ```
150 |
151 | ### Get status of encoder as EventEmitter
152 |
153 | ```node
154 | const Lame = require("node-lame").Lame;
155 |
156 | const encoder = new Lame({
157 | output: "buffer",
158 | bitrate: 192,
159 | }).setFile("./audio-files/demo.wav");
160 |
161 | const emitter = encoder.getEmitter();
162 |
163 | emitter.on("progress", ([progress, eta]) => {
164 | // On progress of encoding. Progress in percent and estimated time of arrival as mm:ss
165 | });
166 |
167 | emitter.on("finish", () => {
168 | // On finish
169 | });
170 |
171 | emitter.on("error", (error) => {
172 | // On error
173 | });
174 |
175 | encoder
176 | .encode()
177 | .then(() => {
178 | // Encoding finished
179 | })
180 | .catch((error) => {
181 | // Something went wrong
182 | });
183 | ```
184 |
185 | ### Decode from file to file
186 |
187 | ```node
188 | const Lame = require("node-lame").Lame;
189 |
190 | const decoder = new Lame({
191 | output: "./audio-files/demo.wav",
192 | }).setFile("./audio-files/demo.mp3");
193 |
194 | decoder
195 | .decode()
196 | .then(() => {
197 | // Decoding finished
198 | })
199 | .catch((error) => {
200 | // Something went wrong
201 | });
202 | ```
203 |
204 | ### Decode from file to buffer
205 |
206 | ```node
207 | const Lame = require("node-lame").Lame;
208 |
209 | const decoder = new Lame({
210 | output: "buffer",
211 | }).setFile("./audio-files/demo.mp3");
212 |
213 | decoder
214 | .decode()
215 | .then(() => {
216 | // Decoding finished
217 | const buffer = decoder.getBuffer();
218 | })
219 | .catch((error) => {
220 | // Something went wrong
221 | });
222 | ```
223 |
224 | ### Decode from buffer to file
225 |
226 | ```node
227 | [...]
228 |
229 | const Lame = require("node-lame").Lame;
230 |
231 | const decoder = new Lame({
232 | "output": "./audio-files/demo.wav"
233 | }).setBuffer(mp3InputBuffer);
234 |
235 | decoder.decode()
236 | .then(() => {
237 | // Decoding finished
238 | })
239 | .catch((error) => {
240 | // Something went wrong
241 | });
242 | ```
243 |
244 | ### Decode from buffer to buffer
245 |
246 | ```node
247 | [...]
248 |
249 | const Lame = require("node-lame").Lame;
250 |
251 | const decoder = new Lame({
252 | "output": "buffer"
253 | }).setBuffer(mp3InputBuffer);
254 |
255 | decoder.decode()
256 | .then(() => {
257 | // Decoding finished
258 | const buffer = decoder.getBuffer();
259 | })
260 | .catch((error) => {
261 | // Something went wrong
262 | });
263 | ```
264 |
265 | ### Get status of decoder as object
266 |
267 | ```node
268 | const Lame = require("node-lame").Lame;
269 |
270 | const decoder = new Lame({
271 | output: "buffer",
272 | }).setFile("./audio-files/demo.mp3");
273 |
274 | decoder
275 | .encode()
276 | .then(() => {
277 | // Decoding finished
278 | })
279 | .catch((error) => {
280 | // Something went wrong
281 | });
282 |
283 | const status = decoder.getStatus();
284 | ```
285 |
286 | ### Get status of decoder as EventEmitter
287 |
288 | ```node
289 | const Lame = require("node-lame").Lame;
290 |
291 | const decoder = new Lame({
292 | output: "buffer",
293 | }).setFile("./audio-files/demo.mp3");
294 |
295 | const emitter = decoder.getEmitter();
296 |
297 | emitter.on("progress", ([progress]) => {
298 | // On progress of decoder; in percent
299 | });
300 |
301 | emitter.on("finish", () => {
302 | // On finish
303 | });
304 |
305 | emitter.on("error", (error) => {
306 | // On error
307 | });
308 |
309 | decoder
310 | .decode()
311 | .then(() => {
312 | // Decoding finished
313 | })
314 | .catch((error) => {
315 | // Something went wrong
316 | });
317 | ```
318 |
319 | ## All options
320 |
321 | | Option | Description | Values | Default |
322 | | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
323 | | output | Output filename | Path |
324 | | raw | Assume the input file is raw pcm. Sampling rate and mono/stereo/jstereo must be specified. For each stereo sample, LAME expects the input data to be ordered left channel first, then right channel. By default, LAME expects them to be signed integers with a bitwidth of 16. | boolean | `false` |
325 | | swap-bytes | Swap bytes in the input file or output file when using decoding. For sorting out little endian/big endian type problems. | boolean | `false` |
326 | | sfreq | Required only for raw PCM input files. Otherwise it will be determined from the header of the input file. LAME will automatically resample the input file to one of the supported MP3 samplerates if necessary. | `8`, `11.025`, `12`, `16`, `22.05`, `24`, `32`, `44.1`, `48` | `undefined` |
327 | | bitwidth | Required only for raw PCM input files. Otherwise it will be determined from the header of the input file. | `8`, `16`, `24`, `32` | `16` |
328 | | signed | Required only for raw PCM input files. Instructs LAME that the samples from the input are signed. | boolean | `false`; `true` for 16, 24 and 32 bits raw pcm data |
329 | | unsigned | Required only for raw PCM input files and only available at bitwidth 8. Instructs LAME that the samples from the input are unsigned (the default for 8 bits raw pcm data, where 0x80 is zero). | boolean | `undefined` |
330 | | little-endian | Required only for raw PCM input files. Instructs LAME that the samples from the input are in little-endian form. | boolean | `undefined` |
331 | | big-endian | Required only for raw PCM input files. Instructs LAME that the samples from the input are in big-endian form. | boolean | `undefined` |
332 | | mp2Input | Assume the input file is a MPEG Layer II (ie MP2) file. If the filename ends in ".mp2" LAME will assume it is a MPEG Layer II file. | boolean | `undefined` |
333 | | mp3Input | Assume the input file is a MP3 file. Useful for downsampling from one mp3 to another. | boolean | `undefined` |
334 | | mode | Details see [LAME man page](https://linux.die.net/man/1/lame). | `s` simple stereo, `j` joint stereo, `f` forced MS stereo, `d` dual mono, `m` mono, `l` left channel only, `r` right channel only | `j` or `s` (see details) |
335 | | to-mono | Mix the stereo input file to mono and encode as mono. The downmix is calculated as the sum of the left and right channel, attenuated by 6 dB. | boolean | `false` |
336 | | channel-different-block-sizes | Allows the left and right channels to use different block size types. | boolean | `false` |
337 | | freeformat | Produces a free format bitstream. With this option, you can use `bitrate` with any bitrate higher than 8 kbps. | `FreeAmp` up to 440 kbps, `in_mpg123` up to 560 kbps, `l3dec` up to 310 kbps, `LAME` up to 560 kbps, `MAD` up to 640 kbps | `undefined` |
338 | | disable-info-tag | Disable writing of the INFO Tag on encoding. | boolean | `false` |
339 | | comp | Instead of choosing bitrate, using this option, user can choose compression ratio to achieve. | number | `undefined` |
340 | | scale | Scales input volume by n. This just multiplies the PCM data (after it has been converted to floating point) by n. | number | `1` |
341 | | scale-l | Same as `scale`, but for left channel only. | number | `undefined` |
342 | | scale-r | Same as `scale`, but for right channel only. | number | `undefined` |
343 | | replaygain-fast | Compute ReplayGain fast but slightly inaccurately. Details see [LAME man page](https://linux.die.net/man/1/lame). | boolean | `false` |
344 | | replaygain-accurate | Compute ReplayGain more accurately and find the peak sample. Details see [LAME man page](https://linux.die.net/man/1/lame). | boolean | `false` |
345 | | no-replaygain | Disable ReplayGain analysis. By default ReplayGain analysis is enabled. Details see [LAME man page](https://linux.die.net/man/1/lame). | boolean | `false` |
346 | | clip-detect | Clipping detection. | boolean | `false` |
347 | | preset | Use one of the built-in presets. Details see [LAME man page](https://linux.die.net/man/1/lame). | `medium`, `standard`, `extreme` or `insane` | `undefined` |
348 | | noasm | Disable specific assembly optimizations. Quality will not increase, only speed will be reduced. | `mmx`, `3dnow` or `sse` | `undefined` (probably depending on OS) |
349 | | quality | Bitrate is of course the main influence on quality. The higher the bitrate, the higher the quality. But for a given bitrate, we have a choice of algorithms to determine the best scalefactors and Huffman encoding (noise shaping). | `0` (best) to `9` (worst) | `5` |
350 | | bitrate | For MPEG-1 (sampling frequencies of 32, 44.1 and 48 kHz): n = `32`, `40`, `48`, `56`, `64`, `80`, `96`, `112`, `128`, `160`, `192`, `224`, `256`, `320`; For MPEG-2 (sampling frequencies of 16, 22.05 and 24 kHz): n = `8`, `16`, `24`, `32`, `40`, `48`, `56`, `64`, `80`, `96`, `112`, `128`, `144`, `160`; For MPEG-2.5 (sampling frequencies of 8, 11.025 and 12 kHz): n = `8`, `16`, `24`, `32`, `40`, `48`, `56`, `64` | See description | `128` for MPEG1 and `64` for MPEG2 |
351 | | force-bitrate | Strictly enforce the `bitrate` option. This is mainly for use with hardware players that do not support low bitrate mp3. | boolean | `false` |
352 | | cbr | Enforce use of constant bitrate. | boolean | `false` |
353 | | abr | ABR (average bitrate) options. Turns on encoding with a targeted average bitrate of n kbits, allowing to use frames of different sizes. | `8` to `310` | `undefined` |
354 | | vbr | Use variable bitrate. | boolean | `false` |
355 | | vbr-quality | Enable `vbr` and specifies the value of VBR quality. | `0` (best) to `9` (worst) | `4` |
356 | | ignore-noise-in-sfb21 | LAME ignore noise in sfb21, like in CBR. | boolean | `false` |
357 | | emp | All this does is set a flag in the MP3 header bitstream. If you have a PCM input file where one of the above types of (obsolete) emphasis has been applied, you can set this flag in LAME. Then the mp3 decoder should de-emphasize the output during playback, although most decoders ignore this flag. | `n` none, `5` 0/15 microseconds, `c` citt j.17 | `n` |
358 | | mark-as-copyrighted | Mark the encoded file as being copyrighted. | boolean | `false` |
359 | | mark-as-copy | Mark the encoded file as being a copy. | boolean | `false` |
360 | | crc-error-protection | Turn on CRC error protection.It will add a cyclic redundancy check (CRC) code in each frame, allowing to detect transmission errors that could occur on the MP3 stream. | boolean | `false` |
361 | | nores | Disable the bit reservoir. Each frame will then become independent from previous ones, but the quality will be lower. | boolean | `false` |
362 | | strictly-enforce-ISO | With this option, LAME will enforce the 7680 bit limitation on total frame size. | boolean | `false` |
363 | | lowpass | Set a lowpass filtering frequency in kHz. Frequencies specified one will be cutoff. | number | `undefined` |
364 | | lowpass-width | Set the width of the lowpass filter in percent. | number | `15` |
365 | | highpass | Set an highpass filtering frequency in kHz. | number | `undefined` |
366 | | highpass-width | Set the width of the highpass filter in percent. | number | `15` |
367 | | resample | Output sampling frequency (for encoding). If not specified, LAME will automatically resample the input when using high compression ratios. | `8`, `11.025`, `12`, `16`, `22.05`, `24`, `32`, `44.1`, `48` | `undefined` |
368 | | meta | Meta data for MP3. | Object | `undefined` |
369 |
370 | _Meta options_
371 |
372 | | Option | Description | Values | Default |
373 | | ----------------- | ----------------------------------------------------------------------------- | ------- | ----------- |
374 | | title | Set title tag (max 30 chars for version 1 tag). | String | `undefined` |
375 | | artist | Set artist tag (max 30 chars for version 1 tag). | String | `undefined` |
376 | | album | Set album tag (max 30 chars for version 1 tag). | String | `undefined` |
377 | | year | Set year tag. | String | `undefined` |
378 | | comment | Set user-defined text (max 30 chars for v1 tag, 28 for v1.1). | String | `undefined` |
379 | | track | Set track tag, with or without number of total tracks. | String | `undefined` |
380 | | genre | Set genre tag (max 30 chars for version 1 tag). | String | `undefined` |
381 | | artwork | Set album artwork image (path to jpeg/png/gif file, v2.3 tag). | String | `undefined` |
382 | | add-id3v2 | Force addition of version 2 tag. | boolean | `false` |
383 | | id3v1-only | Add only a version 1 tag. | boolean | `false` |
384 | | id3v2-only | Add only a version 2 tag. | boolean | `false` |
385 | | id3v2-latin1 | Add meta options in ISO-8859-1 text encoding. | boolean | `false` |
386 | | id3v2-utf16 | Add meta options in unicode text encoding. | boolean | `false` |
387 | | space-id3v1 | Pad version 1 tag with spaces instead of nulls. | boolean | `false` |
388 | | pad-id3v2 | Same as `pad-id3v2-size` value `128` | boolean | `false` |
389 | | pad-id3v2-size | Adds version 2 tag, pad with extra "num" bytes. | number | `undefined` |
390 | | ignore-tag-errors | Ignore errors in values passed for tags, use defaults in case an error occurs | boolean | `false` |
391 | | genre-list | Print alphabetically sorted ID3 genre list and exit | string | `undefined` |
392 |
393 | Option description text from [LAME man page](https://linux.die.net/man/1/lame). Based on LAME version [3.99.5](https://sourceforge.net/projects/lame/files/lame/3.99/) from Feb 28, 2012.
394 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | import { EventEmitter } from "events";
2 |
3 | declare namespace Options {
4 | type sfreq = 8 | 11.025 | 12 | 16 | 22.05 | 24 | 32 | 44.1 | 48;
5 | type bitwidth = 8 | 16 | 24 | 32;
6 | type mode = "s" | "j" | "f" | "d" | "m" | "l" | "r";
7 | type freeformat = "FreeAmp" | "in_mpg123" | "l3dec" | "LAME" | "MAD";
8 | type preset = "medium" | "standard" | "extreme" | "insane";
9 | type noasm = "mmx" | "3dnow" | "sse";
10 | type quality = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
11 | type bitrate =
12 | | 8
13 | | 16
14 | | 24
15 | | 32
16 | | 40
17 | | 48
18 | | 56
19 | | 64
20 | | 80
21 | | 96
22 | | 112
23 | | 128
24 | | 144
25 | | 160
26 | | 192
27 | | 224
28 | | 256
29 | | 320;
30 | type emp = "n" | 5 | "c";
31 | type resample = 8 | 11.025 | 12 | 16 | 22.05 | 24 | 32 | 44.1 | 48;
32 |
33 | interface meta {
34 | title?: string;
35 | artist?: string;
36 | album?: string;
37 | year?: string;
38 | comment?: string;
39 | track?: string;
40 | genre?: string;
41 | artwork?: string;
42 |
43 | "add-id3v2"?: boolean;
44 | "id3v1-only"?: boolean;
45 | "id3v2-only"?: boolean;
46 | "id3v2-latin1"?: boolean;
47 | "id3v2-utf16"?: boolean;
48 | "space-id3v1"?: boolean;
49 | "pad-id3v2-size"?: number;
50 | "genre-list"?: string;
51 | "ignore-tag-errors"?: boolean;
52 | }
53 | }
54 |
55 | declare interface Options {
56 | output: string | "buffer";
57 | raw?: boolean;
58 | "swap-bytes"?: boolean;
59 | sfreq?: Options.sfreq;
60 | bitwidth?: Options.bitwidth;
61 | signed?: boolean;
62 | unsigned?: boolean;
63 | "little-endian"?: boolean;
64 | "big-endian"?: boolean;
65 | mp2Input?: boolean;
66 | mp3Input?: boolean;
67 | mode?: Options.mode;
68 | "to-mono"?: boolean;
69 | "channel-different-block-sizes"?: boolean;
70 | freeformat?: Options.freeformat;
71 | "disable-info-tag"?: boolean;
72 | comp?: number;
73 | scale?: number;
74 | "scale-l"?: number;
75 | "scale-r"?: number;
76 | "replaygain-fast"?: boolean;
77 | "replaygain-accurate"?: boolean;
78 | "no-replaygain"?: boolean;
79 | "clip-detect"?: boolean;
80 | preset?: Options.preset;
81 | noasm?: Options.noasm;
82 | quality?: Options.quality;
83 | bitrate?: Options.bitrate;
84 | "force-bitrate"?: boolean;
85 | cbr?: boolean;
86 | abr?: number;
87 | vbr?: boolean;
88 | "vbr-quality"?: number;
89 | "ignore-noise-in-sfb21"?: boolean;
90 | emp?: Options.emp;
91 | "mark-as-copyrighted"?: boolean;
92 | "mark-as-copy"?: boolean;
93 | "crc-error-protection"?: boolean;
94 | nores?: boolean;
95 | "strictly-enforce-ISO"?: boolean;
96 | lowpass?: number;
97 | "lowpass-width"?: number;
98 | highpass?: number;
99 | "highpass-width"?: number;
100 | resample?: Options.resample;
101 | meta?: Options.meta;
102 | }
103 |
104 | declare interface LameStatus {
105 | started: boolean;
106 | finished: boolean;
107 | progress: number;
108 | eta: string;
109 | }
110 |
111 | declare class Lame {
112 | constructor(options: Options);
113 |
114 | public setFile(path: string): Lame;
115 | public setBuffer(file: Buffer): Lame;
116 | public getFile(): string;
117 | public getBuffer(): Buffer;
118 | public getEmitter(): EventEmitter;
119 | public getStatus(): LameStatus;
120 |
121 | public encode(): Promise;
122 | public decode(): Promise;
123 | private progress(type: "encode" | "decode"): Promise;
124 | private execProgress(
125 | inputFilePath: string,
126 | args: string[],
127 | type: "encode" | "decode"
128 | );
129 | private tempFilePathGenerator(type: "raw" | "encoded"): string;
130 | private removeTempFilesOnError();
131 | }
132 |
133 | export { Lame };
134 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @author Jan Karres (https://jankarres.com/)
3 | */
4 |
5 | "use strict";
6 |
7 | module.exports = require('./lib/build/Lame');
8 |
--------------------------------------------------------------------------------
/lib/build/Lame.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.Lame = void 0;
4 | const LameOptions_1 = require("./LameOptions");
5 | const fs_1 = require("fs");
6 | const util_1 = require("util");
7 | const child_process_1 = require("child_process");
8 | const events_1 = require("events");
9 | /**
10 | * Wrapper for Lame for Node
11 | *
12 | * @class Lame
13 | */
14 | class Lame {
15 | /**
16 | * Creates an instance of Lame and set all options
17 | * @param {Options} options
18 | */
19 | constructor(options) {
20 | this.status = {
21 | started: false,
22 | finished: false,
23 | progress: undefined,
24 | eta: undefined
25 | };
26 | this.emitter = new events_1.EventEmitter();
27 | this.options = options;
28 | this.args = new LameOptions_1.LameOptions(this.options).getArguments();
29 | }
30 | /**
31 | * Set file path of audio to decode/encode
32 | *
33 | * @param {string} filePath
34 | */
35 | setFile(path) {
36 | if (!fs_1.existsSync(path)) {
37 | throw new Error("Audio file (path) does not exist");
38 | }
39 | this.filePath = path;
40 | this.fileBuffer = undefined;
41 | return this;
42 | }
43 | /**
44 | * Set file buffer of audio to decode/encode
45 | *
46 | * @param {Buffer} file
47 | */
48 | setBuffer(file) {
49 | if (!util_1.isBuffer(file)) {
50 | throw new Error("Audio file (buffer) dose not exist");
51 | }
52 | this.fileBuffer = file;
53 | this.filePath = undefined;
54 | return this;
55 | }
56 | /**
57 | * Get decoded/encoded file path
58 | *
59 | * @returns {string} Path of decoded/encoded file
60 | */
61 | getFile() {
62 | if (this.progressedFilePath == undefined) {
63 | throw new Error("Audio is not yet decoded/encoded");
64 | }
65 | return this.progressedFilePath;
66 | }
67 | /**
68 | * Get decoded/encoded file as buffer
69 | *
70 | * @returns {Buffer} decoded/Encoded file
71 | */
72 | getBuffer() {
73 | if (this.progressedBuffer == undefined) {
74 | throw new Error("Audio is not yet decoded/encoded");
75 | }
76 | return this.progressedBuffer;
77 | }
78 | /**
79 | * Get event emitter
80 | *
81 | * @returns {EventEmitter}
82 | */
83 | getEmitter() {
84 | return this.emitter;
85 | }
86 | /**
87 | * Get status of converter
88 | *
89 | * @returns {LameStatus}
90 | */
91 | getStatus() {
92 | return this.status;
93 | }
94 | /**
95 | * Encode audio file by Lame
96 | *
97 | * @return {Promise}
98 | */
99 | encode() {
100 | return this.progress("encode");
101 | }
102 | /**
103 | * Decode audio file by Lame
104 | *
105 | * @return {Promise}
106 | */
107 | decode() {
108 | return this.progress("decode");
109 | }
110 | /**
111 | * Decode/Encode audio file by Lame
112 | *
113 | * @return {Promise}
114 | */
115 | progress(type) {
116 | if (this.filePath == undefined && this.fileBuffer == undefined) {
117 | throw new Error("Audio file to encode is not set");
118 | }
119 | // Set decode flag to progress a MP3 to WAV decode
120 | const args = this.args;
121 | if (type == "decode") {
122 | args.push("--decode");
123 | }
124 | if (this.fileBuffer != undefined) {
125 | // File buffer is set; write it as temp file
126 | this.fileBufferTempFilePath = this.tempFilePathGenerator("raw", type);
127 | return new Promise((resolve, reject) => {
128 | fs_1.writeFile(this.fileBufferTempFilePath, this.fileBuffer, err => {
129 | if (err) {
130 | reject(err);
131 | return;
132 | }
133 | resolve(this.fileBufferTempFilePath);
134 | });
135 | })
136 | .then((file) => {
137 | return this.execProgress(file, args, type);
138 | })
139 | .catch((error) => {
140 | this.removeTempFilesOnError();
141 | throw error;
142 | });
143 | }
144 | else {
145 | // File path is set
146 | return this.execProgress(this.filePath, args, type).catch((error) => {
147 | this.removeTempFilesOnError();
148 | throw error;
149 | });
150 | }
151 | }
152 | /**
153 | * Execute decoding/encoding via spawn Lame
154 | *
155 | * @private
156 | * @param {string} inputFilePath Path of input file
157 | */
158 | execProgress(inputFilePath, args, type) {
159 | // Add output settings args
160 | args.push("--disptime");
161 | args.push("1");
162 | // Add output file to args, if not undefined in options
163 | if (this.options.output == "buffer") {
164 | const tempOutPath = this.tempFilePathGenerator("encoded", type);
165 | args.unshift(`${tempOutPath}`);
166 | // Set decode/encoded file path
167 | this.progressedBufferTempFilePath = tempOutPath;
168 | }
169 | else {
170 | // Set decode/encoded file path
171 | this.progressedFilePath = this.options.output;
172 | args.unshift(this.progressedFilePath);
173 | }
174 | // Add input file to args
175 | args.unshift(inputFilePath);
176 | // Spawn instance of encoder and hook output methods
177 | this.status.started = true;
178 | this.status.finished = false;
179 | this.status.progress = 0;
180 | this.status.eta = undefined;
181 | /**
182 | * Handles output of stdout (and stderr)
183 | * Parses data from output into object
184 | *
185 | * @param {(String | Buffer)} data
186 | */
187 | const progressStdout = (data) => {
188 | data = data.toString().trim();
189 | // Every output of Lame comes as "stderr". Deciding if it is an error or valid data by regex
190 | if (data.length > 6) {
191 | if (type == "encode" &&
192 | data.search("Writing LAME Tag...done") > -1) {
193 | // processing done
194 | this.status.finished = true;
195 | this.status.progress = 100;
196 | this.status.eta = "00:00";
197 | this.emitter.emit("finish");
198 | this.emitter.emit("progress", [
199 | this.status.progress,
200 | this.status.eta
201 | ]);
202 | }
203 | else if (type == "encode" &&
204 | data.search(/\((( [0-9])|([0-9]{2})|(100))%\)\|/) > -1) {
205 | // status of processing
206 | const progressMatch = data.match(/\((( [0-9])|([0-9]{2})|(100))%\)\|/);
207 | const etaMatch = data.match(/[0-9]{1,2}:[0-9][0-9] /);
208 | const progress = String(progressMatch[1]);
209 | let eta = null;
210 | if (etaMatch != null) {
211 | eta = etaMatch[0].trim();
212 | }
213 | if (progress != null &&
214 | Number(progress) > this.status.progress) {
215 | this.status.progress = Number(progress);
216 | }
217 | if (eta != null) {
218 | this.status.eta = eta;
219 | }
220 | this.emitter.emit("progress", [
221 | this.status.progress,
222 | this.status.eta
223 | ]);
224 | }
225 | else if (type == "decode" &&
226 | data.search(/[0-9]{1,10}\/[0-9]{1,10}/) > -1) {
227 | const progressMatch = data.match(/[0-9]{1,10}\/[0-9]{1,10}/);
228 | const progressAbsolute = progressMatch[0].split("/");
229 | const progress = Math.floor((Number(progressAbsolute[0]) /
230 | Number(progressAbsolute[1])) *
231 | 100);
232 | if (!isNaN(progress) &&
233 | Number(progress) > this.status.progress) {
234 | this.status.progress = Number(progress);
235 | }
236 | this.emitter.emit("progress", [
237 | this.status.progress,
238 | this.status.eta
239 | ]);
240 | }
241 | else if (data.search(/^lame: /) > -1 ||
242 | data.search(/^Warning: /) > -1 ||
243 | data.search(/Error /) > -1) {
244 | // Unexpected output => error
245 | if (data.search(/^lame: /) == -1) {
246 | this.emitter.emit("error", new Error("lame: " + data));
247 | }
248 | else {
249 | this.emitter.emit("error", new Error(String(data)));
250 | }
251 | }
252 | }
253 | };
254 | const progressOnClose = code => {
255 | if (code == 0) {
256 | if (!this.status.finished) {
257 | this.emitter.emit("finish");
258 | }
259 | this.status.finished = true;
260 | this.status.progress = 100;
261 | this.status.eta = "00:00";
262 | }
263 | if (code === 255) {
264 | this.emitter.emit("error", new Error("Unexpected termination of the process, possibly directly after the start. Please check if the input and/or output does not exist."));
265 | }
266 | };
267 | /**
268 | * Handles error throw of Lame instance
269 | *
270 | * @param {Error} error
271 | */
272 | const progressError = (error) => {
273 | this.emitter.emit("error", error);
274 | };
275 | const instance = child_process_1.spawn("lame", args);
276 | instance.stdout.on("data", progressStdout);
277 | instance.stderr.on("data", progressStdout); // Most output, even non-errors, are on stderr
278 | instance.on("close", progressOnClose);
279 | instance.on("error", progressError);
280 | // Return promise of finish encoding progress
281 | return new Promise((resolve, reject) => {
282 | this.emitter.on("finish", () => {
283 | // If input was buffer, remove temp file
284 | if (this.fileBufferTempFilePath != undefined) {
285 | fs_1.unlinkSync(this.fileBufferTempFilePath);
286 | }
287 | // If output should be a buffer, load decoded/encoded audio file in object and remove temp file
288 | if (this.options.output == "buffer") {
289 | fs_1.readFile(this.progressedBufferTempFilePath, null, (error, data) => {
290 | // Remove temp decoded/encoded file
291 | fs_1.unlinkSync(this.progressedBufferTempFilePath);
292 | if (error) {
293 | reject(error);
294 | return;
295 | }
296 | this.progressedBuffer = Buffer.from(data);
297 | this.progressedBufferTempFilePath = undefined;
298 | resolve(this);
299 | });
300 | }
301 | else {
302 | resolve(this);
303 | }
304 | });
305 | this.emitter.on("error", error => {
306 | reject(error);
307 | });
308 | });
309 | }
310 | /**
311 | * Generate temp file path
312 | *
313 | * @param {("raw" | "encoded")} type
314 | * @returns {string} Path
315 | */
316 | tempFilePathGenerator(type, progressType) {
317 | const prefix = `${__dirname}/../.`;
318 | let path = `${prefix}./temp/${type}/`;
319 | let possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
320 | for (let i = 0; i < 32; i++) {
321 | path += possible.charAt(Math.floor(Math.random() * possible.length));
322 | }
323 | if (type == "raw" && progressType == "decode") {
324 | path += `.mp3`;
325 | }
326 | if (!fs_1.existsSync(`${prefix}./temp/${path}`)) {
327 | return path;
328 | }
329 | else {
330 | return this.tempFilePathGenerator(type, progressType);
331 | }
332 | }
333 | /**
334 | * Remove temp files, if error occurred
335 | */
336 | removeTempFilesOnError() {
337 | if (this.fileBufferTempFilePath != undefined && fs_1.existsSync(this.fileBufferTempFilePath)) {
338 | fs_1.unlinkSync(this.fileBufferTempFilePath);
339 | }
340 | if (this.progressedBufferTempFilePath != undefined && fs_1.existsSync(this.progressedBufferTempFilePath)) {
341 | fs_1.unlinkSync(this.progressedBufferTempFilePath);
342 | }
343 | }
344 | }
345 | exports.Lame = Lame;
346 | //# sourceMappingURL=Lame.js.map
--------------------------------------------------------------------------------
/lib/build/Lame.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"Lame.js","sourceRoot":"","sources":["../src/Lame.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,2BAKY;AACZ,+BAAgD;AAChD,iDAAsC;AACtC,mCAAsC;AAEtC;;;;GAIG;AACH,MAAM,IAAI;IAoBN;;;OAGG;IACH,YAAY,OAAgB;QAvBpB,WAAM,GAAe;YACzB,OAAO,EAAE,KAAK;YACd,QAAQ,EAAE,KAAK;YACf,QAAQ,EAAE,SAAS;YACnB,GAAG,EAAE,SAAS;SACjB,CAAC;QACM,YAAO,GAAiB,IAAI,qBAAY,EAAE,CAAC;QAkB/C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,yBAAW,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,CAAC;IAC7D,CAAC;IAED;;;;OAIG;IACI,OAAO,CAAC,IAAY;QACvB,IAAI,CAAC,eAAY,CAAC,IAAI,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;SACvD;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAE5B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACI,SAAS,CAAC,IAAY;QACzB,IAAI,CAAC,eAAY,CAAC,IAAI,CAAC,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;SACzD;QAED,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;QAE1B,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACI,OAAO;QACV,IAAI,IAAI,CAAC,kBAAkB,IAAI,SAAS,EAAE;YACtC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;SACvD;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACI,SAAS;QACZ,IAAI,IAAI,CAAC,gBAAgB,IAAI,SAAS,EAAE;YACpC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;SACvD;QAED,OAAO,IAAI,CAAC,gBAAgB,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,UAAU;QACb,OAAO,IAAI,CAAC,OAAO,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACI,SAAS;QACZ,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACI,MAAM;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACI,MAAM;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACK,QAAQ,CAAC,IAAyB;QACtC,IAAI,IAAI,CAAC,QAAQ,IAAI,SAAS,IAAI,IAAI,CAAC,UAAU,IAAI,SAAS,EAAE;YAC5D,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;SACtD;QAED,kDAAkD;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,IAAI,IAAI,IAAI,QAAQ,EAAE;YAClB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;SACzB;QAED,IAAI,IAAI,CAAC,UAAU,IAAI,SAAS,EAAE;YAC9B,4CAA4C;YAC5C,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,qBAAqB,CACpD,KAAK,EACL,IAAI,CACP,CAAC;YAEF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnC,cAAW,CACP,IAAI,CAAC,sBAAsB,EAC3B,IAAI,CAAC,UAAU,EACf,GAAG,CAAC,EAAE;oBACF,IAAI,GAAG,EAAE;wBACL,MAAM,CAAC,GAAG,CAAC,CAAC;wBACZ,OAAO;qBACV;oBAED,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;gBACzC,CAAC,CACJ,CAAC;YACN,CAAC,CAAC;iBACG,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE;gBACnB,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAC/C,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAY,EAAE,EAAE;gBACpB,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,CAAC;SACV;aAAM;YACH,mBAAmB;YACnB,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CACrD,CAAC,KAAY,EAAE,EAAE;gBACb,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC9B,MAAM,KAAK,CAAC;YAChB,CAAC,CACJ,CAAC;SACL;IACL,CAAC;IAED;;;;;OAKG;IACK,YAAY,CAChB,aAAqB,EACrB,IAAc,EACd,IAAyB;QAEzB,2BAA2B;QAC3B,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QACxB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEf,uDAAuD;QACvD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,QAAQ,EAAE;YACjC,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAChE,IAAI,CAAC,OAAO,CAAC,GAAG,WAAW,EAAE,CAAC,CAAC;YAE/B,+BAA+B;YAC/B,IAAI,CAAC,4BAA4B,GAAG,WAAW,CAAC;SACnD;aAAM;YACH,+BAA+B;YAC/B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAC9C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;SACzC;QAED,yBAAyB;QACzB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAE5B,oDAAoD;QACpD,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,SAAS,CAAC;QAE5B;;;;;WAKG;QACH,MAAM,cAAc,GAAG,CAAC,IAAqB,EAAE,EAAE;YAC7C,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;YAE9B,4FAA4F;YAC5F,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;gBACjB,IACI,IAAI,IAAI,QAAQ;oBAChB,IAAI,CAAC,MAAM,CAAC,yBAAyB,CAAC,GAAG,CAAC,CAAC,EAC7C;oBACE,kBAAkB;oBAClB,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;oBAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,GAAG,CAAC;oBAC3B,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC;oBAE1B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC5B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE;wBAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ;wBACpB,IAAI,CAAC,MAAM,CAAC,GAAG;qBAClB,CAAC,CAAC;iBACN;qBAAM,IACH,IAAI,IAAI,QAAQ;oBAChB,IAAI,CAAC,MAAM,CAAC,oCAAoC,CAAC,GAAG,CAAC,CAAC,EACxD;oBACE,uBAAuB;oBACvB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAC5B,oCAAoC,CACvC,CAAC;oBACF,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;oBAEtD,MAAM,QAAQ,GAAW,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;oBAClD,IAAI,GAAG,GAAW,IAAI,CAAC;oBACvB,IAAI,QAAQ,IAAI,IAAI,EAAE;wBAClB,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;qBAC5B;oBAED,IACI,QAAQ,IAAI,IAAI;wBAChB,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EACzC;wBACE,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;qBAC3C;oBAED,IAAI,GAAG,IAAI,IAAI,EAAE;wBACb,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;qBACzB;oBAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE;wBAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ;wBACpB,IAAI,CAAC,MAAM,CAAC,GAAG;qBAClB,CAAC,CAAC;iBACN;qBAAM,IACH,IAAI,IAAI,QAAQ;oBAChB,IAAI,CAAC,MAAM,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,EAC9C;oBACE,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAC5B,0BAA0B,CAC7B,CAAC;oBACF,MAAM,gBAAgB,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CACvB,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;wBACxB,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC5B,GAAG,CACV,CAAC;oBAEF,IACI,CAAC,KAAK,CAAC,QAAQ,CAAC;wBAChB,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EACzC;wBACE,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;qBAC3C;oBAED,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE;wBAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ;wBACpB,IAAI,CAAC,MAAM,CAAC,GAAG;qBAClB,CAAC,CAAC;iBACN;qBAAM,IACH,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;oBAC3B,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;oBAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAC5B;oBACE,6BAA6B;oBAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,EAAE;wBAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC;qBAC1D;yBAAM;wBACH,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;qBACvD;iBACJ;aACJ;QACL,CAAC,CAAC;QAEF,MAAM,eAAe,GAAG,IAAI,CAAC,EAAE;YAC3B,IAAI,IAAI,IAAI,CAAC,EAAE;gBACX,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE;oBACvB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;iBAC/B;gBAED,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,GAAG,CAAC;gBAC3B,IAAI,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,CAAC;aAC7B;YAED,IAAI,IAAI,KAAK,GAAG,EAAE;gBACd,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,mIAAmI,CAAC,CAAC,CAAC;aAC9K;QACL,CAAC,CAAC;QAEF;;;;WAIG;QACH,MAAM,aAAa,GAAG,CAAC,KAAY,EAAE,EAAE;YACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,MAAM,QAAQ,GAAG,qBAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,8CAA8C;QAC1F,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QACtC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAEpC,6CAA6C;QAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;gBAC3B,wCAAwC;gBACxC,IAAI,IAAI,CAAC,sBAAsB,IAAI,SAAS,EAAE;oBAC1C,eAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;iBAC7C;gBAED,+FAA+F;gBAC/F,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,QAAQ,EAAE;oBACjC,aAAU,CACN,IAAI,CAAC,4BAA4B,EACjC,IAAI,EACJ,CAAC,KAAK,EAAE,IAAY,EAAE,EAAE;wBACpB,mCAAmC;wBACnC,eAAY,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;wBAEhD,IAAI,KAAK,EAAE;4BACP,MAAM,CAAC,KAAK,CAAC,CAAC;4BACd,OAAO;yBACV;wBAED,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBAC1C,IAAI,CAAC,4BAA4B,GAAG,SAAS,CAAC;wBAE9C,OAAO,CAAC,IAAI,CAAC,CAAC;oBAClB,CAAC,CACJ,CAAC;iBACL;qBAAM;oBACH,OAAO,CAAC,IAAI,CAAC,CAAC;iBACjB;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;gBAC7B,MAAM,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED;;;;;OAKG;IACK,qBAAqB,CACzB,IAAuB,EACvB,YAAiC;QAEjC,MAAM,MAAM,GAAG,GAAG,SAAS,OAAO,CAAC;QACnC,IAAI,IAAI,GAAG,GAAG,MAAM,UAAU,IAAI,GAAG,CAAC;QACtC,IAAI,QAAQ,GACR,gEAAgE,CAAC;QAErE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;YACzB,IAAI,IAAI,QAAQ,CAAC,MAAM,CACnB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAC9C,CAAC;SACL;QAED,IAAI,IAAI,IAAI,KAAK,IAAI,YAAY,IAAI,QAAQ,EAAE;YAC3C,IAAI,IAAI,MAAM,CAAC;SAClB;QAED,IAAI,CAAC,eAAY,CAAC,GAAG,MAAM,UAAU,IAAI,EAAE,CAAC,EAAE;YAC1C,OAAO,IAAI,CAAC;SACf;aAAM;YACH,OAAO,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;SACzD;IACL,CAAC;IAED;;OAEG;IACK,sBAAsB;QAC1B,IAAI,IAAI,CAAC,sBAAsB,IAAI,SAAS,IAAI,eAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,EAAE;YACvF,eAAY,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;SAC7C;QAED,IAAI,IAAI,CAAC,4BAA4B,IAAI,SAAS,IAAI,eAAY,CAAC,IAAI,CAAC,4BAA4B,CAAC,EAAE;YACnG,eAAY,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;SACnD;IACL,CAAC;CACJ;AAEQ,oBAAI"}
--------------------------------------------------------------------------------
/lib/build/LameOptions.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | exports.LameOptions = void 0;
4 | /**
5 | * All options of node-lame; build argument array for binary
6 | *
7 | * @class LameOptions
8 | */
9 | class LameOptions {
10 | /**
11 | * Validate all options and build argument array for binary
12 | * @param {Object} options
13 | */
14 | constructor(options) {
15 | this.args = [];
16 | // Output is required
17 | if (options["output"] == undefined) {
18 | throw new Error("lame: Invalid option: 'output' is required");
19 | }
20 | // Save options as arguments
21 | for (const key in options) {
22 | const value = options[key];
23 | let arg;
24 | switch (key) {
25 | case "output":
26 | arg = this.output(value);
27 | break;
28 | case "raw":
29 | arg = this.raw(value);
30 | break;
31 | case "swap-bytes":
32 | arg = this.swapBytes(value);
33 | break;
34 | case "sfreq":
35 | arg = this.sfreq(value);
36 | break;
37 | case "bitwidth":
38 | arg = this.bitwidth(value);
39 | break;
40 | case "signed":
41 | arg = this.signed(value);
42 | break;
43 | case "unsigned":
44 | arg = this.unsigned(value);
45 | break;
46 | case "little-endian":
47 | arg = this.littleEndian(value);
48 | break;
49 | case "big-endian":
50 | arg = this.bigEndian(value);
51 | break;
52 | case "mp2Input":
53 | arg = this.mp2Input(value);
54 | break;
55 | case "mp3Input":
56 | arg = this.mp3Input(value);
57 | break;
58 | case "mode":
59 | arg = this.mode(value);
60 | break;
61 | case "to-mono":
62 | arg = this.toMono(value);
63 | break;
64 | case "channel-different-block-sizes":
65 | arg = this.channelDifferentBlockSize(value);
66 | break;
67 | case "freeformat":
68 | arg = this.freeformat(value);
69 | break;
70 | case "disable-info-tag":
71 | arg = this.disableInfoTag(value);
72 | break;
73 | case "comp":
74 | arg = this.comp(value);
75 | break;
76 | case "scale":
77 | arg = this.scale(value);
78 | break;
79 | case "scale-l":
80 | arg = this.scaleL(value);
81 | break;
82 | case "scale-r":
83 | arg = this.scaleR(value);
84 | break;
85 | case "replaygain-fast":
86 | arg = this.replaygainFast(value);
87 | break;
88 | case "replaygain-accurate":
89 | arg = this.replaygainAccurate(value);
90 | break;
91 | case "no-replaygain":
92 | arg = this.noreplaygain(value);
93 | break;
94 | case "clip-detect":
95 | arg = this.clipDetect(value);
96 | break;
97 | case "preset":
98 | arg = this.preset(value);
99 | break;
100 | case "noasm":
101 | arg = this.noasm(value);
102 | break;
103 | case "quality":
104 | arg = this.quality(value);
105 | break;
106 | case "bitrate":
107 | arg = this.bitrate(value);
108 | break;
109 | case "force-bitrate":
110 | arg = this.forceBitrate(value);
111 | break;
112 | case "cbr":
113 | arg = this.cbr(value);
114 | break;
115 | case "abr":
116 | arg = this.abr(value);
117 | break;
118 | case "vbr":
119 | arg = this.vbr(value);
120 | break;
121 | case "vbr-quality":
122 | arg = this.vbrQuality(value);
123 | break;
124 | case "ignore-noise-in-sfb21":
125 | arg = this.ignoreNoiseInSfb21(value);
126 | break;
127 | case "emp":
128 | arg = this.emp(value);
129 | break;
130 | case "mark-as-copyrighted":
131 | arg = this.markAsCopyrighted(value);
132 | break;
133 | case "mark-as-copy":
134 | arg = this.markAsCopy(value);
135 | break;
136 | case "crc-error-protection":
137 | arg = this.crcErrorProtection(value);
138 | break;
139 | case "nores":
140 | arg = this.nores(value);
141 | break;
142 | case "strictly-enforce-ISO":
143 | arg = this.strictlyEnforceIso(value);
144 | break;
145 | case "lowpass":
146 | arg = this.lowpass(value);
147 | break;
148 | case "lowpass-width":
149 | arg = this.lowpassWidth(value);
150 | break;
151 | case "highpass":
152 | arg = this.highpass(value);
153 | break;
154 | case "highpass-width":
155 | arg = this.highpassWidth(value);
156 | break;
157 | case "resample":
158 | arg = this.resample(value);
159 | break;
160 | case "meta":
161 | arg = this.meta(value);
162 | break;
163 | default:
164 | throw new Error("Unknown parameter " + key);
165 | }
166 | if (arg != undefined) {
167 | for (const i in arg) {
168 | this.args.push(arg[i]);
169 | }
170 | }
171 | }
172 | }
173 | /**
174 | * Get all arguments for binary
175 | */
176 | getArguments() {
177 | return this.args;
178 | }
179 | output(value) {
180 | return undefined; // Handled in Lame class, because of fixed position (2nd parameter)
181 | }
182 | raw(value) {
183 | if (value == true) {
184 | return [`-r`];
185 | }
186 | else {
187 | return undefined;
188 | }
189 | }
190 | swapBytes(value) {
191 | if (value == true) {
192 | return [`-x`];
193 | }
194 | else {
195 | return undefined;
196 | }
197 | }
198 | sfreq(value) {
199 | if (value == 8 ||
200 | value == 11.025 ||
201 | value == 12 ||
202 | value == 16 ||
203 | value == 22.05 ||
204 | value == 24 ||
205 | value == 32 ||
206 | value == 44.1 ||
207 | value == 48) {
208 | return [`-s`, value];
209 | }
210 | else {
211 | throw new Error("lame: Invalid option: 'sfreq' is not in range of 8, 11.025, 12, 16, 22.05, 24, 32, 44.1 or 48.");
212 | }
213 | }
214 | bitwidth(value) {
215 | if (value == 8 || value == 16 || value == 24 || value == 32) {
216 | return [`--bitwidth`, value];
217 | }
218 | else {
219 | throw new Error("lame: Invalid option: 'sfreq' is not in range of 8, 16, 24 or 32.");
220 | }
221 | }
222 | signed(value) {
223 | if (value == true) {
224 | return [`--signed`];
225 | }
226 | else {
227 | return undefined;
228 | }
229 | }
230 | unsigned(value) {
231 | if (value == true) {
232 | return [`--unsigned`];
233 | }
234 | else {
235 | return undefined;
236 | }
237 | }
238 | littleEndian(value) {
239 | if (value == true) {
240 | return [`--little-endian`];
241 | }
242 | else {
243 | return undefined;
244 | }
245 | }
246 | bigEndian(value) {
247 | if (value == true) {
248 | return [`--big-endian`];
249 | }
250 | else {
251 | return undefined;
252 | }
253 | }
254 | mp2Input(value) {
255 | if (value == true) {
256 | return [`--mp2input`];
257 | }
258 | else {
259 | return undefined;
260 | }
261 | }
262 | mp3Input(value) {
263 | if (value == true) {
264 | return [`--mp3input`];
265 | }
266 | else {
267 | return undefined;
268 | }
269 | }
270 | mode(value) {
271 | if (value == "s" ||
272 | value == "j" ||
273 | value == "f" ||
274 | value == "d" ||
275 | value == "m" ||
276 | value == "l" ||
277 | value == "r") {
278 | return [`-m`, value];
279 | }
280 | else {
281 | throw new Error("lame: Invalid option: 'mode' is not in range of 's', 'j', 'f', 'd', 'm', 'l' or 'r'.");
282 | }
283 | }
284 | toMono(value) {
285 | if (value == true) {
286 | return [`-a`];
287 | }
288 | else {
289 | return undefined;
290 | }
291 | }
292 | channelDifferentBlockSize(value) {
293 | if (value == true) {
294 | return [`-d`];
295 | }
296 | else {
297 | return undefined;
298 | }
299 | }
300 | freeformat(value) {
301 | if (value == "FreeAmp" ||
302 | value == "in_mpg123" ||
303 | value == "l3dec" ||
304 | value == "LAME" ||
305 | value == "MAD") {
306 | return [`--freeformat`, value];
307 | }
308 | else {
309 | throw new Error("lame: Invalid option: 'mode' is not in range of 'FreeAmp', 'in_mpg123', 'l3dec', 'LAME', 'MAD'.");
310 | }
311 | }
312 | disableInfoTag(value) {
313 | if (value == true) {
314 | return [`-t`];
315 | }
316 | else {
317 | return undefined;
318 | }
319 | }
320 | comp(value) {
321 | return [`--comp`, value];
322 | }
323 | scale(value) {
324 | return [`--scale`, value];
325 | }
326 | scaleL(value) {
327 | return [`--scale-l`, value];
328 | }
329 | scaleR(value) {
330 | return [`--scale-r`, value];
331 | }
332 | replaygainFast(value) {
333 | if (value == true) {
334 | return [`--replaygain-fast`];
335 | }
336 | else {
337 | return undefined;
338 | }
339 | }
340 | replaygainAccurate(value) {
341 | if (value == true) {
342 | return [`--replaygain-accurate`];
343 | }
344 | else {
345 | return undefined;
346 | }
347 | }
348 | noreplaygain(value) {
349 | if (value == true) {
350 | return [`--noreplaygain`];
351 | }
352 | else {
353 | return undefined;
354 | }
355 | }
356 | clipDetect(value) {
357 | if (value == true) {
358 | return [`--clipdetect`];
359 | }
360 | else {
361 | return undefined;
362 | }
363 | }
364 | preset(value) {
365 | if (value == "medium" ||
366 | value == "standard" ||
367 | value == "extreme" ||
368 | value == "insane") {
369 | return [`--preset`, value];
370 | }
371 | else {
372 | throw new Error("lame: Invalid option: 'mode' is not in range of 'medium', 'standard', 'extreme' or 'insane'.");
373 | }
374 | }
375 | noasm(value) {
376 | if (value == "mmx" || value == "3dnow" || value == "sse") {
377 | return [`--noasm`, value];
378 | }
379 | else {
380 | throw new Error("lame: Invalid option: 'noasm' is not in range of 'mmx', '3dnow' or 'sse'.");
381 | }
382 | }
383 | quality(value) {
384 | if (value >= 0 && value <= 9) {
385 | return [`-q`, value];
386 | }
387 | else {
388 | throw new Error("lame: Invalid option: 'quality' is not in range of 0 to 9.");
389 | }
390 | }
391 | bitrate(value) {
392 | if (value == 8 ||
393 | value == 16 ||
394 | value == 24 ||
395 | value == 32 ||
396 | value == 40 ||
397 | value == 48 ||
398 | value == 56 ||
399 | value == 64 ||
400 | value == 80 ||
401 | value == 96 ||
402 | value == 112 ||
403 | value == 128 ||
404 | value == 144 ||
405 | value == 160 ||
406 | value == 192 ||
407 | value == 224 ||
408 | value == 256 ||
409 | value == 320) {
410 | return [`-b`, value];
411 | }
412 | else {
413 | throw new Error("lame: Invalid option: 'bitrate' is not in range of 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256 or 320.");
414 | }
415 | }
416 | forceBitrate(value) {
417 | if (value == true) {
418 | return [`-F`];
419 | }
420 | else {
421 | return undefined;
422 | }
423 | }
424 | cbr(value) {
425 | if (value == true) {
426 | return [`--cbr`];
427 | }
428 | else {
429 | return undefined;
430 | }
431 | }
432 | abr(value) {
433 | if (value >= 8 && value <= 310) {
434 | return [`--abr`, value];
435 | }
436 | else {
437 | throw new Error("lame: Invalid option: 'abr' is not in range of 8 to 310.");
438 | }
439 | }
440 | vbr(value) {
441 | if (value == true) {
442 | return [`-v`];
443 | }
444 | else {
445 | return undefined;
446 | }
447 | }
448 | vbrQuality(value) {
449 | if (value >= 0 && value <= 9) {
450 | return [`-V`, value];
451 | }
452 | else {
453 | throw new Error("lame: Invalid option: 'vbrQuality' is not in range of 0 to 9.");
454 | }
455 | }
456 | ignoreNoiseInSfb21(value) {
457 | if (value == true) {
458 | return [`-Y`];
459 | }
460 | else {
461 | return undefined;
462 | }
463 | }
464 | emp(value) {
465 | if (value == "n" || value == 5 || value == "c") {
466 | return [`-e`, value];
467 | }
468 | else {
469 | throw new Error("lame: Invalid option: 'emp' is not in range of 'n', 5 or 'c'.");
470 | }
471 | }
472 | markAsCopyrighted(value) {
473 | if (value == true) {
474 | return [`-c`];
475 | }
476 | else {
477 | return undefined;
478 | }
479 | }
480 | markAsCopy(value) {
481 | if (value == true) {
482 | return [`-o`];
483 | }
484 | else {
485 | return undefined;
486 | }
487 | }
488 | crcErrorProtection(value) {
489 | if (value == true) {
490 | return [`-p`];
491 | }
492 | else {
493 | return undefined;
494 | }
495 | }
496 | nores(value) {
497 | if (value == true) {
498 | return [`--nores`];
499 | }
500 | else {
501 | return undefined;
502 | }
503 | }
504 | strictlyEnforceIso(value) {
505 | if (value == true) {
506 | return [`--strictly-enforce-ISO`];
507 | }
508 | else {
509 | return undefined;
510 | }
511 | }
512 | lowpass(value) {
513 | return [`--lowpass`, value];
514 | }
515 | lowpassWidth(value) {
516 | return [`--lowpass-width`, value];
517 | }
518 | highpass(value) {
519 | return [`--highpass`, value];
520 | }
521 | highpassWidth(value) {
522 | return [`--highpass-width`, value];
523 | }
524 | resample(value) {
525 | if (value == 8 ||
526 | value == 11.025 ||
527 | value == 12 ||
528 | value == 16 ||
529 | value == 22.05 ||
530 | value == 24 ||
531 | value == 32 ||
532 | value == 44.1 ||
533 | value == 48) {
534 | return [`--resample`, value];
535 | }
536 | else {
537 | throw new Error("lame: Invalid option: 'resample' is not in range of 8, 11.025, 12, 16, 22.05, 24, 32, 44.1 or 48.");
538 | }
539 | }
540 | meta(metaObj) {
541 | for (const key in metaObj) {
542 | const value = metaObj[key];
543 | if (key == "title" ||
544 | key == "artist" ||
545 | key == "album" ||
546 | key == "year" ||
547 | key == "comment" ||
548 | key == "track" ||
549 | key == "genre" ||
550 | key == "artwork" ||
551 | key == "genre-list" ||
552 | key == "pad-id3v2-size") {
553 | let arg0;
554 | if (key == "title") {
555 | arg0 = `--tt`;
556 | }
557 | else if (key == "artist") {
558 | arg0 = `--ta`;
559 | }
560 | else if (key == "album") {
561 | arg0 = `--tl`;
562 | }
563 | else if (key == "year") {
564 | arg0 = `--ty`;
565 | }
566 | else if (key == "comment") {
567 | arg0 = `--tc`;
568 | }
569 | else if (key == "track") {
570 | arg0 = `--tn`;
571 | }
572 | else if (key == "genre") {
573 | arg0 = `--tg`;
574 | }
575 | else if (key == "artwork") {
576 | arg0 = `--ti`;
577 | }
578 | else if (key == "genre-list") {
579 | arg0 = `--genre-list`;
580 | }
581 | else if (key == "pad-id3v2-size") {
582 | arg0 = `--pad-id3v2-size`;
583 | }
584 | else {
585 | throw new Error(`lame: Invalid option: 'meta' unknown property '${key}'`);
586 | }
587 | const arg1 = `${value}`;
588 | this.args.push(arg0);
589 | this.args.push(arg1);
590 | }
591 | else if (key == "add-id3v2" ||
592 | key == "id3v1-only" ||
593 | key == "id3v2-only" ||
594 | key == "id3v2-latin1" ||
595 | key == "id3v2-utf16" ||
596 | key == "space-id3v1" ||
597 | key == "pad-id3v2" ||
598 | key == "ignore-tag-errors") {
599 | this.args.push(`--${key}`);
600 | }
601 | else {
602 | throw new Error(`lame: Invalid option: 'meta' unknown property '${key}'`);
603 | }
604 | }
605 | return undefined;
606 | }
607 | }
608 | exports.LameOptions = LameOptions;
609 | //# sourceMappingURL=LameOptions.js.map
--------------------------------------------------------------------------------
/lib/build/LameOptions.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"LameOptions.js","sourceRoot":"","sources":["../src/LameOptions.ts"],"names":[],"mappings":"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"}
--------------------------------------------------------------------------------
/lib/build/LameTypings.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 | Object.defineProperty(exports, "__esModule", { value: true });
3 | //# sourceMappingURL=LameTypings.js.map
--------------------------------------------------------------------------------
/lib/build/LameTypings.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"file":"LameTypings.js","sourceRoot":"","sources":["../src/LameTypings.ts"],"names":[],"mappings":""}
--------------------------------------------------------------------------------
/lib/src/Lame.ts:
--------------------------------------------------------------------------------
1 | import { LameStatus, Options } from "./LameTypings";
2 | import { LameOptions } from "./LameOptions";
3 | import {
4 | existsSync as fsExistsSync,
5 | readFile as fsReadFile,
6 | writeFile as fsWriteFile,
7 | unlinkSync as fsUnlinkSync
8 | } from "fs";
9 | import { isBuffer as utilIsBuffer } from "util";
10 | import { spawn } from "child_process";
11 | import { EventEmitter } from "events";
12 |
13 | /**
14 | * Wrapper for Lame for Node
15 | *
16 | * @class Lame
17 | */
18 | class Lame {
19 | private status: LameStatus = {
20 | started: false,
21 | finished: false,
22 | progress: undefined,
23 | eta: undefined
24 | };
25 | private emitter: EventEmitter = new EventEmitter();
26 |
27 | private options: Options;
28 | private args: string[];
29 |
30 | private filePath: string;
31 | private fileBuffer: Buffer;
32 | private fileBufferTempFilePath: string;
33 |
34 | private progressedFilePath: string;
35 | private progressedBuffer: Buffer;
36 | private progressedBufferTempFilePath: string;
37 |
38 | /**
39 | * Creates an instance of Lame and set all options
40 | * @param {Options} options
41 | */
42 | constructor(options: Options) {
43 | this.options = options;
44 | this.args = new LameOptions(this.options).getArguments();
45 | }
46 |
47 | /**
48 | * Set file path of audio to decode/encode
49 | *
50 | * @param {string} filePath
51 | */
52 | public setFile(path: string): Lame {
53 | if (!fsExistsSync(path)) {
54 | throw new Error("Audio file (path) does not exist");
55 | }
56 |
57 | this.filePath = path;
58 | this.fileBuffer = undefined;
59 |
60 | return this;
61 | }
62 |
63 | /**
64 | * Set file buffer of audio to decode/encode
65 | *
66 | * @param {Buffer} file
67 | */
68 | public setBuffer(file: Buffer): Lame {
69 | if (!utilIsBuffer(file)) {
70 | throw new Error("Audio file (buffer) dose not exist");
71 | }
72 |
73 | this.fileBuffer = file;
74 | this.filePath = undefined;
75 |
76 | return this;
77 | }
78 |
79 | /**
80 | * Get decoded/encoded file path
81 | *
82 | * @returns {string} Path of decoded/encoded file
83 | */
84 | public getFile(): string {
85 | if (this.progressedFilePath == undefined) {
86 | throw new Error("Audio is not yet decoded/encoded");
87 | }
88 |
89 | return this.progressedFilePath;
90 | }
91 |
92 | /**
93 | * Get decoded/encoded file as buffer
94 | *
95 | * @returns {Buffer} decoded/Encoded file
96 | */
97 | public getBuffer(): Buffer {
98 | if (this.progressedBuffer == undefined) {
99 | throw new Error("Audio is not yet decoded/encoded");
100 | }
101 |
102 | return this.progressedBuffer;
103 | }
104 |
105 | /**
106 | * Get event emitter
107 | *
108 | * @returns {EventEmitter}
109 | */
110 | public getEmitter(): EventEmitter {
111 | return this.emitter;
112 | }
113 |
114 | /**
115 | * Get status of converter
116 | *
117 | * @returns {LameStatus}
118 | */
119 | public getStatus(): LameStatus {
120 | return this.status;
121 | }
122 |
123 | /**
124 | * Encode audio file by Lame
125 | *
126 | * @return {Promise}
127 | */
128 | public encode(): Promise {
129 | return this.progress("encode");
130 | }
131 |
132 | /**
133 | * Decode audio file by Lame
134 | *
135 | * @return {Promise}
136 | */
137 | public decode(): Promise {
138 | return this.progress("decode");
139 | }
140 |
141 | /**
142 | * Decode/Encode audio file by Lame
143 | *
144 | * @return {Promise}
145 | */
146 | private progress(type: "encode" | "decode"): Promise {
147 | if (this.filePath == undefined && this.fileBuffer == undefined) {
148 | throw new Error("Audio file to encode is not set");
149 | }
150 |
151 | // Set decode flag to progress a MP3 to WAV decode
152 | const args = this.args;
153 | if (type == "decode") {
154 | args.push("--decode");
155 | }
156 |
157 | if (this.fileBuffer != undefined) {
158 | // File buffer is set; write it as temp file
159 | this.fileBufferTempFilePath = this.tempFilePathGenerator(
160 | "raw",
161 | type
162 | );
163 |
164 | return new Promise((resolve, reject) => {
165 | fsWriteFile(
166 | this.fileBufferTempFilePath,
167 | this.fileBuffer,
168 | err => {
169 | if (err) {
170 | reject(err);
171 | return;
172 | }
173 |
174 | resolve(this.fileBufferTempFilePath);
175 | }
176 | );
177 | })
178 | .then((file: string) => {
179 | return this.execProgress(file, args, type);
180 | })
181 | .catch((error: Error) => {
182 | this.removeTempFilesOnError();
183 | throw error;
184 | });
185 | } else {
186 | // File path is set
187 | return this.execProgress(this.filePath, args, type).catch(
188 | (error: Error) => {
189 | this.removeTempFilesOnError();
190 | throw error;
191 | }
192 | );
193 | }
194 | }
195 |
196 | /**
197 | * Execute decoding/encoding via spawn Lame
198 | *
199 | * @private
200 | * @param {string} inputFilePath Path of input file
201 | */
202 | private execProgress(
203 | inputFilePath: string,
204 | args: string[],
205 | type: "encode" | "decode"
206 | ) {
207 | // Add output settings args
208 | args.push("--disptime");
209 | args.push("1");
210 |
211 | // Add output file to args, if not undefined in options
212 | if (this.options.output == "buffer") {
213 | const tempOutPath = this.tempFilePathGenerator("encoded", type);
214 | args.unshift(`${tempOutPath}`);
215 |
216 | // Set decode/encoded file path
217 | this.progressedBufferTempFilePath = tempOutPath;
218 | } else {
219 | // Set decode/encoded file path
220 | this.progressedFilePath = this.options.output;
221 | args.unshift(this.progressedFilePath);
222 | }
223 |
224 | // Add input file to args
225 | args.unshift(inputFilePath);
226 |
227 | // Spawn instance of encoder and hook output methods
228 | this.status.started = true;
229 | this.status.finished = false;
230 | this.status.progress = 0;
231 | this.status.eta = undefined;
232 |
233 | /**
234 | * Handles output of stdout (and stderr)
235 | * Parses data from output into object
236 | *
237 | * @param {(String | Buffer)} data
238 | */
239 | const progressStdout = (data: String | Buffer) => {
240 | data = data.toString().trim();
241 |
242 | // Every output of Lame comes as "stderr". Deciding if it is an error or valid data by regex
243 | if (data.length > 6) {
244 | if (
245 | type == "encode" &&
246 | data.search("Writing LAME Tag...done") > -1
247 | ) {
248 | // processing done
249 | this.status.finished = true;
250 | this.status.progress = 100;
251 | this.status.eta = "00:00";
252 |
253 | this.emitter.emit("finish");
254 | this.emitter.emit("progress", [
255 | this.status.progress,
256 | this.status.eta
257 | ]);
258 | } else if (
259 | type == "encode" &&
260 | data.search(/\((( [0-9])|([0-9]{2})|(100))%\)\|/) > -1
261 | ) {
262 | // status of processing
263 | const progressMatch = data.match(
264 | /\((( [0-9])|([0-9]{2})|(100))%\)\|/
265 | );
266 | const etaMatch = data.match(/[0-9]{1,2}:[0-9][0-9] /);
267 |
268 | const progress: string = String(progressMatch[1]);
269 | let eta: string = null;
270 | if (etaMatch != null) {
271 | eta = etaMatch[0].trim();
272 | }
273 |
274 | if (
275 | progress != null &&
276 | Number(progress) > this.status.progress
277 | ) {
278 | this.status.progress = Number(progress);
279 | }
280 |
281 | if (eta != null) {
282 | this.status.eta = eta;
283 | }
284 |
285 | this.emitter.emit("progress", [
286 | this.status.progress,
287 | this.status.eta
288 | ]);
289 | } else if (
290 | type == "decode" &&
291 | data.search(/[0-9]{1,10}\/[0-9]{1,10}/) > -1
292 | ) {
293 | const progressMatch = data.match(
294 | /[0-9]{1,10}\/[0-9]{1,10}/
295 | );
296 | const progressAbsolute = progressMatch[0].split("/");
297 | const progress = Math.floor(
298 | (Number(progressAbsolute[0]) /
299 | Number(progressAbsolute[1])) *
300 | 100
301 | );
302 |
303 | if (
304 | !isNaN(progress) &&
305 | Number(progress) > this.status.progress
306 | ) {
307 | this.status.progress = Number(progress);
308 | }
309 |
310 | this.emitter.emit("progress", [
311 | this.status.progress,
312 | this.status.eta
313 | ]);
314 | } else if (
315 | data.search(/^lame: /) > -1 ||
316 | data.search(/^Warning: /) > -1 ||
317 | data.search(/Error /) > -1
318 | ) {
319 | // Unexpected output => error
320 | if (data.search(/^lame: /) == -1) {
321 | this.emitter.emit("error", new Error("lame: " + data));
322 | } else {
323 | this.emitter.emit("error", new Error(String(data)));
324 | }
325 | }
326 | }
327 | };
328 |
329 | const progressOnClose = code => {
330 | if (code == 0) {
331 | if (!this.status.finished) {
332 | this.emitter.emit("finish");
333 | }
334 |
335 | this.status.finished = true;
336 | this.status.progress = 100;
337 | this.status.eta = "00:00";
338 | }
339 |
340 | if (code === 255) {
341 | this.emitter.emit("error", new Error("Unexpected termination of the process, possibly directly after the start. Please check if the input and/or output does not exist."));
342 | }
343 | };
344 |
345 | /**
346 | * Handles error throw of Lame instance
347 | *
348 | * @param {Error} error
349 | */
350 | const progressError = (error: Error) => {
351 | this.emitter.emit("error", error);
352 | };
353 |
354 | const instance = spawn("lame", args);
355 | instance.stdout.on("data", progressStdout);
356 | instance.stderr.on("data", progressStdout); // Most output, even non-errors, are on stderr
357 | instance.on("close", progressOnClose);
358 | instance.on("error", progressError);
359 |
360 | // Return promise of finish encoding progress
361 | return new Promise((resolve, reject) => {
362 | this.emitter.on("finish", () => {
363 | // If input was buffer, remove temp file
364 | if (this.fileBufferTempFilePath != undefined) {
365 | fsUnlinkSync(this.fileBufferTempFilePath);
366 | }
367 |
368 | // If output should be a buffer, load decoded/encoded audio file in object and remove temp file
369 | if (this.options.output == "buffer") {
370 | fsReadFile(
371 | this.progressedBufferTempFilePath,
372 | null,
373 | (error, data: string) => {
374 | // Remove temp decoded/encoded file
375 | fsUnlinkSync(this.progressedBufferTempFilePath);
376 |
377 | if (error) {
378 | reject(error);
379 | return;
380 | }
381 |
382 | this.progressedBuffer = Buffer.from(data);
383 | this.progressedBufferTempFilePath = undefined;
384 |
385 | resolve(this);
386 | }
387 | );
388 | } else {
389 | resolve(this);
390 | }
391 | });
392 |
393 | this.emitter.on("error", error => {
394 | reject(error);
395 | });
396 | });
397 | }
398 |
399 | /**
400 | * Generate temp file path
401 | *
402 | * @param {("raw" | "encoded")} type
403 | * @returns {string} Path
404 | */
405 | private tempFilePathGenerator(
406 | type: "raw" | "encoded",
407 | progressType: "encode" | "decode"
408 | ): string {
409 | const prefix = `${__dirname}/../.`;
410 | let path = `${prefix}./temp/${type}/`;
411 | let possible =
412 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
413 |
414 | for (let i = 0; i < 32; i++) {
415 | path += possible.charAt(
416 | Math.floor(Math.random() * possible.length)
417 | );
418 | }
419 |
420 | if (type == "raw" && progressType == "decode") {
421 | path += `.mp3`;
422 | }
423 |
424 | if (!fsExistsSync(`${prefix}./temp/${path}`)) {
425 | return path;
426 | } else {
427 | return this.tempFilePathGenerator(type, progressType);
428 | }
429 | }
430 |
431 | /**
432 | * Remove temp files, if error occurred
433 | */
434 | private removeTempFilesOnError() {
435 | if (this.fileBufferTempFilePath != undefined && fsExistsSync(this.fileBufferTempFilePath)) {
436 | fsUnlinkSync(this.fileBufferTempFilePath);
437 | }
438 |
439 | if (this.progressedBufferTempFilePath != undefined && fsExistsSync(this.progressedBufferTempFilePath)) {
440 | fsUnlinkSync(this.progressedBufferTempFilePath);
441 | }
442 | }
443 | }
444 |
445 | export { Lame };
446 |
--------------------------------------------------------------------------------
/lib/src/LameOptions.ts:
--------------------------------------------------------------------------------
1 | import { Options } from "./LameTypings";
2 | import * as fs from "fs";
3 |
4 | /**
5 | * All options of node-lame; build argument array for binary
6 | *
7 | * @class LameOptions
8 | */
9 | class LameOptions {
10 | private args = [];
11 | /**
12 | * Validate all options and build argument array for binary
13 | * @param {Object} options
14 | */
15 | constructor(options: Options) {
16 | // Output is required
17 | if (options["output"] == undefined) {
18 | throw new Error("lame: Invalid option: 'output' is required");
19 | }
20 |
21 | // Save options as arguments
22 | for (const key in options) {
23 | const value = options[key];
24 | let arg;
25 |
26 | switch (key) {
27 | case "output":
28 | arg = this.output(value);
29 | break;
30 | case "raw":
31 | arg = this.raw(value);
32 | break;
33 | case "swap-bytes":
34 | arg = this.swapBytes(value);
35 | break;
36 | case "sfreq":
37 | arg = this.sfreq(value);
38 | break;
39 | case "bitwidth":
40 | arg = this.bitwidth(value);
41 | break;
42 | case "signed":
43 | arg = this.signed(value);
44 | break;
45 | case "unsigned":
46 | arg = this.unsigned(value);
47 | break;
48 | case "little-endian":
49 | arg = this.littleEndian(value);
50 | break;
51 | case "big-endian":
52 | arg = this.bigEndian(value);
53 | break;
54 | case "mp2Input":
55 | arg = this.mp2Input(value);
56 | break;
57 | case "mp3Input":
58 | arg = this.mp3Input(value);
59 | break;
60 | case "mode":
61 | arg = this.mode(value);
62 | break;
63 | case "to-mono":
64 | arg = this.toMono(value);
65 | break;
66 | case "channel-different-block-sizes":
67 | arg = this.channelDifferentBlockSize(value);
68 | break;
69 | case "freeformat":
70 | arg = this.freeformat(value);
71 | break;
72 | case "disable-info-tag":
73 | arg = this.disableInfoTag(value);
74 | break;
75 | case "comp":
76 | arg = this.comp(value);
77 | break;
78 | case "scale":
79 | arg = this.scale(value);
80 | break;
81 | case "scale-l":
82 | arg = this.scaleL(value);
83 | break;
84 | case "scale-r":
85 | arg = this.scaleR(value);
86 | break;
87 | case "replaygain-fast":
88 | arg = this.replaygainFast(value);
89 | break;
90 | case "replaygain-accurate":
91 | arg = this.replaygainAccurate(value);
92 | break;
93 | case "no-replaygain":
94 | arg = this.noreplaygain(value);
95 | break;
96 | case "clip-detect":
97 | arg = this.clipDetect(value);
98 | break;
99 | case "preset":
100 | arg = this.preset(value);
101 | break;
102 | case "noasm":
103 | arg = this.noasm(value);
104 | break;
105 | case "quality":
106 | arg = this.quality(value);
107 | break;
108 | case "bitrate":
109 | arg = this.bitrate(value);
110 | break;
111 | case "force-bitrate":
112 | arg = this.forceBitrate(value);
113 | break;
114 | case "cbr":
115 | arg = this.cbr(value);
116 | break;
117 | case "abr":
118 | arg = this.abr(value);
119 | break;
120 | case "vbr":
121 | arg = this.vbr(value);
122 | break;
123 | case "vbr-quality":
124 | arg = this.vbrQuality(value);
125 | break;
126 | case "ignore-noise-in-sfb21":
127 | arg = this.ignoreNoiseInSfb21(value);
128 | break;
129 | case "emp":
130 | arg = this.emp(value);
131 | break;
132 | case "mark-as-copyrighted":
133 | arg = this.markAsCopyrighted(value);
134 | break;
135 | case "mark-as-copy":
136 | arg = this.markAsCopy(value);
137 | break;
138 | case "crc-error-protection":
139 | arg = this.crcErrorProtection(value);
140 | break;
141 | case "nores":
142 | arg = this.nores(value);
143 | break;
144 | case "strictly-enforce-ISO":
145 | arg = this.strictlyEnforceIso(value);
146 | break;
147 | case "lowpass":
148 | arg = this.lowpass(value);
149 | break;
150 | case "lowpass-width":
151 | arg = this.lowpassWidth(value);
152 | break;
153 | case "highpass":
154 | arg = this.highpass(value);
155 | break;
156 | case "highpass-width":
157 | arg = this.highpassWidth(value);
158 | break;
159 | case "resample":
160 | arg = this.resample(value);
161 | break;
162 | case "meta":
163 | arg = this.meta(value);
164 | break;
165 | default:
166 | throw new Error("Unknown parameter " + key);
167 | }
168 |
169 | if (arg != undefined) {
170 | for (const i in arg) {
171 | this.args.push(arg[i]);
172 | }
173 | }
174 | }
175 | }
176 |
177 | /**
178 | * Get all arguments for binary
179 | */
180 | public getArguments() {
181 | return this.args;
182 | }
183 |
184 | private output(value) {
185 | return undefined; // Handled in Lame class, because of fixed position (2nd parameter)
186 | }
187 |
188 | private raw(value) {
189 | if (value == true) {
190 | return [`-r`];
191 | } else {
192 | return undefined;
193 | }
194 | }
195 |
196 | private swapBytes(value) {
197 | if (value == true) {
198 | return [`-x`];
199 | } else {
200 | return undefined;
201 | }
202 | }
203 |
204 | private sfreq(value) {
205 | if (
206 | value == 8 ||
207 | value == 11.025 ||
208 | value == 12 ||
209 | value == 16 ||
210 | value == 22.05 ||
211 | value == 24 ||
212 | value == 32 ||
213 | value == 44.1 ||
214 | value == 48
215 | ) {
216 | return [`-s`, value];
217 | } else {
218 | throw new Error(
219 | "lame: Invalid option: 'sfreq' is not in range of 8, 11.025, 12, 16, 22.05, 24, 32, 44.1 or 48."
220 | );
221 | }
222 | }
223 |
224 | private bitwidth(value) {
225 | if (value == 8 || value == 16 || value == 24 || value == 32) {
226 | return [`--bitwidth`, value];
227 | } else {
228 | throw new Error(
229 | "lame: Invalid option: 'sfreq' is not in range of 8, 16, 24 or 32."
230 | );
231 | }
232 | }
233 |
234 | private signed(value) {
235 | if (value == true) {
236 | return [`--signed`];
237 | } else {
238 | return undefined;
239 | }
240 | }
241 |
242 | private unsigned(value) {
243 | if (value == true) {
244 | return [`--unsigned`];
245 | } else {
246 | return undefined;
247 | }
248 | }
249 |
250 | private littleEndian(value) {
251 | if (value == true) {
252 | return [`--little-endian`];
253 | } else {
254 | return undefined;
255 | }
256 | }
257 |
258 | private bigEndian(value) {
259 | if (value == true) {
260 | return [`--big-endian`];
261 | } else {
262 | return undefined;
263 | }
264 | }
265 |
266 | private mp2Input(value) {
267 | if (value == true) {
268 | return [`--mp2input`];
269 | } else {
270 | return undefined;
271 | }
272 | }
273 |
274 | private mp3Input(value) {
275 | if (value == true) {
276 | return [`--mp3input`];
277 | } else {
278 | return undefined;
279 | }
280 | }
281 |
282 | private mode(value) {
283 | if (
284 | value == "s" ||
285 | value == "j" ||
286 | value == "f" ||
287 | value == "d" ||
288 | value == "m" ||
289 | value == "l" ||
290 | value == "r"
291 | ) {
292 | return [`-m`, value];
293 | } else {
294 | throw new Error(
295 | "lame: Invalid option: 'mode' is not in range of 's', 'j', 'f', 'd', 'm', 'l' or 'r'."
296 | );
297 | }
298 | }
299 |
300 | private toMono(value) {
301 | if (value == true) {
302 | return [`-a`];
303 | } else {
304 | return undefined;
305 | }
306 | }
307 |
308 | private channelDifferentBlockSize(value) {
309 | if (value == true) {
310 | return [`-d`];
311 | } else {
312 | return undefined;
313 | }
314 | }
315 |
316 | private freeformat(value) {
317 | if (
318 | value == "FreeAmp" ||
319 | value == "in_mpg123" ||
320 | value == "l3dec" ||
321 | value == "LAME" ||
322 | value == "MAD"
323 | ) {
324 | return [`--freeformat`, value];
325 | } else {
326 | throw new Error(
327 | "lame: Invalid option: 'mode' is not in range of 'FreeAmp', 'in_mpg123', 'l3dec', 'LAME', 'MAD'."
328 | );
329 | }
330 | }
331 |
332 | private disableInfoTag(value) {
333 | if (value == true) {
334 | return [`-t`];
335 | } else {
336 | return undefined;
337 | }
338 | }
339 |
340 | private comp(value) {
341 | return [`--comp`, value];
342 | }
343 |
344 | private scale(value) {
345 | return [`--scale`, value];
346 | }
347 |
348 | private scaleL(value) {
349 | return [`--scale-l`, value];
350 | }
351 |
352 | private scaleR(value) {
353 | return [`--scale-r`, value];
354 | }
355 |
356 | private replaygainFast(value) {
357 | if (value == true) {
358 | return [`--replaygain-fast`];
359 | } else {
360 | return undefined;
361 | }
362 | }
363 |
364 | private replaygainAccurate(value) {
365 | if (value == true) {
366 | return [`--replaygain-accurate`];
367 | } else {
368 | return undefined;
369 | }
370 | }
371 |
372 | private noreplaygain(value) {
373 | if (value == true) {
374 | return [`--noreplaygain`];
375 | } else {
376 | return undefined;
377 | }
378 | }
379 |
380 | private clipDetect(value) {
381 | if (value == true) {
382 | return [`--clipdetect`];
383 | } else {
384 | return undefined;
385 | }
386 | }
387 |
388 | private preset(value) {
389 | if (
390 | value == "medium" ||
391 | value == "standard" ||
392 | value == "extreme" ||
393 | value == "insane"
394 | ) {
395 | return [`--preset`, value];
396 | } else {
397 | throw new Error(
398 | "lame: Invalid option: 'mode' is not in range of 'medium', 'standard', 'extreme' or 'insane'."
399 | );
400 | }
401 | }
402 |
403 | private noasm(value) {
404 | if (value == "mmx" || value == "3dnow" || value == "sse") {
405 | return [`--noasm`, value];
406 | } else {
407 | throw new Error(
408 | "lame: Invalid option: 'noasm' is not in range of 'mmx', '3dnow' or 'sse'."
409 | );
410 | }
411 | }
412 |
413 | private quality(value) {
414 | if (value >= 0 && value <= 9) {
415 | return [`-q`, value];
416 | } else {
417 | throw new Error(
418 | "lame: Invalid option: 'quality' is not in range of 0 to 9."
419 | );
420 | }
421 | }
422 |
423 | private bitrate(value) {
424 | if (
425 | value == 8 ||
426 | value == 16 ||
427 | value == 24 ||
428 | value == 32 ||
429 | value == 40 ||
430 | value == 48 ||
431 | value == 56 ||
432 | value == 64 ||
433 | value == 80 ||
434 | value == 96 ||
435 | value == 112 ||
436 | value == 128 ||
437 | value == 144 ||
438 | value == 160 ||
439 | value == 192 ||
440 | value == 224 ||
441 | value == 256 ||
442 | value == 320
443 | ) {
444 | return [`-b`, value];
445 | } else {
446 | throw new Error(
447 | "lame: Invalid option: 'bitrate' is not in range of 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256 or 320."
448 | );
449 | }
450 | }
451 |
452 | private forceBitrate(value) {
453 | if (value == true) {
454 | return [`-F`];
455 | } else {
456 | return undefined;
457 | }
458 | }
459 |
460 | private cbr(value) {
461 | if (value == true) {
462 | return [`--cbr`];
463 | } else {
464 | return undefined;
465 | }
466 | }
467 |
468 | private abr(value) {
469 | if (value >= 8 && value <= 310) {
470 | return [`--abr`, value];
471 | } else {
472 | throw new Error(
473 | "lame: Invalid option: 'abr' is not in range of 8 to 310."
474 | );
475 | }
476 | }
477 |
478 | private vbr(value) {
479 | if (value == true) {
480 | return [`-v`];
481 | } else {
482 | return undefined;
483 | }
484 | }
485 |
486 | private vbrQuality(value) {
487 | if (value >= 0 && value <= 9) {
488 | return [`-V`, value];
489 | } else {
490 | throw new Error(
491 | "lame: Invalid option: 'vbrQuality' is not in range of 0 to 9."
492 | );
493 | }
494 | }
495 |
496 | private ignoreNoiseInSfb21(value) {
497 | if (value == true) {
498 | return [`-Y`];
499 | } else {
500 | return undefined;
501 | }
502 | }
503 |
504 | private emp(value) {
505 | if (value == "n" || value == 5 || value == "c") {
506 | return [`-e`, value];
507 | } else {
508 | throw new Error(
509 | "lame: Invalid option: 'emp' is not in range of 'n', 5 or 'c'."
510 | );
511 | }
512 | }
513 |
514 | private markAsCopyrighted(value) {
515 | if (value == true) {
516 | return [`-c`];
517 | } else {
518 | return undefined;
519 | }
520 | }
521 |
522 | private markAsCopy(value) {
523 | if (value == true) {
524 | return [`-o`];
525 | } else {
526 | return undefined;
527 | }
528 | }
529 |
530 | private crcErrorProtection(value) {
531 | if (value == true) {
532 | return [`-p`];
533 | } else {
534 | return undefined;
535 | }
536 | }
537 |
538 | private nores(value) {
539 | if (value == true) {
540 | return [`--nores`];
541 | } else {
542 | return undefined;
543 | }
544 | }
545 |
546 | private strictlyEnforceIso(value) {
547 | if (value == true) {
548 | return [`--strictly-enforce-ISO`];
549 | } else {
550 | return undefined;
551 | }
552 | }
553 |
554 | private lowpass(value) {
555 | return [`--lowpass`, value];
556 | }
557 |
558 | private lowpassWidth(value) {
559 | return [`--lowpass-width`, value];
560 | }
561 |
562 | private highpass(value) {
563 | return [`--highpass`, value];
564 | }
565 |
566 | private highpassWidth(value) {
567 | return [`--highpass-width`, value];
568 | }
569 |
570 | private resample(value) {
571 | if (
572 | value == 8 ||
573 | value == 11.025 ||
574 | value == 12 ||
575 | value == 16 ||
576 | value == 22.05 ||
577 | value == 24 ||
578 | value == 32 ||
579 | value == 44.1 ||
580 | value == 48
581 | ) {
582 | return [`--resample`, value];
583 | } else {
584 | throw new Error(
585 | "lame: Invalid option: 'resample' is not in range of 8, 11.025, 12, 16, 22.05, 24, 32, 44.1 or 48."
586 | );
587 | }
588 | }
589 |
590 | private meta(metaObj) {
591 | for (const key in metaObj) {
592 | const value = metaObj[key];
593 |
594 | if (
595 | key == "title" ||
596 | key == "artist" ||
597 | key == "album" ||
598 | key == "year" ||
599 | key == "comment" ||
600 | key == "track" ||
601 | key == "genre" ||
602 | key == "artwork" ||
603 | key == "genre-list" ||
604 | key == "pad-id3v2-size"
605 | ) {
606 | let arg0;
607 | if (key == "title") {
608 | arg0 = `--tt`;
609 | } else if (key == "artist") {
610 | arg0 = `--ta`;
611 | } else if (key == "album") {
612 | arg0 = `--tl`;
613 | } else if (key == "year") {
614 | arg0 = `--ty`;
615 | } else if (key == "comment") {
616 | arg0 = `--tc`;
617 | } else if (key == "track") {
618 | arg0 = `--tn`;
619 | } else if (key == "genre") {
620 | arg0 = `--tg`;
621 | } else if (key == "artwork") {
622 | arg0 = `--ti`;
623 | } else if (key == "genre-list") {
624 | arg0 = `--genre-list`;
625 | } else if (key == "pad-id3v2-size") {
626 | arg0 = `--pad-id3v2-size`;
627 | } else {
628 | throw new Error(
629 | `lame: Invalid option: 'meta' unknown property '${key}'`
630 | );
631 | }
632 |
633 | const arg1 = `${value}`;
634 |
635 | this.args.push(arg0);
636 | this.args.push(arg1);
637 | } else if (
638 | key == "add-id3v2" ||
639 | key == "id3v1-only" ||
640 | key == "id3v2-only" ||
641 | key == "id3v2-latin1" ||
642 | key == "id3v2-utf16" ||
643 | key == "space-id3v1" ||
644 | key == "pad-id3v2" ||
645 | key == "ignore-tag-errors"
646 | ) {
647 | this.args.push(`--${key}`);
648 | } else {
649 | throw new Error(
650 | `lame: Invalid option: 'meta' unknown property '${key}'`
651 | );
652 | }
653 | }
654 |
655 | return undefined;
656 | }
657 | }
658 |
659 | export { LameOptions };
660 |
--------------------------------------------------------------------------------
/lib/src/LameTypings.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Status data of lame instance
3 | *
4 | * @interface LameStatus
5 | */
6 | interface LameStatus {
7 | started: boolean;
8 | finished: boolean;
9 | progress: number;
10 | eta: string;
11 | }
12 |
13 | /**
14 | * Raw options interface and types for Typescript definitions
15 | */
16 | namespace Options {
17 | export type sfreq = 8 | 11.025 | 12 | 16 | 22.05 | 24 | 32 | 44.1 | 48;
18 | export type bitwidth = 8 | 16 | 24 | 32;
19 | export type mode = "s" | "j" | "f" | "d" | "m" | "l" | "r";
20 | export type freeformat = "FreeAmp" | "in_mpg123" | "l3dec" | "LAME" | "MAD";
21 | export type preset = "medium" | "standard" | "extreme" | "insane";
22 | export type noasm = "mmx" | "3dnow" | "sse";
23 | export type quality = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
24 | export type bitrate =
25 | | 8
26 | | 16
27 | | 24
28 | | 32
29 | | 40
30 | | 48
31 | | 56
32 | | 64
33 | | 80
34 | | 96
35 | | 112
36 | | 128
37 | | 144
38 | | 160
39 | | 192
40 | | 224
41 | | 256
42 | | 320;
43 | export type emp = "n" | 5 | "c";
44 | export type resample = 8 | 11.025 | 12 | 16 | 22.05 | 24 | 32 | 44.1 | 48;
45 |
46 | export interface meta {
47 | title?: string;
48 | artist?: string;
49 | album?: string;
50 | year?: string;
51 | comment?: string;
52 | track?: string;
53 | genre?: string;
54 |
55 | "add-id3v2"?: boolean;
56 | "id3v1-only"?: boolean;
57 | "id3v2-only"?: boolean;
58 | "id3v2-latin1"?: boolean;
59 | "id3v2-utf16"?: boolean;
60 | "space-id3v1"?: boolean;
61 | "pad-id3v2-size"?: number;
62 | "genre-list"?: string;
63 | "ignore-tag-errors"?: boolean;
64 | }
65 | }
66 |
67 | interface Options {
68 | output: string | "buffer";
69 | raw?: boolean;
70 | "swap-bytes"?: boolean;
71 | sfreq?: Options.sfreq;
72 | bitwidth?: Options.bitwidth;
73 | signed?: boolean;
74 | unsigned?: boolean;
75 | "little-endian"?: boolean;
76 | "big-endian"?: boolean;
77 | mp2Input?: boolean;
78 | mp3Input?: boolean;
79 | mode?: Options.mode;
80 | "to-mono"?: boolean;
81 | "channel-different-block-sizes"?: boolean;
82 | freeformat?: Options.freeformat;
83 | "disable-info-tag"?: boolean;
84 | comp?: number;
85 | scale?: number;
86 | "scale-l"?: number;
87 | "scale-r"?: number;
88 | "replaygain-fast"?: boolean;
89 | "replaygain-accurate"?: boolean;
90 | "no-replaygain"?: boolean;
91 | "clip-detect"?: boolean;
92 | preset?: Options.preset;
93 | noasm?: Options.noasm;
94 | quality?: Options.quality;
95 | bitrate?: Options.bitrate;
96 | "force-bitrate"?: boolean;
97 | cbr?: boolean;
98 | abr?: number;
99 | vbr?: boolean;
100 | "vbr-quality"?: number;
101 | "ignore-noise-in-sfb21"?: boolean;
102 | emp?: Options.emp;
103 | "mark-as-copyrighted"?: boolean;
104 | "mark-as-copy"?: boolean;
105 | "crc-error-protection"?: boolean;
106 | nores?: boolean;
107 | "strictly-enforce-ISO"?: boolean;
108 | lowpass?: number;
109 | "lowpass-width"?: number;
110 | highpass?: number;
111 | "highpass-width"?: number;
112 | resample?: Options.resample;
113 | meta?: Options.meta;
114 | }
115 |
116 | export { LameStatus, Options };
117 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-lame",
3 | "version": "1.3.2",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@cspotcode/source-map-consumer": {
8 | "version": "0.8.0",
9 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz",
10 | "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==",
11 | "dev": true
12 | },
13 | "@cspotcode/source-map-support": {
14 | "version": "0.6.1",
15 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.6.1.tgz",
16 | "integrity": "sha512-DX3Z+T5dt1ockmPdobJS/FAsQPW4V4SrWEhD2iYQT2Cb2tQsiMnYxrcUH9By/Z3B+v0S5LMBkQtV/XOBbpLEOg==",
17 | "dev": true,
18 | "requires": {
19 | "@cspotcode/source-map-consumer": "0.8.0"
20 | }
21 | },
22 | "@tsconfig/node10": {
23 | "version": "1.0.8",
24 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz",
25 | "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==",
26 | "dev": true
27 | },
28 | "@tsconfig/node12": {
29 | "version": "1.0.9",
30 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz",
31 | "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==",
32 | "dev": true
33 | },
34 | "@tsconfig/node14": {
35 | "version": "1.0.1",
36 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz",
37 | "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==",
38 | "dev": true
39 | },
40 | "@tsconfig/node16": {
41 | "version": "1.0.2",
42 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz",
43 | "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==",
44 | "dev": true
45 | },
46 | "@types/chai": {
47 | "version": "4.2.21",
48 | "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.21.tgz",
49 | "integrity": "sha512-yd+9qKmJxm496BOV9CMNaey8TWsikaZOwMRwPHQIjcOJM9oV+fi9ZMNw3JsVnbEEbo2gRTDnGEBv8pjyn67hNg==",
50 | "dev": true
51 | },
52 | "@types/fs-extra": {
53 | "version": "9.0.12",
54 | "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.12.tgz",
55 | "integrity": "sha512-I+bsBr67CurCGnSenZZ7v94gd3tc3+Aj2taxMT4yu4ABLuOgOjeFxX3dokG24ztSRg5tnT00sL8BszO7gSMoIw==",
56 | "dev": true,
57 | "requires": {
58 | "@types/node": "*"
59 | }
60 | },
61 | "@types/mocha": {
62 | "version": "8.2.1",
63 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.2.1.tgz",
64 | "integrity": "sha512-NysN+bNqj6E0Hv4CTGWSlPzMW6vTKjDpOteycDkV4IWBsO+PU48JonrPzV9ODjiI2XrjmA05KInLgF5ivZ/YGQ==",
65 | "dev": true
66 | },
67 | "@types/node": {
68 | "version": "14.17.10",
69 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.10.tgz",
70 | "integrity": "sha512-09x2d6kNBwjHgyh3jOUE2GE4DFoxDriDvWdu6mFhMP1ysynGYazt4ecZmJlL6/fe4Zi2vtYvTvtL7epjQQrBhA==",
71 | "dev": true
72 | },
73 | "@ungap/promise-all-settled": {
74 | "version": "1.1.2",
75 | "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz",
76 | "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==",
77 | "dev": true
78 | },
79 | "acorn": {
80 | "version": "8.4.1",
81 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.4.1.tgz",
82 | "integrity": "sha512-asabaBSkEKosYKMITunzX177CXxQ4Q8BSSzMTKD+FefUhipQC70gfW5SiUDhYQ3vk8G+81HqQk7Fv9OXwwn9KA==",
83 | "dev": true
84 | },
85 | "acorn-walk": {
86 | "version": "8.1.1",
87 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.1.1.tgz",
88 | "integrity": "sha512-FbJdceMlPHEAWJOILDk1fXD8lnTlEIWFkqtfk+MvmL5q/qlHfN7GEHcsFZWt/Tea9jRNPWUZG4G976nqAAmU9w==",
89 | "dev": true
90 | },
91 | "ansi-colors": {
92 | "version": "4.1.1",
93 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
94 | "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
95 | "dev": true
96 | },
97 | "ansi-regex": {
98 | "version": "3.0.0",
99 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
100 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
101 | "dev": true
102 | },
103 | "ansi-styles": {
104 | "version": "4.3.0",
105 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
106 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
107 | "dev": true,
108 | "requires": {
109 | "color-convert": "^2.0.1"
110 | }
111 | },
112 | "anymatch": {
113 | "version": "3.1.2",
114 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
115 | "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==",
116 | "dev": true,
117 | "requires": {
118 | "normalize-path": "^3.0.0",
119 | "picomatch": "^2.0.4"
120 | }
121 | },
122 | "arg": {
123 | "version": "4.1.3",
124 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
125 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
126 | "dev": true
127 | },
128 | "argparse": {
129 | "version": "2.0.1",
130 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
131 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
132 | "dev": true
133 | },
134 | "assertion-error": {
135 | "version": "1.1.0",
136 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
137 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
138 | "dev": true
139 | },
140 | "balanced-match": {
141 | "version": "1.0.2",
142 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
143 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
144 | "dev": true
145 | },
146 | "binary-extensions": {
147 | "version": "2.2.0",
148 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
149 | "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
150 | "dev": true
151 | },
152 | "brace-expansion": {
153 | "version": "1.1.11",
154 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
155 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
156 | "dev": true,
157 | "requires": {
158 | "balanced-match": "^1.0.0",
159 | "concat-map": "0.0.1"
160 | }
161 | },
162 | "braces": {
163 | "version": "3.0.3",
164 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
165 | "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
166 | "dev": true,
167 | "requires": {
168 | "fill-range": "^7.1.1"
169 | },
170 | "dependencies": {
171 | "fill-range": {
172 | "version": "7.1.1",
173 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
174 | "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
175 | "dev": true,
176 | "requires": {
177 | "to-regex-range": "^5.0.1"
178 | }
179 | }
180 | }
181 | },
182 | "browser-stdout": {
183 | "version": "1.3.1",
184 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
185 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
186 | "dev": true
187 | },
188 | "camelcase": {
189 | "version": "6.2.0",
190 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
191 | "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==",
192 | "dev": true
193 | },
194 | "chai": {
195 | "version": "4.3.4",
196 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz",
197 | "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==",
198 | "dev": true,
199 | "requires": {
200 | "assertion-error": "^1.1.0",
201 | "check-error": "^1.0.2",
202 | "deep-eql": "^3.0.1",
203 | "get-func-name": "^2.0.0",
204 | "pathval": "^1.1.1",
205 | "type-detect": "^4.0.5"
206 | }
207 | },
208 | "chalk": {
209 | "version": "4.1.2",
210 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
211 | "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
212 | "dev": true,
213 | "requires": {
214 | "ansi-styles": "^4.1.0",
215 | "supports-color": "^7.1.0"
216 | },
217 | "dependencies": {
218 | "supports-color": {
219 | "version": "7.2.0",
220 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
221 | "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
222 | "dev": true,
223 | "requires": {
224 | "has-flag": "^4.0.0"
225 | }
226 | }
227 | }
228 | },
229 | "check-error": {
230 | "version": "1.0.2",
231 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
232 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
233 | "dev": true
234 | },
235 | "chokidar": {
236 | "version": "3.5.1",
237 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
238 | "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
239 | "dev": true,
240 | "requires": {
241 | "anymatch": "~3.1.1",
242 | "braces": "~3.0.2",
243 | "fsevents": "~2.3.1",
244 | "glob-parent": "~5.1.0",
245 | "is-binary-path": "~2.1.0",
246 | "is-glob": "~4.0.1",
247 | "normalize-path": "~3.0.0",
248 | "readdirp": "~3.5.0"
249 | }
250 | },
251 | "cliui": {
252 | "version": "7.0.4",
253 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
254 | "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
255 | "dev": true,
256 | "requires": {
257 | "string-width": "^4.2.0",
258 | "strip-ansi": "^6.0.0",
259 | "wrap-ansi": "^7.0.0"
260 | },
261 | "dependencies": {
262 | "ansi-regex": {
263 | "version": "5.0.0",
264 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
265 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
266 | "dev": true
267 | },
268 | "is-fullwidth-code-point": {
269 | "version": "3.0.0",
270 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
271 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
272 | "dev": true
273 | },
274 | "string-width": {
275 | "version": "4.2.2",
276 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
277 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
278 | "dev": true,
279 | "requires": {
280 | "emoji-regex": "^8.0.0",
281 | "is-fullwidth-code-point": "^3.0.0",
282 | "strip-ansi": "^6.0.0"
283 | }
284 | },
285 | "strip-ansi": {
286 | "version": "6.0.0",
287 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
288 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
289 | "dev": true,
290 | "requires": {
291 | "ansi-regex": "^5.0.0"
292 | }
293 | }
294 | }
295 | },
296 | "color-convert": {
297 | "version": "2.0.1",
298 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
299 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
300 | "dev": true,
301 | "requires": {
302 | "color-name": "~1.1.4"
303 | }
304 | },
305 | "color-name": {
306 | "version": "1.1.4",
307 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
308 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
309 | "dev": true
310 | },
311 | "concat-map": {
312 | "version": "0.0.1",
313 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
314 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
315 | "dev": true
316 | },
317 | "create-require": {
318 | "version": "1.1.1",
319 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
320 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
321 | "dev": true
322 | },
323 | "debug": {
324 | "version": "4.3.1",
325 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
326 | "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
327 | "dev": true,
328 | "requires": {
329 | "ms": "2.1.2"
330 | },
331 | "dependencies": {
332 | "ms": {
333 | "version": "2.1.2",
334 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
335 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
336 | "dev": true
337 | }
338 | }
339 | },
340 | "decamelize": {
341 | "version": "4.0.0",
342 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
343 | "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
344 | "dev": true
345 | },
346 | "deep-eql": {
347 | "version": "3.0.1",
348 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
349 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
350 | "dev": true,
351 | "requires": {
352 | "type-detect": "^4.0.0"
353 | }
354 | },
355 | "diff": {
356 | "version": "5.0.0",
357 | "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
358 | "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
359 | "dev": true
360 | },
361 | "emoji-regex": {
362 | "version": "8.0.0",
363 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
364 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
365 | "dev": true
366 | },
367 | "escalade": {
368 | "version": "3.1.1",
369 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
370 | "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
371 | "dev": true
372 | },
373 | "escape-string-regexp": {
374 | "version": "4.0.0",
375 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
376 | "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
377 | "dev": true
378 | },
379 | "find-up": {
380 | "version": "5.0.0",
381 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
382 | "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
383 | "dev": true,
384 | "requires": {
385 | "locate-path": "^6.0.0",
386 | "path-exists": "^4.0.0"
387 | }
388 | },
389 | "flat": {
390 | "version": "5.0.2",
391 | "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
392 | "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
393 | "dev": true
394 | },
395 | "fs-extra": {
396 | "version": "10.0.0",
397 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
398 | "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
399 | "dev": true,
400 | "requires": {
401 | "graceful-fs": "^4.2.0",
402 | "jsonfile": "^6.0.1",
403 | "universalify": "^2.0.0"
404 | }
405 | },
406 | "fs.realpath": {
407 | "version": "1.0.0",
408 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
409 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
410 | "dev": true
411 | },
412 | "fsevents": {
413 | "version": "2.3.2",
414 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
415 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
416 | "dev": true,
417 | "optional": true
418 | },
419 | "get-caller-file": {
420 | "version": "2.0.5",
421 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
422 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
423 | "dev": true
424 | },
425 | "get-func-name": {
426 | "version": "2.0.0",
427 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
428 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
429 | "dev": true
430 | },
431 | "glob": {
432 | "version": "7.1.6",
433 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
434 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
435 | "dev": true,
436 | "requires": {
437 | "fs.realpath": "^1.0.0",
438 | "inflight": "^1.0.4",
439 | "inherits": "2",
440 | "minimatch": "^3.0.4",
441 | "once": "^1.3.0",
442 | "path-is-absolute": "^1.0.0"
443 | }
444 | },
445 | "glob-parent": {
446 | "version": "5.1.2",
447 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
448 | "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
449 | "dev": true,
450 | "requires": {
451 | "is-glob": "^4.0.1"
452 | }
453 | },
454 | "graceful-fs": {
455 | "version": "4.2.8",
456 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
457 | "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
458 | "dev": true
459 | },
460 | "growl": {
461 | "version": "1.10.5",
462 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
463 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
464 | "dev": true
465 | },
466 | "has-flag": {
467 | "version": "4.0.0",
468 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
469 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
470 | "dev": true
471 | },
472 | "he": {
473 | "version": "1.2.0",
474 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
475 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
476 | "dev": true
477 | },
478 | "inflight": {
479 | "version": "1.0.6",
480 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
481 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
482 | "dev": true,
483 | "requires": {
484 | "once": "^1.3.0",
485 | "wrappy": "1"
486 | }
487 | },
488 | "inherits": {
489 | "version": "2.0.4",
490 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
491 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
492 | "dev": true
493 | },
494 | "is-binary-path": {
495 | "version": "2.1.0",
496 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
497 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
498 | "dev": true,
499 | "requires": {
500 | "binary-extensions": "^2.0.0"
501 | }
502 | },
503 | "is-extglob": {
504 | "version": "2.1.1",
505 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
506 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
507 | "dev": true
508 | },
509 | "is-fullwidth-code-point": {
510 | "version": "2.0.0",
511 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
512 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
513 | "dev": true
514 | },
515 | "is-glob": {
516 | "version": "4.0.1",
517 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
518 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
519 | "dev": true,
520 | "requires": {
521 | "is-extglob": "^2.1.1"
522 | }
523 | },
524 | "is-number": {
525 | "version": "7.0.0",
526 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
527 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
528 | "dev": true
529 | },
530 | "is-plain-obj": {
531 | "version": "2.1.0",
532 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
533 | "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
534 | "dev": true
535 | },
536 | "isexe": {
537 | "version": "2.0.0",
538 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
539 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
540 | "dev": true
541 | },
542 | "js-yaml": {
543 | "version": "4.0.0",
544 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz",
545 | "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==",
546 | "dev": true,
547 | "requires": {
548 | "argparse": "^2.0.1"
549 | }
550 | },
551 | "jsonfile": {
552 | "version": "6.1.0",
553 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
554 | "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
555 | "dev": true,
556 | "requires": {
557 | "graceful-fs": "^4.1.6",
558 | "universalify": "^2.0.0"
559 | }
560 | },
561 | "locate-path": {
562 | "version": "6.0.0",
563 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
564 | "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
565 | "dev": true,
566 | "requires": {
567 | "p-locate": "^5.0.0"
568 | }
569 | },
570 | "log-symbols": {
571 | "version": "4.0.0",
572 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz",
573 | "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==",
574 | "dev": true,
575 | "requires": {
576 | "chalk": "^4.0.0"
577 | }
578 | },
579 | "make-error": {
580 | "version": "1.3.6",
581 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
582 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
583 | "dev": true
584 | },
585 | "minimatch": {
586 | "version": "3.0.4",
587 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
588 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
589 | "dev": true,
590 | "requires": {
591 | "brace-expansion": "^1.1.7"
592 | }
593 | },
594 | "mocha": {
595 | "version": "8.4.0",
596 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz",
597 | "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==",
598 | "dev": true,
599 | "requires": {
600 | "@ungap/promise-all-settled": "1.1.2",
601 | "ansi-colors": "4.1.1",
602 | "browser-stdout": "1.3.1",
603 | "chokidar": "3.5.1",
604 | "debug": "4.3.1",
605 | "diff": "5.0.0",
606 | "escape-string-regexp": "4.0.0",
607 | "find-up": "5.0.0",
608 | "glob": "7.1.6",
609 | "growl": "1.10.5",
610 | "he": "1.2.0",
611 | "js-yaml": "4.0.0",
612 | "log-symbols": "4.0.0",
613 | "minimatch": "3.0.4",
614 | "ms": "2.1.3",
615 | "nanoid": "3.1.20",
616 | "serialize-javascript": "5.0.1",
617 | "strip-json-comments": "3.1.1",
618 | "supports-color": "8.1.1",
619 | "which": "2.0.2",
620 | "wide-align": "1.1.3",
621 | "workerpool": "6.1.0",
622 | "yargs": "16.2.0",
623 | "yargs-parser": "20.2.4",
624 | "yargs-unparser": "2.0.0"
625 | }
626 | },
627 | "ms": {
628 | "version": "2.1.3",
629 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
630 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
631 | "dev": true
632 | },
633 | "nanoid": {
634 | "version": "3.1.20",
635 | "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
636 | "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==",
637 | "dev": true
638 | },
639 | "normalize-path": {
640 | "version": "3.0.0",
641 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
642 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
643 | "dev": true
644 | },
645 | "once": {
646 | "version": "1.4.0",
647 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
648 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
649 | "dev": true,
650 | "requires": {
651 | "wrappy": "1"
652 | }
653 | },
654 | "p-limit": {
655 | "version": "3.1.0",
656 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
657 | "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
658 | "dev": true,
659 | "requires": {
660 | "yocto-queue": "^0.1.0"
661 | }
662 | },
663 | "p-locate": {
664 | "version": "5.0.0",
665 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
666 | "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
667 | "dev": true,
668 | "requires": {
669 | "p-limit": "^3.0.2"
670 | }
671 | },
672 | "path-exists": {
673 | "version": "4.0.0",
674 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
675 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
676 | "dev": true
677 | },
678 | "path-is-absolute": {
679 | "version": "1.0.1",
680 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
681 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
682 | "dev": true
683 | },
684 | "pathval": {
685 | "version": "1.1.1",
686 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
687 | "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
688 | "dev": true
689 | },
690 | "picomatch": {
691 | "version": "2.3.0",
692 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz",
693 | "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==",
694 | "dev": true
695 | },
696 | "randombytes": {
697 | "version": "2.1.0",
698 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
699 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
700 | "dev": true,
701 | "requires": {
702 | "safe-buffer": "^5.1.0"
703 | }
704 | },
705 | "readdirp": {
706 | "version": "3.5.0",
707 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
708 | "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
709 | "dev": true,
710 | "requires": {
711 | "picomatch": "^2.2.1"
712 | }
713 | },
714 | "require-directory": {
715 | "version": "2.1.1",
716 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
717 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
718 | "dev": true
719 | },
720 | "safe-buffer": {
721 | "version": "5.2.1",
722 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
723 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
724 | "dev": true
725 | },
726 | "serialize-javascript": {
727 | "version": "5.0.1",
728 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz",
729 | "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==",
730 | "dev": true,
731 | "requires": {
732 | "randombytes": "^2.1.0"
733 | }
734 | },
735 | "string-width": {
736 | "version": "2.1.1",
737 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
738 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
739 | "dev": true,
740 | "requires": {
741 | "is-fullwidth-code-point": "^2.0.0",
742 | "strip-ansi": "^4.0.0"
743 | }
744 | },
745 | "strip-ansi": {
746 | "version": "4.0.0",
747 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
748 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
749 | "dev": true,
750 | "requires": {
751 | "ansi-regex": "^3.0.0"
752 | }
753 | },
754 | "strip-json-comments": {
755 | "version": "3.1.1",
756 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
757 | "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
758 | "dev": true
759 | },
760 | "supports-color": {
761 | "version": "8.1.1",
762 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
763 | "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
764 | "dev": true,
765 | "requires": {
766 | "has-flag": "^4.0.0"
767 | }
768 | },
769 | "to-regex-range": {
770 | "version": "5.0.1",
771 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
772 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
773 | "dev": true,
774 | "requires": {
775 | "is-number": "^7.0.0"
776 | }
777 | },
778 | "ts-node": {
779 | "version": "10.2.1",
780 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.2.1.tgz",
781 | "integrity": "sha512-hCnyOyuGmD5wHleOQX6NIjJtYVIO8bPP8F2acWkB4W06wdlkgyvJtubO/I9NkI88hCFECbsEgoLc0VNkYmcSfw==",
782 | "dev": true,
783 | "requires": {
784 | "@cspotcode/source-map-support": "0.6.1",
785 | "@tsconfig/node10": "^1.0.7",
786 | "@tsconfig/node12": "^1.0.7",
787 | "@tsconfig/node14": "^1.0.0",
788 | "@tsconfig/node16": "^1.0.2",
789 | "acorn": "^8.4.1",
790 | "acorn-walk": "^8.1.1",
791 | "arg": "^4.1.0",
792 | "create-require": "^1.1.0",
793 | "diff": "^4.0.1",
794 | "make-error": "^1.1.1",
795 | "yn": "3.1.1"
796 | },
797 | "dependencies": {
798 | "diff": {
799 | "version": "4.0.2",
800 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
801 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
802 | "dev": true
803 | }
804 | }
805 | },
806 | "type-detect": {
807 | "version": "4.0.8",
808 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
809 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
810 | "dev": true
811 | },
812 | "typescript": {
813 | "version": "4.3.5",
814 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
815 | "integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
816 | "dev": true
817 | },
818 | "universalify": {
819 | "version": "2.0.0",
820 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
821 | "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
822 | "dev": true
823 | },
824 | "which": {
825 | "version": "2.0.2",
826 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
827 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
828 | "dev": true,
829 | "requires": {
830 | "isexe": "^2.0.0"
831 | }
832 | },
833 | "wide-align": {
834 | "version": "1.1.3",
835 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
836 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
837 | "dev": true,
838 | "requires": {
839 | "string-width": "^1.0.2 || 2"
840 | }
841 | },
842 | "workerpool": {
843 | "version": "6.1.0",
844 | "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz",
845 | "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==",
846 | "dev": true
847 | },
848 | "wrap-ansi": {
849 | "version": "7.0.0",
850 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
851 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
852 | "dev": true,
853 | "requires": {
854 | "ansi-styles": "^4.0.0",
855 | "string-width": "^4.1.0",
856 | "strip-ansi": "^6.0.0"
857 | },
858 | "dependencies": {
859 | "ansi-regex": {
860 | "version": "5.0.0",
861 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
862 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
863 | "dev": true
864 | },
865 | "is-fullwidth-code-point": {
866 | "version": "3.0.0",
867 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
868 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
869 | "dev": true
870 | },
871 | "string-width": {
872 | "version": "4.2.2",
873 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
874 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
875 | "dev": true,
876 | "requires": {
877 | "emoji-regex": "^8.0.0",
878 | "is-fullwidth-code-point": "^3.0.0",
879 | "strip-ansi": "^6.0.0"
880 | }
881 | },
882 | "strip-ansi": {
883 | "version": "6.0.0",
884 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
885 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
886 | "dev": true,
887 | "requires": {
888 | "ansi-regex": "^5.0.0"
889 | }
890 | }
891 | }
892 | },
893 | "wrappy": {
894 | "version": "1.0.2",
895 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
896 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
897 | "dev": true
898 | },
899 | "y18n": {
900 | "version": "5.0.8",
901 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
902 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
903 | "dev": true
904 | },
905 | "yargs": {
906 | "version": "16.2.0",
907 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
908 | "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
909 | "dev": true,
910 | "requires": {
911 | "cliui": "^7.0.2",
912 | "escalade": "^3.1.1",
913 | "get-caller-file": "^2.0.5",
914 | "require-directory": "^2.1.1",
915 | "string-width": "^4.2.0",
916 | "y18n": "^5.0.5",
917 | "yargs-parser": "^20.2.2"
918 | },
919 | "dependencies": {
920 | "ansi-regex": {
921 | "version": "5.0.0",
922 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
923 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
924 | "dev": true
925 | },
926 | "is-fullwidth-code-point": {
927 | "version": "3.0.0",
928 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
929 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
930 | "dev": true
931 | },
932 | "string-width": {
933 | "version": "4.2.2",
934 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz",
935 | "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==",
936 | "dev": true,
937 | "requires": {
938 | "emoji-regex": "^8.0.0",
939 | "is-fullwidth-code-point": "^3.0.0",
940 | "strip-ansi": "^6.0.0"
941 | }
942 | },
943 | "strip-ansi": {
944 | "version": "6.0.0",
945 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
946 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
947 | "dev": true,
948 | "requires": {
949 | "ansi-regex": "^5.0.0"
950 | }
951 | }
952 | }
953 | },
954 | "yargs-parser": {
955 | "version": "20.2.4",
956 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
957 | "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
958 | "dev": true
959 | },
960 | "yargs-unparser": {
961 | "version": "2.0.0",
962 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
963 | "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
964 | "dev": true,
965 | "requires": {
966 | "camelcase": "^6.0.0",
967 | "decamelize": "^4.0.0",
968 | "flat": "^5.0.2",
969 | "is-plain-obj": "^2.1.0"
970 | }
971 | },
972 | "yn": {
973 | "version": "3.1.1",
974 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
975 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
976 | "dev": true
977 | },
978 | "yocto-queue": {
979 | "version": "0.1.0",
980 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
981 | "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
982 | "dev": true
983 | }
984 | }
985 | }
986 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "node-lame",
3 | "description": "LAME MP3 encoder for Node.js",
4 | "version": "1.3.2",
5 | "homepage": "https://github.com/devowlio/node-lame",
6 | "repository": {
7 | "type": "git",
8 | "url": "git+https://github.com/devowlio/node-lame.git"
9 | },
10 | "bugs": {
11 | "url": "https://github.com/devowlio/node-lame/issues"
12 | },
13 | "author": {
14 | "name": "Jan Karres",
15 | "email": "jan.karres@devowl.io",
16 | "url": "https://jankarres.com/"
17 | },
18 | "contributors": [
19 | {
20 | "name": "devowl.io GmbH",
21 | "email": "mail@devowl.io"
22 | }
23 | ],
24 | "keywords": [
25 | "mp3",
26 | "wav",
27 | "LAME",
28 | "MPEG-1",
29 | "MPEG-2",
30 | "encoder",
31 | "audio"
32 | ],
33 | "license": "ISC",
34 | "engines": {
35 | "node": ">=12.20"
36 | },
37 | "scripts": {
38 | "build": "tsc",
39 | "test": "./node_modules/.bin/mocha"
40 | },
41 | "files": [
42 | "lib/build/",
43 | "temp/",
44 | "index.js",
45 | "index.d.ts",
46 | "README.md"
47 | ],
48 | "dependencies": {},
49 | "devDependencies": {
50 | "@types/chai": "~4.2.21",
51 | "@types/fs-extra": "~9.0.12",
52 | "@types/mocha": "~8.2.1",
53 | "@types/node": "^14.10.1",
54 | "chai": "~4.3.4",
55 | "fs-extra": "~10.0.0",
56 | "mocha": "~8.4.0",
57 | "ts-node": "~10.2.1",
58 | "typescript": "~4.3.5"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/temp/encoded/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devowlio/node-lame/66ba6bd82f7dddabce1a26bad40a48bf61433940/temp/encoded/.keep
--------------------------------------------------------------------------------
/temp/raw/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devowlio/node-lame/66ba6bd82f7dddabce1a26bad40a48bf61433940/temp/raw/.keep
--------------------------------------------------------------------------------
/test/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devowlio/node-lame/66ba6bd82f7dddabce1a26bad40a48bf61433940/test/.keep
--------------------------------------------------------------------------------
/test/example.mp3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devowlio/node-lame/66ba6bd82f7dddabce1a26bad40a48bf61433940/test/example.mp3
--------------------------------------------------------------------------------
/test/example.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devowlio/node-lame/66ba6bd82f7dddabce1a26bad40a48bf61433940/test/example.wav
--------------------------------------------------------------------------------
/test/example.wav_LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal (CC0 1.0), Public Domain Dedication
2 | See: https://creativecommons.org/publicdomain/zero/1.0/
3 |
4 | Original file "Music Box.wav" by VSokorelos
5 |
6 | Source: https://www.freesound.org/people/VSokorelos/sounds/344219/
--------------------------------------------------------------------------------
/test/notAWavFile.wav:
--------------------------------------------------------------------------------
1 | not a wav file
2 |
--------------------------------------------------------------------------------
/test/notAnMp3File.mp3:
--------------------------------------------------------------------------------
1 | not an mp3 file
2 |
--------------------------------------------------------------------------------
/test/testpic.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devowlio/node-lame/66ba6bd82f7dddabce1a26bad40a48bf61433940/test/testpic.jpg
--------------------------------------------------------------------------------
/test/tests.js:
--------------------------------------------------------------------------------
1 | const testCase = require("mocha").describe;
2 | const assertions = require("mocha").it;
3 | const assert = require("chai").assert;
4 | const fs = require("fs");
5 | const fsp = require("fs-extra");
6 |
7 | const Lame = require("../index").Lame;
8 |
9 | testCase("Lame class", () => {
10 | const TEST_FILE_DURATION = 12; // Audio duration of the TEST_FILE in seconds
11 | const RESULT_DURATION_TOLERANCE = 1; // Max difference between TEST_FILE duration and converted file duration in seconds
12 | const EXPECTED_WAV_SIZE = 2142500; // Size of an correctly converted wav file in bytes
13 | const WAV_SIZE_TOLERANCE = 500; // Max difference between EXPECTED_WAV_SIZE and the actual size of the converted file
14 |
15 | testCase("Encode to .mp3", () => {
16 | const TEST_FILE = "./test/example.wav";
17 | const OUTPUT_FILE = "./test/encoded.mp3";
18 |
19 | /**
20 | * @testname Set invalid wav file
21 | * Try to convert a .wav file that contains invalid audio data
22 | */
23 | assertions("Set invalid wav file", () => {
24 | let errorCaught = false;
25 | const targetBitrate = 128;
26 |
27 | const instance = new Lame({
28 | output: OUTPUT_FILE,
29 | bitrate: targetBitrate
30 | });
31 |
32 | instance.setFile("./test/notAWavFile.wav");
33 |
34 | return instance.encode().catch(error => {
35 | errorCaught = true;
36 |
37 | const expected =
38 | "lame: Warning: unsupported audio format\nCan't init infile './test/notAWavFile.wav'";
39 | const actual = error.message;
40 |
41 | assert.equal(actual, expected);
42 | assert.isTrue(errorCaught);
43 | });
44 | });
45 |
46 | /**
47 | * @testname Encode file to file
48 | * Convert a .wav file to a .mp3 file
49 | */
50 | assertions("Encode file to file", () => {
51 | const targetBitrate = 128;
52 |
53 | const instance = new Lame({
54 | output: OUTPUT_FILE,
55 | bitrate: targetBitrate
56 | });
57 |
58 | instance.setFile(TEST_FILE);
59 |
60 | return instance.encode().then(() => {
61 | // Test expected file duration
62 | return fsp.stat(OUTPUT_FILE).then(stats => {
63 | const size = stats.size;
64 | const resultDuration = (size * 8) / (targetBitrate * 1000);
65 | fs.unlinkSync(OUTPUT_FILE);
66 |
67 | const isDurationWithinTolerance =
68 | TEST_FILE_DURATION - resultDuration <
69 | RESULT_DURATION_TOLERANCE &&
70 | TEST_FILE_DURATION - resultDuration >
71 | -1 * RESULT_DURATION_TOLERANCE;
72 | assert.isTrue(isDurationWithinTolerance);
73 | });
74 | });
75 | });
76 |
77 | /**
78 | * @testname Encode file to buffer
79 | * Convert a .wav file to a buffer
80 | */
81 | assertions("Encode file to buffer", () => {
82 | const targetBitrate = 128;
83 | const output = "buffer";
84 |
85 | const instance = new Lame({
86 | output: output,
87 | bitrate: targetBitrate
88 | });
89 |
90 | instance.setFile(TEST_FILE);
91 |
92 | return instance.encode().then(() => {
93 | // Test expected file duration
94 | const buffer = instance.getBuffer();
95 |
96 | const size = buffer.byteLength;
97 | resultDuration = (size * 8) / (targetBitrate * 1000);
98 |
99 | const isDurationWithinTolerance =
100 | TEST_FILE_DURATION - resultDuration <
101 | RESULT_DURATION_TOLERANCE &&
102 | TEST_FILE_DURATION - resultDuration >
103 | -1 * RESULT_DURATION_TOLERANCE;
104 | assert(isDurationWithinTolerance);
105 | });
106 | });
107 |
108 | /**
109 | * @testname Encode buffer to file
110 | * Read a .wav file into a buffer. Then convert the buffer to a .mp3 file.
111 | */
112 | assertions("Encode buffer to file", () => {
113 | const targetBitrate = 128;
114 |
115 | return fsp.readFile(TEST_FILE).then(inputBuffer => {
116 | const instance = new Lame({
117 | output: OUTPUT_FILE,
118 | bitrate: targetBitrate
119 | });
120 |
121 | instance.setBuffer(inputBuffer);
122 |
123 | return instance.encode().then(() => {
124 | // Test expected file duration
125 | return fsp.stat(OUTPUT_FILE).then(stats => {
126 | const size = stats.size;
127 | const resultDuration =
128 | (size * 8) / (targetBitrate * 1000);
129 | fs.unlinkSync(OUTPUT_FILE);
130 |
131 | const isDurationWithinTolerance =
132 | TEST_FILE_DURATION - resultDuration <
133 | RESULT_DURATION_TOLERANCE &&
134 | TEST_FILE_DURATION - resultDuration >
135 | -1 * RESULT_DURATION_TOLERANCE;
136 | assert.isTrue(isDurationWithinTolerance);
137 | });
138 | });
139 | });
140 | });
141 |
142 | /**
143 | * @testname Encode buffer to buffer
144 | * Read a .wav file into a buffer. Then convert the buffer to a buffer containing .mp3 data.
145 | */
146 | assertions("Encode buffer to buffer", () => {
147 | const targetBitrate = 128;
148 |
149 | return fsp.readFile(TEST_FILE).then(inputBuffer => {
150 | const instance = new Lame({
151 | output: "buffer",
152 | bitrate: targetBitrate
153 | });
154 | instance.setBuffer(inputBuffer);
155 |
156 | return instance.encode().then(() => {
157 | // Test expected file duration
158 | const buffer = instance.getBuffer();
159 |
160 | const size = buffer.byteLength;
161 | const resultDuration = (size * 8) / (targetBitrate * 1000);
162 |
163 | const isDurationWithinTolerance =
164 | TEST_FILE_DURATION - resultDuration <
165 | RESULT_DURATION_TOLERANCE &&
166 | TEST_FILE_DURATION - resultDuration >
167 | -1 * RESULT_DURATION_TOLERANCE;
168 | assert.isTrue(isDurationWithinTolerance);
169 | });
170 | });
171 | });
172 | });
173 |
174 | testCase("Decode to .wav", () => {
175 | const TEST_FILE = "./test/example.mp3";
176 | const OUTPUT_FILE = "./test/converted.wav";
177 |
178 | /**
179 | * @testname Set invalid wav file
180 | * Try to convert a .mp3 file that contains invalid audio data
181 | */
182 | assertions("Set invalid mp3 file", () => {
183 | let errorCaught = false;
184 | const targetBitrate = 128;
185 |
186 | const instance = new Lame({
187 | output: OUTPUT_FILE,
188 | bitrate: targetBitrate
189 | });
190 |
191 | instance.setFile("./test/notAnMp3File.mp3");
192 |
193 | return instance.decode().catch(error => {
194 | errorCaught = true;
195 |
196 | const expected =
197 | "lame: Error reading headers in mp3 input file ./test/notAnMp3File.mp3.\nCan't init infile './test/notAnMp3File.mp3'";
198 | const actual = error.message;
199 |
200 | assert.equal(actual, expected);
201 | assert.isTrue(errorCaught);
202 | });
203 | });
204 |
205 | /**
206 | * @testname Decode file to file
207 | * Convert a .mp3 file to a .wav file
208 | */
209 | assertions("Decode file to file", () => {
210 | const targetBitrate = 128;
211 |
212 | const instance = new Lame({
213 | output: OUTPUT_FILE,
214 | bitrate: targetBitrate
215 | });
216 |
217 | instance.setFile(TEST_FILE);
218 |
219 | return instance.decode().then(() => {
220 | // Test expected file size
221 | return fsp.stat(OUTPUT_FILE).then(stats => {
222 | fs.unlinkSync(OUTPUT_FILE);
223 |
224 | const actualSize = stats.size;
225 | const isSizeWithinTolerance =
226 | EXPECTED_WAV_SIZE - actualSize < WAV_SIZE_TOLERANCE &&
227 | EXPECTED_WAV_SIZE - actualSize >
228 | -1 * WAV_SIZE_TOLERANCE;
229 | assert.isTrue(isSizeWithinTolerance);
230 | });
231 | });
232 | });
233 |
234 | /**
235 | * @testname Decode file to buffer
236 | * Convert a .mp3 file to a buffer
237 | */
238 | assertions("Decode file to buffer", () => {
239 | const targetBitrate = 128;
240 | const output = "buffer";
241 |
242 | const instance = new Lame({
243 | output: output,
244 | bitrate: targetBitrate
245 | });
246 |
247 | instance.setFile(TEST_FILE);
248 |
249 | return instance.decode().then(() => {
250 | // Test expected file size
251 | const buffer = instance.getBuffer();
252 |
253 | const actualSize = buffer.byteLength;
254 | const isSizeWithinTolerance =
255 | EXPECTED_WAV_SIZE - actualSize < WAV_SIZE_TOLERANCE &&
256 | EXPECTED_WAV_SIZE - actualSize > -1 * WAV_SIZE_TOLERANCE;
257 | assert.isTrue(isSizeWithinTolerance);
258 | });
259 | });
260 |
261 | /**
262 | * @testname Decode buffer to file
263 | * Read a .mp3 file into a buffer. Then convert the buffer to a .wav file.
264 | */
265 | assertions("Decode buffer to file", () => {
266 | const targetBitrate = 128;
267 |
268 | return fsp.readFile(TEST_FILE).then(inputBuffer => {
269 | const instance = new Lame({
270 | output: OUTPUT_FILE,
271 | bitrate: targetBitrate
272 | });
273 |
274 | instance.setBuffer(inputBuffer);
275 |
276 | return instance.decode().then(() => {
277 | // Test expected file size
278 | return fsp.stat(OUTPUT_FILE).then(stats => {
279 | fs.unlinkSync(OUTPUT_FILE);
280 |
281 | const actualSize = stats.size;
282 | const isSizeWithinTolerance =
283 | EXPECTED_WAV_SIZE - actualSize <
284 | WAV_SIZE_TOLERANCE &&
285 | EXPECTED_WAV_SIZE - actualSize >
286 | -1 * WAV_SIZE_TOLERANCE;
287 | assert.isTrue(isSizeWithinTolerance);
288 | });
289 | });
290 | });
291 | });
292 |
293 | /**
294 | * @testname Decode buffer to buffer
295 | * Read a .mp3 file into a buffer. Then convert the buffer to a buffer containing .wav data.
296 | */
297 | assertions("Decode buffer to buffer", () => {
298 | const targetBitrate = 128;
299 |
300 | return fsp.readFile(TEST_FILE).then(inputBuffer => {
301 | const instance = new Lame({
302 | output: "buffer",
303 | bitrate: targetBitrate
304 | });
305 | instance.setBuffer(inputBuffer);
306 |
307 | return instance.decode().then(() => {
308 | // Test expected file size
309 | const buffer = instance.getBuffer();
310 |
311 | const actualSize = buffer.byteLength;
312 | const isSizeWithinTolerance =
313 | EXPECTED_WAV_SIZE - actualSize < WAV_SIZE_TOLERANCE &&
314 | EXPECTED_WAV_SIZE - actualSize >
315 | -1 * WAV_SIZE_TOLERANCE;
316 | assert.isTrue(isSizeWithinTolerance);
317 | });
318 | });
319 | });
320 | });
321 |
322 | testCase("Other", () => {
323 | const TEST_FILE = "./test/example.wav";
324 | const OUTPUT_FILE = "./test/encoded.mp3";
325 |
326 |
327 | /**
328 | * @testname Encode empty buffer to not existing path
329 | */
330 | assertions("Encode empty buffer to not existing path", () => {
331 | let errorCaught = false;
332 | const invalidBuffer = Buffer.alloc(100, 0x00);
333 |
334 | const instance = new Lame({
335 | raw: true,
336 | output: "DOES_NOT_EXIST/output.mp3"
337 | });
338 |
339 | instance.setBuffer(invalidBuffer);
340 |
341 | return instance.encode().catch(error => {
342 | errorCaught = true;
343 | })
344 | .finally(() => {
345 | assert.isTrue(errorCaught);
346 | });
347 | });
348 |
349 | /**
350 | * @testname Option output required
351 | * Call Lame constructor with empty options object
352 | */
353 | assertions("Option output required", () => {
354 | let errorCaught = false;
355 |
356 | try {
357 | const instance = new Lame({});
358 | } catch (error) {
359 | errorCaught = true;
360 | const expected = "lame: Invalid option: 'output' is required";
361 | const actual = error.message;
362 |
363 | assert.equal(actual, expected);
364 | }
365 |
366 | assert.isTrue(errorCaught);
367 | });
368 |
369 | /**
370 | * @testname Option bitrate is required
371 | * Call Lame constructor with no bitrate specified in options object
372 | */
373 | assertions("Option bitrate is required", () => {
374 | let errorCaught = false;
375 |
376 | const instance = new Lame({
377 | output: OUTPUT_FILE
378 | });
379 |
380 | instance.setFile("./test/notAWavFile.wav");
381 |
382 | return instance.encode().catch(error => {
383 | errorCaught = true;
384 |
385 | const expected =
386 | "lame: Warning: unsupported audio format\nCan't init infile './test/notAWavFile.wav'";
387 | const actual = error.message;
388 |
389 | assert.equal(actual, expected);
390 | assert.isTrue(errorCaught);
391 | });
392 | });
393 |
394 | /**
395 | * @testname Set not existing file
396 | * Try to convert not existing file
397 | */
398 | assertions("Set not existing file", () => {
399 | let errorCaught = false;
400 |
401 | try {
402 | const instance = new Lame({
403 | output: OUTPUT_FILE
404 | });
405 |
406 | instance.setFile("./test/not-existing.wav");
407 | } catch (error) {
408 | errorCaught = true;
409 |
410 | const expected = "Audio file (path) does not exist";
411 | const actual = error.message;
412 |
413 | assert.equal(actual, expected);
414 | }
415 |
416 | assert.isTrue(errorCaught);
417 | });
418 |
419 | /**
420 | * @testname Get status object before start
421 | * Setup the converter properly, then read the status object without calling the encode function.
422 | */
423 | assertions("Get status object before start", () => {
424 | const targetBitrate = 128;
425 |
426 | const instance = new Lame({
427 | output: OUTPUT_FILE,
428 | bitrate: targetBitrate
429 | });
430 |
431 | instance.setFile(TEST_FILE);
432 |
433 | const actual = instance.getStatus();
434 |
435 | const expected = {
436 | started: false,
437 | finished: false,
438 | progress: undefined,
439 | eta: undefined
440 | };
441 |
442 | assert.deepEqual(actual, expected);
443 | });
444 |
445 | /**
446 | * @testname Get status object during converting
447 | * Setup the converter properly, call the encode function and immediately read the status object.
448 | */
449 | assertions("Get status object during converting", () => {
450 | const targetBitrate = 128;
451 |
452 | const instance = new Lame({
453 | output: OUTPUT_FILE,
454 | bitrate: targetBitrate
455 | });
456 |
457 | instance.setFile(TEST_FILE);
458 | const emitter = instance.getEmitter();
459 |
460 | instance.encode().then(() => {
461 | fs.unlinkSync(OUTPUT_FILE);
462 | });
463 |
464 | const actual = instance.getStatus();
465 | const expected = {
466 | started: true,
467 | finished: false,
468 | progress: 0,
469 | eta: undefined
470 | };
471 |
472 | assert.deepEqual(actual, expected);
473 |
474 | // Ensure next test will executed after finishing encoding
475 | return new Promise(resolve => {
476 | emitter.on("finish", resolve);
477 | });
478 | });
479 |
480 | /**
481 | * @testname Get status object after converting
482 | * Setup the converter properly, call the encode function and read the status object afterwards.
483 | */
484 | assertions("Get status object after converting", () => {
485 | const targetBitrate = 128;
486 |
487 | const instance = new Lame({
488 | output: OUTPUT_FILE,
489 | bitrate: targetBitrate
490 | });
491 |
492 | instance.setFile(TEST_FILE);
493 |
494 | return instance.encode().then(() => {
495 | const actual = instance.getStatus();
496 |
497 | const expected = {
498 | started: true,
499 | finished: true,
500 | progress: 100,
501 | eta: "00:00"
502 | };
503 |
504 | fs.unlinkSync(OUTPUT_FILE);
505 | assert.deepEqual(actual, expected);
506 | });
507 | });
508 |
509 | /**
510 | * @testname Get status eventEmitter successful converting
511 | * Setup the converter properly, call the encode function and check if progress and finish were emitted.
512 | */
513 | assertions("Get status eventEmitter successful converting", () => {
514 | const targetBitrate = 128;
515 |
516 | const instance = new Lame({
517 | output: OUTPUT_FILE,
518 | bitrate: targetBitrate
519 | });
520 |
521 | instance.setFile(TEST_FILE);
522 |
523 | const emitter = instance.getEmitter();
524 |
525 | let progressTriggered = false;
526 | let finishTriggered = false;
527 |
528 | emitter.on("progress", () => {
529 | progressTriggered = true;
530 | });
531 |
532 | emitter.on("finish", () => {
533 | finishTriggered = true;
534 |
535 | fs.unlinkSync(OUTPUT_FILE);
536 | });
537 |
538 | emitter.on("error", error => {
539 | assert.isTrue(false);
540 | });
541 |
542 | return instance.encode().then(() => {
543 | // error expected is irrelevant for this test
544 | assert.isTrue(progressTriggered);
545 | assert.isTrue(finishTriggered);
546 | });
547 | });
548 |
549 | /**
550 | * @testname Get status eventEmitter unsuccessful converting
551 | * Setup the converter with invalid source file, call the encode function and check if an error is emitted.
552 | */
553 | assertions("Get status eventEmitter unsuccessful converting", () => {
554 | const targetBitrate = 128;
555 |
556 | const instance = new Lame({
557 | output: OUTPUT_FILE,
558 | bitrate: targetBitrate
559 | });
560 |
561 | instance.setFile("./test/notAWavFile.wav");
562 |
563 | const emitter = instance.getEmitter();
564 |
565 | let errorTriggered = false;
566 |
567 | emitter.on("error", error => {
568 | errorTriggered = true;
569 | });
570 |
571 | return instance.encode().catch(() => {
572 | return new Promise(resolve => {
573 | setTimeout(() => {
574 | assert.isTrue(errorTriggered);
575 |
576 | resolve();
577 | }, 500);
578 | });
579 | });
580 | });
581 |
582 | /**
583 | * @testname Options
584 | * Specify optional Options and check if they are set in the options object.
585 | */
586 | assertions("Options", () => {
587 | const instance = new Lame({
588 | output: OUTPUT_FILE,
589 | bitrate: 128,
590 | raw: true,
591 | "swap-bytes": true,
592 | sfreq: 22.05,
593 | bitwidth: 32,
594 | signed: true,
595 | unsigned: true,
596 | "little-endian": true,
597 | "big-endian": true,
598 | mp2Input: true,
599 | mp3Input: true,
600 | mode: "r",
601 | "to-mono": true,
602 | "channel-different-block-sizes": true,
603 | freeformat: "FreeAmp",
604 | "disable-info-tag": true,
605 | comp: 5,
606 | scale: 2,
607 | "scale-l": 1,
608 | "scale-r": 3,
609 | "replaygain-fast": true,
610 | "replaygain-accurate": true,
611 | "no-replaygain": true,
612 | "clip-detect": true,
613 | preset: "medium",
614 | noasm: "sse",
615 | quality: 3,
616 | "force-bitrate": true,
617 | cbr: true,
618 | abr: 45,
619 | vbr: true,
620 | "vbr-quality": 6,
621 | "ignore-noise-in-sfb21": true,
622 | emp: "5",
623 | "mark-as-copyrighted": true,
624 | "mark-as-copy": true,
625 | "crc-error-protection": true,
626 | nores: true,
627 | "strictly-enforce-ISO": true,
628 | lowpass: 55,
629 | "lowpass-width": 9,
630 | highpass: 400,
631 | "highpass-width": 4,
632 | resample: 44.1,
633 | meta: {
634 | title: "test title",
635 | artist: "test artist",
636 | album: "test album",
637 | year: "2017",
638 | comment: "test comment",
639 | track: "3",
640 | genre: "test genre",
641 | artwork: "testpic.jpg",
642 | "add-id3v2": true,
643 | "id3v1-only": true,
644 | "id3v2-only": true,
645 | "id3v2-latin1": true,
646 | "id3v2-utf16": true,
647 | "space-id3v1": true,
648 | "pad-id3v2": true,
649 | "pad-id3v2-size": 2,
650 | "ignore-tag-errors": true,
651 | "genre-list": "test, genres"
652 | }
653 | });
654 | instance.setFile(TEST_FILE);
655 |
656 | expected = [
657 | "-b",
658 | 128,
659 | "-r",
660 | "-x",
661 | "-s",
662 | 22.05,
663 | "--bitwidth",
664 | 32,
665 | "--signed",
666 | "--unsigned",
667 | "--little-endian",
668 | "--big-endian",
669 | "--mp2input",
670 | "--mp3input",
671 | "-m",
672 | "r",
673 | "-a",
674 | "-d",
675 | "--freeformat",
676 | "FreeAmp",
677 | "-t",
678 | "--comp",
679 | 5,
680 | "--scale",
681 | 2,
682 | "--scale-l",
683 | 1,
684 | "--scale-r",
685 | 3,
686 | "--replaygain-fast",
687 | "--replaygain-accurate",
688 | "--noreplaygain",
689 | "--clipdetect",
690 | "--preset",
691 | "medium",
692 | "--noasm",
693 | "sse",
694 | "-q",
695 | 3,
696 | "-F",
697 | "--cbr",
698 | "--abr",
699 | 45,
700 | "-v",
701 | "-V",
702 | 6,
703 | "-Y",
704 | "-e",
705 | "5",
706 | "-c",
707 | "-o",
708 | "-p",
709 | "--nores",
710 | "--strictly-enforce-ISO",
711 | "--lowpass",
712 | 55,
713 | "--lowpass-width",
714 | 9,
715 | "--highpass",
716 | 400,
717 | "--highpass-width",
718 | 4,
719 | "--resample",
720 | 44.1,
721 | "--tt",
722 | "test title",
723 | "--ta",
724 | "test artist",
725 | "--tl",
726 | "test album",
727 | "--ty",
728 | "2017",
729 | "--tc",
730 | "test comment",
731 | "--tn",
732 | "3",
733 | "--tg",
734 | "test genre",
735 | "--ti",
736 | "testpic.jpg",
737 | "--add-id3v2",
738 | "--id3v1-only",
739 | "--id3v2-only",
740 | "--id3v2-latin1",
741 | "--id3v2-utf16",
742 | "--space-id3v1",
743 | "--pad-id3v2",
744 | "--pad-id3v2-size",
745 | "2",
746 | "--ignore-tag-errors",
747 | "--genre-list",
748 | "test, genres"
749 | ];
750 |
751 | const actual = instance.args;
752 | assert.deepEqual(expected, actual);
753 | });
754 | });
755 | });
756 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "module": "commonjs",
5 | "jsx": "preserve",
6 | "outDir": "lib/build/",
7 | "sourceMap": true,
8 | "removeComments": false,
9 | "alwaysStrict": true,
10 | "noImplicitAny": false,
11 | "noImplicitReturns": false
12 | },
13 | "include": ["lib/src/*.ts"],
14 | "formatCodeOptions": {
15 | "indentSize": 5,
16 | "tabSize": 5,
17 | "newLineCharacter": "\r\n",
18 | "convertTabsToSpaces": false,
19 | "insertSpaceAfterCommaDelimiter": true,
20 | "insertSpaceAfterSemicolonInForStatements": true,
21 | "insertSpaceBeforeAndAfterBinaryOperators": true,
22 | "insertSpaceAfterKeywordsInControlFlowStatements": true,
23 | "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false,
24 | "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false,
25 | "placeOpenBraceOnNewLineForFunctions": false,
26 | "placeOpenBraceOnNewLineForControlBlocks": false
27 | },
28 | "compileOnSave": true,
29 | "buildOnSave": false
30 | }
31 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "defaultSeverity": "error",
3 | "extends": [
4 | "tslint:recommended",
5 | "tslint-config-airbnb",
6 | "tslint-config-prettier"
7 | ],
8 | "jsRules": {
9 | "indent": [true, "spaces", 4]
10 | },
11 | "rules": {
12 | "indent": [true, "spaces", 4]
13 | },
14 | "rulesDirectory": []
15 | }
16 |
--------------------------------------------------------------------------------