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.
- package/dist/plugins/minimap.min.js +1 -1
- package/dist/renderer.d.ts +2 -0
- package/dist/renderer.js +25 -15
- package/dist/wavesurfer.d.ts +2 -1
- package/dist/wavesurfer.js +0 -1
- package/dist/wavesurfer.min.js +1 -1
- package/package.json +1 -1
- package/dist/cypress/support/commands.d.ts +0 -1
- package/dist/cypress/support/commands.js +0 -39
- package/dist/cypress/support/e2e.d.ts +0 -1
- package/dist/cypress/support/e2e.js +0 -18
- package/dist/cypress.config.d.ts +0 -2
- package/dist/cypress.config.js +0 -10
- package/dist/plugins/envelope.min.cjs +0 -1
- package/dist/plugins/minimap.min.cjs +0 -1
- package/dist/plugins/multitrack.d.ts +0 -117
- package/dist/plugins/multitrack.js +0 -507
- package/dist/plugins/multitrack.min.cjs +0 -1
- package/dist/plugins/multitrack.min.js +0 -1
- package/dist/plugins/record.min.cjs +0 -1
- package/dist/plugins/regions.min.cjs +0 -1
- package/dist/plugins/spectrogram.min.cjs +0 -1
- package/dist/plugins/timeline.min.cjs +0 -1
- package/dist/src/base-plugin.d.ts +0 -13
- package/dist/src/base-plugin.js +0 -22
- package/dist/src/decoder.d.ts +0 -9
- package/dist/src/decoder.js +0 -48
- package/dist/src/event-emitter.d.ts +0 -19
- package/dist/src/event-emitter.js +0 -45
- package/dist/src/fetcher.d.ts +0 -5
- package/dist/src/fetcher.js +0 -7
- package/dist/src/player.d.ts +0 -45
- package/dist/src/player.js +0 -114
- package/dist/src/plugins/envelope.d.ts +0 -71
- package/dist/src/plugins/envelope.js +0 -350
- package/dist/src/plugins/minimap.d.ts +0 -39
- package/dist/src/plugins/minimap.js +0 -117
- package/dist/src/plugins/record.d.ts +0 -26
- package/dist/src/plugins/record.js +0 -124
- package/dist/src/plugins/regions.d.ts +0 -93
- package/dist/src/plugins/regions.js +0 -395
- package/dist/src/plugins/spectrogram-fft.d.ts +0 -9
- package/dist/src/plugins/spectrogram-fft.js +0 -150
- package/dist/src/plugins/spectrogram.d.ts +0 -69
- package/dist/src/plugins/spectrogram.js +0 -340
- package/dist/src/plugins/timeline.d.ts +0 -45
- package/dist/src/plugins/timeline.js +0 -162
- package/dist/src/renderer.d.ts +0 -41
- package/dist/src/renderer.js +0 -420
- package/dist/src/timer.d.ts +0 -11
- package/dist/src/timer.js +0 -19
- package/dist/src/wavesurfer.d.ts +0 -149
- package/dist/src/wavesurfer.js +0 -229
- package/dist/wavesurfer.min.cjs +0 -1
package/dist/src/wavesurfer.js
DELETED
|
@@ -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;
|
package/dist/wavesurfer.min.cjs
DELETED
|
@@ -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})()));
|