wavesurfer.js 7.0.0-beta.6 → 7.0.0-beta.7

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.
Files changed (54) hide show
  1. package/dist/plugins/minimap.min.js +1 -1
  2. package/dist/renderer.d.ts +2 -0
  3. package/dist/renderer.js +25 -15
  4. package/dist/wavesurfer.d.ts +2 -1
  5. package/dist/wavesurfer.js +0 -1
  6. package/dist/wavesurfer.min.js +1 -1
  7. package/package.json +1 -1
  8. package/dist/cypress/support/commands.d.ts +0 -1
  9. package/dist/cypress/support/commands.js +0 -39
  10. package/dist/cypress/support/e2e.d.ts +0 -1
  11. package/dist/cypress/support/e2e.js +0 -18
  12. package/dist/cypress.config.d.ts +0 -2
  13. package/dist/cypress.config.js +0 -10
  14. package/dist/plugins/envelope.min.cjs +0 -1
  15. package/dist/plugins/minimap.min.cjs +0 -1
  16. package/dist/plugins/multitrack.d.ts +0 -117
  17. package/dist/plugins/multitrack.js +0 -507
  18. package/dist/plugins/multitrack.min.cjs +0 -1
  19. package/dist/plugins/multitrack.min.js +0 -1
  20. package/dist/plugins/record.min.cjs +0 -1
  21. package/dist/plugins/regions.min.cjs +0 -1
  22. package/dist/plugins/spectrogram.min.cjs +0 -1
  23. package/dist/plugins/timeline.min.cjs +0 -1
  24. package/dist/src/base-plugin.d.ts +0 -13
  25. package/dist/src/base-plugin.js +0 -22
  26. package/dist/src/decoder.d.ts +0 -9
  27. package/dist/src/decoder.js +0 -48
  28. package/dist/src/event-emitter.d.ts +0 -19
  29. package/dist/src/event-emitter.js +0 -45
  30. package/dist/src/fetcher.d.ts +0 -5
  31. package/dist/src/fetcher.js +0 -7
  32. package/dist/src/player.d.ts +0 -45
  33. package/dist/src/player.js +0 -114
  34. package/dist/src/plugins/envelope.d.ts +0 -71
  35. package/dist/src/plugins/envelope.js +0 -350
  36. package/dist/src/plugins/minimap.d.ts +0 -39
  37. package/dist/src/plugins/minimap.js +0 -117
  38. package/dist/src/plugins/record.d.ts +0 -26
  39. package/dist/src/plugins/record.js +0 -124
  40. package/dist/src/plugins/regions.d.ts +0 -93
  41. package/dist/src/plugins/regions.js +0 -395
  42. package/dist/src/plugins/spectrogram-fft.d.ts +0 -9
  43. package/dist/src/plugins/spectrogram-fft.js +0 -150
  44. package/dist/src/plugins/spectrogram.d.ts +0 -69
  45. package/dist/src/plugins/spectrogram.js +0 -340
  46. package/dist/src/plugins/timeline.d.ts +0 -45
  47. package/dist/src/plugins/timeline.js +0 -162
  48. package/dist/src/renderer.d.ts +0 -41
  49. package/dist/src/renderer.js +0 -420
  50. package/dist/src/timer.d.ts +0 -11
  51. package/dist/src/timer.js +0 -19
  52. package/dist/src/wavesurfer.d.ts +0 -149
  53. package/dist/src/wavesurfer.js +0 -229
  54. package/dist/wavesurfer.min.cjs +0 -1
