wavesurfer.js 7.0.0-beta.10 → 7.0.0-beta.12
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 +26 -7
- package/dist/draggable.js +2 -2
- package/dist/fetcher.d.ts +1 -3
- package/dist/fetcher.js +2 -6
- package/dist/player.d.ts +2 -2
- package/dist/player.js +10 -8
- package/dist/plugins/envelope.d.ts +1 -1
- package/dist/plugins/envelope.js +1 -1
- package/dist/plugins/envelope.min.cjs +1 -1
- package/dist/plugins/minimap.d.ts +1 -1
- package/dist/plugins/minimap.js +1 -1
- package/dist/plugins/minimap.min.cjs +1 -1
- package/dist/plugins/record.d.ts +1 -1
- package/dist/plugins/record.js +1 -1
- package/dist/plugins/record.min.cjs +1 -1
- package/dist/plugins/regions.d.ts +2 -2
- package/dist/plugins/regions.js +29 -35
- package/dist/plugins/regions.min.cjs +1 -1
- package/dist/plugins/spectrogram.d.ts +5 -1
- package/dist/plugins/spectrogram.js +164 -20
- package/dist/plugins/spectrogram.min.cjs +1 -1
- package/dist/plugins/timeline.d.ts +1 -1
- package/dist/plugins/timeline.js +1 -1
- package/dist/plugins/timeline.min.cjs +1 -1
- package/dist/renderer.js +5 -4
- package/dist/wavesurfer.d.ts +3 -1
- package/dist/wavesurfer.js +2 -2
- package/dist/wavesurfer.min.cjs +1 -1
- package/package.json +3 -3
- package/dist/plugins/spectrogram-fft.d.ts +0 -9
- package/dist/plugins/spectrogram-fft.js +0 -150
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ npm install --save wavesurfer.js@beta
|
|
|
27
27
|
import WaveSurfer from 'wavesurfer.js'
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
Alternatively, import it from a CDN as a ES6 module
|
|
30
|
+
Alternatively, import it from a CDN as a ES6 module:
|
|
31
31
|
|
|
32
32
|
```html
|
|
33
33
|
<script type="module">
|
|
@@ -39,12 +39,20 @@ Alternatively, import it from a CDN as a ES6 module directly in the browser:
|
|
|
39
39
|
|
|
40
40
|
Or, as a UMD script tag which exports the library as a global `WaveSurfer` variable:
|
|
41
41
|
```html
|
|
42
|
-
<script src="https://unpkg.com/wavesurfer.js@beta/dist/wavesurfer.min.cjs"></script>
|
|
42
|
+
<script type="text/javascript" src="https://unpkg.com/wavesurfer.js@beta/dist/wavesurfer.min.cjs"></script>
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
To import
|
|
45
|
+
To import one of the plugins, e.g. the Timeline plugin:
|
|
46
46
|
```js
|
|
47
|
+
import Timeline from 'wavesurfer.js/dist/plugins/timeline.js'
|
|
48
|
+
|
|
49
|
+
// or with a CDN:
|
|
50
|
+
|
|
47
51
|
import Timeline from 'https://unpkg.com/wavesurfer.js@beta/dist/plugins/timeline.js'
|
|
52
|
+
|
|
53
|
+
// or as a script tag
|
|
54
|
+
|
|
55
|
+
<script type="text/javascript" src="https://unpkg.com/wavesurfer.js@beta/dist/plugins/timeline.min.cjs"></script>
|
|
48
56
|
```
|
|
49
57
|
|
|
50
58
|
TypeScript types are included in the package, so there's no need to install `@types/wavesurfer.js`.
|
|
@@ -64,12 +72,12 @@ The "official" plugins have been completely rewritten and enhanced:
|
|
|
64
72
|
* [Minimap](https://wavesurfer-js.org/examples/#minimap.js) – a small waveform that serves as a scrollbar for the main waveform
|
|
65
73
|
* [Envelope](https://wavesurfer-js.org/examples/#envelope.js) – a graphical interface to add fade-in and -out effects and control volume
|
|
66
74
|
* [Record](https://wavesurfer-js.org/examples/#record.js) – records audio from the microphone and renders a waveform
|
|
67
|
-
* [Spectrogram](https://wavesurfer-js.org/examples/#spectrogram.js) – visualization of an audio frequency spectrum
|
|
75
|
+
* [Spectrogram](https://wavesurfer-js.org/examples/#spectrogram.js) – visualization of an audio frequency spectrum (written by @akreal)
|
|
68
76
|
|
|
69
77
|
## CSS styling
|
|
70
78
|
|
|
71
79
|
wavesurfer.js v7 is rendered into a Shadow DOM tree. This isolates its CSS from the rest of the web page.
|
|
72
|
-
However, it's still possible to style various wavesurfer.js elements
|
|
80
|
+
However, it's still possible to style various wavesurfer.js elements with CSS via the `::part()` pseudo-selector.
|
|
73
81
|
For example:
|
|
74
82
|
|
|
75
83
|
```css
|
|
@@ -107,6 +115,7 @@ Most options, events, and methods are similar to those in previous versions.
|
|
|
107
115
|
* `skipLength` – there's no `skipForward` and `skipBackward` methods anymore
|
|
108
116
|
* `splitChannelsOptions` – you should now use `splitChannels` to pass the channel options. Pass `height: 0` to hide a channel. See [this example](https://wavesurfer-js.org/examples/#split-channels.js).
|
|
109
117
|
* `xhr`, `drawingContextAttributes`, `maxCanvasWidth`, `forceDecode` – removed to reduce code complexity
|
|
118
|
+
* `barMinHeight` - the minimum bar height is now 1 pixel by default
|
|
110
119
|
|
|
111
120
|
### Removed methods
|
|
112
121
|
* `getFilters`, `setFilter` – as there's no Web Audio "backend"
|
|
@@ -127,7 +136,12 @@ Have a question about integrating wavesurfer.js on your website? Feel free to as
|
|
|
127
136
|
### FAQ
|
|
128
137
|
|
|
129
138
|
* **Q**: Does wavesurfer support large files?
|
|
130
|
-
* **A**: Since wavesurfer decodes audio entirely in the browser, large
|
|
139
|
+
* **A**: Since wavesurfer decodes audio entirely in the browser using Web Audio, large clips may result in an innacurately timed waveform or fail to decode at all due to memory constraints. We recommend using pre-decoded peaks for large files (see [this example](https://wavesurfer-js.org/examples/#predecoded.js)). You can use a tool like [bbc/audiowaveform](https://github.com/bbc/audiowaveform) to generate peaks.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
* **Q**: What about streaming audio?
|
|
144
|
+
* **A**: Streaming isn't supported because wavesurfer needs to download the entire audio file to decode and render it.
|
|
131
145
|
|
|
132
146
|
## Development
|
|
133
147
|
|
|
@@ -150,8 +164,13 @@ This command will open http://localhost:9090 in your browser with live reload, a
|
|
|
150
164
|
## Tests
|
|
151
165
|
|
|
152
166
|
The tests are written in the Cypress framework. They are a mix of e2e and visual regression tests.
|
|
153
|
-
To run the test suite locally:
|
|
154
167
|
|
|
168
|
+
To run the test suite locally, first build the project:
|
|
169
|
+
```
|
|
170
|
+
yarn build
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Then launch the tests:
|
|
155
174
|
```
|
|
156
175
|
yarn cypress
|
|
157
176
|
```
|
package/dist/draggable.js
CHANGED
|
@@ -16,11 +16,11 @@ export function makeDraggable(element, onDrag, onStart, onEnd, threshold = 5) {
|
|
|
16
16
|
const x = e.clientX;
|
|
17
17
|
const y = e.clientY;
|
|
18
18
|
if (isDragging || Math.abs(x - startX) >= threshold || Math.abs(y - startY) >= threshold) {
|
|
19
|
+
const { left, top } = element.getBoundingClientRect();
|
|
19
20
|
if (!isDragging) {
|
|
20
21
|
isDragging = true;
|
|
21
|
-
onStart?.(startX, startY);
|
|
22
|
+
onStart?.(startX - left, startY - top);
|
|
22
23
|
}
|
|
23
|
-
const { left, top } = element.getBoundingClientRect();
|
|
24
24
|
onDrag(x - startX, y - startY, x - left, y - top);
|
|
25
25
|
startX = x;
|
|
26
26
|
startY = y;
|
package/dist/fetcher.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
declare function
|
|
2
|
-
declare function fetchBlob(url: string): Promise<Blob>;
|
|
1
|
+
declare function fetchBlob(url: string, init?: RequestInit): Promise<Blob>;
|
|
3
2
|
declare const Fetcher: {
|
|
4
|
-
fetchArrayBuffer: typeof fetchArrayBuffer;
|
|
5
3
|
fetchBlob: typeof fetchBlob;
|
|
6
4
|
};
|
|
7
5
|
export default Fetcher;
|
package/dist/fetcher.js
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
async function
|
|
2
|
-
return fetch(url).then((response) => response.
|
|
3
|
-
}
|
|
4
|
-
async function fetchBlob(url) {
|
|
5
|
-
return fetch(url).then((response) => response.blob());
|
|
1
|
+
async function fetchBlob(url, init) {
|
|
2
|
+
return fetch(url, init).then((response) => response.blob());
|
|
6
3
|
}
|
|
7
4
|
const Fetcher = {
|
|
8
|
-
fetchArrayBuffer,
|
|
9
5
|
fetchBlob,
|
|
10
6
|
};
|
|
11
7
|
export default Fetcher;
|
package/dist/player.d.ts
CHANGED
|
@@ -6,13 +6,13 @@ type PlayerOptions = {
|
|
|
6
6
|
};
|
|
7
7
|
declare class Player<T extends GeneralEventTypes> extends EventEmitter<T> {
|
|
8
8
|
protected media: HTMLMediaElement;
|
|
9
|
-
private isExternalMedia;
|
|
10
9
|
constructor(options: PlayerOptions);
|
|
11
10
|
protected onMediaEvent(event: keyof HTMLMediaElementEventMap, callback: () => void, options?: AddEventListenerOptions): () => void;
|
|
12
11
|
protected onceMediaEvent(event: keyof HTMLMediaElementEventMap, callback: () => void): () => void;
|
|
12
|
+
private getSrc;
|
|
13
13
|
private revokeSrc;
|
|
14
14
|
protected setSrc(url: string, blob?: Blob): void;
|
|
15
|
-
destroy(): void;
|
|
15
|
+
protected destroy(): void;
|
|
16
16
|
/** Start playing the audio */
|
|
17
17
|
play(): Promise<void>;
|
|
18
18
|
/** Pause the audio */
|
package/dist/player.js
CHANGED
|
@@ -2,10 +2,8 @@ import EventEmitter from './event-emitter.js';
|
|
|
2
2
|
class Player extends EventEmitter {
|
|
3
3
|
constructor(options) {
|
|
4
4
|
super();
|
|
5
|
-
this.isExternalMedia = false;
|
|
6
5
|
if (options.media) {
|
|
7
6
|
this.media = options.media;
|
|
8
|
-
this.isExternalMedia = true;
|
|
9
7
|
}
|
|
10
8
|
else {
|
|
11
9
|
this.media = document.createElement('audio');
|
|
@@ -26,26 +24,30 @@ class Player extends EventEmitter {
|
|
|
26
24
|
onceMediaEvent(event, callback) {
|
|
27
25
|
return this.onMediaEvent(event, callback, { once: true });
|
|
28
26
|
}
|
|
27
|
+
getSrc() {
|
|
28
|
+
return this.media.currentSrc || this.media.src || '';
|
|
29
|
+
}
|
|
29
30
|
revokeSrc() {
|
|
30
|
-
const src = this.
|
|
31
|
+
const src = this.getSrc();
|
|
31
32
|
if (src.startsWith('blob:')) {
|
|
32
|
-
URL.revokeObjectURL(
|
|
33
|
+
URL.revokeObjectURL(src);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
setSrc(url, blob) {
|
|
36
|
-
const src = this.
|
|
37
|
+
const src = this.getSrc();
|
|
37
38
|
if (src === url)
|
|
38
39
|
return;
|
|
39
40
|
this.revokeSrc();
|
|
40
41
|
const newSrc = blob instanceof Blob ? URL.createObjectURL(blob) : url;
|
|
41
42
|
this.media.src = newSrc;
|
|
43
|
+
this.media.load();
|
|
42
44
|
}
|
|
43
45
|
destroy() {
|
|
44
46
|
this.media.pause();
|
|
45
47
|
this.revokeSrc();
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
48
|
+
this.media.src = '';
|
|
49
|
+
// Load resets the media element to its initial state
|
|
50
|
+
this.media.load();
|
|
49
51
|
}
|
|
50
52
|
/** Start playing the audio */
|
|
51
53
|
play() {
|
|
@@ -31,7 +31,7 @@ export type EnvelopePluginEvents = {
|
|
|
31
31
|
'fade-out-change': [time: number];
|
|
32
32
|
'volume-change': [volume: number];
|
|
33
33
|
};
|
|
34
|
-
declare class EnvelopePlugin extends BasePlugin<EnvelopePluginEvents, EnvelopePluginOptions> {
|
|
34
|
+
export declare class EnvelopePlugin extends BasePlugin<EnvelopePluginEvents, EnvelopePluginOptions> {
|
|
35
35
|
protected options: Options;
|
|
36
36
|
private polyline;
|
|
37
37
|
private audioContext;
|
package/dist/plugins/envelope.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Envelope=e():t.Envelope=e()}(WaveSurfer,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>a});const i=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},n=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}},s={fadeInStart:0,fadeOutEnd:0,fadeInEnd:0,fadeOutStart:0,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 o extends i{constructor(t,e){super(),this.top=0,this.padding=t.dragPointSize/2+1;const i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("viewBox","0 0 0 0"),i.setAttribute("preserveAspectRatio","none"),i.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),i.setAttribute("part","envelope"),this.svg=i;const n=document.createElementNS("http://www.w3.org/2000/svg","polyline");n.setAttribute("points","0,0 0,0 0,0 0,0"),n.setAttribute("stroke",t.lineColor),n.setAttribute("stroke-width",t.lineWidth),n.setAttribute("fill","none"),n.setAttribute("style","pointer-events: none;"),n.setAttribute("part","polyline"),i.appendChild(n);const s=document.createElementNS("http://www.w3.org/2000/svg","line");s.setAttribute("stroke","transparent"),s.setAttribute("stroke-width",(3*t.lineWidth).toString()),s.setAttribute("style","cursor: ns-resize; pointer-events: all;"),s.setAttribute("part","line"),i.appendChild(s),[0,1].forEach((()=>{const e=document.createElementNS("http://www.w3.org/2000/svg","circle");e.setAttribute("r",(t.dragPointSize/2).toString()),e.setAttribute("fill",t.dragPointFill),e.setAttribute("stroke",t.dragPointStroke||t.dragPointFill),e.setAttribute("stroke-width","2"),e.setAttribute("style","cursor: ew-resize; pointer-events: all;"),e.setAttribute("part","circle"),i.appendChild(e)})),e.appendChild(i);{const t=t=>{const e=this.top+t,{height:n}=i.viewBox.baseVal;if(e<-.5||e>n)return;const s=Math.min(1,Math.max(0,(n-e)/n));this.emit("line-move",s)},e=(t,e)=>{const s=n.points.getItem(t).x+e,{width:o}=i.viewBox.baseVal;this.emit("point-move",t,s/o)};this.makeDraggable(s,((e,i)=>t(i)));const o=this.svg.querySelectorAll("circle");Array.from(o).forEach(((t,i)=>{this.makeDraggable(t,(t=>e(i+1,t)))}))}}makeDraggable(t,e){!function(t,e,i,n,s=5){let o=()=>{};if(!t)return o;t.addEventListener("pointerdown",(r=>{r.preventDefault(),r.stopPropagation();let a=r.clientX,u=r.clientY,h=!1;const d=n=>{n.preventDefault(),n.stopPropagation();const o=n.clientX,r=n.clientY;if(h||Math.abs(o-a)>=s||Math.abs(r-u)>=s){
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Envelope=e():t.Envelope=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>a});const i=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},n=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}},s={fadeInStart:0,fadeOutEnd:0,fadeInEnd:0,fadeOutStart:0,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 o extends i{constructor(t,e){super(),this.top=0,this.padding=t.dragPointSize/2+1;const i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("viewBox","0 0 0 0"),i.setAttribute("preserveAspectRatio","none"),i.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),i.setAttribute("part","envelope"),this.svg=i;const n=document.createElementNS("http://www.w3.org/2000/svg","polyline");n.setAttribute("points","0,0 0,0 0,0 0,0"),n.setAttribute("stroke",t.lineColor),n.setAttribute("stroke-width",t.lineWidth),n.setAttribute("fill","none"),n.setAttribute("style","pointer-events: none;"),n.setAttribute("part","polyline"),i.appendChild(n);const s=document.createElementNS("http://www.w3.org/2000/svg","line");s.setAttribute("stroke","transparent"),s.setAttribute("stroke-width",(3*t.lineWidth).toString()),s.setAttribute("style","cursor: ns-resize; pointer-events: all;"),s.setAttribute("part","line"),i.appendChild(s),[0,1].forEach((()=>{const e=document.createElementNS("http://www.w3.org/2000/svg","circle");e.setAttribute("r",(t.dragPointSize/2).toString()),e.setAttribute("fill",t.dragPointFill),e.setAttribute("stroke",t.dragPointStroke||t.dragPointFill),e.setAttribute("stroke-width","2"),e.setAttribute("style","cursor: ew-resize; pointer-events: all;"),e.setAttribute("part","circle"),i.appendChild(e)})),e.appendChild(i);{const t=t=>{const e=this.top+t,{height:n}=i.viewBox.baseVal;if(e<-.5||e>n)return;const s=Math.min(1,Math.max(0,(n-e)/n));this.emit("line-move",s)},e=(t,e)=>{const s=n.points.getItem(t).x+e,{width:o}=i.viewBox.baseVal;this.emit("point-move",t,s/o)};this.makeDraggable(s,((e,i)=>t(i)));const o=this.svg.querySelectorAll("circle");Array.from(o).forEach(((t,i)=>{this.makeDraggable(t,(t=>e(i+1,t)))}))}}makeDraggable(t,e){!function(t,e,i,n,s=5){let o=()=>{};if(!t)return o;t.addEventListener("pointerdown",(r=>{r.preventDefault(),r.stopPropagation();let a=r.clientX,u=r.clientY,h=!1;const d=n=>{n.preventDefault(),n.stopPropagation();const o=n.clientX,r=n.clientY;if(h||Math.abs(o-a)>=s||Math.abs(r-u)>=s){const{left:n,top:s}=t.getBoundingClientRect();h||(h=!0,i?.(a-n,u-s)),e(o-a,r-u,o-n,r-s),a=o,u=r}},l=t=>{h&&(t.preventDefault(),t.stopPropagation())},p=()=>{h&&n?.(),o()};o=()=>{document.removeEventListener("pointermove",d),document.removeEventListener("pointerup",p),document.removeEventListener("pointerleave",p),setTimeout((()=>{document.removeEventListener("click",l,!0)}),10)},document.addEventListener("pointermove",d),document.addEventListener("pointerup",p),document.addEventListener("pointerleave",p),document.addEventListener("click",l,!0)}))}(t,e)}update({x1:t,x2:e,x3:i,x4:n,y:s}){const o=this.svg.clientWidth,r=this.svg.clientHeight;this.top=r-s*r;const a=Math.max(this.padding,Math.min(this.top,r-this.padding));this.svg.setAttribute("viewBox",`0 0 ${o} ${r}`);const u=this.svg.querySelector("polyline"),{points:h}=u;h.getItem(0).x=t*o,h.getItem(0).y=r,h.getItem(1).x=e*o,h.getItem(1).y=a,h.getItem(2).x=i*o,h.getItem(2).y=a,h.getItem(3).x=n*o,h.getItem(3).y=r;const d=this.svg.querySelector("line");d.setAttribute("x1",h.getItem(1).x.toString()),d.setAttribute("x2",h.getItem(2).x.toString()),d.setAttribute("y1",a.toString()),d.setAttribute("y2",a.toString());const l=this.svg.querySelectorAll("circle");Array.from(l).forEach(((t,e)=>{const i=h.getItem(e+1);t.setAttribute("cx",i.x.toString()),t.setAttribute("cy",i.y.toString())}))}destroy(){this.svg.remove()}}class r extends n{constructor(t){super(t),this.polyline=null,this.audioContext=null,this.gainNode=null,this.volume=1,this.isFadingIn=!1,this.isFadingOut=!1,this.naturalVolumeExponent=1.5,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.volume=this.options.volume??1}static create(t){return new r(t)}destroy(){this.polyline?.destroy(),super.destroy()}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.initWebAudio(),this.initSvg(),this.initFadeEffects(),this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{const t=this.wavesurfer?.getDuration();t&&(this.options.fadeInStart=this.options.fadeInStart||0,this.options.fadeOutEnd=this.options.fadeOutEnd||t,this.options.fadeInEnd=this.options.fadeInEnd||this.options.fadeInStart,this.options.fadeOutStart=this.options.fadeOutStart||this.options.fadeOutEnd,this.renderPolyline())})))}initSvg(){if(!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new o(this.options,t),this.subscriptions.push(this.polyline.on("line-move",(t=>{this.setVolume(this.naturalVolume(t))})),this.polyline.on("point-move",((t,e)=>{const i=e*(this.wavesurfer?.getDuration()||0);if(1===t){if(i<this.options.fadeInStart||i>this.options.fadeOutStart)return;this.options.fadeInEnd=i,this.emit("fade-in-change",i)}else if(2===t){if(i>this.options.fadeOutEnd||i<this.options.fadeInEnd)return;this.options.fadeOutStart=i,this.emit("fade-out-change",i)}this.renderPolyline()})))}renderPolyline(){if(!this.polyline||!this.wavesurfer)return;const t=this.wavesurfer.getDuration();t&&this.polyline.update({x1:this.options.fadeInStart/t,x2:this.options.fadeInEnd/t,x3:this.options.fadeOutStart/t,x4:this.options.fadeOutEnd/t,y:this.invertNaturalVolume(this.volume)})}initWebAudio(){const t=this.wavesurfer?.getMediaElement();if(!t)return null;this.volume=this.options.volume??t.volume;const e=new window.AudioContext;this.gainNode=e.createGain(),this.setGainValue(),e.createMediaElementSource(t).connect(this.gainNode),this.gainNode.connect(e.destination),this.audioContext=e}invertNaturalVolume(t){return Math.pow((t-1e-4)/.9999,1/this.naturalVolumeExponent)}naturalVolume(t){return 1e-4+.9999*Math.pow(t,this.naturalVolumeExponent)}setGainValue(){this.gainNode&&(this.gainNode.gain.value=this.volume)}initFadeEffects(){if(!this.audioContext||!this.wavesurfer)return;const t=this.wavesurfer.on("timeupdate",(t=>{if(!this.audioContext||!this.gainNode)return;if(!this.wavesurfer?.isPlaying())return;if("suspended"===this.audioContext.state&&this.audioContext.resume(),!this.isFadingIn&&t>=this.options.fadeInStart&&t<=this.options.fadeInEnd)return this.isFadingIn=!0,this.gainNode.gain.setValueAtTime(0,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(this.volume,this.audioContext.currentTime+(this.options.fadeInEnd-t));if(!this.isFadingOut&&t>=this.options.fadeOutStart&&t<=this.options.fadeOutEnd)return this.isFadingOut=!0,this.gainNode.gain.setValueAtTime(this.volume,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(0,this.audioContext.currentTime+(this.options.fadeOutEnd-t));let e=!1;this.isFadingIn&&(t<this.options.fadeInStart||t>this.options.fadeInEnd)&&(this.isFadingIn=!1,e=!0),this.isFadingOut&&(t<this.options.fadeOutStart||t>=this.options.fadeOutEnd)&&(this.isFadingOut=!1,e=!0),e&&(this.gainNode.gain.cancelScheduledValues(this.audioContext.currentTime),this.setGainValue())}));this.subscriptions.push(t)}getCurrentVolume(){return this.gainNode?this.gainNode.gain.value:this.volume}setStartTime(t,e=!1){if(e){const e=this.options.fadeInEnd-this.options.fadeInStart;this.options.fadeInEnd=t+e}this.options.fadeInStart=t,this.renderPolyline()}setEndTime(t,e=!1){if(e){const e=this.options.fadeOutEnd-this.options.fadeOutStart;this.options.fadeOutStart=t-e}this.options.fadeOutEnd=t,this.renderPolyline()}setVolume(t){this.volume=t,this.setGainValue(),this.renderPolyline(),this.emit("volume-change",t)}}const a=r;return e.default})()));
|
|
@@ -16,7 +16,7 @@ export type MinimapPluginEvents = {
|
|
|
16
16
|
ready: [];
|
|
17
17
|
interaction: [];
|
|
18
18
|
};
|
|
19
|
-
declare class MinimapPlugin extends BasePlugin<MinimapPluginEvents, MinimapPluginOptions> {
|
|
19
|
+
export declare class MinimapPlugin extends BasePlugin<MinimapPluginEvents, MinimapPluginOptions> {
|
|
20
20
|
protected options: MinimapPluginOptions & typeof defaultOptions;
|
|
21
21
|
private minimapWrapper;
|
|
22
22
|
private miniWavesurfer;
|
package/dist/plugins/minimap.js
CHANGED
|
@@ -8,7 +8,7 @@ const defaultOptions = {
|
|
|
8
8
|
overlayColor: 'rgba(100, 100, 100, 0.1)',
|
|
9
9
|
insertPosition: 'afterend',
|
|
10
10
|
};
|
|
11
|
-
class MinimapPlugin extends BasePlugin {
|
|
11
|
+
export class MinimapPlugin extends BasePlugin {
|
|
12
12
|
constructor(options) {
|
|
13
13
|
super(options);
|
|
14
14
|
this.miniWavesurfer = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Minimap=e():t.Minimap=e()}(WaveSurfer,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>g});const i=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},s=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}},r={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},n=async function(t){return fetch(t).then((t=>t.blob()))},o=class extends i{constructor(t){super(),this.isExternalMedia=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}revokeSrc(){(this.media.currentSrc||this.media.src||"").startsWith("blob:")&&URL.revokeObjectURL(this.media.currentSrc)}setSrc(t,e){if((this.media.currentSrc||this.media.src||"")===t)return;this.revokeSrc();const i=e instanceof Blob?URL.createObjectURL(e):t;this.media.src=i}destroy(){this.media.pause(),this.revokeSrc(),this.isExternalMedia||this.media.remove()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}};class a extends i{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");this.parent=e;const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,r=(t+i)/e;this.emit("scroll",s,r)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){!function(t,e,i,s,r=5){let n=()=>{};if(!t)return n;t.addEventListener("pointerdown",(o=>{o.preventDefault(),o.stopPropagation();let a=o.clientX,h=o.clientY,l=!1;const c=s=>{s.preventDefault(),s.stopPropagation();const n=s.clientX,o=s.clientY;if(l||Math.abs(n-a)>=r||Math.abs(o-h)>=r){l||(l=!0,i?.(a,h));const{left:s,top:r}=t.getBoundingClientRect();e(n-a,o-h,n-s,o-r),a=n,h=o}},d=t=>{l&&(t.preventDefault(),t.stopPropagation())},u=()=>{l&&s?.(),n()};n=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",u),document.removeEventListener("pointerleave",u),setTimeout((()=>{document.removeEventListener("click",d,!0)}),10)},document.addEventListener("pointermove",c),document.addEventListener("pointerup",u),document.addEventListener("pointerleave",u),document.addEventListener("click",d,!0)}))}(this.wrapper,((t,e,i)=>{this.emit("drag",Math.max(0,Math.min(1,i/this.wrapper.clientWidth)))}),(()=>this.isDragging=!0),(()=>this.isDragging=!1))}getHeight(){return null==this.options.height?128:isNaN(Number(this.options.height))?"auto"===this.options.height&&this.parent.clientHeight||128:Number(this.options.height)}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.getHeight()}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress" part="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return t[0]||"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const r=e*s;i.addColorStop(r,t)})),i}renderBars(t,e,i){if(i.fillStyle=this.convertColorValues(e.waveColor),e.renderFunction)return void e.renderFunction(t,i);const s=t[0],r=t[1]||t[0],n=s.length,o=window.devicePixelRatio||1,{width:a,height:h}=i.canvas,l=h/2,c=e.barHeight||1,d=e.barWidth?e.barWidth*o:1,u=e.barGap?e.barGap*o:e.barWidth?d/2:0,p=e.barRadius||0,m=a/(d+u)/n;let g=1;if(e.normalize){g=0;for(let t=0;t<n;t++){const e=Math.abs(s[t]);e>g&&(g=e)}}const v=l/g*c;i.beginPath();let f=0,y=0,b=0;for(let t=0;t<=n;t++){const n=Math.round(t*m);if(n>f){const t=Math.round(y*v),s=t+Math.round(b*v)||1;let r=l-t;"top"===e.barAlign?r=0:"bottom"===e.barAlign&&(r=h-s),i.roundRect(f*(d+u),r,d,s,p),f=n,y=0,b=0}const o=Math.abs(s[t]||0),a=Math.abs(r[t]||0);o>y&&(y=o),a>b&&(b=a)}i.fill(),i.closePath()}renderSingleCanvas(t,e,i,s,r,n,o,a){const h=window.devicePixelRatio||1,l=document.createElement("canvas"),c=t[0].length;l.width=Math.round(i*(n-r)/c),l.height=s*h,l.style.width=`${Math.floor(l.width/h)}px`,l.style.height=`${s}px`,l.style.left=`${Math.floor(r*i/h/c)}px`,o.appendChild(l);const d=l.getContext("2d");this.renderBars(t.map((t=>t.slice(r,n))),e,d);const u=l.cloneNode();a.appendChild(u);const p=u.getContext("2d");l.width>0&&l.height>0&&p.drawImage(l,0,0),p.globalCompositeOperation="source-in",p.fillStyle=this.convertColorValues(e.progressColor),p.fillRect(0,0,l.width,l.height)}renderWaveform(t,e,i){const s=document.createElement("div"),r=this.getHeight();s.style.height=`${r}px`,this.canvasWrapper.style.minHeight=`${r}px`,this.canvasWrapper.appendChild(s);const n=s.cloneNode();this.progressWrapper.appendChild(n);const{scrollLeft:o,scrollWidth:h,clientWidth:l}=this.scrollContainer,c=t[0].length,d=c/h;let u=Math.min(a.MAX_CANVAS_WIDTH,l);if(e.barWidth||e.barGap){const t=e.barWidth||.5,i=t+(e.barGap||t/2);u%i!=0&&(u=Math.floor(u/i)*i)}const p=Math.floor(Math.abs(o)*d),m=Math.floor(p+u*d),g=m-p,v=(o,a)=>{this.renderSingleCanvas(t,e,i,r,Math.max(0,o),Math.min(a,c),s,n)},f=this.createDelay(),y=this.createDelay(),b=(t,e)=>{v(t,e),t>0&&f((()=>{b(t-g,e-g)}))},w=(t,e)=>{v(t,e),e<c&&y((()=>{w(t+g,e+g)}))};b(p,m),m<c&&w(m,m+g)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[];const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const r=this.options.fillParent&&!this.isScrolling,n=(r?i:s)*e;if(this.wrapper.style.width=r?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i={...this.options,...this.options.splitChannels[e]};this.renderWaveform([t.getChannelData(e)],i,n)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,n)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:r}=this.scrollContainer,n=r*t,o=i/2;if(n>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||n<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;n-(s+o)>=t&&n<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=n-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=n<s?n-t:n-i+t}else this.scrollContainer.scrollLeft=n;{const{scrollLeft:t}=this.scrollContainer,e=t/r,s=(t+i)/r;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}a.MAX_CANVAS_WIDTH=4e3;const h=a,l=class extends i{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}},c={waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class d extends o{static create(t){return new d(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.duration=null,this.subscriptions=[],this.options=Object.assign({},c,t),this.timer=new l,this.renderer=new h(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options=Object.assign({},this.options,t),this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction",this.getCurrentTime()),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction",e*this.getDuration()),this.emit("drag",e))})))}}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(t,e,i){this.decodedData=null,this.duration=null,this.emit("load",t);const s=e?void 0:await n(t);if(this.setSrc(t,s),this.duration=i||this.getDuration()||await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getDuration())))}))||0,e)this.decodedData=r.createBuffer(e,this.duration);else if(s){const t=await s.arrayBuffer();this.decodedData=await r.decode(t,this.options.sampleRate),0!==this.duration&&this.duration!==1/0||(this.duration=this.decodedData.duration)}this.emit("decode",this.duration),this.decodedData&&this.renderer.render(this.decodedData),this.emit("ready",this.duration)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){return null!==this.duration?this.duration:super.getDuration()}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}async playPause(){return this.isPlaying()?this.pause():this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const u=d,p={height:50,overlayColor:"rgba(100, 100, 100, 0.1)",insertPosition:"afterend"};class m extends s{constructor(t){super(t),this.miniWavesurfer=null,this.container=null,this.options=Object.assign({},p,t),this.minimapWrapper=this.initMinimapWrapper(),this.overlay=this.initOverlay()}static create(t){return new m(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.options.container?("string"==typeof this.options.container?this.container=document.querySelector(this.options.container):this.options.container instanceof HTMLElement&&(this.container=this.options.container),this.container?.appendChild(this.minimapWrapper)):(this.container=this.wavesurfer.getWrapper().parentElement,this.container?.insertAdjacentElement(this.options.insertPosition,this.minimapWrapper)),this.initWaveSurferEvents()}initMinimapWrapper(){const t=document.createElement("div");return t.style.position="relative",t.setAttribute("part","minimap"),t}initOverlay(){const t=document.createElement("div");return t.setAttribute("style","position: absolute; z-index: 2; left: 0; top: 0; bottom: 0; transition: left 100ms ease-out; pointer-events: none;"),t.style.backgroundColor=this.options.overlayColor,this.minimapWrapper.appendChild(t),t}initMinimap(){if(this.miniWavesurfer&&(this.miniWavesurfer.destroy(),this.miniWavesurfer=null),!this.wavesurfer)return;const t=this.wavesurfer.getDecodedData(),e=this.wavesurfer.getMediaElement();t&&e&&(this.miniWavesurfer=u.create({...this.options,container:this.minimapWrapper,minPxPerSec:0,fillParent:!0,media:e,peaks:[t.getChannelData(0)],duration:t.duration}),this.subscriptions.push(this.miniWavesurfer.on("ready",(()=>{this.emit("ready")})),this.miniWavesurfer.on("interaction",(()=>{this.emit("interaction")}))))}getOverlayWidth(){const t=this.wavesurfer?.getWrapper().clientWidth||1;return Math.round(this.minimapWrapper.clientWidth/t*100)}onRedraw(){const t=this.getOverlayWidth();this.overlay.style.width=`${t}%`}onScroll(t){if(!this.wavesurfer)return;const e=this.wavesurfer.getDuration();this.overlay.style.left=t/e*100+"%"}initWaveSurferEvents(){this.wavesurfer&&this.subscriptions.push(this.wavesurfer.on("decode",(()=>{this.initMinimap()})),this.wavesurfer.on("scroll",(t=>{this.onScroll(t)})),this.wavesurfer.on("redraw",(()=>{this.onRedraw()})))}destroy(){this.miniWavesurfer?.destroy(),this.minimapWrapper.remove(),super.destroy()}}const g=m;return e.default})()));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Minimap=e():t.Minimap=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var s in i)t.o(i,s)&&!t.o(e,s)&&Object.defineProperty(e,s,{enumerable:!0,get:i[s]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>g});const i=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),s=this.on(t,(()=>{i(),s()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},s=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.subscriptions.forEach((t=>t()))}},r={decode:async function(t,e){const i=new AudioContext({sampleRate:e}),s=i.decodeAudioData(t);return s.finally((()=>i.close())),s},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}},n=async function(t,e){return fetch(t,e).then((t=>t.blob()))},o=class extends i{constructor(t){super(),t.media?this.media=t.media:this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}getSrc(){return this.media.currentSrc||this.media.src||""}revokeSrc(){const t=this.getSrc();t.startsWith("blob:")&&URL.revokeObjectURL(t)}setSrc(t,e){if(this.getSrc()===t)return;this.revokeSrc();const i=e instanceof Blob?URL.createObjectURL(e):t;this.media.src=i,this.media.load()}destroy(){this.media.pause(),this.revokeSrc(),this.media.src="",this.media.load()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}};class a extends i{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");this.parent=e;const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,r=(t+i)/e;this.emit("scroll",s,r)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){!function(t,e,i,s,r=5){let n=()=>{};if(!t)return n;t.addEventListener("pointerdown",(o=>{o.preventDefault(),o.stopPropagation();let a=o.clientX,h=o.clientY,l=!1;const c=s=>{s.preventDefault(),s.stopPropagation();const n=s.clientX,o=s.clientY;if(l||Math.abs(n-a)>=r||Math.abs(o-h)>=r){const{left:s,top:r}=t.getBoundingClientRect();l||(l=!0,i?.(a-s,h-r)),e(n-a,o-h,n-s,o-r),a=n,h=o}},d=t=>{l&&(t.preventDefault(),t.stopPropagation())},u=()=>{l&&s?.(),n()};n=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",u),document.removeEventListener("pointerleave",u),setTimeout((()=>{document.removeEventListener("click",d,!0)}),10)},document.addEventListener("pointermove",c),document.addEventListener("pointerup",u),document.addEventListener("pointerleave",u),document.addEventListener("click",d,!0)}))}(this.wrapper,((t,e,i)=>{this.emit("drag",Math.max(0,Math.min(1,i/this.wrapper.clientWidth)))}),(()=>this.isDragging=!0),(()=>this.isDragging=!1))}getHeight(){return null==this.options.height?128:isNaN(Number(this.options.height))?"auto"===this.options.height&&this.parent.clientHeight||128:Number(this.options.height)}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.getHeight()}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress" part="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){this.container.remove(),this.resizeObserver?.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return t[0]||"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const r=e*s;i.addColorStop(r,t)})),i}renderBars(t,e,i){if(i.fillStyle=this.convertColorValues(e.waveColor),e.renderFunction)return void e.renderFunction(t,i);const s=t[0],r=t[1]||t[0],n=s.length,o=window.devicePixelRatio||1,{width:a,height:h}=i.canvas,l=h/2,c=e.barHeight||1,d=e.barWidth?e.barWidth*o:1,u=e.barGap?e.barGap*o:e.barWidth?d/2:0,p=e.barRadius||0,m=a/(d+u)/n;let g=1;if(e.normalize){g=0;for(let t=0;t<n;t++){const e=Math.abs(s[t]);e>g&&(g=e)}}const v=l/g*c;i.beginPath();let f=0,y=0,b=0;for(let t=0;t<=n;t++){const n=Math.round(t*m);if(n>f){const t=Math.round(y*v),s=t+Math.round(b*v)||1;let r=l-t;"top"===e.barAlign?r=0:"bottom"===e.barAlign&&(r=h-s),i.roundRect(f*(d+u),r,d,s,p),f=n,y=0,b=0}const o=Math.abs(s[t]||0),a=Math.abs(r[t]||0);o>y&&(y=o),a>b&&(b=a)}i.fill(),i.closePath()}renderSingleCanvas(t,e,i,s,r,n,o,a){const h=window.devicePixelRatio||1,l=document.createElement("canvas"),c=t[0].length;l.width=Math.round(i*(n-r)/c),l.height=s*h,l.style.width=`${Math.floor(l.width/h)}px`,l.style.height=`${s}px`,l.style.left=`${Math.floor(r*i/h/c)}px`,o.appendChild(l);const d=l.getContext("2d");this.renderBars(t.map((t=>t.slice(r,n))),e,d);const u=l.cloneNode();a.appendChild(u);const p=u.getContext("2d");l.width>0&&l.height>0&&p.drawImage(l,0,0),p.globalCompositeOperation="source-in",p.fillStyle=this.convertColorValues(e.progressColor),p.fillRect(0,0,l.width,l.height)}renderWaveform(t,e,i){const s=document.createElement("div"),r=this.getHeight();s.style.height=`${r}px`,this.canvasWrapper.style.minHeight=`${r}px`,this.canvasWrapper.appendChild(s);const n=s.cloneNode();this.progressWrapper.appendChild(n);const{scrollLeft:o,scrollWidth:h,clientWidth:l}=this.scrollContainer,c=t[0].length,d=c/h;let u=Math.min(a.MAX_CANVAS_WIDTH,l);if(e.barWidth||e.barGap){const t=e.barWidth||.5,i=t+(e.barGap||t/2);u%i!=0&&(u=Math.floor(u/i)*i)}const p=Math.floor(Math.abs(o)*d),m=Math.floor(p+u*d),g=m-p,v=(o,a)=>{this.renderSingleCanvas(t,e,i,r,Math.max(0,o),Math.min(a,c),s,n)},f=this.createDelay(),y=this.createDelay(),b=(t,e)=>{v(t,e),t>0&&f((()=>{b(t-g,e-g)}))},w=(t,e)=>{v(t,e),e<c&&y((()=>{w(t+g,e+g)}))};b(p,m),m<c&&w(m,m+g)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[],this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.wrapper.style.width="";const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const r=this.options.fillParent&&!this.isScrolling,n=(r?i:s)*e;if(this.wrapper.style.width=r?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i={...this.options,...this.options.splitChannels[e]};this.renderWaveform([t.getChannelData(e)],i,n)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,n)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:r}=this.scrollContainer,n=r*t,o=i/2;if(n>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||n<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;n-(s+o)>=t&&n<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=n-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=n<s?n-t:n-i+t}else this.scrollContainer.scrollLeft=n;{const{scrollLeft:t}=this.scrollContainer,e=t/r,s=(t+i)/r;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}a.MAX_CANVAS_WIDTH=4e3;const h=a,l=class extends i{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}},c={waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class d extends o{static create(t){return new d(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.duration=null,this.subscriptions=[],this.options=Object.assign({},c,t),this.timer=new l,this.renderer=new h(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const e=this.options.url||this.options.media?.currentSrc||this.options.media?.src;e&&this.load(e,this.options.peaks,this.options.duration)}setOptions(t){this.options=Object.assign({},this.options,t),this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction",this.getCurrentTime()),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction",e*this.getDuration()),this.emit("drag",e))})))}}initPlugins(){this.options.plugins?.length&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}async load(t,e,i){this.decodedData=null,this.duration=null,this.emit("load",t);const s=e?void 0:await n(t,this.options.fetchParams);if(this.setSrc(t,s),this.duration=i||this.getDuration()||await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getDuration())))}))||0,e)this.decodedData=r.createBuffer(e,this.duration);else if(s){const t=await s.arrayBuffer();this.decodedData=await r.decode(t,this.options.sampleRate),0!==this.duration&&this.duration!==1/0||(this.duration=this.decodedData.duration)}this.emit("decode",this.duration),this.decodedData&&this.renderer.render(this.decodedData),this.emit("ready",this.duration)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){return null!==this.duration?this.duration:super.getDuration()}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}async playPause(){return this.isPlaying()?this.pause():this.play()}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t())),this.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const u=d,p={height:50,overlayColor:"rgba(100, 100, 100, 0.1)",insertPosition:"afterend"};class m extends s{constructor(t){super(t),this.miniWavesurfer=null,this.container=null,this.options=Object.assign({},p,t),this.minimapWrapper=this.initMinimapWrapper(),this.overlay=this.initOverlay()}static create(t){return new m(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.options.container?("string"==typeof this.options.container?this.container=document.querySelector(this.options.container):this.options.container instanceof HTMLElement&&(this.container=this.options.container),this.container?.appendChild(this.minimapWrapper)):(this.container=this.wavesurfer.getWrapper().parentElement,this.container?.insertAdjacentElement(this.options.insertPosition,this.minimapWrapper)),this.initWaveSurferEvents()}initMinimapWrapper(){const t=document.createElement("div");return t.style.position="relative",t.setAttribute("part","minimap"),t}initOverlay(){const t=document.createElement("div");return t.setAttribute("style","position: absolute; z-index: 2; left: 0; top: 0; bottom: 0; transition: left 100ms ease-out; pointer-events: none;"),t.style.backgroundColor=this.options.overlayColor,this.minimapWrapper.appendChild(t),t}initMinimap(){if(this.miniWavesurfer&&(this.miniWavesurfer.destroy(),this.miniWavesurfer=null),!this.wavesurfer)return;const t=this.wavesurfer.getDecodedData(),e=this.wavesurfer.getMediaElement();t&&e&&(this.miniWavesurfer=u.create({...this.options,container:this.minimapWrapper,minPxPerSec:0,fillParent:!0,media:e,peaks:[t.getChannelData(0)],duration:t.duration}),this.subscriptions.push(this.miniWavesurfer.on("ready",(()=>{this.emit("ready")})),this.miniWavesurfer.on("interaction",(()=>{this.emit("interaction")}))))}getOverlayWidth(){const t=this.wavesurfer?.getWrapper().clientWidth||1;return Math.round(this.minimapWrapper.clientWidth/t*100)}onRedraw(){const t=this.getOverlayWidth();this.overlay.style.width=`${t}%`}onScroll(t){if(!this.wavesurfer)return;const e=this.wavesurfer.getDuration();this.overlay.style.left=t/e*100+"%"}initWaveSurferEvents(){this.wavesurfer&&this.subscriptions.push(this.wavesurfer.on("decode",(()=>{this.initMinimap()})),this.wavesurfer.on("scroll",(t=>{this.onScroll(t)})),this.wavesurfer.on("redraw",(()=>{this.onRedraw()})))}destroy(){this.miniWavesurfer?.destroy(),this.minimapWrapper.remove(),super.destroy()}}const g=m;return e.default})()));
|
package/dist/plugins/record.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ export type RecordPluginEvents = {
|
|
|
12
12
|
startRecording: [];
|
|
13
13
|
stopRecording: [];
|
|
14
14
|
};
|
|
15
|
-
declare class RecordPlugin extends BasePlugin<RecordPluginEvents, RecordPluginOptions> {
|
|
15
|
+
export declare class RecordPlugin extends BasePlugin<RecordPluginEvents, RecordPluginOptions> {
|
|
16
16
|
private mediaRecorder;
|
|
17
17
|
private recordedUrl;
|
|
18
18
|
static create(options?: RecordPluginOptions): RecordPlugin;
|
package/dist/plugins/record.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import BasePlugin from '../base-plugin.js';
|
|
5
5
|
const MIME_TYPES = ['audio/webm', 'audio/wav', 'audio/mpeg', 'audio/mp4', 'audio/mp3'];
|
|
6
6
|
const findSupportedMimeType = () => MIME_TYPES.find((mimeType) => MediaRecorder.isTypeSupported(mimeType));
|
|
7
|
-
class RecordPlugin extends BasePlugin {
|
|
7
|
+
export class RecordPlugin extends BasePlugin {
|
|
8
8
|
constructor() {
|
|
9
9
|
super(...arguments);
|
|
10
10
|
this.mediaRecorder = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Record=t():e.Record=t()}(WaveSurfer,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>n});const r=class{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const r=this.on(e,t),i=this.on(e,(()=>{r(),i()}));return r}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}},i=class extends r{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.subscriptions.forEach((e=>e()))}},s=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class o extends i{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new o(e||{})}loadBlob(e,t){const r=new Blob(e,{type:t});this.recordedUrl=URL.createObjectURL(r),this.wavesurfer?.load(this.recordedUrl)}render(e){if(!this.wavesurfer)return()=>{};const t=this.wavesurfer.getWrapper(),r=document.createElement("canvas");r.width=t.clientWidth,r.height=t.clientHeight,r.style.zIndex="10",t.appendChild(r);const i=r.getContext("2d"),s=new AudioContext,o=s.createMediaStreamSource(e),n=s.createAnalyser();let
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Record=t():e.Record=t()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var e={d:(t,r)=>{for(var i in r)e.o(r,i)&&!e.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:r[i]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>n});const r=class{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const r=this.on(e,t),i=this.on(e,(()=>{r(),i()}));return r}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}},i=class extends r{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.subscriptions.forEach((e=>e()))}},s=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class o extends i{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new o(e||{})}loadBlob(e,t){const r=new Blob(e,{type:t});this.recordedUrl=URL.createObjectURL(r),this.wavesurfer?.load(this.recordedUrl)}render(e){if(!this.wavesurfer)return()=>{};const t=this.wavesurfer.getWrapper(),r=document.createElement("canvas");r.width=t.clientWidth,r.height=t.clientHeight,r.style.zIndex="10",t.appendChild(r);const i=r.getContext("2d"),s=new AudioContext,o=s.createMediaStreamSource(e),n=s.createAnalyser();let d;o.connect(n);const a=()=>{if(!i)return;i.clearRect(0,0,r.width,r.height);const e=n.frequencyBinCount,t=new Uint8Array(e);n.getByteTimeDomainData(t),i.lineWidth=this.options.lineWidth||2;const s=this.options.realtimeWaveColor||this.wavesurfer?.options.waveColor||"";i.strokeStyle=Array.isArray(s)?s[0]:s,i.beginPath();const o=1*r.width/e;let c=0;for(let s=0;s<e;s++){const e=t[s]/128*r.height/2;0===s?i.moveTo(c,e):i.lineTo(c,e),c+=o}i.lineTo(r.width,r.height/2),i.stroke(),d=requestAnimationFrame(a)};return a(),()=>{d&&cancelAnimationFrame(d),o&&(o.disconnect(),o.mediaStream.getTracks().forEach((e=>e.stop()))),s&&s.close(),r?.remove()}}cleanUp(){this.stopRecording(),this.wavesurfer?.empty(),this.recordedUrl&&(URL.revokeObjectURL(this.recordedUrl),this.recordedUrl="")}async startRecording(){let e;this.cleanUp();try{e=await navigator.mediaDevices.getUserMedia({audio:!0})}catch(e){throw new Error("Error accessing the microphone: "+e.message)}const t=this.render(e),r=new MediaRecorder(e,{mimeType:this.options.mimeType||s.find((e=>MediaRecorder.isTypeSupported(e))),audioBitsPerSecond:this.options.audioBitsPerSecond}),i=[];r.addEventListener("dataavailable",(e=>{e.data.size>0&&i.push(e.data)})),r.addEventListener("stop",(()=>{t(),this.loadBlob(i,r.mimeType),this.emit("stopRecording")})),r.start(),this.emit("startRecording"),this.mediaRecorder=r}isRecording(){return"recording"===this.mediaRecorder?.state}stopRecording(){this.isRecording()&&this.mediaRecorder?.stop()}getRecordedUrl(){return this.recordedUrl}destroy(){super.destroy(),this.cleanUp()}}const n=o;return t.default})()));
|
|
@@ -47,7 +47,7 @@ export declare class Region extends EventEmitter<RegionEvents> {
|
|
|
47
47
|
private initMouseEvents;
|
|
48
48
|
private onStartMoving;
|
|
49
49
|
private onEndMoving;
|
|
50
|
-
|
|
50
|
+
_onUpdate(dx: number, sides: Array<'start' | 'end'>): void;
|
|
51
51
|
private onMove;
|
|
52
52
|
private onResize;
|
|
53
53
|
private onEndResizing;
|
|
@@ -65,7 +65,7 @@ export declare class Region extends EventEmitter<RegionEvents> {
|
|
|
65
65
|
/** Remove the region */
|
|
66
66
|
remove(): void;
|
|
67
67
|
}
|
|
68
|
-
declare class RegionsPlugin extends BasePlugin<RegionsPluginEvents, RegionsPluginOptions> {
|
|
68
|
+
export declare class RegionsPlugin extends BasePlugin<RegionsPluginEvents, RegionsPluginOptions> {
|
|
69
69
|
private regions;
|
|
70
70
|
private regionsContainer;
|
|
71
71
|
/** Create an instance of RegionsPlugin */
|
package/dist/plugins/regions.js
CHANGED
|
@@ -111,7 +111,7 @@ export class Region extends EventEmitter {
|
|
|
111
111
|
this.element.style.cursor = 'grab';
|
|
112
112
|
this.emit('update-end');
|
|
113
113
|
}
|
|
114
|
-
|
|
114
|
+
_onUpdate(dx, sides) {
|
|
115
115
|
if (!this.element.parentElement)
|
|
116
116
|
return;
|
|
117
117
|
const deltaSeconds = (dx / this.element.parentElement.clientWidth) * this.totalDuration;
|
|
@@ -130,12 +130,12 @@ export class Region extends EventEmitter {
|
|
|
130
130
|
onMove(dx) {
|
|
131
131
|
if (!this.drag)
|
|
132
132
|
return;
|
|
133
|
-
this.
|
|
133
|
+
this._onUpdate(dx, ['start', 'end']);
|
|
134
134
|
}
|
|
135
135
|
onResize(dx, side) {
|
|
136
136
|
if (!this.resize)
|
|
137
137
|
return;
|
|
138
|
-
this.
|
|
138
|
+
this._onUpdate(dx, [side]);
|
|
139
139
|
}
|
|
140
140
|
onEndResizing() {
|
|
141
141
|
if (!this.resize)
|
|
@@ -182,7 +182,7 @@ export class Region extends EventEmitter {
|
|
|
182
182
|
this.element = null;
|
|
183
183
|
}
|
|
184
184
|
}
|
|
185
|
-
class RegionsPlugin extends BasePlugin {
|
|
185
|
+
export class RegionsPlugin extends BasePlugin {
|
|
186
186
|
/** Create an instance of RegionsPlugin */
|
|
187
187
|
constructor(options) {
|
|
188
188
|
super(options);
|
|
@@ -291,49 +291,43 @@ class RegionsPlugin extends BasePlugin {
|
|
|
291
291
|
const wrapper = this.wavesurfer?.getWrapper()?.querySelector('div');
|
|
292
292
|
if (!wrapper)
|
|
293
293
|
return () => undefined;
|
|
294
|
+
const initialSize = 5;
|
|
294
295
|
let region = null;
|
|
295
|
-
let
|
|
296
|
+
let startX = 0;
|
|
296
297
|
return makeDraggable(wrapper,
|
|
297
298
|
// On drag move
|
|
298
|
-
(dx,
|
|
299
|
-
if (!this.wavesurfer)
|
|
300
|
-
return;
|
|
301
|
-
if (!region) {
|
|
302
|
-
const duration = this.wavesurfer.getDuration();
|
|
303
|
-
const box = wrapper.getBoundingClientRect();
|
|
304
|
-
let start = (x / box.width) * duration;
|
|
305
|
-
let end = ((x - box.left) / box.width) * duration;
|
|
306
|
-
if (start > end)
|
|
307
|
-
[start, end] = [end, start];
|
|
308
|
-
region = new Region({
|
|
309
|
-
...options,
|
|
310
|
-
start,
|
|
311
|
-
end,
|
|
312
|
-
}, duration);
|
|
313
|
-
this.regionsContainer.appendChild(region.element);
|
|
314
|
-
}
|
|
315
|
-
sumDx += dx;
|
|
299
|
+
(dx, _dy, x) => {
|
|
316
300
|
if (region) {
|
|
317
|
-
|
|
318
|
-
|
|
301
|
+
// Update the end position of the region
|
|
302
|
+
// If we're dragging to the left, we need to update the start instead
|
|
303
|
+
region._onUpdate(dx, [x > startX ? 'end' : 'start']);
|
|
319
304
|
}
|
|
320
305
|
},
|
|
321
306
|
// On drag start
|
|
322
|
-
() =>
|
|
307
|
+
(x) => {
|
|
308
|
+
startX = x;
|
|
309
|
+
if (!this.wavesurfer)
|
|
310
|
+
return;
|
|
311
|
+
const duration = this.wavesurfer.getDuration();
|
|
312
|
+
const width = this.wavesurfer.getWrapper().clientWidth;
|
|
313
|
+
// Calculate the start time of the region
|
|
314
|
+
const start = (x / width) * duration;
|
|
315
|
+
// Give the region a small initial size
|
|
316
|
+
const end = ((x + initialSize) / width) * duration;
|
|
317
|
+
// Create a region but don't save it until the drag ends
|
|
318
|
+
region = new Region({
|
|
319
|
+
...options,
|
|
320
|
+
start,
|
|
321
|
+
end,
|
|
322
|
+
}, duration);
|
|
323
|
+
// Just add it to the DOM for now
|
|
324
|
+
this.regionsContainer.appendChild(region.element);
|
|
325
|
+
},
|
|
323
326
|
// On drag end
|
|
324
327
|
() => {
|
|
325
328
|
if (region) {
|
|
326
329
|
this.saveRegion(region);
|
|
327
330
|
region = null;
|
|
328
|
-
sumDx = 0;
|
|
329
|
-
// Prevent a click event on the waveform
|
|
330
|
-
if (this.wavesurfer) {
|
|
331
|
-
const { interact } = this.wavesurfer.options;
|
|
332
|
-
if (interact) {
|
|
333
|
-
this.wavesurfer.toggleInteraction(false);
|
|
334
|
-
setTimeout(() => this.wavesurfer?.toggleInteraction(interact), 10);
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
331
|
}
|
|
338
332
|
});
|
|
339
333
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Regions=t():e.Regions=t()}(WaveSurfer,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>a});const i=class{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const i=this.on(e,t),n=this.on(e,(()=>{i(),n()}));return i}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}},n=class extends i{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.subscriptions.forEach((e=>e()))}};function s(e,t,i,n,s=5){let r=()=>{};if(!e)return r;const o=o=>{o.preventDefault(),o.stopPropagation();let a=o.clientX,l=o.clientY,d=!1;const h=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(d||Math.abs(r-a)>=s||Math.abs(o-l)>=s){
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.Regions=t():e.Regions=t()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var e={d:(t,i)=>{for(var n in i)e.o(i,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:i[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{default:()=>a});const i=class{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const i=this.on(e,t),n=this.on(e,(()=>{i(),n()}));return i}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}},n=class extends i{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.subscriptions.forEach((e=>e()))}};function s(e,t,i,n,s=5){let r=()=>{};if(!e)return r;const o=o=>{o.preventDefault(),o.stopPropagation();let a=o.clientX,l=o.clientY,d=!1;const h=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(d||Math.abs(r-a)>=s||Math.abs(o-l)>=s){const{left:n,top:s}=e.getBoundingClientRect();d||(d=!0,i?.(a-n,l-s)),t(r-a,o-l,r-n,o-s),a=r,l=o}},c=e=>{d&&(e.preventDefault(),e.stopPropagation())},u=()=>{d&&n?.(),r()};r=()=>{document.removeEventListener("pointermove",h),document.removeEventListener("pointerup",u),document.removeEventListener("pointerleave",u),setTimeout((()=>{document.removeEventListener("click",c,!0)}),10)},document.addEventListener("pointermove",h),document.addEventListener("pointerup",u),document.addEventListener("pointerleave",u),document.addEventListener("click",c,!0)};return e.addEventListener("pointerdown",o),()=>{r(),e.removeEventListener("pointerdown",o)}}class r extends i{constructor(e,t){super(),this.totalDuration=t,this.id=e.id||`region-${Math.random().toString(32).slice(2)}`,this.start=e.start,this.end=e.end??e.start,this.drag=e.drag??!0,this.resize=e.resize??!0,this.color=e.color??"rgba(0, 0, 0, 0.1)",this.element=this.initElement(e.content),this.renderPosition(),this.initMouseEvents()}initElement(e){const t=document.createElement("div"),i=this.start===this.end;if(t.setAttribute("part",`${i?"marker":"region"} ${this.id}`),t.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n padding: 0.2em ${i?.2:.4}em;\n pointer-events: all;\n `),e&&("string"==typeof e?(this.content=document.createElement("div"),this.content.textContent=e):this.content=e,this.content.setAttribute("part","region-content"),t.appendChild(this.content)),!i){const e=document.createElement("div");e.setAttribute("data-resize","left"),e.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),e.setAttribute("part","region-handle region-handle-left");const i=e.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),t.appendChild(e),t.appendChild(i)}return t}renderPosition(){const e=this.start/this.totalDuration,t=this.end/this.totalDuration;this.element.style.left=100*e+"%",this.element.style.width=100*(t-e)+"%"}initMouseEvents(){const{element:e}=this;e&&(e.addEventListener("click",(e=>this.emit("click",e))),e.addEventListener("mouseenter",(e=>this.emit("over",e))),e.addEventListener("mouseleave",(e=>this.emit("leave",e))),e.addEventListener("dblclick",(e=>this.emit("dblclick",e))),s(e,(e=>this.onMove(e)),(()=>this.onStartMoving()),(()=>this.onEndMoving())),s(e.querySelector('[data-resize="left"]'),(e=>this.onResize(e,"start")),(()=>null),(()=>this.onEndResizing()),1),s(e.querySelector('[data-resize="right"]'),(e=>this.onResize(e,"end")),(()=>null),(()=>this.onEndResizing()),1))}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(e,t){if(!this.element.parentElement)return;const i=e/this.element.parentElement.clientWidth*this.totalDuration;t.forEach((e=>{this[e]+=i,"start"===e?this.start=Math.max(0,Math.min(this.start,this.end)):this.end=Math.max(this.start,Math.min(this.end,this.totalDuration))})),this.renderPosition(),this.emit("update")}onMove(e){this.drag&&this._onUpdate(e,["start","end"])}onResize(e,t){this.resize&&this._onUpdate(e,[t])}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(e){this.totalDuration=e,this.renderPosition()}play(){this.emit("play")}setOptions(e){e.color&&(this.color=e.color,this.element.style.backgroundColor=this.color),void 0!==e.drag&&(this.drag=e.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==e.resize&&(this.resize=e.resize,this.element.querySelectorAll("[data-resize]").forEach((e=>{e.style.cursor=this.resize?"ew-resize":"default"}))),void 0===e.start&&void 0===e.end||(this.start=e.start??this.start,this.end=e.end??this.end,this.renderPosition())}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class o extends n{constructor(e){super(e),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(e){return new o(e)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer)}initRegionsContainer(){const e=document.createElement("div");return e.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),e}getRegions(){return this.regions}avoidOverlapping(e){if(!e.content)return;const t=e.content,i=t.getBoundingClientRect().left,n=e.element.scrollWidth,s=this.regions.filter((t=>{if(t===e||!t.content)return!1;const s=t.content.getBoundingClientRect().left,r=t.element.scrollWidth;return i<s+r&&s<i+n})).map((e=>e.content?.getBoundingClientRect().height||0)).reduce(((e,t)=>e+t),0);t.style.marginTop=`${s}px`}saveRegion(e){this.regionsContainer.appendChild(e.element),this.avoidOverlapping(e),this.regions.push(e),this.emit("region-created",e);const t=[e.on("update-end",(()=>{this.avoidOverlapping(e),this.emit("region-updated",e)})),e.on("play",(()=>{this.wavesurfer?.play(),this.wavesurfer?.setTime(e.start)})),e.on("click",(t=>{this.emit("region-clicked",e,t)})),e.on("dblclick",(t=>{this.emit("region-double-clicked",e,t)})),e.once("remove",(()=>{t.forEach((e=>e())),this.regions=this.regions.filter((t=>t!==e))}))];this.subscriptions.push(...t)}addRegion(e){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const t=this.wavesurfer.getDuration(),i=new r(e,t);return t?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(e=>{i._setTotalDuration(e),this.saveRegion(i)}))),i}enableDragSelection(e){const t=this.wavesurfer?.getWrapper()?.querySelector("div");if(!t)return()=>{};let i=null,n=0;return s(t,((e,t,s)=>{i&&i._onUpdate(e,[s>n?"end":"start"])}),(t=>{if(n=t,!this.wavesurfer)return;const s=this.wavesurfer.getDuration(),o=this.wavesurfer.getWrapper().clientWidth;i=new r({...e,start:t/o*s,end:(t+5)/o*s},s),this.regionsContainer.appendChild(i.element)}),(()=>{i&&(this.saveRegion(i),i=null)}))}clearRegions(){this.regions.forEach((e=>e.remove()))}destroy(){this.clearRegions(),super.destroy()}}const a=o;return t.default})()));
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
* ]
|
|
18
18
|
* });
|
|
19
19
|
*/
|
|
20
|
+
/**
|
|
21
|
+
* Spectrogram plugin for wavesurfer.
|
|
22
|
+
*/
|
|
20
23
|
import BasePlugin from '../base-plugin.js';
|
|
21
24
|
export type SpectrogramPluginOptions = {
|
|
22
25
|
/** Selector of element or element in which to render */
|
|
@@ -50,7 +53,7 @@ export type SpectrogramPluginEvents = {
|
|
|
50
53
|
ready: [];
|
|
51
54
|
click: [relativeX: number];
|
|
52
55
|
};
|
|
53
|
-
export
|
|
56
|
+
export declare class SpectrogramPlugin extends BasePlugin<SpectrogramPluginEvents, SpectrogramPluginOptions> {
|
|
54
57
|
static create(options?: SpectrogramPluginOptions): SpectrogramPlugin;
|
|
55
58
|
utils: {
|
|
56
59
|
style: (el: HTMLElement, styles: Record<string, string>) => CSSStyleDeclaration & Record<string, string>;
|
|
@@ -70,3 +73,4 @@ export default class SpectrogramPlugin extends BasePlugin<SpectrogramPluginEvent
|
|
|
70
73
|
loadLabels(bgFill: any, fontSizeFreq: any, fontSizeUnit: any, fontType: any, textColorFreq: any, textColorUnit: any, textAlign: any, container: any): void;
|
|
71
74
|
resample(oldMatrix: any): Uint8Array[];
|
|
72
75
|
}
|
|
76
|
+
export default SpectrogramPlugin;
|