wavesurfer.js 7.9.8 → 7.10.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 +3 -47
- package/dist/base-plugin.d.ts +1 -0
- package/dist/base-plugin.js +9 -0
- package/dist/fft.d.ts +54 -0
- package/dist/fft.js +341 -0
- package/dist/player.js +11 -9
- package/dist/plugins/envelope.cjs +1 -1
- package/dist/plugins/envelope.esm.js +1 -1
- package/dist/plugins/envelope.js +1 -1
- package/dist/plugins/envelope.min.js +1 -1
- package/dist/plugins/hover.cjs +1 -1
- package/dist/plugins/hover.esm.js +1 -1
- package/dist/plugins/hover.js +1 -1
- package/dist/plugins/hover.min.js +1 -1
- package/dist/plugins/minimap.cjs +1 -1
- package/dist/plugins/minimap.esm.js +1 -1
- package/dist/plugins/minimap.js +1 -1
- package/dist/plugins/minimap.min.js +1 -1
- package/dist/plugins/record.cjs +1 -1
- package/dist/plugins/record.esm.js +1 -1
- package/dist/plugins/record.js +1 -1
- package/dist/plugins/record.min.js +1 -1
- package/dist/plugins/regions.cjs +1 -1
- package/dist/plugins/regions.esm.js +1 -1
- package/dist/plugins/regions.js +1 -1
- package/dist/plugins/regions.min.js +1 -1
- package/dist/plugins/spectrogram-windowed.cjs +1 -0
- package/dist/plugins/spectrogram-windowed.d.ts +138 -0
- package/dist/plugins/spectrogram-windowed.esm.js +1 -0
- package/dist/plugins/spectrogram-windowed.js +1 -0
- package/dist/plugins/spectrogram-windowed.min.js +1 -0
- package/dist/plugins/spectrogram-worker.d.ts +5 -0
- package/dist/plugins/spectrogram-worker.js +85 -0
- package/dist/plugins/spectrogram.cjs +1 -1
- package/dist/plugins/spectrogram.d.ts +41 -24
- package/dist/plugins/spectrogram.esm.js +1 -1
- package/dist/plugins/spectrogram.js +1 -1
- package/dist/plugins/spectrogram.min.js +1 -1
- package/dist/plugins/timeline.cjs +1 -1
- package/dist/plugins/timeline.esm.js +1 -1
- package/dist/plugins/timeline.js +1 -1
- package/dist/plugins/timeline.min.js +1 -1
- package/dist/plugins/zoom.cjs +1 -1
- package/dist/plugins/zoom.esm.js +1 -1
- package/dist/plugins/zoom.js +1 -1
- package/dist/plugins/zoom.min.js +1 -1
- package/dist/types.d.ts +3 -0
- package/dist/wavesurfer.cjs +1 -1
- package/dist/wavesurfer.d.ts +2 -0
- package/dist/wavesurfer.esm.js +1 -1
- package/dist/wavesurfer.js +11 -8
- package/dist/wavesurfer.min.js +1 -1
- package/package.json +6 -5
package/README.md
CHANGED
|
@@ -15,10 +15,9 @@
|
|
|
15
15
|
3. [Plugins](#plugins)
|
|
16
16
|
4. [CSS styling](#css-styling)
|
|
17
17
|
5. [Frequent questions](#questions)
|
|
18
|
-
6. [
|
|
19
|
-
7. [
|
|
20
|
-
8. [
|
|
21
|
-
9. [Feedback](#feedback)
|
|
18
|
+
6. [Development](#development)
|
|
19
|
+
7. [Tests](#tests)
|
|
20
|
+
8. [Feedback](#feedback)
|
|
22
21
|
|
|
23
22
|
## Getting started
|
|
24
23
|
|
|
@@ -132,49 +131,6 @@ However, please keep in mind that this forum is dedicated to wavesurfer-specific
|
|
|
132
131
|
Generally, wavesurfer.js doesn't aim to be a wrapper for all things Web Audio. It's just a player with a waveform visualization. It does allow connecting itself to a Web Audio graph by exporting its audio element (see <a href="https://wavesurfer.xyz/examples/?4436ec40a2ab943243755e659ae32196">this example</a>) but nothign more than that. Please don't expect wavesurfer to be able to cut, add effects, or process your audio in any way.
|
|
133
132
|
</details>
|
|
134
133
|
|
|
135
|
-
## Upgrading from v6 to v7
|
|
136
|
-
|
|
137
|
-
Wavesurfer.js v7 is a TypeScript rewrite of wavesurfer.js that brings several improvements:
|
|
138
|
-
|
|
139
|
-
* Typed API for better development experience
|
|
140
|
-
* Enhanced decoding and rendering performance
|
|
141
|
-
* New and improved plugins
|
|
142
|
-
|
|
143
|
-
Most options, events, and methods are similar to those in previous versions.
|
|
144
|
-
|
|
145
|
-
### Notable differences
|
|
146
|
-
* HTML audio playback by default (used to be an opt-in via `backend: "MediaElement"`)
|
|
147
|
-
* The Markers plugin is removed – you should use the Regions plugin with just a `startTime`.
|
|
148
|
-
* No Microphone plugin – superseded by the new Record plugin with more features.
|
|
149
|
-
* The Cursor plugin is replaced by the Hover plugin.
|
|
150
|
-
|
|
151
|
-
### Removed options
|
|
152
|
-
* `audioContext`, `closeAudioContext`, `audioScriptProcessor`
|
|
153
|
-
* `autoCenterImmediately` – `autoCenter` is now always immediate unless the audio is playing
|
|
154
|
-
* `backgroundColor`, `hideCursor` – this can be easily set via CSS
|
|
155
|
-
* `mediaType` – you should instead pass an entire media element in the `media` option. [Example](https://wavesurfer.xyz/examples/?video.js).
|
|
156
|
-
* `partialRender` – done by default
|
|
157
|
-
* `pixelRatio` – `window.devicePixelRatio` is used by default
|
|
158
|
-
* `renderer` – there's just one renderer for now, so no need for this option
|
|
159
|
-
* `responsive` – responsiveness is enabled by default
|
|
160
|
-
* `scrollParent` – the container will scroll if `minPxPerSec` is set to a higher value
|
|
161
|
-
* `skipLength` – there's no `skipForward` and `skipBackward` methods anymore
|
|
162
|
-
* `splitChannelsOptions` – you should now use `splitChannels` to pass the channel options. Pass `height: 0` to hide a channel. See [this example](https://wavesurfer.xyz/examples/?split-channels.js).
|
|
163
|
-
* `drawingContextAttributes`, `maxCanvasWidth`, `forceDecode` – removed to reduce code complexity
|
|
164
|
-
* `xhr` - please use `fetchParams` instead
|
|
165
|
-
* `barMinHeight` - the minimum bar height is now 1 pixel by default
|
|
166
|
-
|
|
167
|
-
### Removed methods
|
|
168
|
-
* `getFilters`, `setFilter` – see the [Web Audio example](https://wavesurfer.xyz/examples/?webaudio.js)
|
|
169
|
-
* `drawBuffer` – to redraw the waveform, use `setOptions` instead and pass new rendering options
|
|
170
|
-
* `cancelAjax` – you can pass an [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal) in `fetchParams`
|
|
171
|
-
* `skipForward`, `skipBackward`, `setPlayEnd` – can be implemented using `setTime(time)`
|
|
172
|
-
* `exportPCM` is replaced with `exportPeaks` which returns arrays of floats
|
|
173
|
-
* `toggleMute` is now called `setMuted(true | false)`
|
|
174
|
-
* `setHeight`, `setWaveColor`, `setCursorColor`, etc. – use `setOptions` with the corresponding params instead. E.g., `wavesurfer.setOptions({ height: 300, waveColor: '#abc' })`
|
|
175
|
-
|
|
176
|
-
See the complete [documentation of the new API](http://wavesurfer.xyz/docs).
|
|
177
|
-
|
|
178
134
|
## Development
|
|
179
135
|
|
|
180
136
|
To get started with development, follow these steps:
|
package/dist/base-plugin.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare class BasePlugin<EventTypes extends BasePluginEvents, Options> ex
|
|
|
9
9
|
protected wavesurfer?: WaveSurfer;
|
|
10
10
|
protected subscriptions: (() => void)[];
|
|
11
11
|
protected options: Options;
|
|
12
|
+
private isDestroyed;
|
|
12
13
|
/** Create a plugin instance */
|
|
13
14
|
constructor(options: Options);
|
|
14
15
|
/** Called after this.wavesurfer is available */
|
package/dist/base-plugin.js
CHANGED
|
@@ -5,6 +5,7 @@ export class BasePlugin extends EventEmitter {
|
|
|
5
5
|
constructor(options) {
|
|
6
6
|
super();
|
|
7
7
|
this.subscriptions = [];
|
|
8
|
+
this.isDestroyed = false;
|
|
8
9
|
this.options = options;
|
|
9
10
|
}
|
|
10
11
|
/** Called after this.wavesurfer is available */
|
|
@@ -13,6 +14,11 @@ export class BasePlugin extends EventEmitter {
|
|
|
13
14
|
}
|
|
14
15
|
/** Do not call directly, only called by WavesSurfer internally */
|
|
15
16
|
_init(wavesurfer) {
|
|
17
|
+
// Reset state if plugin was previously destroyed
|
|
18
|
+
if (this.isDestroyed) {
|
|
19
|
+
this.subscriptions = [];
|
|
20
|
+
this.isDestroyed = false;
|
|
21
|
+
}
|
|
16
22
|
this.wavesurfer = wavesurfer;
|
|
17
23
|
this.onInit();
|
|
18
24
|
}
|
|
@@ -20,6 +26,9 @@ export class BasePlugin extends EventEmitter {
|
|
|
20
26
|
destroy() {
|
|
21
27
|
this.emit('destroy');
|
|
22
28
|
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
29
|
+
this.subscriptions = [];
|
|
30
|
+
this.isDestroyed = true;
|
|
31
|
+
this.wavesurfer = undefined;
|
|
23
32
|
}
|
|
24
33
|
}
|
|
25
34
|
export default BasePlugin;
|
package/dist/fft.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FFT (Fast Fourier Transform) implementation
|
|
3
|
+
* Based on https://github.com/corbanbrook/dsp.js
|
|
4
|
+
*
|
|
5
|
+
* Centralized FFT functionality for spectrogram plugins
|
|
6
|
+
*/
|
|
7
|
+
export declare const ERB_A: number;
|
|
8
|
+
export declare function hzToMel(hz: number): number;
|
|
9
|
+
export declare function melToHz(mel: number): number;
|
|
10
|
+
export declare function hzToLog(hz: number): number;
|
|
11
|
+
export declare function logToHz(log: number): number;
|
|
12
|
+
export declare function hzToBark(hz: number): number;
|
|
13
|
+
export declare function barkToHz(bark: number): number;
|
|
14
|
+
export declare function hzToErb(hz: number): number;
|
|
15
|
+
export declare function erbToHz(erb: number): number;
|
|
16
|
+
export declare function hzToScale(hz: number, scale: 'linear' | 'logarithmic' | 'mel' | 'bark' | 'erb'): number;
|
|
17
|
+
export declare function scaleToHz(scale: number, scaleType: 'linear' | 'logarithmic' | 'mel' | 'bark' | 'erb'): number;
|
|
18
|
+
export declare function applyFilterBank(fftPoints: Float32Array, filterBank: number[][]): Float32Array;
|
|
19
|
+
export declare function createFilterBankForScale(scale: 'linear' | 'logarithmic' | 'mel' | 'bark' | 'erb', numFilters: number, fftSamples: number, sampleRate: number): number[][] | null;
|
|
20
|
+
export declare const COLOR_MAPS: {
|
|
21
|
+
gray: () => number[][];
|
|
22
|
+
igray: () => number[][];
|
|
23
|
+
roseus: () => number[][];
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Set up color map based on options
|
|
27
|
+
*/
|
|
28
|
+
export declare function setupColorMap(colorMap?: number[][] | 'gray' | 'igray' | 'roseus'): number[][];
|
|
29
|
+
/**
|
|
30
|
+
* Format frequency value for display
|
|
31
|
+
*/
|
|
32
|
+
export declare function freqType(freq: number): string;
|
|
33
|
+
/**
|
|
34
|
+
* Get frequency unit for display
|
|
35
|
+
*/
|
|
36
|
+
export declare function unitType(freq: number): string;
|
|
37
|
+
/**
|
|
38
|
+
* Get frequency value for label at given index
|
|
39
|
+
*/
|
|
40
|
+
export declare function getLabelFrequency(index: number, labelIndex: number, frequencyMin: number, frequencyMax: number, scale: 'linear' | 'logarithmic' | 'mel' | 'bark' | 'erb'): number;
|
|
41
|
+
/**
|
|
42
|
+
* Create wrapper click handler for relative position calculation
|
|
43
|
+
*/
|
|
44
|
+
export declare function createWrapperClickHandler(wrapper: HTMLElement, emit: (event: string, ...args: any[]) => void): (e: MouseEvent) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Calculate FFT - Based on https://github.com/corbanbrook/dsp.js
|
|
47
|
+
*/
|
|
48
|
+
declare function FFT(bufferSize: number, sampleRate: number, windowFunc: string, alpha: number): void;
|
|
49
|
+
export declare class FFT {
|
|
50
|
+
constructor(bufferSize: number, sampleRate: number, windowFunc: string, alpha: number);
|
|
51
|
+
calculateSpectrum(buffer: Float32Array): Float32Array;
|
|
52
|
+
}
|
|
53
|
+
export { FFT };
|
|
54
|
+
export default FFT;
|
package/dist/fft.js
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FFT (Fast Fourier Transform) implementation
|
|
3
|
+
* Based on https://github.com/corbanbrook/dsp.js
|
|
4
|
+
*
|
|
5
|
+
* Centralized FFT functionality for spectrogram plugins
|
|
6
|
+
*/
|
|
7
|
+
// @ts-nocheck
|
|
8
|
+
export const ERB_A = (1000 * Math.log(10)) / (24.7 * 4.37);
|
|
9
|
+
// Frequency scaling functions
|
|
10
|
+
export function hzToMel(hz) {
|
|
11
|
+
return 2595 * Math.log10(1 + hz / 700);
|
|
12
|
+
}
|
|
13
|
+
export function melToHz(mel) {
|
|
14
|
+
return 700 * (Math.pow(10, mel / 2595) - 1);
|
|
15
|
+
}
|
|
16
|
+
export function hzToLog(hz) {
|
|
17
|
+
return Math.log10(Math.max(1, hz));
|
|
18
|
+
}
|
|
19
|
+
export function logToHz(log) {
|
|
20
|
+
return Math.pow(10, log);
|
|
21
|
+
}
|
|
22
|
+
export function hzToBark(hz) {
|
|
23
|
+
// https://www.mathworks.com/help/audio/ref/hz2bark.html#function_hz2bark_sep_mw_06bea6f7-353b-4479-a58d-ccadb90e44de
|
|
24
|
+
let bark = (26.81 * hz) / (1960 + hz) - 0.53;
|
|
25
|
+
if (bark < 2) {
|
|
26
|
+
bark += 0.15 * (2 - bark);
|
|
27
|
+
}
|
|
28
|
+
if (bark > 20.1) {
|
|
29
|
+
bark += 0.22 * (bark - 20.1);
|
|
30
|
+
}
|
|
31
|
+
return bark;
|
|
32
|
+
}
|
|
33
|
+
export function barkToHz(bark) {
|
|
34
|
+
// https://www.mathworks.com/help/audio/ref/bark2hz.html#function_bark2hz_sep_mw_bee310ea-48ac-4d95-ae3d-80f3e4149555
|
|
35
|
+
if (bark < 2) {
|
|
36
|
+
bark = (bark - 0.3) / 0.85;
|
|
37
|
+
}
|
|
38
|
+
if (bark > 20.1) {
|
|
39
|
+
bark = (bark + 4.422) / 1.22;
|
|
40
|
+
}
|
|
41
|
+
return 1960 * ((bark + 0.53) / (26.28 - bark));
|
|
42
|
+
}
|
|
43
|
+
export function hzToErb(hz) {
|
|
44
|
+
// https://www.mathworks.com/help/audio/ref/hz2erb.html#function_hz2erb_sep_mw_06bea6f7-353b-4479-a58d-ccadb90e44de
|
|
45
|
+
return ERB_A * Math.log10(1 + hz * 0.00437);
|
|
46
|
+
}
|
|
47
|
+
export function erbToHz(erb) {
|
|
48
|
+
// https://it.mathworks.com/help/audio/ref/erb2hz.html?#function_erb2hz_sep_mw_bee310ea-48ac-4d95-ae3d-80f3e4149555
|
|
49
|
+
return (Math.pow(10, erb / ERB_A) - 1) / 0.00437;
|
|
50
|
+
}
|
|
51
|
+
// Generic scale conversion functions
|
|
52
|
+
export function hzToScale(hz, scale) {
|
|
53
|
+
switch (scale) {
|
|
54
|
+
case 'mel':
|
|
55
|
+
return hzToMel(hz);
|
|
56
|
+
case 'logarithmic':
|
|
57
|
+
return hzToLog(hz);
|
|
58
|
+
case 'bark':
|
|
59
|
+
return hzToBark(hz);
|
|
60
|
+
case 'erb':
|
|
61
|
+
return hzToErb(hz);
|
|
62
|
+
default:
|
|
63
|
+
return hz;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function scaleToHz(scale, scaleType) {
|
|
67
|
+
switch (scaleType) {
|
|
68
|
+
case 'mel':
|
|
69
|
+
return melToHz(scale);
|
|
70
|
+
case 'logarithmic':
|
|
71
|
+
return logToHz(scale);
|
|
72
|
+
case 'bark':
|
|
73
|
+
return barkToHz(scale);
|
|
74
|
+
case 'erb':
|
|
75
|
+
return erbToHz(scale);
|
|
76
|
+
default:
|
|
77
|
+
return scale;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Filter bank functions
|
|
81
|
+
function createFilterBank(numFilters, fftSamples, sampleRate, hzToScaleFunc, scaleToHzFunc) {
|
|
82
|
+
const filterMin = hzToScaleFunc(0);
|
|
83
|
+
const filterMax = hzToScaleFunc(sampleRate / 2);
|
|
84
|
+
const filterBank = Array.from({ length: numFilters }, () => Array(fftSamples / 2 + 1).fill(0));
|
|
85
|
+
const scale = sampleRate / fftSamples;
|
|
86
|
+
for (let i = 0; i < numFilters; i++) {
|
|
87
|
+
let hz = scaleToHzFunc(filterMin + (i / numFilters) * (filterMax - filterMin));
|
|
88
|
+
let j = Math.floor(hz / scale);
|
|
89
|
+
let hzLow = j * scale;
|
|
90
|
+
let hzHigh = (j + 1) * scale;
|
|
91
|
+
let r = (hz - hzLow) / (hzHigh - hzLow);
|
|
92
|
+
filterBank[i][j] = 1 - r;
|
|
93
|
+
filterBank[i][j + 1] = r;
|
|
94
|
+
}
|
|
95
|
+
return filterBank;
|
|
96
|
+
}
|
|
97
|
+
export function applyFilterBank(fftPoints, filterBank) {
|
|
98
|
+
const numFilters = filterBank.length;
|
|
99
|
+
const logSpectrum = Float32Array.from({ length: numFilters }, () => 0);
|
|
100
|
+
for (let i = 0; i < numFilters; i++) {
|
|
101
|
+
for (let j = 0; j < fftPoints.length; j++) {
|
|
102
|
+
logSpectrum[i] += fftPoints[j] * filterBank[i][j];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return logSpectrum;
|
|
106
|
+
}
|
|
107
|
+
// Centralized filter bank creation based on scale type
|
|
108
|
+
export function createFilterBankForScale(scale, numFilters, fftSamples, sampleRate) {
|
|
109
|
+
switch (scale) {
|
|
110
|
+
case 'mel':
|
|
111
|
+
return createFilterBank(numFilters, fftSamples, sampleRate, hzToMel, melToHz);
|
|
112
|
+
case 'logarithmic':
|
|
113
|
+
return createFilterBank(numFilters, fftSamples, sampleRate, hzToLog, logToHz);
|
|
114
|
+
case 'bark':
|
|
115
|
+
return createFilterBank(numFilters, fftSamples, sampleRate, hzToBark, barkToHz);
|
|
116
|
+
case 'erb':
|
|
117
|
+
return createFilterBank(numFilters, fftSamples, sampleRate, hzToErb, erbToHz);
|
|
118
|
+
case 'linear':
|
|
119
|
+
default:
|
|
120
|
+
return null; // No filter bank for linear scale
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export const COLOR_MAPS = {
|
|
124
|
+
gray: () => {
|
|
125
|
+
const colorMap = [];
|
|
126
|
+
for (let i = 0; i < 256; i++) {
|
|
127
|
+
const val = (255 - i) / 256;
|
|
128
|
+
colorMap.push([val, val, val, 1]);
|
|
129
|
+
}
|
|
130
|
+
return colorMap;
|
|
131
|
+
},
|
|
132
|
+
igray: () => {
|
|
133
|
+
const colorMap = [];
|
|
134
|
+
for (let i = 0; i < 256; i++) {
|
|
135
|
+
const val = i / 256;
|
|
136
|
+
colorMap.push([val, val, val, 1]);
|
|
137
|
+
}
|
|
138
|
+
return colorMap;
|
|
139
|
+
},
|
|
140
|
+
roseus: () => [
|
|
141
|
+
[0.004528, 0.004341, 0.004307, 1], [0.005625, 0.006156, 0.006010, 1], [0.006628, 0.008293, 0.008161, 1], [0.007551, 0.010738, 0.010790, 1], [0.008382, 0.013482, 0.013941, 1], [0.009111, 0.016520, 0.017662, 1], [0.009727, 0.019846, 0.022009, 1], [0.010223, 0.023452, 0.027035, 1], [0.010593, 0.027331, 0.032799, 1], [0.010833, 0.031475, 0.039361, 1], [0.010941, 0.035875, 0.046415, 1], [0.010918, 0.040520, 0.053597, 1], [0.010768, 0.045158, 0.060914, 1], [0.010492, 0.049708, 0.068367, 1], [0.010098, 0.054171, 0.075954, 1], [0.009594, 0.058549, 0.083672, 1], [0.008989, 0.062840, 0.091521, 1], [0.008297, 0.067046, 0.099499, 1], [0.007530, 0.071165, 0.107603, 1], [0.006704, 0.075196, 0.115830, 1], [0.005838, 0.079140, 0.124178, 1], [0.004949, 0.082994, 0.132643, 1], [0.004062, 0.086758, 0.141223, 1], [0.003198, 0.090430, 0.149913, 1], [0.002382, 0.094010, 0.158711, 1], [0.001643, 0.097494, 0.167612, 1], [0.001009, 0.100883, 0.176612, 1], [0.000514, 0.104174, 0.185704, 1], [0.000187, 0.107366, 0.194886, 1], [0.000066, 0.110457, 0.204151, 1], [0.000186, 0.113445, 0.213496, 1], [0.000587, 0.116329, 0.222914, 1], [0.001309, 0.119106, 0.232397, 1], [0.002394, 0.121776, 0.241942, 1], [0.003886, 0.124336, 0.251542, 1], [0.005831, 0.126784, 0.261189, 1], [0.008276, 0.129120, 0.270876, 1], [0.011268, 0.131342, 0.280598, 1], [0.014859, 0.133447, 0.290345, 1], [0.019100, 0.135435, 0.300111, 1], [0.024043, 0.137305, 0.309888, 1], [0.029742, 0.139054, 0.319669, 1], [0.036252, 0.140683, 0.329441, 1], [0.043507, 0.142189, 0.339203, 1], [0.050922, 0.143571, 0.348942, 1], [0.058432, 0.144831, 0.358649, 1], [0.066041, 0.145965, 0.368319, 1], [0.073744, 0.146974, 0.377938, 1], [0.081541, 0.147858, 0.387501, 1], [0.089431, 0.148616, 0.396998, 1], [0.097411, 0.149248, 0.406419, 1], [0.105479, 0.149754, 0.415755, 1], [0.113634, 0.150134, 0.424998, 1], [0.121873, 0.150389, 0.434139, 1], [0.130192, 0.150521, 0.443167, 1], [0.138591, 0.150528, 0.452075, 1], [0.147065, 0.150413, 0.460852, 1], [0.155614, 0.150175, 0.469493, 1], [0.164232, 0.149818, 0.477985, 1], [0.172917, 0.149343, 0.486322, 1], [0.181666, 0.148751, 0.494494, 1], [0.190476, 0.148046, 0.502493, 1], [0.199344, 0.147229, 0.510313, 1], [0.208267, 0.146302, 0.517944, 1], [0.217242, 0.145267, 0.525380, 1], [0.226264, 0.144131, 0.532613, 1], [0.235331, 0.142894, 0.539635, 1], [0.244440, 0.141559, 0.546442, 1], [0.253587, 0.140131, 0.553026, 1], [0.262769, 0.138615, 0.559381, 1], [0.271981, 0.137016, 0.565500, 1], [0.281222, 0.135335, 0.571381, 1], [0.290487, 0.133581, 0.577017, 1], [0.299774, 0.131757, 0.582404, 1], [0.309080, 0.129867, 0.587538, 1], [0.318399, 0.127920, 0.592415, 1], [0.327730, 0.125921, 0.597032, 1], [0.337069, 0.123877, 0.601385, 1], [0.346413, 0.121793, 0.605474, 1], [0.355758, 0.119678, 0.609295, 1], [0.365102, 0.117540, 0.612846, 1], [0.374443, 0.115386, 0.616127, 1], [0.383774, 0.113226, 0.619138, 1], [0.393096, 0.111066, 0.621876, 1], [0.402404, 0.108918, 0.624343, 1], [0.411694, 0.106794, 0.626540, 1], [0.420967, 0.104698, 0.628466, 1], [0.430217, 0.102645, 0.630123, 1], [0.439442, 0.100647, 0.631513, 1], [0.448637, 0.098717, 0.632638, 1], [0.457805, 0.096861, 0.633499, 1], [0.466940, 0.095095, 0.634100, 1], [0.476040, 0.093433, 0.634443, 1], [0.485102, 0.091885, 0.634532, 1], [0.494125, 0.090466, 0.634370, 1], [0.503104, 0.089190, 0.633962, 1], [0.512041, 0.088067, 0.633311, 1], [0.520931, 0.087108, 0.632420, 1], [0.529773, 0.086329, 0.631297, 1], [0.538564, 0.085738, 0.629944, 1], [0.547302, 0.085346, 0.628367, 1], [0.555986, 0.085162, 0.626572, 1], [0.564615, 0.085190, 0.624563, 1], [0.573187, 0.085439, 0.622345, 1], [0.581698, 0.085913, 0.619926, 1], [0.590149, 0.086615, 0.617311, 1], [0.598538, 0.087543, 0.614503, 1], [0.606862, 0.088700, 0.611511, 1], [0.615120, 0.090084, 0.608343, 1], [0.623312, 0.091690, 0.605001, 1], [0.631438, 0.093511, 0.601489, 1], [0.639492, 0.095546, 0.597821, 1], [0.647476, 0.097787, 0.593999, 1], [0.655389, 0.100226, 0.590028, 1], [0.663230, 0.102856, 0.585914, 1], [0.670995, 0.105669, 0.581667, 1], [0.678686, 0.108658, 0.577291, 1], [0.686302, 0.111813, 0.572790, 1], [0.693840, 0.115129, 0.568175, 1], [0.701300, 0.118597, 0.563449, 1], [0.708682, 0.122209, 0.558616, 1], [0.715984, 0.125959, 0.553687, 1], [0.723206, 0.129840, 0.548666, 1], [0.730346, 0.133846, 0.543558, 1], [0.737406, 0.137970, 0.538366, 1], [0.744382, 0.142209, 0.533101, 1], [0.751274, 0.146556, 0.527767, 1], [0.758082, 0.151008, 0.522369, 1], [0.764805, 0.155559, 0.516912, 1], [0.771443, 0.160206, 0.511402, 1], [0.777995, 0.164946, 0.505845, 1], [0.784459, 0.169774, 0.500246, 1], [0.790836, 0.174689, 0.494607, 1], [0.797125, 0.179688, 0.488935, 1], [0.803325, 0.184767, 0.483238, 1], [0.809435, 0.189925, 0.477518, 1], [0.815455, 0.195160, 0.471781, 1], [0.821384, 0.200471, 0.466028, 1], [0.827222, 0.205854, 0.460267, 1], [0.832968, 0.211308, 0.454505, 1], [0.838621, 0.216834, 0.448738, 1], [0.844181, 0.222428, 0.442979, 1], [0.849647, 0.228090, 0.437230, 1], [0.855019, 0.233819, 0.431491, 1], [0.860295, 0.239613, 0.425771, 1], [0.865475, 0.245471, 0.420074, 1], [0.870558, 0.251393, 0.414403, 1], [0.875545, 0.257380, 0.408759, 1], [0.880433, 0.263427, 0.403152, 1], [0.885223, 0.269535, 0.397585, 1], [0.889913, 0.275705, 0.392058, 1], [0.894503, 0.281934, 0.386578, 1], [0.898993, 0.288222, 0.381152, 1], [0.903381, 0.294569, 0.375781, 1], [0.907667, 0.300974, 0.370469, 1], [0.911849, 0.307435, 0.365223, 1], [0.915928, 0.313953, 0.360048, 1], [0.919902, 0.320527, 0.354948, 1], [0.923771, 0.327155, 0.349928, 1], [0.927533, 0.333838, 0.344994, 1], [0.931188, 0.340576, 0.340149, 1], [0.934736, 0.347366, 0.335403, 1], [0.938175, 0.354207, 0.330762, 1], [0.941504, 0.361101, 0.326229, 1], [0.944723, 0.368045, 0.321814, 1], [0.947831, 0.375039, 0.317523, 1], [0.950826, 0.382083, 0.313364, 1], [0.953709, 0.389175, 0.309345, 1], [0.956478, 0.396314, 0.305477, 1], [0.959133, 0.403499, 0.301766, 1], [0.961671, 0.410731, 0.298221, 1], [0.964093, 0.418008, 0.294853, 1], [0.966399, 0.425327, 0.291676, 1], [0.968586, 0.432690, 0.288696, 1], [0.970654, 0.440095, 0.285926, 1], [0.972603, 0.447540, 0.283380, 1], [0.974431, 0.455025, 0.281067, 1], [0.976139, 0.462547, 0.279003, 1], [0.977725, 0.470107, 0.277198, 1], [0.979188, 0.477703, 0.275666, 1], [0.980529, 0.485332, 0.274422, 1], [0.981747, 0.492995, 0.273476, 1], [0.982840, 0.500690, 0.272842, 1], [0.983808, 0.508415, 0.272532, 1], [0.984653, 0.516168, 0.272560, 1], [0.985373, 0.523948, 0.272937, 1], [0.985966, 0.531754, 0.273673, 1], [0.986436, 0.539582, 0.274779, 1], [0.986780, 0.547434, 0.276264, 1], [0.986998, 0.555305, 0.278135, 1], [0.987091, 0.563195, 0.280401, 1], [0.987061, 0.571100, 0.283066, 1], [0.986907, 0.579019, 0.286137, 1], [0.986629, 0.586950, 0.289615, 1], [0.986229, 0.594891, 0.293503, 1], [0.985709, 0.602839, 0.297802, 1], [0.985069, 0.610792, 0.302512, 1], [0.984310, 0.618748, 0.307632, 1], [0.983435, 0.626704, 0.313159, 1], [0.982445, 0.634657, 0.319089, 1], [0.981341, 0.642606, 0.325420, 1], [0.980130, 0.650546, 0.332144, 1], [0.978812, 0.658475, 0.339257, 1], [0.977392, 0.666391, 0.346753, 1], [0.975870, 0.674290, 0.354625, 1], [0.974252, 0.682170, 0.362865, 1], [0.972545, 0.690026, 0.371466, 1], [0.970750, 0.697856, 0.380419, 1], [0.968873, 0.705658, 0.389718, 1], [0.966921, 0.713426, 0.399353, 1], [0.964901, 0.721157, 0.409313, 1], [0.962815, 0.728851, 0.419594, 1], [0.960677, 0.736500, 0.430181, 1], [0.958490, 0.744103, 0.441070, 1], [0.956263, 0.751656, 0.452248, 1], [0.954009, 0.759153, 0.463702, 1], [0.951732, 0.766595, 0.475429, 1], [0.949445, 0.773974, 0.487414, 1], [0.947158, 0.781289, 0.499647, 1], [0.944885, 0.788535, 0.512116, 1], [0.942634, 0.795709, 0.524811, 1], [0.940423, 0.802807, 0.537717, 1], [0.938261, 0.809825, 0.550825, 1], [0.936163, 0.816760, 0.564121, 1], [0.934146, 0.823608, 0.577591, 1], [0.932224, 0.830366, 0.591220, 1], [0.930412, 0.837031, 0.604997, 1], [0.928727, 0.843599, 0.618904, 1], [0.927187, 0.850066, 0.632926, 1], [0.925809, 0.856432, 0.647047, 1], [0.924610, 0.862691, 0.661249, 1], [0.923607, 0.868843, 0.675517, 1], [0.922820, 0.874884, 0.689832, 1], [0.922265, 0.880812, 0.704174, 1], [0.921962, 0.886626, 0.718523, 1], [0.921930, 0.892323, 0.732859, 1], [0.922183, 0.897903, 0.747163, 1], [0.922741, 0.903364, 0.761410, 1], [0.923620, 0.908706, 0.775580, 1], [0.924837, 0.913928, 0.789648, 1], [0.926405, 0.919031, 0.803590, 1], [0.928340, 0.924015, 0.817381, 1], [0.930655, 0.928881, 0.830995, 1], [0.933360, 0.933631, 0.844405, 1], [0.936466, 0.938267, 0.857583, 1], [0.939982, 0.942791, 0.870499, 1], [0.943914, 0.947207, 0.883122, 1], [0.948267, 0.951519, 0.895421, 1], [0.953044, 0.955732, 0.907359, 1], [0.958246, 0.959852, 0.918901, 1], [0.963869, 0.963887, 0.930004, 1], [0.969909, 0.967845, 0.940623, 1], [0.976355, 0.971737, 0.950704, 1], [0.983195, 0.975580, 0.960181, 1], [0.990402, 0.979395, 0.968966, 1], [0.997930, 0.983217, 0.976920, 1]
|
|
142
|
+
]
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Set up color map based on options
|
|
146
|
+
*/
|
|
147
|
+
export function setupColorMap(colorMap = 'roseus') {
|
|
148
|
+
if (colorMap && typeof colorMap !== 'string') {
|
|
149
|
+
if (colorMap.length < 256) {
|
|
150
|
+
throw new Error('Colormap must contain 256 elements');
|
|
151
|
+
}
|
|
152
|
+
for (let i = 0; i < colorMap.length; i++) {
|
|
153
|
+
const cmEntry = colorMap[i];
|
|
154
|
+
if (cmEntry.length !== 4) {
|
|
155
|
+
throw new Error('ColorMap entries must contain 4 values');
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return colorMap;
|
|
159
|
+
}
|
|
160
|
+
const mapGenerator = COLOR_MAPS[colorMap];
|
|
161
|
+
if (!mapGenerator) {
|
|
162
|
+
throw Error("No such colormap '" + colorMap + "'");
|
|
163
|
+
}
|
|
164
|
+
return mapGenerator();
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Format frequency value for display
|
|
168
|
+
*/
|
|
169
|
+
export function freqType(freq) {
|
|
170
|
+
return freq >= 1000 ? (freq / 1000).toFixed(1) : Math.round(freq).toString();
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get frequency unit for display
|
|
174
|
+
*/
|
|
175
|
+
export function unitType(freq) {
|
|
176
|
+
return freq >= 1000 ? 'kHz' : 'Hz';
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get frequency value for label at given index
|
|
180
|
+
*/
|
|
181
|
+
export function getLabelFrequency(index, labelIndex, frequencyMin, frequencyMax, scale) {
|
|
182
|
+
const scaleMin = hzToScale(frequencyMin, scale);
|
|
183
|
+
const scaleMax = hzToScale(frequencyMax, scale);
|
|
184
|
+
return scaleToHz(scaleMin + (index / labelIndex) * (scaleMax - scaleMin), scale);
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Create wrapper click handler for relative position calculation
|
|
188
|
+
*/
|
|
189
|
+
export function createWrapperClickHandler(wrapper, emit) {
|
|
190
|
+
return (e) => {
|
|
191
|
+
const rect = wrapper.getBoundingClientRect();
|
|
192
|
+
const relativeX = e.clientX - rect.left;
|
|
193
|
+
const relativeWidth = rect.width;
|
|
194
|
+
const relativePosition = relativeX / relativeWidth;
|
|
195
|
+
emit('click', relativePosition);
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Calculate FFT - Based on https://github.com/corbanbrook/dsp.js
|
|
200
|
+
*/
|
|
201
|
+
function FFT(bufferSize, sampleRate, windowFunc, alpha) {
|
|
202
|
+
this.bufferSize = bufferSize;
|
|
203
|
+
this.sampleRate = sampleRate;
|
|
204
|
+
this.bandwidth = (2 / bufferSize) * (sampleRate / 2);
|
|
205
|
+
this.sinTable = new Float32Array(bufferSize);
|
|
206
|
+
this.cosTable = new Float32Array(bufferSize);
|
|
207
|
+
this.windowValues = new Float32Array(bufferSize);
|
|
208
|
+
this.reverseTable = new Uint32Array(bufferSize);
|
|
209
|
+
this.peakBand = 0;
|
|
210
|
+
this.peak = 0;
|
|
211
|
+
var i;
|
|
212
|
+
switch (windowFunc) {
|
|
213
|
+
case 'bartlett':
|
|
214
|
+
for (i = 0; i < bufferSize; i++) {
|
|
215
|
+
this.windowValues[i] = (2 / (bufferSize - 1)) * ((bufferSize - 1) / 2 - Math.abs(i - (bufferSize - 1) / 2));
|
|
216
|
+
}
|
|
217
|
+
break;
|
|
218
|
+
case 'bartlettHann':
|
|
219
|
+
for (i = 0; i < bufferSize; i++) {
|
|
220
|
+
this.windowValues[i] =
|
|
221
|
+
0.62 - 0.48 * Math.abs(i / (bufferSize - 1) - 0.5) - 0.38 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1));
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
case 'blackman':
|
|
225
|
+
alpha = alpha || 0.16;
|
|
226
|
+
for (i = 0; i < bufferSize; i++) {
|
|
227
|
+
this.windowValues[i] =
|
|
228
|
+
(1 - alpha) / 2 -
|
|
229
|
+
0.5 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1)) +
|
|
230
|
+
(alpha / 2) * Math.cos((4 * Math.PI * i) / (bufferSize - 1));
|
|
231
|
+
}
|
|
232
|
+
break;
|
|
233
|
+
case 'cosine':
|
|
234
|
+
for (i = 0; i < bufferSize; i++) {
|
|
235
|
+
this.windowValues[i] = Math.cos((Math.PI * i) / (bufferSize - 1) - Math.PI / 2);
|
|
236
|
+
}
|
|
237
|
+
break;
|
|
238
|
+
case 'gauss':
|
|
239
|
+
alpha = alpha || 0.25;
|
|
240
|
+
for (i = 0; i < bufferSize; i++) {
|
|
241
|
+
this.windowValues[i] = Math.pow(Math.E, -0.5 * Math.pow((i - (bufferSize - 1) / 2) / ((alpha * (bufferSize - 1)) / 2), 2));
|
|
242
|
+
}
|
|
243
|
+
break;
|
|
244
|
+
case 'hamming':
|
|
245
|
+
for (i = 0; i < bufferSize; i++) {
|
|
246
|
+
this.windowValues[i] = 0.54 - 0.46 * Math.cos((Math.PI * 2 * i) / (bufferSize - 1));
|
|
247
|
+
}
|
|
248
|
+
break;
|
|
249
|
+
case 'hann':
|
|
250
|
+
case undefined:
|
|
251
|
+
for (i = 0; i < bufferSize; i++) {
|
|
252
|
+
this.windowValues[i] = 0.5 * (1 - Math.cos((Math.PI * 2 * i) / (bufferSize - 1)));
|
|
253
|
+
}
|
|
254
|
+
break;
|
|
255
|
+
case 'lanczoz':
|
|
256
|
+
for (i = 0; i < bufferSize; i++) {
|
|
257
|
+
this.windowValues[i] =
|
|
258
|
+
Math.sin(Math.PI * ((2 * i) / (bufferSize - 1) - 1)) / (Math.PI * ((2 * i) / (bufferSize - 1) - 1));
|
|
259
|
+
}
|
|
260
|
+
break;
|
|
261
|
+
case 'rectangular':
|
|
262
|
+
for (i = 0; i < bufferSize; i++) {
|
|
263
|
+
this.windowValues[i] = 1;
|
|
264
|
+
}
|
|
265
|
+
break;
|
|
266
|
+
case 'triangular':
|
|
267
|
+
for (i = 0; i < bufferSize; i++) {
|
|
268
|
+
this.windowValues[i] = (2 / bufferSize) * (bufferSize / 2 - Math.abs(i - (bufferSize - 1) / 2));
|
|
269
|
+
}
|
|
270
|
+
break;
|
|
271
|
+
default:
|
|
272
|
+
throw Error("No such window function '" + windowFunc + "'");
|
|
273
|
+
}
|
|
274
|
+
var limit = 1;
|
|
275
|
+
var bit = bufferSize >> 1;
|
|
276
|
+
var i;
|
|
277
|
+
while (limit < bufferSize) {
|
|
278
|
+
for (i = 0; i < limit; i++) {
|
|
279
|
+
this.reverseTable[i + limit] = this.reverseTable[i] + bit;
|
|
280
|
+
}
|
|
281
|
+
limit = limit << 1;
|
|
282
|
+
bit = bit >> 1;
|
|
283
|
+
}
|
|
284
|
+
for (i = 0; i < bufferSize; i++) {
|
|
285
|
+
this.sinTable[i] = Math.sin(-Math.PI / i);
|
|
286
|
+
this.cosTable[i] = Math.cos(-Math.PI / i);
|
|
287
|
+
}
|
|
288
|
+
this.calculateSpectrum = function (buffer) {
|
|
289
|
+
var bufferSize = this.bufferSize, cosTable = this.cosTable, sinTable = this.sinTable, reverseTable = this.reverseTable, real = new Float32Array(bufferSize), imag = new Float32Array(bufferSize), bSi = 2 / this.bufferSize, sqrt = Math.sqrt, rval, ival, mag, spectrum = new Float32Array(bufferSize / 2);
|
|
290
|
+
var k = Math.floor(Math.log(bufferSize) / Math.LN2);
|
|
291
|
+
if (Math.pow(2, k) !== bufferSize) {
|
|
292
|
+
throw 'Invalid buffer size, must be a power of 2.';
|
|
293
|
+
}
|
|
294
|
+
if (bufferSize !== buffer.length) {
|
|
295
|
+
throw ('Supplied buffer is not the same size as defined FFT. FFT Size: ' +
|
|
296
|
+
bufferSize +
|
|
297
|
+
' Buffer Size: ' +
|
|
298
|
+
buffer.length);
|
|
299
|
+
}
|
|
300
|
+
var halfSize = 1, phaseShiftStepReal, phaseShiftStepImag, currentPhaseShiftReal, currentPhaseShiftImag, off, tr, ti, tmpReal;
|
|
301
|
+
for (var i = 0; i < bufferSize; i++) {
|
|
302
|
+
real[i] = buffer[reverseTable[i]] * this.windowValues[reverseTable[i]];
|
|
303
|
+
imag[i] = 0;
|
|
304
|
+
}
|
|
305
|
+
while (halfSize < bufferSize) {
|
|
306
|
+
phaseShiftStepReal = cosTable[halfSize];
|
|
307
|
+
phaseShiftStepImag = sinTable[halfSize];
|
|
308
|
+
currentPhaseShiftReal = 1;
|
|
309
|
+
currentPhaseShiftImag = 0;
|
|
310
|
+
for (var fftStep = 0; fftStep < halfSize; fftStep++) {
|
|
311
|
+
var i = fftStep;
|
|
312
|
+
while (i < bufferSize) {
|
|
313
|
+
off = i + halfSize;
|
|
314
|
+
tr = currentPhaseShiftReal * real[off] - currentPhaseShiftImag * imag[off];
|
|
315
|
+
ti = currentPhaseShiftReal * imag[off] + currentPhaseShiftImag * real[off];
|
|
316
|
+
real[off] = real[i] - tr;
|
|
317
|
+
imag[off] = imag[i] - ti;
|
|
318
|
+
real[i] += tr;
|
|
319
|
+
imag[i] += ti;
|
|
320
|
+
i += halfSize << 1;
|
|
321
|
+
}
|
|
322
|
+
tmpReal = currentPhaseShiftReal;
|
|
323
|
+
currentPhaseShiftReal = tmpReal * phaseShiftStepReal - currentPhaseShiftImag * phaseShiftStepImag;
|
|
324
|
+
currentPhaseShiftImag = tmpReal * phaseShiftStepImag + currentPhaseShiftImag * phaseShiftStepReal;
|
|
325
|
+
}
|
|
326
|
+
halfSize = halfSize << 1;
|
|
327
|
+
}
|
|
328
|
+
for (var i = 0, N = bufferSize / 2; i < N; i++) {
|
|
329
|
+
rval = real[i];
|
|
330
|
+
ival = imag[i];
|
|
331
|
+
mag = bSi * sqrt(rval * rval + ival * ival);
|
|
332
|
+
if (mag > this.peak) {
|
|
333
|
+
this.peakBand = i;
|
|
334
|
+
this.peak = mag;
|
|
335
|
+
}
|
|
336
|
+
spectrum[i] = mag;
|
|
337
|
+
}
|
|
338
|
+
return spectrum;
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
export default FFT;
|
package/dist/player.js
CHANGED
|
@@ -53,20 +53,22 @@ class Player extends EventEmitter {
|
|
|
53
53
|
return this.media.canPlayType(type) !== '';
|
|
54
54
|
}
|
|
55
55
|
setSrc(url, blob) {
|
|
56
|
-
const
|
|
57
|
-
if (url &&
|
|
58
|
-
return;
|
|
56
|
+
const prevSrc = this.getSrc();
|
|
57
|
+
if (url && prevSrc === url)
|
|
58
|
+
return; // no need to change the source
|
|
59
59
|
this.revokeSrc();
|
|
60
60
|
const newSrc = blob instanceof Blob && (this.canPlayType(blob.type) || !url) ? URL.createObjectURL(blob) : url;
|
|
61
61
|
// Reset the media element, otherwise it keeps the previous source
|
|
62
|
-
if (
|
|
62
|
+
if (prevSrc) {
|
|
63
63
|
this.media.removeAttribute('src');
|
|
64
64
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
65
|
+
if (newSrc || url) {
|
|
66
|
+
try {
|
|
67
|
+
this.media.src = newSrc;
|
|
68
|
+
}
|
|
69
|
+
catch (_a) {
|
|
70
|
+
this.media.src = url;
|
|
71
|
+
}
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
destroy() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),null==i?void 0:i.once){const i=()=>{this.un(t,i),this.un(t,e)};return this.on(t,i),i}return()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}_init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function i(t,e,i,o,n=3,s=0,r=100){if(!t)return()=>{};const l=matchMedia("(pointer: coarse)").matches;let h=()=>{};const a=a=>{if(a.button!==s)return;a.preventDefault(),a.stopPropagation();let u=a.clientX,c=a.clientY,d=!1;const p=Date.now(),m=o=>{if(o.preventDefault(),o.stopPropagation(),l&&Date.now()-p<r)return;const s=o.clientX,h=o.clientY,a=s-u,m=h-c;if(d||Math.abs(a)>n||Math.abs(m)>n){const o=t.getBoundingClientRect(),{left:n,top:r}=o;d||(null==i||i(u-n,c-r),d=!0),e(a,m,s-n,h-r),u=s,c=h}},v=e=>{if(d){const i=e.clientX,n=e.clientY,s=t.getBoundingClientRect(),{left:r,top:l}=s;null==o||o(i-r,n-l)}h()},g=t=>{t.relatedTarget&&t.relatedTarget!==document.documentElement||v(t)},f=t=>{d&&(t.stopPropagation(),t.preventDefault())},y=t=>{d&&t.preventDefault()};document.addEventListener("pointermove",m),document.addEventListener("pointerup",v),document.addEventListener("pointerout",g),document.addEventListener("pointercancel",g),document.addEventListener("touchmove",y,{passive:!1}),document.addEventListener("click",f,{capture:!0}),h=()=>{document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",v),document.removeEventListener("pointerout",g),document.removeEventListener("pointercancel",g),document.removeEventListener("touchmove",y),setTimeout((()=>{document.removeEventListener("click",f,{capture:!0})}),10)}};return t.addEventListener("pointerdown",a),()=>{h(),t.removeEventListener("pointerdown",a)}}function o(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,n]of Object.entries(e))if("children"===t&&n)for(const[t,e]of Object.entries(n))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(o(t,e));else"style"===t?Object.assign(i.style,n):"textContent"===t?i.textContent=n:i.setAttribute(t,n.toString());return i}function n(t,e,i){const n=o(t,e||{});return null==i||i.appendChild(n),n}const s={points:[],lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class r extends t{constructor(t,e){super(),this.subscriptions=[],this.subscriptions=[],this.options=t,this.polyPoints=new Map;const o=e.clientWidth,s=e.clientHeight,r=n("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:`0 0 ${o} ${s}`,preserveAspectRatio:"none",style:{position:"absolute",left:"0",top:"0",zIndex:"4"},part:"envelope"},e);this.svg=r;const l=n("polyline",{xmlns:"http://www.w3.org/2000/svg",points:`0,${s} ${o},${s}`,stroke:t.lineColor,"stroke-width":t.lineWidth,fill:"none",part:"polyline",style:t.dragLine?{cursor:"row-resize",pointerEvents:"stroke"}:{}},r);t.dragLine&&this.subscriptions.push(i(l,((t,e)=>{const{height:i}=r.viewBox.baseVal,{points:o}=l;for(let t=1;t<o.numberOfItems-1;t++){const n=o.getItem(t);n.y=Math.min(i,Math.max(0,n.y+e))}const n=r.querySelectorAll("ellipse");Array.from(n).forEach((t=>{const o=Math.min(i,Math.max(0,Number(t.getAttribute("cy"))+e));t.setAttribute("cy",o.toString())})),this.emit("line-move",e/i)}))),r.addEventListener("dblclick",(t=>{const e=r.getBoundingClientRect(),i=t.clientX-e.left,o=t.clientY-e.top;this.emit("point-create",i/e.width,o/e.height)}));{let t;const e=()=>clearTimeout(t);r.addEventListener("touchstart",(i=>{1===i.touches.length?t=window.setTimeout((()=>{i.preventDefault();const t=r.getBoundingClientRect(),e=i.touches[0].clientX-t.left,o=i.touches[0].clientY-t.top;this.emit("point-create",e/t.width,o/t.height)}),500):e()})),r.addEventListener("touchmove",e),r.addEventListener("touchend",e)}}makeDraggable(t,e){this.subscriptions.push(i(t,e,(()=>t.style.cursor="grabbing"),(()=>t.style.cursor="grab"),1))}createCircle(t,e){const i=this.options.dragPointSize/2;return n("ellipse",{xmlns:"http://www.w3.org/2000/svg",cx:t,cy:e,rx:i,ry:i,fill:this.options.dragPointFill,stroke:this.options.dragPointStroke,"stroke-width":"2",style:{cursor:"grab",pointerEvents:"all"},part:"envelope-circle"},this.svg)}removePolyPoint(t){const e=this.polyPoints.get(t);if(!e)return;const{polyPoint:i,circle:o}=e,{points:n}=this.svg.querySelector("polyline"),s=Array.from(n).findIndex((t=>t.x===i.x&&t.y===i.y));n.removeItem(s),o.remove(),this.polyPoints.delete(t)}addPolyPoint(t,e,i){const{svg:o}=this,{width:n,height:s}=o.viewBox.baseVal,r=t*n,l=s-e*s,h=this.options.dragPointSize/2,a=o.createSVGPoint();a.x=t*n,a.y=s-e*s;const u=this.createCircle(r,l),{points:c}=o.querySelector("polyline"),d=Array.from(c).findIndex((t=>t.x>=r));c.insertItemBefore(a,Math.max(d,1)),this.polyPoints.set(i,{polyPoint:a,circle:u}),this.makeDraggable(u,((t,e)=>{const o=a.x+t,r=a.y+e;if(o<-h||r<-h||o>n+h||r>s+h)return void this.emit("point-dragout",i);const l=Array.from(c).find((t=>t.x>a.x)),d=Array.from(c).findLast((t=>t.x<a.x));l&&o>=l.x||d&&o<=d.x||(a.x=o,a.y=r,u.setAttribute("cx",o.toString()),u.setAttribute("cy",r.toString()),this.emit("point-move",i,o/n,r/s))}))}update(){const{svg:t}=this,e=t.viewBox.baseVal.width/t.clientWidth,i=t.viewBox.baseVal.height/t.clientHeight;t.querySelectorAll("ellipse").forEach((t=>{const o=this.options.dragPointSize/2,n=o*e,s=o*i;t.setAttribute("rx",n.toString()),t.setAttribute("ry",s.toString())}))}destroy(){this.subscriptions.forEach((t=>t())),this.polyPoints.clear(),this.svg.remove()}}class l extends e{constructor(t){super(t),this.polyline=null,this.throttleTimeout=null,this.volume=1,this.points=t.points||[],this.options=Object.assign({},s,t),this.options.lineColor=this.options.lineColor||s.lineColor,this.options.dragPointFill=this.options.dragPointFill||s.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||s.dragPointStroke,this.options.dragPointSize=this.options.dragPointSize||s.dragPointSize}static create(t){return new l(t)}addPoint(t){var e;t.id||(t.id=Math.random().toString(36).slice(2));const i=this.points.findLastIndex((e=>e.time<t.time));this.points.splice(i+1,0,t),this.emitPoints();const o=null===(e=this.wavesurfer)||void 0===e?void 0:e.getDuration();o&&this.addPolyPoint(t,o)}removePoint(t){var e;const i=this.points.indexOf(t);i>-1&&(this.points.splice(i,1),null===(e=this.polyline)||void 0===e||e.removePolyPoint(t),this.emitPoints())}getPoints(){return this.points}setPoints(t){this.points.slice().forEach((t=>this.removePoint(t))),t.forEach((t=>this.addPoint(t)))}destroy(){var t;null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}getCurrentVolume(){return this.volume}setVolume(t){var e;this.volume=t,null===(e=this.wavesurfer)||void 0===e||e.setVolume(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const{options:e}=this;e.volume=null!==(t=e.volume)&&void 0!==t?t:this.wavesurfer.getVolume(),this.setVolume(e.volume),this.subscriptions.push(this.wavesurfer.on("decode",(t=>{this.initPolyline(),this.points.forEach((e=>{this.addPolyPoint(e,t)}))})),this.wavesurfer.on("redraw",(()=>{var t;null===(t=this.polyline)||void 0===t||t.update()})),this.wavesurfer.on("timeupdate",(t=>{this.onTimeUpdate(t)})))}emitPoints(){this.throttleTimeout&&clearTimeout(this.throttleTimeout),this.throttleTimeout=setTimeout((()=>{this.emit("points-change",this.points)}),200)}initPolyline(){if(this.polyline&&this.polyline.destroy(),!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new r(this.options,t),this.subscriptions.push(this.polyline.on("point-move",((t,e,i)=>{var o;const n=(null===(o=this.wavesurfer)||void 0===o?void 0:o.getDuration())||0;t.time=e*n,t.volume=1-i,this.emitPoints()})),this.polyline.on("point-dragout",(t=>{this.removePoint(t)})),this.polyline.on("point-create",((t,e)=>{var i;this.addPoint({time:t*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0),volume:1-e})})),this.polyline.on("line-move",(t=>{var e;this.points.forEach((e=>{e.volume=Math.min(1,Math.max(0,e.volume-t))})),this.emitPoints(),this.onTimeUpdate((null===(e=this.wavesurfer)||void 0===e?void 0:e.getCurrentTime())||0)})))}addPolyPoint(t,e){var i;null===(i=this.polyline)||void 0===i||i.addPolyPoint(t.time/e,t.volume,t)}onTimeUpdate(t){if(!this.wavesurfer)return;let e=this.points.find((e=>e.time>t));e||(e={time:this.wavesurfer.getDuration()||0,volume:0});let i=this.points.findLast((e=>e.time<=t));i||(i={time:0,volume:0});const o=e.time-i.time,n=e.volume-i.volume,s=i.volume+(t-i.time)*(n/o),r=Math.min(1,Math.max(0,s)),l=Math.round(100*r)/100;l!==this.getCurrentVolume()&&(this.setVolume(l),this.emit("volume-change",l))}}module.exports=l;
|
|
1
|
+
"use strict";class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),null==i?void 0:i.once){const i=()=>{this.un(t,i),this.un(t,e)};return this.on(t,i),i}return()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.isDestroyed=!1,this.options=t}onInit(){}_init(t){this.isDestroyed&&(this.subscriptions=[],this.isDestroyed=!1),this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.subscriptions=[],this.isDestroyed=!0,this.wavesurfer=void 0}}function i(t,e,i,o,n=3,s=0,r=100){if(!t)return()=>{};const l=matchMedia("(pointer: coarse)").matches;let h=()=>{};const a=a=>{if(a.button!==s)return;a.preventDefault(),a.stopPropagation();let u=a.clientX,c=a.clientY,d=!1;const p=Date.now(),m=o=>{if(o.preventDefault(),o.stopPropagation(),l&&Date.now()-p<r)return;const s=o.clientX,h=o.clientY,a=s-u,m=h-c;if(d||Math.abs(a)>n||Math.abs(m)>n){const o=t.getBoundingClientRect(),{left:n,top:r}=o;d||(null==i||i(u-n,c-r),d=!0),e(a,m,s-n,h-r),u=s,c=h}},v=e=>{if(d){const i=e.clientX,n=e.clientY,s=t.getBoundingClientRect(),{left:r,top:l}=s;null==o||o(i-r,n-l)}h()},g=t=>{t.relatedTarget&&t.relatedTarget!==document.documentElement||v(t)},f=t=>{d&&(t.stopPropagation(),t.preventDefault())},y=t=>{d&&t.preventDefault()};document.addEventListener("pointermove",m),document.addEventListener("pointerup",v),document.addEventListener("pointerout",g),document.addEventListener("pointercancel",g),document.addEventListener("touchmove",y,{passive:!1}),document.addEventListener("click",f,{capture:!0}),h=()=>{document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",v),document.removeEventListener("pointerout",g),document.removeEventListener("pointercancel",g),document.removeEventListener("touchmove",y),setTimeout((()=>{document.removeEventListener("click",f,{capture:!0})}),10)}};return t.addEventListener("pointerdown",a),()=>{h(),t.removeEventListener("pointerdown",a)}}function o(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,n]of Object.entries(e))if("children"===t&&n)for(const[t,e]of Object.entries(n))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(o(t,e));else"style"===t?Object.assign(i.style,n):"textContent"===t?i.textContent=n:i.setAttribute(t,n.toString());return i}function n(t,e,i){const n=o(t,e||{});return null==i||i.appendChild(n),n}const s={points:[],lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class r extends t{constructor(t,e){super(),this.subscriptions=[],this.subscriptions=[],this.options=t,this.polyPoints=new Map;const o=e.clientWidth,s=e.clientHeight,r=n("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:`0 0 ${o} ${s}`,preserveAspectRatio:"none",style:{position:"absolute",left:"0",top:"0",zIndex:"4"},part:"envelope"},e);this.svg=r;const l=n("polyline",{xmlns:"http://www.w3.org/2000/svg",points:`0,${s} ${o},${s}`,stroke:t.lineColor,"stroke-width":t.lineWidth,fill:"none",part:"polyline",style:t.dragLine?{cursor:"row-resize",pointerEvents:"stroke"}:{}},r);t.dragLine&&this.subscriptions.push(i(l,((t,e)=>{const{height:i}=r.viewBox.baseVal,{points:o}=l;for(let t=1;t<o.numberOfItems-1;t++){const n=o.getItem(t);n.y=Math.min(i,Math.max(0,n.y+e))}const n=r.querySelectorAll("ellipse");Array.from(n).forEach((t=>{const o=Math.min(i,Math.max(0,Number(t.getAttribute("cy"))+e));t.setAttribute("cy",o.toString())})),this.emit("line-move",e/i)}))),r.addEventListener("dblclick",(t=>{const e=r.getBoundingClientRect(),i=t.clientX-e.left,o=t.clientY-e.top;this.emit("point-create",i/e.width,o/e.height)}));{let t;const e=()=>clearTimeout(t);r.addEventListener("touchstart",(i=>{1===i.touches.length?t=window.setTimeout((()=>{i.preventDefault();const t=r.getBoundingClientRect(),e=i.touches[0].clientX-t.left,o=i.touches[0].clientY-t.top;this.emit("point-create",e/t.width,o/t.height)}),500):e()})),r.addEventListener("touchmove",e),r.addEventListener("touchend",e)}}makeDraggable(t,e){this.subscriptions.push(i(t,e,(()=>t.style.cursor="grabbing"),(()=>t.style.cursor="grab"),1))}createCircle(t,e){const i=this.options.dragPointSize/2;return n("ellipse",{xmlns:"http://www.w3.org/2000/svg",cx:t,cy:e,rx:i,ry:i,fill:this.options.dragPointFill,stroke:this.options.dragPointStroke,"stroke-width":"2",style:{cursor:"grab",pointerEvents:"all"},part:"envelope-circle"},this.svg)}removePolyPoint(t){const e=this.polyPoints.get(t);if(!e)return;const{polyPoint:i,circle:o}=e,{points:n}=this.svg.querySelector("polyline"),s=Array.from(n).findIndex((t=>t.x===i.x&&t.y===i.y));n.removeItem(s),o.remove(),this.polyPoints.delete(t)}addPolyPoint(t,e,i){const{svg:o}=this,{width:n,height:s}=o.viewBox.baseVal,r=t*n,l=s-e*s,h=this.options.dragPointSize/2,a=o.createSVGPoint();a.x=t*n,a.y=s-e*s;const u=this.createCircle(r,l),{points:c}=o.querySelector("polyline"),d=Array.from(c).findIndex((t=>t.x>=r));c.insertItemBefore(a,Math.max(d,1)),this.polyPoints.set(i,{polyPoint:a,circle:u}),this.makeDraggable(u,((t,e)=>{const o=a.x+t,r=a.y+e;if(o<-h||r<-h||o>n+h||r>s+h)return void this.emit("point-dragout",i);const l=Array.from(c).find((t=>t.x>a.x)),d=Array.from(c).findLast((t=>t.x<a.x));l&&o>=l.x||d&&o<=d.x||(a.x=o,a.y=r,u.setAttribute("cx",o.toString()),u.setAttribute("cy",r.toString()),this.emit("point-move",i,o/n,r/s))}))}update(){const{svg:t}=this,e=t.viewBox.baseVal.width/t.clientWidth,i=t.viewBox.baseVal.height/t.clientHeight;t.querySelectorAll("ellipse").forEach((t=>{const o=this.options.dragPointSize/2,n=o*e,s=o*i;t.setAttribute("rx",n.toString()),t.setAttribute("ry",s.toString())}))}destroy(){this.subscriptions.forEach((t=>t())),this.polyPoints.clear(),this.svg.remove()}}class l extends e{constructor(t){super(t),this.polyline=null,this.throttleTimeout=null,this.volume=1,this.points=t.points||[],this.options=Object.assign({},s,t),this.options.lineColor=this.options.lineColor||s.lineColor,this.options.dragPointFill=this.options.dragPointFill||s.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||s.dragPointStroke,this.options.dragPointSize=this.options.dragPointSize||s.dragPointSize}static create(t){return new l(t)}addPoint(t){var e;t.id||(t.id=Math.random().toString(36).slice(2));const i=this.points.findLastIndex((e=>e.time<t.time));this.points.splice(i+1,0,t),this.emitPoints();const o=null===(e=this.wavesurfer)||void 0===e?void 0:e.getDuration();o&&this.addPolyPoint(t,o)}removePoint(t){var e;const i=this.points.indexOf(t);i>-1&&(this.points.splice(i,1),null===(e=this.polyline)||void 0===e||e.removePolyPoint(t),this.emitPoints())}getPoints(){return this.points}setPoints(t){this.points.slice().forEach((t=>this.removePoint(t))),t.forEach((t=>this.addPoint(t)))}destroy(){var t;null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}getCurrentVolume(){return this.volume}setVolume(t){var e;this.volume=t,null===(e=this.wavesurfer)||void 0===e||e.setVolume(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const{options:e}=this;e.volume=null!==(t=e.volume)&&void 0!==t?t:this.wavesurfer.getVolume(),this.setVolume(e.volume),this.subscriptions.push(this.wavesurfer.on("decode",(t=>{this.initPolyline(),this.points.forEach((e=>{this.addPolyPoint(e,t)}))})),this.wavesurfer.on("redraw",(()=>{var t;null===(t=this.polyline)||void 0===t||t.update()})),this.wavesurfer.on("timeupdate",(t=>{this.onTimeUpdate(t)})))}emitPoints(){this.throttleTimeout&&clearTimeout(this.throttleTimeout),this.throttleTimeout=setTimeout((()=>{this.emit("points-change",this.points)}),200)}initPolyline(){if(this.polyline&&this.polyline.destroy(),!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new r(this.options,t),this.subscriptions.push(this.polyline.on("point-move",((t,e,i)=>{var o;const n=(null===(o=this.wavesurfer)||void 0===o?void 0:o.getDuration())||0;t.time=e*n,t.volume=1-i,this.emitPoints()})),this.polyline.on("point-dragout",(t=>{this.removePoint(t)})),this.polyline.on("point-create",((t,e)=>{var i;this.addPoint({time:t*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0),volume:1-e})})),this.polyline.on("line-move",(t=>{var e;this.points.forEach((e=>{e.volume=Math.min(1,Math.max(0,e.volume-t))})),this.emitPoints(),this.onTimeUpdate((null===(e=this.wavesurfer)||void 0===e?void 0:e.getCurrentTime())||0)})))}addPolyPoint(t,e){var i;null===(i=this.polyline)||void 0===i||i.addPolyPoint(t.time/e,t.volume,t)}onTimeUpdate(t){if(!this.wavesurfer)return;let e=this.points.find((e=>e.time>t));e||(e={time:this.wavesurfer.getDuration()||0,volume:0});let i=this.points.findLast((e=>e.time<=t));i||(i={time:0,volume:0});const o=e.time-i.time,n=e.volume-i.volume,s=i.volume+(t-i.time)*(n/o),r=Math.min(1,Math.max(0,s)),l=Math.round(100*r)/100;l!==this.getCurrentVolume()&&(this.setVolume(l),this.emit("volume-change",l))}}module.exports=l;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),null==i?void 0:i.once){const i=()=>{this.un(t,i),this.un(t,e)};return this.on(t,i),i}return()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}_init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function i(t,e,i,o,n=3,s=0,r=100){if(!t)return()=>{};const l=matchMedia("(pointer: coarse)").matches;let
|
|
1
|
+
class t{constructor(){this.listeners={}}on(t,e,i){if(this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),null==i?void 0:i.once){const i=()=>{this.un(t,i),this.un(t,e)};return this.on(t,i),i}return()=>this.un(t,e)}un(t,e){var i;null===(i=this.listeners[t])||void 0===i||i.delete(e)}once(t,e){return this.on(t,e,{once:!0})}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.isDestroyed=!1,this.options=t}onInit(){}_init(t){this.isDestroyed&&(this.subscriptions=[],this.isDestroyed=!1),this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.subscriptions=[],this.isDestroyed=!0,this.wavesurfer=void 0}}function i(t,e,i,o,n=3,s=0,r=100){if(!t)return()=>{};const l=matchMedia("(pointer: coarse)").matches;let h=()=>{};const a=a=>{if(a.button!==s)return;a.preventDefault(),a.stopPropagation();let u=a.clientX,c=a.clientY,d=!1;const p=Date.now(),m=o=>{if(o.preventDefault(),o.stopPropagation(),l&&Date.now()-p<r)return;const s=o.clientX,h=o.clientY,a=s-u,m=h-c;if(d||Math.abs(a)>n||Math.abs(m)>n){const o=t.getBoundingClientRect(),{left:n,top:r}=o;d||(null==i||i(u-n,c-r),d=!0),e(a,m,s-n,h-r),u=s,c=h}},v=e=>{if(d){const i=e.clientX,n=e.clientY,s=t.getBoundingClientRect(),{left:r,top:l}=s;null==o||o(i-r,n-l)}h()},g=t=>{t.relatedTarget&&t.relatedTarget!==document.documentElement||v(t)},f=t=>{d&&(t.stopPropagation(),t.preventDefault())},y=t=>{d&&t.preventDefault()};document.addEventListener("pointermove",m),document.addEventListener("pointerup",v),document.addEventListener("pointerout",g),document.addEventListener("pointercancel",g),document.addEventListener("touchmove",y,{passive:!1}),document.addEventListener("click",f,{capture:!0}),h=()=>{document.removeEventListener("pointermove",m),document.removeEventListener("pointerup",v),document.removeEventListener("pointerout",g),document.removeEventListener("pointercancel",g),document.removeEventListener("touchmove",y),setTimeout((()=>{document.removeEventListener("click",f,{capture:!0})}),10)}};return t.addEventListener("pointerdown",a),()=>{h(),t.removeEventListener("pointerdown",a)}}function o(t,e){const i=e.xmlns?document.createElementNS(e.xmlns,t):document.createElement(t);for(const[t,n]of Object.entries(e))if("children"===t&&n)for(const[t,e]of Object.entries(n))e instanceof Node?i.appendChild(e):"string"==typeof e?i.appendChild(document.createTextNode(e)):i.appendChild(o(t,e));else"style"===t?Object.assign(i.style,n):"textContent"===t?i.textContent=n:i.setAttribute(t,n.toString());return i}function n(t,e,i){const n=o(t,e||{});return null==i||i.appendChild(n),n}const s={points:[],lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class r extends t{constructor(t,e){super(),this.subscriptions=[],this.subscriptions=[],this.options=t,this.polyPoints=new Map;const o=e.clientWidth,s=e.clientHeight,r=n("svg",{xmlns:"http://www.w3.org/2000/svg",width:"100%",height:"100%",viewBox:`0 0 ${o} ${s}`,preserveAspectRatio:"none",style:{position:"absolute",left:"0",top:"0",zIndex:"4"},part:"envelope"},e);this.svg=r;const l=n("polyline",{xmlns:"http://www.w3.org/2000/svg",points:`0,${s} ${o},${s}`,stroke:t.lineColor,"stroke-width":t.lineWidth,fill:"none",part:"polyline",style:t.dragLine?{cursor:"row-resize",pointerEvents:"stroke"}:{}},r);t.dragLine&&this.subscriptions.push(i(l,((t,e)=>{const{height:i}=r.viewBox.baseVal,{points:o}=l;for(let t=1;t<o.numberOfItems-1;t++){const n=o.getItem(t);n.y=Math.min(i,Math.max(0,n.y+e))}const n=r.querySelectorAll("ellipse");Array.from(n).forEach((t=>{const o=Math.min(i,Math.max(0,Number(t.getAttribute("cy"))+e));t.setAttribute("cy",o.toString())})),this.emit("line-move",e/i)}))),r.addEventListener("dblclick",(t=>{const e=r.getBoundingClientRect(),i=t.clientX-e.left,o=t.clientY-e.top;this.emit("point-create",i/e.width,o/e.height)}));{let t;const e=()=>clearTimeout(t);r.addEventListener("touchstart",(i=>{1===i.touches.length?t=window.setTimeout((()=>{i.preventDefault();const t=r.getBoundingClientRect(),e=i.touches[0].clientX-t.left,o=i.touches[0].clientY-t.top;this.emit("point-create",e/t.width,o/t.height)}),500):e()})),r.addEventListener("touchmove",e),r.addEventListener("touchend",e)}}makeDraggable(t,e){this.subscriptions.push(i(t,e,(()=>t.style.cursor="grabbing"),(()=>t.style.cursor="grab"),1))}createCircle(t,e){const i=this.options.dragPointSize/2;return n("ellipse",{xmlns:"http://www.w3.org/2000/svg",cx:t,cy:e,rx:i,ry:i,fill:this.options.dragPointFill,stroke:this.options.dragPointStroke,"stroke-width":"2",style:{cursor:"grab",pointerEvents:"all"},part:"envelope-circle"},this.svg)}removePolyPoint(t){const e=this.polyPoints.get(t);if(!e)return;const{polyPoint:i,circle:o}=e,{points:n}=this.svg.querySelector("polyline"),s=Array.from(n).findIndex((t=>t.x===i.x&&t.y===i.y));n.removeItem(s),o.remove(),this.polyPoints.delete(t)}addPolyPoint(t,e,i){const{svg:o}=this,{width:n,height:s}=o.viewBox.baseVal,r=t*n,l=s-e*s,h=this.options.dragPointSize/2,a=o.createSVGPoint();a.x=t*n,a.y=s-e*s;const u=this.createCircle(r,l),{points:c}=o.querySelector("polyline"),d=Array.from(c).findIndex((t=>t.x>=r));c.insertItemBefore(a,Math.max(d,1)),this.polyPoints.set(i,{polyPoint:a,circle:u}),this.makeDraggable(u,((t,e)=>{const o=a.x+t,r=a.y+e;if(o<-h||r<-h||o>n+h||r>s+h)return void this.emit("point-dragout",i);const l=Array.from(c).find((t=>t.x>a.x)),d=Array.from(c).findLast((t=>t.x<a.x));l&&o>=l.x||d&&o<=d.x||(a.x=o,a.y=r,u.setAttribute("cx",o.toString()),u.setAttribute("cy",r.toString()),this.emit("point-move",i,o/n,r/s))}))}update(){const{svg:t}=this,e=t.viewBox.baseVal.width/t.clientWidth,i=t.viewBox.baseVal.height/t.clientHeight;t.querySelectorAll("ellipse").forEach((t=>{const o=this.options.dragPointSize/2,n=o*e,s=o*i;t.setAttribute("rx",n.toString()),t.setAttribute("ry",s.toString())}))}destroy(){this.subscriptions.forEach((t=>t())),this.polyPoints.clear(),this.svg.remove()}}class l extends e{constructor(t){super(t),this.polyline=null,this.throttleTimeout=null,this.volume=1,this.points=t.points||[],this.options=Object.assign({},s,t),this.options.lineColor=this.options.lineColor||s.lineColor,this.options.dragPointFill=this.options.dragPointFill||s.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||s.dragPointStroke,this.options.dragPointSize=this.options.dragPointSize||s.dragPointSize}static create(t){return new l(t)}addPoint(t){var e;t.id||(t.id=Math.random().toString(36).slice(2));const i=this.points.findLastIndex((e=>e.time<t.time));this.points.splice(i+1,0,t),this.emitPoints();const o=null===(e=this.wavesurfer)||void 0===e?void 0:e.getDuration();o&&this.addPolyPoint(t,o)}removePoint(t){var e;const i=this.points.indexOf(t);i>-1&&(this.points.splice(i,1),null===(e=this.polyline)||void 0===e||e.removePolyPoint(t),this.emitPoints())}getPoints(){return this.points}setPoints(t){this.points.slice().forEach((t=>this.removePoint(t))),t.forEach((t=>this.addPoint(t)))}destroy(){var t;null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}getCurrentVolume(){return this.volume}setVolume(t){var e;this.volume=t,null===(e=this.wavesurfer)||void 0===e||e.setVolume(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const{options:e}=this;e.volume=null!==(t=e.volume)&&void 0!==t?t:this.wavesurfer.getVolume(),this.setVolume(e.volume),this.subscriptions.push(this.wavesurfer.on("decode",(t=>{this.initPolyline(),this.points.forEach((e=>{this.addPolyPoint(e,t)}))})),this.wavesurfer.on("redraw",(()=>{var t;null===(t=this.polyline)||void 0===t||t.update()})),this.wavesurfer.on("timeupdate",(t=>{this.onTimeUpdate(t)})))}emitPoints(){this.throttleTimeout&&clearTimeout(this.throttleTimeout),this.throttleTimeout=setTimeout((()=>{this.emit("points-change",this.points)}),200)}initPolyline(){if(this.polyline&&this.polyline.destroy(),!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new r(this.options,t),this.subscriptions.push(this.polyline.on("point-move",((t,e,i)=>{var o;const n=(null===(o=this.wavesurfer)||void 0===o?void 0:o.getDuration())||0;t.time=e*n,t.volume=1-i,this.emitPoints()})),this.polyline.on("point-dragout",(t=>{this.removePoint(t)})),this.polyline.on("point-create",((t,e)=>{var i;this.addPoint({time:t*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0),volume:1-e})})),this.polyline.on("line-move",(t=>{var e;this.points.forEach((e=>{e.volume=Math.min(1,Math.max(0,e.volume-t))})),this.emitPoints(),this.onTimeUpdate((null===(e=this.wavesurfer)||void 0===e?void 0:e.getCurrentTime())||0)})))}addPolyPoint(t,e){var i;null===(i=this.polyline)||void 0===i||i.addPolyPoint(t.time/e,t.volume,t)}onTimeUpdate(t){if(!this.wavesurfer)return;let e=this.points.find((e=>e.time>t));e||(e={time:this.wavesurfer.getDuration()||0,volume:0});let i=this.points.findLast((e=>e.time<=t));i||(i={time:0,volume:0});const o=e.time-i.time,n=e.volume-i.volume,s=i.volume+(t-i.time)*(n/o),r=Math.min(1,Math.max(0,s)),l=Math.round(100*r)/100;l!==this.getCurrentVolume()&&(this.setVolume(l),this.emit("volume-change",l))}}export{l as default};
|