@@ -1,229 +0,0 @@
1
- import Decoder from './decoder.js';
2
- import Fetcher from './fetcher.js';
3
- import Player from './player.js';
4
- import Renderer from './renderer.js';
5
- import Timer from './timer.js';
6
- const defaultOptions = {
7
- height: 128,
8
- waveColor: '#999',
9
- progressColor: '#555',
10
- cursorWidth: 1,
11
- minPxPerSec: 0,
12
- fillParent: true,
13
- interact: true,
14
- autoScroll: true,
15
- autoCenter: true,
16
- sampleRate: 8000,
17
- };
18
- class WaveSurfer extends Player {
19
- options;
20
- renderer;
21
- timer;
22
- plugins = [];
23
- decodedData = null;
24
- subscriptions = [];
25
- /** Create a new WaveSurfer instance */
26
- static create(options) {
27
- return new WaveSurfer(options);
28
- }
29
- /** Create a new WaveSurfer instance */
30
- constructor(options) {
31
- super({
32
- media: options.media,
33
- autoplay: options.autoplay,
34
- playbackRate: options.audioRate,
35
- });
36
- this.options = Object.assign({}, defaultOptions, options);
37
- this.timer = new Timer();
38
- this.renderer = new Renderer(this.options);
39
- this.initPlayerEvents();
40
- this.initRendererEvents();
41
- this.initTimerEvents();
42
- this.initPlugins();
43
- const url = this.options.url || this.options.media?.currentSrc || this.options.media?.src;
44
- if (url) {
45
- this.load(url, this.options.peaks, this.options.duration);
46
- }
47
- }
48
- setOptions(options) {
49
- this.options = { ...this.options, ...options };
50
- this.renderer.setOptions(this.options);
51
- if (options.audioRate) {
52
- this.setPlaybackRate(options.audioRate);
53
- }
54
- }
55
- initPlayerEvents() {
56
- this.subscriptions.push(this.onMediaEvent('timeupdate', () => {
57
- const currentTime = this.getCurrentTime();
58
- this.renderer.renderProgress(currentTime / this.getDuration(), this.isPlaying());
59
- this.emit('timeupdate', currentTime);
60
- }), this.onMediaEvent('play', () => {
61
- this.emit('play');
62
- this.timer.start();
63
- }), this.onMediaEvent('pause', () => {
64
- this.emit('pause');
65
- this.timer.stop();
66
- }), this.onMediaEvent('ended', () => {
67
- this.emit('finish');
68
- }), this.onMediaEvent('seeking', () => {
69
- this.emit('seeking', this.getCurrentTime());
70
- }));
71
- }
72
- initRendererEvents() {
73
- this.subscriptions.push(
74
- // Seek on click
75
- this.renderer.on('click', (relativeX) => {
76
- if (this.options.interact) {
77
- this.seekTo(relativeX);
78
- this.emit('interaction');
79
- this.emit('click', relativeX);
80
- }
81
- }),
82
- // Scroll
83
- this.renderer.on('scroll', (startX, endX) => {
84
- const duration = this.getDuration();
85
- this.emit('scroll', startX * duration, endX * duration);
86
- }),
87
- // Redraw
88
- this.renderer.on('render', () => {
89
- this.emit('redraw');
90
- }));
91
- // Drag
92
- {
93
- let debounce;
94
- this.subscriptions.push(this.renderer.on('drag', (relativeX) => {
95
- if (!this.options.interact)
96
- return;
97
- // Update the visual position
98
- this.renderer.renderProgress(relativeX);
99
- // Set the audio position with a debounce
100
- clearTimeout(debounce);
101
- debounce = setTimeout(() => {
102
- this.seekTo(relativeX);
103
- }, this.isPlaying() ? 0 : 200);
104
- this.emit('interaction');
105
- this.emit('drag', relativeX);
106
- }));
107
- }
108
- }
109
- initTimerEvents() {
110
- // The timer fires every 16ms for a smooth progress animation
111
- this.subscriptions.push(this.timer.on('tick', () => {
112
- const currentTime = this.getCurrentTime();
113
- this.renderer.renderProgress(currentTime / this.getDuration(), true);
114
- this.emit('timeupdate', currentTime);
115
- this.emit('audioprocess', currentTime);
116
- }));
117
- }
118
- initPlugins() {
119
- if (!this.options.plugins?.length)
120
- return;
121
- this.options.plugins.forEach((plugin) => {
122
- this.registerPlugin(plugin);
123
- });
124
- }
125
- /** Register a wavesurfer.js plugin */
126
- registerPlugin(plugin) {
127
- plugin.init(this);
128
- this.plugins.push(plugin);
129
- return plugin;
130
- }
131
- /** For plugins only: get the waveform wrapper div */
132
- getWrapper() {
133
- return this.renderer.getWrapper();
134
- }
135
- /** Get the current scroll position in pixels */
136
- getScroll() {
137
- return this.renderer.getScroll();
138
- }
139
- /** Get all registered plugins */
140
- getActivePlugins() {
141
- return this.plugins;
142
- }
143
- /** Load an audio file by URL, with optional pre-decoded audio data */
144
- async load(url, channelData, duration) {
145
- this.decodedData = null;
146
- this.emit('load', url);
147
- if (channelData) {
148
- // Set the mediaelement source to the URL
149
- this.setSrc(url);
150
- // Pre-decoded audio data
151
- if (!duration) {
152
- // Wait for the audio duration
153
- duration =
154
- (await new Promise((resolve) => {
155
- this.onceMediaEvent('loadedmetadata', () => resolve(this.getMediaElement().duration));
156
- })) || 0;
157
- }
158
- this.decodedData = Decoder.createBuffer(channelData, duration);
159
- }
160
- else {
161
- // Fetch and decode the audio of no pre-computed audio data is provided
162
- const audio = await Fetcher.fetchArrayBuffer(url);
163
- this.setSrc(url);
164
- this.decodedData = await Decoder.decode(audio, this.options.sampleRate);
165
- }
166
- this.emit('decode', this.getDuration());
167
- this.emit('ready', this.getDuration());
168
- this.renderer.render(this.decodedData);
169
- }
170
- /** Zoom in or out */
171
- zoom(minPxPerSec) {
172
- if (!this.decodedData) {
173
- throw new Error('No audio loaded');
174
- }
175
- this.renderer.zoom(minPxPerSec);
176
- this.emit('zoom', minPxPerSec);
177
- }
178
- /** Get the decoded audio data */
179
- getDecodedData() {
180
- return this.decodedData;
181
- }
182
- /** Get the duration of the audio in seconds */
183
- getDuration() {
184
- const audioDuration = super.getDuration();
185
- return audioDuration > 0 && audioDuration < Infinity ? audioDuration : this.decodedData?.duration || 0;
186
- }
187
- /** Toggle if the waveform should react to clicks */
188
- toggleInteraction(isInteractive) {
189
- this.options.interact = isInteractive;
190
- }
191
- /** Seeks to a percentage of audio as [0..1] (0 = beginning, 1 = end) */
192
- seekTo(progress) {
193
- const time = this.getDuration() * progress;
194
- this.setTime(time);
195
- }
196
- /** Play or pause the audio */
197
- playPause() {
198
- if (this.isPlaying()) {
199
- this.pause();
200
- return Promise.resolve();
201
- }
202
- else {
203
- return this.play();
204
- }
205
- }
206
- /** Stop the audio and go to the beginning */
207
- stop() {
208
- this.pause();
209
- this.setTime(0);
210
- }
211
- /** Skip N or -N seconds from the current positions */
212
- skip(seconds) {
213
- this.setTime(this.getCurrentTime() + seconds);
214
- }
215
- /** Empty the waveform by loading a tiny silent audio */
216
- empty() {
217
- this.load('', [[0]], 0.001);
218
- }
219
- /** Unmount wavesurfer */
220
- destroy() {
221
- this.emit('destroy');
222
- this.subscriptions.forEach((unsubscribe) => unsubscribe());
223
- this.plugins.forEach((plugin) => plugin.destroy());
224
- this.timer.destroy();
225
- this.renderer.destroy();
226
- super.destroy();
227
- }
228
- }
229
- export default WaveSurfer;
@@ -1 +0,0 @@
1
- !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.WaveSurfer=e():t.WaveSurfer=e()}(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:()=>d});const i={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}}},s=async function(t){return fetch(t).then((t=>t.arrayBuffer()))},n=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)))}},r=class extends n{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?URL.createObjectURL(new Blob([e],{type:"audio/wav"})):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 o extends n{constructor(t,e){if(super(),this.options={height:0},this.timeout=null,this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options={...e},"string"==typeof t&&(t=document.querySelector(t)),!t)throw new Error("Container not found");const[i,s]=this.initHtml();t.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,n=(t+i)/e;this.emit("scroll",s,n)})),this.resizeObserver=new ResizeObserver((()=>{this.delay((()=>this.reRender()),100)})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){this.wrapper.addEventListener("mousedown",(t=>{const e=t.clientX,i=t=>{if(Math.abs(t.clientX-e)>=5){this.isDragging=!0;const e=this.wrapper.getBoundingClientRect();this.emit("drag",Math.max(0,Math.min(1,(t.clientX-e.left)/e.width)))}},s=()=>{document.removeEventListener("mousemove",i),document.removeEventListener("mouseup",s),this.isDragging=!1};document.addEventListener("mousemove",i),document.addEventListener("mouseup",s)}))}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 position: relative;\n height: ${this.options.height}px;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n height: ${this.options.height}px;\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 .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n width: ${this.options.cursorWidth}px;\n background-color: ${this.options.cursorColor||this.options.progressColor};\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="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()}delay(t,e=10){return this.timeout&&clearTimeout(this.timeout),new Promise((i=>{this.timeout=setTimeout((()=>{i(t())}),e)}))}async renderPeaks(t,e,i,s){const n=null==this.options.barWidth||isNaN(this.options.barWidth)?1:this.options.barWidth*s,r=null==this.options.barGap||isNaN(this.options.barGap)?this.options.barWidth?n/2:0:this.options.barGap*s,a=this.options.barRadius||0,h=this.options.barHeight||1,l=t.getChannelData(0),c=l.length,d=Math.floor(e/(n+r))/c,u=i/2,p=1===t.numberOfChannels,m=p?l:t.getChannelData(1),g=p&&m.some((t=>t<0)),y=(t,i)=>{let o=0,p=0,y=0;const f=document.createElement("canvas");f.width=Math.round(e*(i-t)/c),f.height=this.options.height,f.style.width=`${Math.floor(f.width/s)}px`,f.style.height=`${this.options.height}px`,f.style.left=`${Math.floor(t*e/s/c)}px`,this.canvasWrapper.appendChild(f);const v=f.getContext("2d",{desynchronized:!0});v.beginPath(),v.fillStyle=this.options.waveColor??"",v.roundRect||(v.roundRect=v.fillRect);for(let e=t;e<i;e++){const i=Math.round((e-t)*d);if(i>o){const t=Math.round(p*u*h),e=Math.round(y*u*h);v.roundRect(o*(n+r),u-t,n,t+(e||1),a),o=i,p=0,y=0}const s=g?l[e]:Math.abs(l[e]),c=g?m[e]:Math.abs(m[e]);s>p&&(p=s),(g?c<-y:c>y)&&(y=c<0?-c:c)}v.fill(),v.closePath();const b=f.cloneNode();this.progressWrapper.appendChild(b);const w=b.getContext("2d",{desynchronized:!0});f.width>0&&f.height>0&&w.drawImage(f,0,0),w.globalCompositeOperation="source-in",w.fillStyle=this.options.progressColor??"",w.fillRect(0,0,f.width,f.height)};this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="";const{scrollLeft:f,scrollWidth:v,clientWidth:b}=this.scrollContainer,w=c/v;let C=Math.min(o.MAX_CANVAS_WIDTH,b);C-=C%((n+r)/s);const P=Math.floor(Math.abs(f)*w),E=Math.ceil(P+C*w);y(P,E);const M=E-P;for(let t=E;t<c;t+=M)await this.delay((()=>{y(t,Math.min(c,t+M))}));for(let t=P-1;t>=0;t-=M)await this.delay((()=>{y(Math.max(0,t-M),t)}))}render(t){const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const n=this.options.fillParent&&!this.isScrolling,r=(n?i:s)*e,{height:o}=this.options;this.wrapper.style.width=n?"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.style.height=`${this.options.height}px`,this.renderPeaks(t,r,o,e),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:n}=this.scrollContainer,r=n*t,o=i/2;if(r>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||r<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;r-(s+o)>=t&&r<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=r-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=r<s?r-t:r-i+t}else this.scrollContainer.scrollLeft=r;{const{scrollLeft:t}=this.scrollContainer,e=t/n,s=(t+i)/n;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))}}o.MAX_CANVAS_WIDTH=4e3;const a=o,h=class extends n{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}},l={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class c extends r{static create(t){return new c(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.canPlay=!1,this.subscriptions=[],this.options=Object.assign({},l,t),this.timer=new h,this.renderer=new a(this.options.container,this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initReadyEvent(),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={...this.options,...t},this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}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("canplay",(()=>{this.canPlay=!0,this.emit("canplay",this.getDuration())})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.canPlay&&this.seekTo(t),this.emit("interaction"),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.canPlay&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200)),this.emit("interaction"),this.emit("drag",e))})))}}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)})))}initReadyEvent(){const t=()=>{this.decodedData&&this.canPlay&&this.emit("ready",this.getDuration())};this.subscriptions.push(this.on("decode",t),this.on("canplay",t))}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,n){if(this.decodedData=null,this.canPlay=!1,this.emit("load",t),e)this.setSrc(t),n||(n=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=i.createBuffer(e,n);else{const e=await s(t);this.setSrc(t,e),this.decodedData=await i.decode(e,this.options.sampleRate)}this.emit("decode",this.getDuration()),this.renderer.render(this.decodedData)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){const t=super.getDuration();return t>0&&t<1/0?t:this.decodedData?.duration||0}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return this.isPlaying()?(this.pause(),Promise.resolve()):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 d=c;return e.default})()));