nodejs-audio-visualizer 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.js +31 -15
- package/dist/config.js.map +1 -1
- package/dist/image.d.ts +27 -2
- package/dist/image.js +72 -19
- package/dist/image.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/config.ts +39 -13
- package/src/image.ts +130 -25
- package/src/index.ts +16 -8
- package/src/tests/config.test.ts +60 -0
- package/src/tests/image.test.ts +80 -18
- package/src/tests/snapshots/frameSnapshotSpectrumUpOpacity50.json +1 -0
package/src/image.ts
CHANGED
|
@@ -18,31 +18,94 @@ interface Size {
|
|
|
18
18
|
height: number;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
interface MixColorProps {
|
|
22
|
+
color: Color;
|
|
23
|
+
colorOpacity: number;
|
|
24
|
+
backgroundColor: Color;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const mixValues =(value1: number, value1Opacity: number, value2: number) =>
|
|
28
|
+
Math.round(value2 * (1 - value1Opacity) + value1 * value1Opacity);
|
|
29
|
+
|
|
30
|
+
export const mixColors = ({
|
|
31
|
+
color,
|
|
32
|
+
colorOpacity,
|
|
33
|
+
backgroundColor,
|
|
34
|
+
}: MixColorProps): Color => {
|
|
35
|
+
return {
|
|
36
|
+
red: mixValues(color.red, colorOpacity, backgroundColor.red),
|
|
37
|
+
green: mixValues(color.green, colorOpacity, backgroundColor.green),
|
|
38
|
+
blue: mixValues(color.blue, colorOpacity, backgroundColor.blue),
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
interface DrawRectPorps {
|
|
43
|
+
imageDstBuffer: BmpDecoder;
|
|
44
|
+
position: Position;
|
|
45
|
+
size: Size;
|
|
46
|
+
color: Color;
|
|
47
|
+
opacity: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export const drawRect = ({
|
|
51
|
+
imageDstBuffer,
|
|
52
|
+
position,
|
|
53
|
+
size,
|
|
54
|
+
color,
|
|
55
|
+
opacity,
|
|
56
|
+
}: DrawRectPorps) => {
|
|
22
57
|
for (var currY = position.y; currY < position.y + size.height; currY++) {
|
|
23
58
|
for (var currX = position.x; currX < position.x + size.width; currX++) {
|
|
24
59
|
var idx = (imageDstBuffer.width * currY + currX) << 2;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
60
|
+
if (opacity === 1) {
|
|
61
|
+
imageDstBuffer.data[idx + 1] = color.blue;
|
|
62
|
+
imageDstBuffer.data[idx + 2] = color.green;
|
|
63
|
+
imageDstBuffer.data[idx + 3] = color.red;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const backgroundPixelColor: Color = {
|
|
68
|
+
red: imageDstBuffer.data[idx + 3],
|
|
69
|
+
green: imageDstBuffer.data[idx + 2],
|
|
70
|
+
blue: imageDstBuffer.data[idx + 1],
|
|
71
|
+
};
|
|
72
|
+
const resultColor = mixColors({
|
|
73
|
+
color,
|
|
74
|
+
colorOpacity: opacity,
|
|
75
|
+
backgroundColor: backgroundPixelColor,
|
|
76
|
+
});
|
|
77
|
+
imageDstBuffer.data[idx + 1] = resultColor.blue;
|
|
78
|
+
imageDstBuffer.data[idx + 2] = resultColor.green;
|
|
79
|
+
imageDstBuffer.data[idx + 3] = resultColor.red;
|
|
29
80
|
}
|
|
30
81
|
}
|
|
31
82
|
};
|
|
32
83
|
|
|
33
|
-
|
|
34
|
-
imageDstBuffer: BmpDecoder
|
|
35
|
-
spectrum: number[]
|
|
36
|
-
size: Size
|
|
37
|
-
position: Position
|
|
38
|
-
rotation: RotationAliasName
|
|
39
|
-
|
|
40
|
-
|
|
84
|
+
interface DrawSpectrumProps {
|
|
85
|
+
imageDstBuffer: BmpDecoder;
|
|
86
|
+
spectrum: number[];
|
|
87
|
+
size: Size;
|
|
88
|
+
position: Position;
|
|
89
|
+
rotation: RotationAliasName;
|
|
90
|
+
margin: number;
|
|
91
|
+
color: Color;
|
|
92
|
+
opacity: number;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const drawSpectrum = ({
|
|
96
|
+
imageDstBuffer,
|
|
97
|
+
spectrum,
|
|
98
|
+
size,
|
|
99
|
+
position,
|
|
100
|
+
rotation,
|
|
101
|
+
margin,
|
|
102
|
+
color,
|
|
103
|
+
opacity,
|
|
104
|
+
}: DrawSpectrumProps) => {
|
|
41
105
|
const busWidth = Math.trunc(size.width / spectrum.length);
|
|
42
106
|
const left = Math.trunc(position.x);
|
|
43
107
|
const top = Math.trunc(position.y);
|
|
44
108
|
const height = Math.trunc(size.height);
|
|
45
|
-
const margin = 4;
|
|
46
109
|
|
|
47
110
|
for (let spectrumX = 0; spectrumX < spectrum.length; spectrumX++) {
|
|
48
111
|
const spectrumValue = spectrum[spectrumX];
|
|
@@ -53,24 +116,66 @@ const drawSpectrum = (
|
|
|
53
116
|
const rectX = left + busWidth * spectrumX;
|
|
54
117
|
const rectHeight = Math.trunc(height * spectrumValue);
|
|
55
118
|
const rectY = (rotation === 'up') ? top + height - rectHeight : top;
|
|
56
|
-
drawRect(
|
|
119
|
+
drawRect({
|
|
120
|
+
imageDstBuffer,
|
|
121
|
+
position: { x: rectX + margin, y: rectY },
|
|
122
|
+
size: { width: busWidth - margin / 2, height: rectHeight },
|
|
123
|
+
color,
|
|
124
|
+
opacity,
|
|
125
|
+
});
|
|
57
126
|
}
|
|
58
127
|
};
|
|
59
128
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
129
|
+
interface CreateVisualizerFrameProps {
|
|
130
|
+
backgroundImageBuffer: BmpDecoder;
|
|
131
|
+
spectrum: number[];
|
|
132
|
+
size: Size;
|
|
133
|
+
position: Position;
|
|
134
|
+
rotation: RotationAliasName;
|
|
135
|
+
margin: number;
|
|
136
|
+
color: Color | string;
|
|
137
|
+
opacity: number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export const createVisualizerFrame = ({
|
|
141
|
+
backgroundImageBuffer,
|
|
142
|
+
spectrum,
|
|
143
|
+
size,
|
|
144
|
+
position,
|
|
145
|
+
rotation,
|
|
146
|
+
margin,
|
|
147
|
+
color,
|
|
148
|
+
opacity,
|
|
149
|
+
}: CreateVisualizerFrameProps) => {
|
|
150
|
+
const imageDstBuffer = Object.assign({}, backgroundImageBuffer);
|
|
151
|
+
imageDstBuffer.data = Buffer.from(imageDstBuffer.data);
|
|
63
152
|
const rgbSpectrumColor = (typeof color === 'string') ? hexToRgb(color) : color;
|
|
64
|
-
drawSpectrum(
|
|
65
|
-
|
|
153
|
+
drawSpectrum({
|
|
154
|
+
imageDstBuffer,
|
|
155
|
+
spectrum,
|
|
156
|
+
size,
|
|
157
|
+
position,
|
|
158
|
+
rotation,
|
|
159
|
+
margin,
|
|
160
|
+
color: rgbSpectrumColor,
|
|
161
|
+
opacity,
|
|
162
|
+
});
|
|
163
|
+
return imageDstBuffer;
|
|
66
164
|
};
|
|
67
165
|
|
|
68
166
|
export const convertToBmp = async (filePath: string) =>
|
|
69
|
-
new Promise<Buffer>(async resolve => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
167
|
+
new Promise<Buffer>(async (resolve, reject) => {
|
|
168
|
+
try {
|
|
169
|
+
const image = await Jimp.read(filePath);
|
|
170
|
+
image.getBuffer("image/bmp", (err, value) => {
|
|
171
|
+
if (err) {
|
|
172
|
+
reject(err);
|
|
173
|
+
}
|
|
174
|
+
resolve(value);
|
|
175
|
+
});
|
|
176
|
+
} catch {
|
|
177
|
+
throw new Error(`Cannot procces image file from path: ${filePath}`);
|
|
178
|
+
}
|
|
74
179
|
});
|
|
75
180
|
|
|
76
181
|
export const parseImage = (buffer: Buffer) => decode(buffer);
|
package/src/index.ts
CHANGED
|
@@ -3,11 +3,14 @@ import {
|
|
|
3
3
|
getBackgroundImagePath,
|
|
4
4
|
getOutVideoPath,
|
|
5
5
|
getFPS,
|
|
6
|
+
getSpectrumBusesCount,
|
|
7
|
+
getSpectrumBusMargin,
|
|
6
8
|
getSpectrumWidthAbsolute,
|
|
7
9
|
getSpectrumHeightAbsolute,
|
|
8
10
|
getSpectrumXAbsolute,
|
|
9
11
|
getSpectrumYAbsolute,
|
|
10
12
|
getSpectrumColor,
|
|
13
|
+
getSpectrumOpacityParsed,
|
|
11
14
|
getFfmpeg_cfr,
|
|
12
15
|
getFfmpeg_preset,
|
|
13
16
|
getFrame_processing_delay,
|
|
@@ -42,6 +45,7 @@ export interface Config {
|
|
|
42
45
|
y?: number | PositionAliasName;
|
|
43
46
|
rotation?: RotationAliasName;
|
|
44
47
|
color?: Color | string;
|
|
48
|
+
opacity?: string;
|
|
45
49
|
}
|
|
46
50
|
};
|
|
47
51
|
tweaks?: {
|
|
@@ -81,6 +85,8 @@ export const renderAudioVisualizer = (config: Config, onProgress?: (progress: nu
|
|
|
81
85
|
throw new Error('ffmpeg didn\'t show audio sample rate');
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
const spectrumBusesCount = getSpectrumBusesCount();
|
|
89
|
+
const spectrumBusMargin = getSpectrumBusMargin();
|
|
84
90
|
const FPS = getFPS(config);
|
|
85
91
|
const spectrumWidth =
|
|
86
92
|
getSpectrumWidthAbsolute(config, backgroundImage.width);
|
|
@@ -95,10 +101,10 @@ export const renderAudioVisualizer = (config: Config, onProgress?: (progress: nu
|
|
|
95
101
|
const spectrumColor =
|
|
96
102
|
getSpectrumColor(config) ||
|
|
97
103
|
invertColor(getImageColor(backgroundImage));
|
|
104
|
+
const spectrumOpacity = getSpectrumOpacityParsed(config);
|
|
98
105
|
const ffmpeg_cfr = getFfmpeg_cfr(config);
|
|
99
106
|
const ffmpeg_preset = getFfmpeg_preset(config);
|
|
100
107
|
const frame_processing_delay = getFrame_processing_delay(config);
|
|
101
|
-
const spectrumBusesCount = 64;
|
|
102
108
|
|
|
103
109
|
const audioDuration = audioBuffer.length / sampleRate;
|
|
104
110
|
const framesCount = Math.trunc(audioDuration * FPS);
|
|
@@ -119,14 +125,16 @@ export const renderAudioVisualizer = (config: Config, onProgress?: (progress: nu
|
|
|
119
125
|
const audioDataParser = () =>
|
|
120
126
|
PCM_FORMAT.parseFunction(audioBuffer, i * audioDataStep, i * audioDataStep + audioDataStep);
|
|
121
127
|
const spectrum = processSpectrum(i, audioDataParser);
|
|
122
|
-
const frameImage = createVisualizerFrame(
|
|
123
|
-
backgroundImage,
|
|
128
|
+
const frameImage = createVisualizerFrame({
|
|
129
|
+
backgroundImageBuffer: backgroundImage,
|
|
124
130
|
spectrum,
|
|
125
|
-
{ width: spectrumWidth, height: spectrumHeight },
|
|
126
|
-
{ x: spectrumX, y: spectrumY },
|
|
127
|
-
spectrumRotation,
|
|
128
|
-
|
|
129
|
-
|
|
131
|
+
size: { width: spectrumWidth, height: spectrumHeight },
|
|
132
|
+
position: { x: spectrumX, y: spectrumY },
|
|
133
|
+
rotation: spectrumRotation,
|
|
134
|
+
margin: spectrumBusMargin,
|
|
135
|
+
color: spectrumColor,
|
|
136
|
+
opacity: spectrumOpacity,
|
|
137
|
+
});
|
|
130
138
|
const frameImageBuffer = createImageBuffer(frameImage);
|
|
131
139
|
const isFrameProcessed = ffmpegVideoWriter.stdin.write(frameImageBuffer);
|
|
132
140
|
if (!isFrameProcessed) {
|
package/src/tests/config.test.ts
CHANGED
|
@@ -12,6 +12,8 @@ import {
|
|
|
12
12
|
getSpectrumXAbsolute,
|
|
13
13
|
getSpectrumYAbsolute,
|
|
14
14
|
getSpectrumColor,
|
|
15
|
+
getSpectrumOpacity,
|
|
16
|
+
getSpectrumOpacityParsed,
|
|
15
17
|
getFfmpeg_cfr,
|
|
16
18
|
getFfmpeg_preset,
|
|
17
19
|
getFrame_processing_delay,
|
|
@@ -94,6 +96,24 @@ describe('config', function() {
|
|
|
94
96
|
backgroundImageWidth
|
|
95
97
|
);
|
|
96
98
|
expect(result4).to.throw('Invalid spectrum width value: \'69\'. Use number value or percent value in string, for example: \'30%\'.');
|
|
99
|
+
|
|
100
|
+
const result5 = getSpectrumWidthAbsolute.bind(
|
|
101
|
+
undefined,
|
|
102
|
+
{
|
|
103
|
+
outVideo: { spectrum: { width: 1 }}
|
|
104
|
+
} as Config,
|
|
105
|
+
backgroundImageWidth
|
|
106
|
+
);
|
|
107
|
+
expect(result5).to.throw('Spectrum width \'1\' is too small.');
|
|
108
|
+
|
|
109
|
+
const result6 = getSpectrumWidthAbsolute.bind(
|
|
110
|
+
undefined,
|
|
111
|
+
{
|
|
112
|
+
outVideo: { spectrum: { width: '1%' }}
|
|
113
|
+
} as Config,
|
|
114
|
+
backgroundImageWidth
|
|
115
|
+
);
|
|
116
|
+
expect(result6).to.throw('Spectrum width \'1%\' is too small.');
|
|
97
117
|
});
|
|
98
118
|
|
|
99
119
|
it('getSpectrumHeightAbsolute', function() {
|
|
@@ -267,6 +287,46 @@ describe('config', function() {
|
|
|
267
287
|
expect(result2).equal('#cccc99');
|
|
268
288
|
});
|
|
269
289
|
|
|
290
|
+
it('getSpectrumOpacity', function() {
|
|
291
|
+
const result1 = getSpectrumOpacity({
|
|
292
|
+
outVideo: {}
|
|
293
|
+
} as Config);
|
|
294
|
+
expect(result1).equal(defaults.spectrumOpacity);
|
|
295
|
+
|
|
296
|
+
const result2 = getSpectrumOpacity({
|
|
297
|
+
outVideo: { spectrum: { opacity: '69%' } }
|
|
298
|
+
} as Config);
|
|
299
|
+
expect(result2).equal('69%');
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
it('getSpectrumOpacityParsed', function() {
|
|
303
|
+
const result1 = getSpectrumOpacityParsed({
|
|
304
|
+
outVideo: {}
|
|
305
|
+
} as Config);
|
|
306
|
+
expect(result1).equal(parseInt(defaults.spectrumOpacity) / 100);
|
|
307
|
+
|
|
308
|
+
const result2 = getSpectrumOpacityParsed({
|
|
309
|
+
outVideo: { spectrum: { opacity: '69%' } }
|
|
310
|
+
} as Config);
|
|
311
|
+
expect(result2).equal(0.69);
|
|
312
|
+
|
|
313
|
+
const result3 = getSpectrumOpacityParsed.bind(
|
|
314
|
+
undefined,
|
|
315
|
+
{
|
|
316
|
+
outVideo: { spectrum: { opacity: 'fake value' } }
|
|
317
|
+
} as Config
|
|
318
|
+
);
|
|
319
|
+
expect(result3).to.throw('Invalid spectrum opacity value: \'fake value\'. Use string percent value, for example \'80%\'.');
|
|
320
|
+
|
|
321
|
+
const result4 = getSpectrumOpacityParsed.bind(
|
|
322
|
+
undefined,
|
|
323
|
+
{
|
|
324
|
+
outVideo: { spectrum: { opacity: '103%' } }
|
|
325
|
+
} as Config
|
|
326
|
+
);
|
|
327
|
+
expect(result4).to.throw('Invalid spectrum opacity value: \'103%\'. Percent values must be in range from \'0%\' to \'100%\'.');
|
|
328
|
+
});
|
|
329
|
+
|
|
270
330
|
it('getFfmpeg_cfr', function() {
|
|
271
331
|
const result1 = getFfmpeg_cfr({
|
|
272
332
|
tweaks: {}
|
package/src/tests/image.test.ts
CHANGED
|
@@ -1,11 +1,50 @@
|
|
|
1
1
|
import { expect } from 'chai';
|
|
2
2
|
import path from 'path';
|
|
3
|
-
import
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import {
|
|
5
|
+
drawRect,
|
|
6
|
+
Color,
|
|
7
|
+
createVisualizerFrame,
|
|
8
|
+
parseImage,
|
|
9
|
+
convertToBmp,
|
|
10
|
+
mixValues,
|
|
11
|
+
mixColors,
|
|
12
|
+
} from '../image';
|
|
4
13
|
|
|
5
14
|
import frameSnapshotSpectrumDown from './snapshots/frameSnapshotSpectrumDown.json';
|
|
6
15
|
import frameSnapshotSpectrumUp from './snapshots/frameSnapshotSpectrumUp.json';
|
|
16
|
+
import frameSnapshotSpectrumUpOpacity50 from './snapshots/frameSnapshotSpectrumUpOpacity50.json';
|
|
7
17
|
|
|
8
18
|
describe('image', function () {
|
|
19
|
+
it('mixValues', function () {
|
|
20
|
+
expect(mixValues(420, 0.69, 96)).equal(320);
|
|
21
|
+
expect(mixValues(420, 1, 96)).equal(420);
|
|
22
|
+
expect(mixValues(420, 0, 96)).equal(96);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('mixColors', function () {
|
|
26
|
+
const result1 = mixColors({
|
|
27
|
+
color: { red: 123, green: 69, blue: 96 },
|
|
28
|
+
colorOpacity: 0.24,
|
|
29
|
+
backgroundColor: { red: 69, green: 123, blue: 42 },
|
|
30
|
+
});
|
|
31
|
+
expect(result1).deep.equal({ red: 82, green: 110, blue: 55 });
|
|
32
|
+
|
|
33
|
+
const result2 = mixColors({
|
|
34
|
+
color: { red: 123, green: 69, blue: 96 },
|
|
35
|
+
colorOpacity: 0,
|
|
36
|
+
backgroundColor: { red: 69, green: 123, blue: 42 },
|
|
37
|
+
});
|
|
38
|
+
expect(result2).deep.equal({ red: 69, green: 123, blue: 42 });
|
|
39
|
+
|
|
40
|
+
const result3 = mixColors({
|
|
41
|
+
color: { red: 123, green: 69, blue: 96 },
|
|
42
|
+
colorOpacity: 1,
|
|
43
|
+
backgroundColor: { red: 69, green: 123, blue: 42 },
|
|
44
|
+
});
|
|
45
|
+
expect(result3).deep.equal({ red: 123, green: 69, blue: 96 });
|
|
46
|
+
});
|
|
47
|
+
|
|
9
48
|
it('drawRect', function () {
|
|
10
49
|
const imageWidth = 10;
|
|
11
50
|
const imageHeight = 10;
|
|
@@ -27,7 +66,13 @@ describe('image', function () {
|
|
|
27
66
|
expectedImageData[pixelIndex + 3] = rectColor.red;
|
|
28
67
|
});
|
|
29
68
|
|
|
30
|
-
drawRect(
|
|
69
|
+
drawRect({
|
|
70
|
+
imageDstBuffer: imageDstBuffer as any,
|
|
71
|
+
position: { x: rectX, y: rectY },
|
|
72
|
+
size: { width: rectWidth, height: rectHeight },
|
|
73
|
+
color: rectColor,
|
|
74
|
+
opacity: 1
|
|
75
|
+
});
|
|
31
76
|
expect(imageDstBuffer.data).deep.equal(expectedImageData);
|
|
32
77
|
});
|
|
33
78
|
|
|
@@ -35,26 +80,43 @@ describe('image', function () {
|
|
|
35
80
|
const backgroundImagePath = path.resolve('example/media/background.png');
|
|
36
81
|
const backgroundImageBmpBuffer = await convertToBmp(backgroundImagePath);
|
|
37
82
|
const backgroundImage = parseImage(backgroundImageBmpBuffer);
|
|
38
|
-
const frameSpectrumDown = createVisualizerFrame(
|
|
39
|
-
backgroundImage,
|
|
40
|
-
[0.5, 0, 1],
|
|
41
|
-
{ width: 15, height: 20 },
|
|
42
|
-
{ x: 15, y: 0 },
|
|
43
|
-
'down',
|
|
44
|
-
|
|
45
|
-
|
|
83
|
+
const frameSpectrumDown = createVisualizerFrame({
|
|
84
|
+
backgroundImageBuffer: backgroundImage,
|
|
85
|
+
spectrum: [0.5, 0, 1],
|
|
86
|
+
size: { width: 15, height: 20 },
|
|
87
|
+
position: { x: 15, y: 0 },
|
|
88
|
+
rotation: 'down',
|
|
89
|
+
margin: 4,
|
|
90
|
+
color: { red: 1, green: 1, blue: 1 },
|
|
91
|
+
opacity: 1,
|
|
92
|
+
});
|
|
46
93
|
const resultSpectrumDown = frameSpectrumDown.data.toJSON().data;
|
|
47
94
|
expect(resultSpectrumDown).deep.equal(frameSnapshotSpectrumDown);
|
|
48
95
|
|
|
49
|
-
const frameSpectrumUp = createVisualizerFrame(
|
|
50
|
-
backgroundImage,
|
|
51
|
-
[0.1, 1, 0],
|
|
52
|
-
{ width: 25, height: 23 },
|
|
53
|
-
{ x: 10, y: 5 },
|
|
54
|
-
'up',
|
|
55
|
-
|
|
56
|
-
|
|
96
|
+
const frameSpectrumUp = createVisualizerFrame({
|
|
97
|
+
backgroundImageBuffer: backgroundImage,
|
|
98
|
+
spectrum: [0.1, 1, 0],
|
|
99
|
+
size: { width: 25, height: 23 },
|
|
100
|
+
position: { x: 10, y: 5 },
|
|
101
|
+
rotation: 'up',
|
|
102
|
+
margin: 4,
|
|
103
|
+
color: { red: 0, green: 123, blue: 69 },
|
|
104
|
+
opacity: 1,
|
|
105
|
+
});
|
|
57
106
|
const resultSpectrumUp = frameSpectrumUp.data.toJSON().data;
|
|
58
107
|
expect(resultSpectrumUp).deep.equal(frameSnapshotSpectrumUp);
|
|
108
|
+
|
|
109
|
+
const frameSpectrumUpOpacity50 = createVisualizerFrame({
|
|
110
|
+
backgroundImageBuffer: backgroundImage,
|
|
111
|
+
spectrum: [0.1, 1, 0],
|
|
112
|
+
size: { width: 25, height: 23 },
|
|
113
|
+
position: { x: 10, y: 5 },
|
|
114
|
+
rotation: 'up',
|
|
115
|
+
margin: 4,
|
|
116
|
+
color: { red: 0, green: 123, blue: 69 },
|
|
117
|
+
opacity: 0.5,
|
|
118
|
+
});
|
|
119
|
+
const resultSpectrumUpOpacity50 = frameSpectrumUpOpacity50.data.toJSON().data;
|
|
120
|
+
expect(resultSpectrumUpOpacity50).deep.equal(frameSnapshotSpectrumUpOpacity50);
|
|
59
121
|
});
|
|
60
122
|
});
|