wavesurfer.js 7.0.0-alpha.36 → 7.0.0-alpha.38

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 CHANGED
@@ -15,6 +15,11 @@ Import like this:
15
15
  import WaveSurfer from 'wavesurfer.js'
16
16
  ```
17
17
 
18
+ To import a plugin, e.g. the Timeline plugin:
19
+ ```
20
+ import Timeline from 'wavesurfer.js/dist/plugins/timeline'
21
+ ```
22
+
18
23
  TypeScript types are included in the package, so there's no need to install `@types/wavesurfer.js`.
19
24
 
20
25
  ## Why upgrade to wavesurfer.ts?
@@ -34,23 +39,26 @@ The "official" plugins have been completely rewritten and enhanced:
34
39
  * [Envelope](https://wavesurfer-ts.pages.dev/tutorial/#/examples/envelope.js) – a graphical interface to add fade-in and -out effects and control volume
35
40
  * [Record](https://wavesurfer-ts.pages.dev/tutorial/#/examples/record.js) – records audio from the microphone and renders a waveform
36
41
 
42
+ ## Documentation
43
+ See the documentation on wavesurfer.js [methods](https://wavesurfer-ts.pages.dev/docs/classes/wavesurfer.WaveSurfer), [options](https://wavesurfer-ts.pages.dev/docs/types/wavesurfer.WaveSurferOptions) and [events](https://wavesurfer-ts.pages.dev/docs/types/wavesurfer.WaveSurferEvents) on our website.
44
+
37
45
  ## Migrating from v6 and lower
38
46
 
39
47
  Most options, events, and methods are similar to those in previous versions.
40
48
 
41
49
  ### Notable differences
42
50
  * The `backend` option is removed – HTML5 audio (or video) is the only playback mechanism. However, you can still connect wavesurfer to Web Audio via `MediaElementSourceNode`. See this [example](https://wavesurfer-ts.pages.dev/tutorial/#/examples/webaudio.js).
43
- * The Markers plugin is removed – use the Regions plugin with `startTime` equal to `endTime`
44
- * Plugins now have different APIs
51
+ * The Markers plugin is removed – use the Regions plugin with `startTime` equal to `endTime`.
52
+ * No Microphone plugn superseded by the new Record plugin with more features.
53
+ * No Spectrogram, Cursor and Playhead plugins yet – to be done.
45
54
 
46
55
  ### Removed methods
47
56
  * `getFilters`, `setFilter` – as there's no Web Audio "backend"
48
57
  * `cancelAjax` – ajax is replaced by `fetch`
49
58
  * `loadBlob` – use `URL.createObjectURL()` to convert a blob to a URL and call `load(url)` instead
50
- * `un`, `unAll` – the `on` method now returns an unsubscribe function. E.g., `const unsubscribe = wavesurfer.on('ready', () => ...)`
51
59
  * `skipForward`, `skipBackward`, `setPlayEnd` – can be implemented using `setTime(time)`
52
60
  * `exportPCM` is renamed to `getDecodedData` and doesn't take any params
53
- * `toggleMute` is now called `setMute(true | false)`
61
+ * `toggleMute` is now called `setMuted(true | false)`
54
62
  * `setHeight`, `setWaveColor`, `setCursorColor`, etc. – use `setOptions` with the corresponding params instead. E.g., `wavesurfer.setOptions({ height: 300, waveColor: '#abc' })`
55
63
 
56
64
  See the complete [documentation of the new API](https://wavesurfer-ts.pages.dev/docs/classes/wavesurfer.WaveSurfer).
@@ -1,6 +1,11 @@
1
1
  import EventEmitter, { type GeneralEventTypes } from './event-emitter.js';
2
- import WaveSurfer, { type WaveSurferPluginParams } from './wavesurfer.js';
2
+ import type WaveSurfer from './wavesurfer.js';
3
3
  export type GenericPlugin = BasePlugin<GeneralEventTypes, unknown>;
4
+ export type WaveSurferPluginParams = {
5
+ wavesurfer: WaveSurfer;
6
+ container: HTMLElement;
7
+ wrapper: HTMLElement;
8
+ };
4
9
  export declare class BasePlugin<EventTypes extends GeneralEventTypes, Options> extends EventEmitter<EventTypes> {
5
10
  protected wavesurfer?: WaveSurfer;
6
11
  protected container?: HTMLElement;
package/dist/decoder.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- declare class Decoder {
2
- audioCtx: AudioContext | null;
3
- private initAudioContext;
4
- constructor();
5
- decode(audioData: ArrayBuffer): Promise<AudioBuffer>;
6
- createBuffer(channelData: Float32Array[] | Array<number[]>, duration: number): AudioBuffer;
7
- destroy(): void;
8
- }
1
+ /** Decode an array buffer into an audio buffer */
2
+ declare function decode(audioData: ArrayBuffer): Promise<AudioBuffer>;
3
+ /** Create an audio buffer from pre-decoded audio data */
4
+ declare function createBuffer(channelData: Float32Array[] | Array<number[]>, duration: number): AudioBuffer;
5
+ declare const Decoder: {
6
+ decode: typeof decode;
7
+ createBuffer: typeof createBuffer;
8
+ };
9
9
  export default Decoder;
package/dist/decoder.js CHANGED
@@ -1,50 +1,44 @@
1
- class Decoder {
2
- initAudioContext(sampleRate) {
3
- this.audioCtx = new AudioContext({
4
- latencyHint: 'playback',
5
- sampleRate,
1
+ /** Decode an array buffer into an audio buffer */
2
+ async function decode(audioData) {
3
+ const DEFAULT_SAMPLE_RATE = 8000; // All user agents are required to support a range of 8000Hz to 96000Hz
4
+ const MIN_SAMPLE_RATE = 3000; // Chrome, Safari can do 3kHz
5
+ let audioCtx;
6
+ try {
7
+ audioCtx = new AudioContext({
8
+ sampleRate: MIN_SAMPLE_RATE,
6
9
  });
7
10
  }
8
- constructor() {
9
- this.audioCtx = null;
10
- // Minimum sample rate supported by Web Audio API
11
- const DEFAULT_SAMPLE_RATE = 3000; // Chrome, Safari
12
- const FALLBACK_SAMPLE_RATE = 8000; // Firefox
13
- try {
14
- this.initAudioContext(DEFAULT_SAMPLE_RATE);
15
- }
16
- catch (e) {
17
- this.initAudioContext(FALLBACK_SAMPLE_RATE);
18
- }
19
- }
20
- async decode(audioData) {
21
- if (!this.audioCtx) {
22
- throw new Error('AudioContext is not initialized');
23
- }
24
- return this.audioCtx.decodeAudioData(audioData);
25
- }
26
- createBuffer(channelData, duration) {
27
- // If a single array of numbers is passed, make it an array of arrays
28
- if (typeof channelData[0] === 'number')
29
- channelData = [channelData];
30
- // Normalize to -1..1
31
- if (channelData[0].some((n) => n > 1 || n < -1)) {
32
- const max = Math.max(...channelData[0]);
33
- channelData = channelData.map((channel) => channel.map((n) => n / max));
34
- }
35
- return {
36
- length: channelData[0].length,
37
- duration,
38
- numberOfChannels: channelData.length,
39
- sampleRate: channelData[0].length / duration,
40
- getChannelData: (i) => channelData?.[i],
41
- copyFromChannel: AudioBuffer.prototype.copyFromChannel,
42
- copyToChannel: AudioBuffer.prototype.copyToChannel,
43
- };
11
+ catch (_) {
12
+ audioCtx = new AudioContext({
13
+ sampleRate: DEFAULT_SAMPLE_RATE,
14
+ });
44
15
  }
45
- destroy() {
46
- this.audioCtx?.close();
47
- this.audioCtx = null;
16
+ const decode = audioCtx.decodeAudioData(audioData);
17
+ decode.finally(() => audioCtx.close());
18
+ return decode;
19
+ }
20
+ /** Create an audio buffer from pre-decoded audio data */
21
+ function createBuffer(channelData, duration) {
22
+ // If a single array of numbers is passed, make it an array of arrays
23
+ if (typeof channelData[0] === 'number')
24
+ channelData = [channelData];
25
+ // Normalize to -1..1
26
+ if (channelData[0].some((n) => n > 1 || n < -1)) {
27
+ const max = Math.max(...channelData[0]);
28
+ channelData = channelData.map((channel) => channel.map((n) => n / max));
48
29
  }
30
+ return {
31
+ length: channelData[0].length,
32
+ duration,
33
+ numberOfChannels: channelData.length,
34
+ sampleRate: channelData[0].length / duration,
35
+ getChannelData: (i) => channelData?.[i],
36
+ copyFromChannel: AudioBuffer.prototype.copyFromChannel,
37
+ copyToChannel: AudioBuffer.prototype.copyToChannel,
38
+ };
49
39
  }
40
+ const Decoder = {
41
+ decode,
42
+ createBuffer,
43
+ };
50
44
  export default Decoder;
@@ -1,13 +1,19 @@
1
- export interface GeneralEventTypes {
2
- [eventType: string]: unknown;
3
- }
1
+ export type GeneralEventTypes = {
2
+ [EventName: string]: any[];
3
+ };
4
+ type EventListener<EventTypes extends GeneralEventTypes, EventName extends keyof EventTypes> = (...args: EventTypes[EventName]) => void;
5
+ /** A simple event emitter that can be used to listen to and emit events. */
4
6
  declare class EventEmitter<EventTypes extends GeneralEventTypes> {
5
- private eventTarget;
6
- constructor();
7
- protected emit<T extends keyof EventTypes>(eventType: T, detail?: EventTypes[T]): void;
8
- /** Subscribe to an event and return a function to unsubscribe */
9
- on<T extends keyof EventTypes>(eventType: T, callback: (detail: EventTypes[T]) => void, once?: boolean): () => void;
10
- /** Subscribe to an event once and return a function to unsubscribe */
11
- once<T extends keyof EventTypes>(eventType: T, callback: (detail: EventTypes[T]) => void): () => void;
7
+ private listeners;
8
+ /** Subscribe to an event. Returns an unsubscribe function. */
9
+ on<EventName extends keyof EventTypes>(eventName: EventName, listener: EventListener<EventTypes, EventName>): () => void;
10
+ /** Subscribe to an event only once */
11
+ once<EventName extends keyof EventTypes>(eventName: EventName, listener: EventListener<EventTypes, EventName>): () => void;
12
+ /** Unsubscribe from an event */
13
+ un<EventName extends keyof EventTypes>(eventName: EventName, listener: EventListener<EventTypes, EventName>): void;
14
+ /** Clear all events */
15
+ unAll(): void;
16
+ /** Emit an event */
17
+ protected emit<EventName extends keyof EventTypes>(eventName: EventName, ...args: EventTypes[EventName]): void;
12
18
  }
13
19
  export default EventEmitter;
@@ -1,25 +1,47 @@
1
+ /** A simple event emitter that can be used to listen to and emit events. */
1
2
  class EventEmitter {
2
3
  constructor() {
3
- this.eventTarget = new EventTarget();
4
+ this.listeners = {};
4
5
  }
5
- emit(eventType, detail) {
6
- const e = new CustomEvent(String(eventType), { detail });
7
- this.eventTarget.dispatchEvent(e);
6
+ /** Subscribe to an event. Returns an unsubscribe function. */
7
+ on(eventName, listener) {
8
+ if (!this.listeners[eventName]) {
9
+ this.listeners[eventName] = new Set();
10
+ }
11
+ this.listeners[eventName].add(listener);
12
+ return () => this.un(eventName, listener);
8
13
  }
9
- /** Subscribe to an event and return a function to unsubscribe */
10
- on(eventType, callback, once) {
11
- const handler = (e) => {
12
- if (e instanceof CustomEvent) {
13
- callback(e.detail);
14
+ /** Subscribe to an event only once */
15
+ once(eventName, listener) {
16
+ // The actual subscription
17
+ const unsubscribe = this.on(eventName, listener);
18
+ // Another subscription that will unsubscribe the actual subscription and itself after the first event
19
+ const unsubscribeOnce = this.on(eventName, () => {
20
+ unsubscribe();
21
+ unsubscribeOnce();
22
+ });
23
+ return unsubscribe;
24
+ }
25
+ /** Unsubscribe from an event */
26
+ un(eventName, listener) {
27
+ if (this.listeners[eventName]) {
28
+ if (listener) {
29
+ this.listeners[eventName].delete(listener);
30
+ }
31
+ else {
32
+ delete this.listeners[eventName];
14
33
  }
15
- };
16
- const eventName = String(eventType);
17
- this.eventTarget.addEventListener(eventName, handler, { once });
18
- return () => this.eventTarget.removeEventListener(eventName, handler);
34
+ }
35
+ }
36
+ /** Clear all events */
37
+ unAll() {
38
+ this.listeners = {};
19
39
  }
20
- /** Subscribe to an event once and return a function to unsubscribe */
21
- once(eventType, callback) {
22
- return this.on(eventType, callback, true);
40
+ /** Emit an event */
41
+ emit(eventName, ...args) {
42
+ if (this.listeners[eventName]) {
43
+ this.listeners[eventName].forEach((listener) => listener(...args));
44
+ }
23
45
  }
24
46
  }
25
47
  export default EventEmitter;
package/dist/player.d.ts CHANGED
@@ -8,7 +8,6 @@ declare class Player<T extends GeneralEventTypes> extends EventEmitter<T> {
8
8
  protected media: HTMLMediaElement;
9
9
  protected subscriptions: Array<() => void>;
10
10
  private isExternalMedia;
11
- private hasPlayedOnce;
12
11
  constructor(options: PlayerOptions);
13
12
  protected onMediaEvent(event: keyof HTMLMediaElementEventMap, callback: () => void, options?: AddEventListenerOptions): () => void;
14
13
  protected onceMediaEvent(event: keyof HTMLMediaElementEventMap, callback: () => void): () => void;
package/dist/player.js CHANGED
@@ -4,7 +4,6 @@ class Player extends EventEmitter {
4
4
  super();
5
5
  this.subscriptions = [];
6
6
  this.isExternalMedia = false;
7
- this.hasPlayedOnce = false;
8
7
  if (options.media) {
9
8
  this.media = options.media;
10
9
  this.isExternalMedia = true;
@@ -12,11 +11,6 @@ class Player extends EventEmitter {
12
11
  else {
13
12
  this.media = document.createElement('audio');
14
13
  }
15
- this.subscriptions.push(
16
- // Track the first play() call
17
- this.onceMediaEvent('play', () => {
18
- this.hasPlayedOnce = true;
19
- }));
20
14
  // Autoplay
21
15
  if (options.autoplay) {
22
16
  this.media.autoplay = true;
@@ -57,11 +51,6 @@ class Player extends EventEmitter {
57
51
  }
58
52
  /** Jumpt to a specific time in the audio (in seconds) */
59
53
  setTime(time) {
60
- if (!this.hasPlayedOnce) {
61
- this.media.play()?.then?.(() => {
62
- setTimeout(() => this.media.pause(), 10);
63
- });
64
- }
65
54
  this.media.currentTime = time;
66
55
  }
67
56
  /** Get the duration of the audio in seconds */
@@ -1,5 +1,4 @@
1
- import BasePlugin from '../base-plugin.js';
2
- import type { WaveSurferPluginParams } from '../wavesurfer.js';
1
+ import BasePlugin, { type WaveSurferPluginParams } from '../base-plugin.js';
3
2
  export type EnvelopePluginOptions = {
4
3
  fadeInStart?: number;
5
4
  fadeInEnd?: number;
@@ -24,15 +23,9 @@ declare const defaultOptions: {
24
23
  dragPointStroke: string;
25
24
  };
26
25
  export type EnvelopePluginEvents = {
27
- 'fade-in-change': {
28
- time: number;
29
- };
30
- 'fade-out-change': {
31
- time: number;
32
- };
33
- 'volume-change': {
34
- volume: number;
35
- };
26
+ 'fade-in-change': [time: number];
27
+ 'fade-out-change': [time: number];
28
+ 'volume-change': [volume: number];
36
29
  };
37
30
  declare class EnvelopePlugin extends BasePlugin<EnvelopePluginEvents, EnvelopePluginOptions> {
38
31
  protected options: EnvelopePluginOptions & typeof defaultOptions;
@@ -44,6 +37,7 @@ declare class EnvelopePlugin extends BasePlugin<EnvelopePluginEvents, EnvelopePl
44
37
  private isFadingOut;
45
38
  constructor(options: EnvelopePluginOptions);
46
39
  static create(options: EnvelopePluginOptions): EnvelopePlugin;
40
+ /** Called by wavesurfer, don't call manually */
47
41
  init(params: WaveSurferPluginParams): void;
48
42
  private makeDraggable;
49
43
  private renderPolyline;
@@ -28,12 +28,13 @@ class EnvelopePlugin extends BasePlugin {
28
28
  static create(options) {
29
29
  return new EnvelopePlugin(options);
30
30
  }
31
+ /** Called by wavesurfer, don't call manually */
31
32
  init(params) {
32
33
  super.init(params);
33
34
  if (!this.wavesurfer) {
34
35
  throw Error('WaveSurfer is not initialized');
35
36
  }
36
- this.subscriptions.push(this.wavesurfer.once('decode', ({ duration }) => {
37
+ this.subscriptions.push(this.wavesurfer.once('decode', (duration) => {
37
38
  this.options.fadeInStart = this.options.fadeInStart || 0;
38
39
  this.options.fadeOutEnd = this.options.fadeOutEnd || duration;
39
40
  this.options.fadeInEnd = this.options.fadeInEnd || this.options.fadeInStart;
@@ -183,11 +184,11 @@ class EnvelopePlugin extends BasePlugin {
183
184
  point.x = newX;
184
185
  if (index === 1) {
185
186
  this.options.fadeInEnd = newTime;
186
- this.emit('fade-in-change', { time: newTime });
187
+ this.emit('fade-in-change', newTime);
187
188
  }
188
189
  else if (index === 2) {
189
190
  this.options.fadeOutStart = newTime;
190
- this.emit('fade-out-change', { time: newTime });
191
+ this.emit('fade-out-change', newTime);
191
192
  }
192
193
  // Also allow dragging points vertically
193
194
  if (dy > 1 || dy < -1) {
@@ -237,7 +238,7 @@ class EnvelopePlugin extends BasePlugin {
237
238
  onVolumeChange(volume) {
238
239
  volume = this.naturalVolume(volume);
239
240
  this.volume = volume;
240
- this.emit('volume-change', { volume });
241
+ this.emit('volume-change', volume);
241
242
  if (!this.gainNode)
242
243
  return;
243
244
  this.gainNode.gain.value = volume;
@@ -245,7 +246,7 @@ class EnvelopePlugin extends BasePlugin {
245
246
  initFadeEffects() {
246
247
  if (!this.audioContext || !this.wavesurfer)
247
248
  return;
248
- const unsub = this.wavesurfer.on('timeupdate', ({ currentTime }) => {
249
+ const unsub = this.wavesurfer.on('timeupdate', (currentTime) => {
249
250
  if (!this.audioContext || !this.gainNode)
250
251
  return;
251
252
  if (!this.wavesurfer?.isPlaying())
@@ -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={284:(t,e,i)=>{i.d(e,{Z:()=>o});var n=i(139);class s extends n.Z{constructor(t){super(),this.subscriptions=[],this.options=t}init(t){this.wavesurfer=t.wavesurfer,this.container=t.container,this.wrapper=t.wrapper}destroy(){this.subscriptions.forEach((t=>t()))}}const o=s},139:(t,e,i)=>{i.d(e,{Z:()=>n});const n=class{constructor(){this.eventTarget=new EventTarget}emit(t,e){const i=new CustomEvent(String(t),{detail:e});this.eventTarget.dispatchEvent(i)}on(t,e,i){const n=t=>{t instanceof CustomEvent&&e(t.detail)},s=String(t);return this.eventTarget.addEventListener(s,n,{once:i}),()=>this.eventTarget.removeEventListener(s,n)}once(t,e){return this.on(t,e,!0)}}}},e={};function i(n){var s=e[n];if(void 0!==s)return s.exports;var o=e[n]={exports:{}};return t[n](o,o.exports,i),o.exports}i.d=(t,e)=>{for(var n in e)i.o(e,n)&&!i.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:e[n]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var n={};return(()=>{i.d(n,{default:()=>o});var t=i(284);const e={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 s extends t.Z{constructor(t){super(t),this.svg=null,this.audioContext=null,this.gainNode=null,this.volume=1,this.isFadingIn=!1,this.isFadingOut=!1,this.options=Object.assign({},e,t),this.options.lineColor=this.options.lineColor||e.lineColor,this.options.dragPointFill=this.options.dragPointFill||e.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||e.dragPointStroke,this.volume=this.options.volume??1}static create(t){return new s(t)}init(t){if(super.init(t),!this.wavesurfer)throw Error("WaveSurfer is not initialized");let e;this.subscriptions.push(this.wavesurfer.once("decode",(({duration: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.initWebAudio(),this.initSvg(),this.initFadeEffects()}))),this.subscriptions.push(this.wavesurfer.on("zoom",(()=>{e&&clearTimeout(e),e=setTimeout((()=>{this.svg?.remove(),this.initSvg()}),100)})))}makeDraggable(t,e){t.addEventListener("mousedown",(t=>{let i=t.clientX,n=t.clientY;const s=this.wavesurfer?.options.interact||!0;let o;this.wavesurfer?.toggleInteraction(!1);const r=t=>{const s=t.clientX-i,o=t.clientY-n;i=t.clientX,n=t.clientY,e(s,o)},a=()=>{document.removeEventListener("mousemove",r),document.removeEventListener("mouseup",a),o&&clearTimeout(o),o=setTimeout((()=>{this.wavesurfer?.toggleInteraction(s)}),100)};document.addEventListener("mousemove",r),document.addEventListener("mouseup",a),t.preventDefault(),t.stopPropagation()}))}renderPolyline(){if(!this.svg||!this.wrapper||!this.wavesurfer)return;const t=this.svg.querySelector("polyline"),e=t.points,i=e.getItem(1).y,n=this.wrapper.clientWidth,s=this.wavesurfer.getDuration();e.getItem(0).x=this.options.fadeInStart/s*n,e.getItem(3).x=this.options.fadeOutEnd/s*n;const o=this.svg.querySelector("line");o.setAttribute("x1",e.getItem(1).x.toString()),o.setAttribute("x2",e.getItem(2).x.toString()),o.setAttribute("y1",i.toString()),o.setAttribute("y2",i.toString());const r=this.svg.querySelectorAll("circle");for(let e=0;e<r.length;e++){const n=r[e],s=t.points.getItem(e+1);n.setAttribute("cx",s.x.toString()),n.setAttribute("cy",i.toString())}}initSvg(){if(!this.wrapper||!this.wavesurfer)return;const t=this.wrapper.clientWidth,e=this.wrapper.clientHeight,i=this.wavesurfer.getDuration(),n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.setAttribute("width","100%"),n.setAttribute("height","100%"),n.setAttribute("viewBox",`0 0 ${t} ${e}`),n.setAttribute("preserveAspectRatio","none"),n.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),this.svg=n;const s=document.createElementNS("http://www.w3.org/2000/svg","polyline");s.setAttribute("points","0,0 0,0 0,0 0,0"),s.setAttribute("stroke",this.options.lineColor),s.setAttribute("stroke-width",this.options.lineWidth),s.setAttribute("fill","none"),s.setAttribute("style","pointer-events: none"),n.appendChild(s);const o=document.createElementNS("http://www.w3.org/2000/svg","line");o.setAttribute("stroke","none"),o.setAttribute("stroke-width",(3*this.options.lineWidth).toString()),o.setAttribute("style","cursor: ns-resize; pointer-events: all;"),n.appendChild(o);const r=s.points,a=this.options.dragPointSize/2,u=e-this.volume*e+a;r.getItem(0).x=this.options.fadeInStart/i*t,r.getItem(0).y=e,r.getItem(1).x=this.options.fadeInEnd/i*t,r.getItem(1).y=u,r.getItem(2).x=this.options.fadeOutStart/i*t,r.getItem(2).y=u,r.getItem(3).x=this.options.fadeOutEnd/i*t,r.getItem(3).y=e,[1,2].forEach((()=>{const t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("r",(this.options.dragPointSize/2).toString()),t.setAttribute("fill",this.options.dragPointFill),t.setAttribute("stroke",this.options.dragPointStroke||this.options.dragPointFill),t.setAttribute("stroke-width","2"),t.setAttribute("style","cursor: ew-resize; pointer-events: all;"),n.appendChild(t)})),this.wrapper.appendChild(n),this.renderPolyline();const d=t=>{const i=r.getItem(1).y+t-a;if(i<-.5||i>e)return;r.getItem(1).y=i+a,r.getItem(2).y=i+a,this.renderPolyline();const n=Math.min(1,Math.max(0,(e-i)/e));this.onVolumeChange(n),this.renderPolyline()},h=(e,n,o)=>{const r=s.points.getItem(o),a=r.x+e,u=a/t*i;1===o&&u>this.options.fadeOutStart||u<this.options.fadeInStart||2===o&&u<this.options.fadeInEnd||u>this.options.fadeOutEnd||(r.x=a,1===o?(this.options.fadeInEnd=u,this.emit("fade-in-change",{time:u})):2===o&&(this.options.fadeOutStart=u,this.emit("fade-out-change",{time:u})),n>1||n<-1?d(n):this.renderPolyline())};this.makeDraggable(o,((t,e)=>d(e)));const l=n.querySelectorAll("circle");for(let t=0;t<l.length;t++){const e=t+1;this.makeDraggable(l[t],((t,i)=>h(t,i,e)))}}destroy(){this.svg?.remove(),super.destroy()}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.gainNode.gain.value=this.volume,e.createMediaElementSource(t).connect(this.gainNode),this.gainNode.connect(e.destination),this.audioContext=e}naturalVolume(t){return 1e-4+.9999*Math.pow(t,3)}onVolumeChange(t){t=this.naturalVolume(t),this.volume=t,this.emit("volume-change",{volume:t}),this.gainNode&&(this.gainNode.gain.value=t)}initFadeEffects(){if(!this.audioContext||!this.wavesurfer)return;const t=this.wavesurfer.on("timeupdate",(({currentTime: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,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.gainNode.gain.value=this.volume)}));this.subscriptions.push(t)}getCurrentVolume(){return this.gainNode?this.gainNode.gain.value:this.volume}setStartTime(t){this.options.fadeInStart=t,this.renderPolyline()}setEndTime(t){this.options.fadeOutEnd=t,this.renderPolyline()}}const o=s})(),n.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.Envelope=e():t.Envelope=e()}(WaveSurfer,(()=>(()=>{"use strict";var t={284:(t,e,i)=>{i.d(e,{Z:()=>o});var s=i(139);class n extends s.Z{constructor(t){super(),this.subscriptions=[],this.options=t}init(t){this.wavesurfer=t.wavesurfer,this.container=t.container,this.wrapper=t.wrapper}destroy(){this.subscriptions.forEach((t=>t()))}}const o=n},139:(t,e,i)=>{i.d(e,{Z:()=>s});const s=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)))}}}},e={};function i(s){var n=e[s];if(void 0!==n)return n.exports;var o=e[s]={exports:{}};return t[s](o,o.exports,i),o.exports}i.d=(t,e)=>{for(var s in e)i.o(e,s)&&!i.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:e[s]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);var s={};return(()=>{i.d(s,{default:()=>o});var t=i(284);const e={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 n extends t.Z{constructor(t){super(t),this.svg=null,this.audioContext=null,this.gainNode=null,this.volume=1,this.isFadingIn=!1,this.isFadingOut=!1,this.options=Object.assign({},e,t),this.options.lineColor=this.options.lineColor||e.lineColor,this.options.dragPointFill=this.options.dragPointFill||e.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||e.dragPointStroke,this.volume=this.options.volume??1}static create(t){return new n(t)}init(t){if(super.init(t),!this.wavesurfer)throw Error("WaveSurfer is not initialized");let e;this.subscriptions.push(this.wavesurfer.once("decode",(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.initWebAudio(),this.initSvg(),this.initFadeEffects()}))),this.subscriptions.push(this.wavesurfer.on("zoom",(()=>{e&&clearTimeout(e),e=setTimeout((()=>{this.svg?.remove(),this.initSvg()}),100)})))}makeDraggable(t,e){t.addEventListener("mousedown",(t=>{let i=t.clientX,s=t.clientY;const n=this.wavesurfer?.options.interact||!0;let o;this.wavesurfer?.toggleInteraction(!1);const r=t=>{const n=t.clientX-i,o=t.clientY-s;i=t.clientX,s=t.clientY,e(n,o)},a=()=>{document.removeEventListener("mousemove",r),document.removeEventListener("mouseup",a),o&&clearTimeout(o),o=setTimeout((()=>{this.wavesurfer?.toggleInteraction(n)}),100)};document.addEventListener("mousemove",r),document.addEventListener("mouseup",a),t.preventDefault(),t.stopPropagation()}))}renderPolyline(){if(!this.svg||!this.wrapper||!this.wavesurfer)return;const t=this.svg.querySelector("polyline"),e=t.points,i=e.getItem(1).y,s=this.wrapper.clientWidth,n=this.wavesurfer.getDuration();e.getItem(0).x=this.options.fadeInStart/n*s,e.getItem(3).x=this.options.fadeOutEnd/n*s;const o=this.svg.querySelector("line");o.setAttribute("x1",e.getItem(1).x.toString()),o.setAttribute("x2",e.getItem(2).x.toString()),o.setAttribute("y1",i.toString()),o.setAttribute("y2",i.toString());const r=this.svg.querySelectorAll("circle");for(let e=0;e<r.length;e++){const s=r[e],n=t.points.getItem(e+1);s.setAttribute("cx",n.x.toString()),s.setAttribute("cy",i.toString())}}initSvg(){if(!this.wrapper||!this.wavesurfer)return;const t=this.wrapper.clientWidth,e=this.wrapper.clientHeight,i=this.wavesurfer.getDuration(),s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width","100%"),s.setAttribute("height","100%"),s.setAttribute("viewBox",`0 0 ${t} ${e}`),s.setAttribute("preserveAspectRatio","none"),s.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),this.svg=s;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",this.options.lineColor),n.setAttribute("stroke-width",this.options.lineWidth),n.setAttribute("fill","none"),n.setAttribute("style","pointer-events: none"),s.appendChild(n);const o=document.createElementNS("http://www.w3.org/2000/svg","line");o.setAttribute("stroke","none"),o.setAttribute("stroke-width",(3*this.options.lineWidth).toString()),o.setAttribute("style","cursor: ns-resize; pointer-events: all;"),s.appendChild(o);const r=n.points,a=this.options.dragPointSize/2,h=e-this.volume*e+a;r.getItem(0).x=this.options.fadeInStart/i*t,r.getItem(0).y=e,r.getItem(1).x=this.options.fadeInEnd/i*t,r.getItem(1).y=h,r.getItem(2).x=this.options.fadeOutStart/i*t,r.getItem(2).y=h,r.getItem(3).x=this.options.fadeOutEnd/i*t,r.getItem(3).y=e,[1,2].forEach((()=>{const t=document.createElementNS("http://www.w3.org/2000/svg","circle");t.setAttribute("r",(this.options.dragPointSize/2).toString()),t.setAttribute("fill",this.options.dragPointFill),t.setAttribute("stroke",this.options.dragPointStroke||this.options.dragPointFill),t.setAttribute("stroke-width","2"),t.setAttribute("style","cursor: ew-resize; pointer-events: all;"),s.appendChild(t)})),this.wrapper.appendChild(s),this.renderPolyline();const u=t=>{const i=r.getItem(1).y+t-a;if(i<-.5||i>e)return;r.getItem(1).y=i+a,r.getItem(2).y=i+a,this.renderPolyline();const s=Math.min(1,Math.max(0,(e-i)/e));this.onVolumeChange(s),this.renderPolyline()},d=(e,s,o)=>{const r=n.points.getItem(o),a=r.x+e,h=a/t*i;1===o&&h>this.options.fadeOutStart||h<this.options.fadeInStart||2===o&&h<this.options.fadeInEnd||h>this.options.fadeOutEnd||(r.x=a,1===o?(this.options.fadeInEnd=h,this.emit("fade-in-change",h)):2===o&&(this.options.fadeOutStart=h,this.emit("fade-out-change",h)),s>1||s<-1?u(s):this.renderPolyline())};this.makeDraggable(o,((t,e)=>u(e)));const l=s.querySelectorAll("circle");for(let t=0;t<l.length;t++){const e=t+1;this.makeDraggable(l[t],((t,i)=>d(t,i,e)))}}destroy(){this.svg?.remove(),super.destroy()}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.gainNode.gain.value=this.volume,e.createMediaElementSource(t).connect(this.gainNode),this.gainNode.connect(e.destination),this.audioContext=e}naturalVolume(t){return 1e-4+.9999*Math.pow(t,3)}onVolumeChange(t){t=this.naturalVolume(t),this.volume=t,this.emit("volume-change",t),this.gainNode&&(this.gainNode.gain.value=t)}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,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.gainNode.gain.value=this.volume)}));this.subscriptions.push(t)}getCurrentVolume(){return this.gainNode?this.gainNode.gain.value:this.volume}setStartTime(t){this.options.fadeInStart=t,this.renderPolyline()}setEndTime(t){this.options.fadeOutEnd=t,this.renderPolyline()}}const o=n})(),s.default})()));
@@ -1,5 +1,5 @@
1
- import BasePlugin from '../base-plugin.js';
2
- import { type WaveSurferPluginParams, type WaveSurferOptions } from '../wavesurfer.js';
1
+ import BasePlugin, { type WaveSurferPluginParams } from '../base-plugin.js';
2
+ import { type WaveSurferOptions } from '../wavesurfer.js';
3
3
  export type MinimapPluginOptions = {
4
4
  overlayColor?: string;
5
5
  insertPosition?: InsertPosition;
@@ -10,8 +10,8 @@ declare const defaultOptions: {
10
10
  insertPosition: string;
11
11
  };
12
12
  export type MinimapPluginEvents = {
13
- ready: void;
14
- interaction: void;
13
+ ready: [];
14
+ interaction: [];
15
15
  };
16
16
  declare class MinimapPlugin extends BasePlugin<MinimapPluginEvents, MinimapPluginOptions> {
17
17
  protected options: MinimapPluginOptions & typeof defaultOptions;
@@ -20,6 +20,7 @@ declare class MinimapPlugin extends BasePlugin<MinimapPluginEvents, MinimapPlugi
20
20
  private overlay;
21
21
  constructor(options: MinimapPluginOptions);
22
22
  static create(options: MinimapPluginOptions): MinimapPlugin;
23
+ /** Called by wavesurfer, don't call manually */
23
24
  init(params: WaveSurferPluginParams): void;
24
25
  private initMinimapWrapper;
25
26
  private initOverlay;
@@ -16,6 +16,7 @@ class MinimapPlugin extends BasePlugin {
16
16
  static create(options) {
17
17
  return new MinimapPlugin(options);
18
18
  }
19
+ /** Called by wavesurfer, don't call manually */
19
20
  init(params) {
20
21
  super.init(params);
21
22
  if (!this.wavesurfer) {
@@ -68,7 +69,7 @@ class MinimapPlugin extends BasePlugin {
68
69
  });
69
70
  const overlayWidth = Math.round((this.minimapWrapper.clientWidth / this.wrapper.clientWidth) * 100);
70
71
  this.overlay.style.width = `${overlayWidth}%`;
71
- this.subscriptions.push(this.wavesurfer.on('timeupdate', ({ currentTime }) => {
72
+ this.subscriptions.push(this.wavesurfer.on('timeupdate', (currentTime) => {
72
73
  const offset = Math.max(0, Math.min((currentTime / data.duration) * 100 - overlayWidth / 2, 100 - overlayWidth)).toFixed(2);
73
74
  this.overlay.style.left = `${offset}%`;
74
75
  }));
@@ -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:()=>u});const i=class{constructor(){this.eventTarget=new EventTarget}emit(t,e){const i=new CustomEvent(String(t),{detail:e});this.eventTarget.dispatchEvent(i)}on(t,e,i){const s=t=>{t instanceof CustomEvent&&e(t.detail)},n=String(t);return this.eventTarget.addEventListener(n,s,{once:i}),()=>this.eventTarget.removeEventListener(n,s)}once(t,e){return this.on(t,e,!0)}},s=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}init(t){this.wavesurfer=t.wavesurfer,this.container=t.container,this.wrapper=t.wrapper}destroy(){this.subscriptions.forEach((t=>t()))}};class n extends i{constructor(t,e){super(),this.options={height:0},this.timeout=null,this.isScrolling=!1,this.channelData=null,this.duration=null,this.resizeObserver=null,this.options={...e};let i=null;if("string"==typeof t.container?i=document.querySelector(t.container):t.container instanceof HTMLElement&&(i=t.container),!i)throw new Error("Container not found");const[s,n]=this.initHtml();i.appendChild(s),this.container=s,this.scrollContainer=n.querySelector(".scroll"),this.wrapper=n.querySelector(".wrapper"),this.canvasWrapper=n.querySelector(".canvases"),this.progressWrapper=n.querySelector(".progress"),this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",{relativeX:i})})),this.resizeObserver=new ResizeObserver((()=>{this.delay((()=>this.reRender()),100)})),this.resizeObserver.observe(this.scrollContainer)}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 box-sizing: border-box;\n }\n </style>\n\n <div class="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getContainer(){return this.scrollContainer}getWrapper(){return this.wrapper}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 r=null!=this.options.barWidth?this.options.barWidth*s:1,o=null!=this.options.barGap?this.options.barGap*s:this.options.barWidth?r/2:0,a=this.options.barRadius??0,h=t[0],l=h.length,d=Math.floor(e/(r+o))/l,c=i/2,p=1===t.length,u=p?h:t[1],m=p&&u.some((t=>t<0)),g=(t,i)=>{let n=0,p=0,g=0;const y=document.createElement("canvas");y.width=Math.round(e*(i-t)/l),y.height=this.options.height,y.style.width=`${Math.floor(y.width/s)}px`,y.style.height=`${this.options.height}px`,y.style.left=`${Math.floor(t*e/s/l)}px`,this.canvasWrapper.appendChild(y);const v=y.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>n){const t=Math.round(p*c),e=Math.round(g*c);v.roundRect(n*(r+o),c-t,r,t+e||1,a),n=i,p=0,g=0}const s=m?h[e]:Math.abs(h[e]),l=m?u[e]:Math.abs(u[e]);s>p&&(p=s),(m?l<-g:l>g)&&(g=l<0?-l:l)}v.fill(),v.closePath();const f=y.cloneNode();this.progressWrapper.appendChild(f);const b=f.getContext("2d",{desynchronized:!0});y.width>0&&y.height>0&&b.drawImage(y,0,0),b.globalCompositeOperation="source-in",b.fillStyle=this.options.progressColor??"",b.fillRect(0,0,y.width,y.height)};this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="";const{scrollLeft:y,scrollWidth:v,clientWidth:f}=this.scrollContainer,b=l/v;let w=Math.min(n.MAX_CANVAS_WIDTH,f);w-=w%((r+o)/s);const C=Math.floor(Math.abs(y)*b),W=Math.ceil(C+w*b);g(C,W);const x=W-C;for(let t=W;t<l;t+=x)await this.delay((()=>{g(t,Math.min(l,t+x))}));for(let t=C-1;t>=0;t-=x)await this.delay((()=>{g(Math.max(0,t-x),t)}))}render(t,e){const i=window.devicePixelRatio||1,s=this.scrollContainer.clientWidth,n=Math.ceil(e*(this.options.minPxPerSec||0));this.isScrolling=n>s;const r=this.options.fillParent&&!this.isScrolling,o=(r?s:n)*i,{height:a}=this.options;this.wrapper.style.width=r?"100%":`${n}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.progressWrapper.style.borderRightStyle="solid",this.progressWrapper.style.borderRightColor=`${this.options.cursorColor||this.options.progressColor}`,this.progressWrapper.style.borderRightWidth=`${this.options.cursorWidth}px`,this.canvasWrapper.style.height=`${this.options.height}px`,this.renderPeaks(t,o,a,i),this.channelData=t,this.duration=e}reRender(){if(!this.channelData||!this.duration)return;const t=this.progressWrapper.clientWidth;this.render(this.channelData,this.duration);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}renderProgress(t,e=!1){if(!isNaN(t)&&(this.progressWrapper.style.width=100*t+"%",this.isScrolling&&this.options.autoCenter)){const{clientWidth:i,scrollLeft:s,scrollWidth:n}=this.scrollContainer,r=n*t,o=i/2,a=o/20;(r>s+(e?o:i)||r<s)&&(r-(s+o)>=a&&r<s+i?this.scrollContainer.scrollLeft+=a:this.scrollContainer.scrollLeft=r-o)}}}n.MAX_CANVAS_WIDTH=4e3;const r=n,o=class extends i{constructor(t){super(),this.subscriptions=[],this.isExternalMedia=!1,this.hasPlayedOnce=!1,t.media?(this.media=t.media,this.isExternalMedia=!0):this.media=document.createElement("audio"),this.subscriptions.push(this.onceMediaEvent("play",(()=>{this.hasPlayedOnce=!0}))),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})}loadUrl(t){this.media.src=t}destroy(){this.media.pause(),this.subscriptions.forEach((t=>t())),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.hasPlayedOnce||this.media.play()?.then?.((()=>{setTimeout((()=>this.media.pause()),10)})),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)}},a=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()}},h={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoCenter:!0};class l extends o{static create(t){return new l(t)}constructor(t){super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.canPlay=!1,this.options=Object.assign({},h,t),this.fetcher=new class{async load(t){return fetch(t).then((t=>t.arrayBuffer()))}},this.decoder=new class{initAudioContext(t){this.audioCtx=new AudioContext({latencyHint:"playback",sampleRate:t})}constructor(){this.audioCtx=null;try{this.initAudioContext(3e3)}catch(t){this.initAudioContext(8e3)}}async decode(t){if(!this.audioCtx)throw new Error("AudioContext is not initialized");return this.audioCtx.decodeAudioData(t)}createBuffer(t,e){if("number"==typeof t[0]&&(t=[t]),t[0].some((t=>t>1||t<-1))){const e=Math.max(...t[0]);t=t.map((t=>t.map((t=>t/e))))}return{length:t[0].length,duration:e,numberOfChannels:t.length,sampleRate:t[0].length/e,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}destroy(){this.audioCtx?.close(),this.audioCtx=null}},this.timer=new a,this.renderer=new r({container:this.options.container},this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initReadyEvent(),this.initPlugins();const e=this.options.url||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)}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",{currentTime:t})})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop(),this.getCurrentTime()>=this.getDuration()&&this.emit("finish")})),this.onMediaEvent("canplay",(()=>{this.canPlay=!0,this.emit("canplay",{duration:this.getDuration()})})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",{currentTime:this.getCurrentTime()})})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(({relativeX:t})=>{this.options.interact&&(this.seekTo(t),this.emit("interaction"))})))}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",{currentTime:t})})))}initReadyEvent(){const t=()=>{this.decodedData&&this.canPlay&&this.emit("ready",{duration: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({wavesurfer:this,container:this.renderer.getContainer(),wrapper:this.renderer.getWrapper()}),this.plugins.push(t),t}getActivePlugins(){return this.plugins}async load(t,e,i){if(this.decodedData=null,this.canPlay=!1,this.loadUrl(t),this.emit("loading",{url:t}),null==e){const e=await this.fetcher.load(t),i=await this.decoder.decode(e);this.decodedData=i}else i||(i=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getDuration())))}))||0),this.decodedData=this.decoder.createBuffer(e,i);this.renderAudio(),this.emit("decode",{duration:this.getDuration()}),this.emit("redraw")}renderAudio(){if(!this.decodedData)return;const t=[this.decodedData.getChannelData(0)];this.decodedData.numberOfChannels>1&&t.push(this.decodedData.getChannelData(1)),this.renderer.render(t,this.decodedData.duration)}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",{minPxPerSec: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.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.decoder.destroy(),this.renderer.destroy(),super.destroy()}}const d=l,c={height:50,overlayColor:"rgba(100, 100, 100, 0.1)",insertPosition:"afterend"};class p extends s{constructor(t){super(t),this.miniWavesurfer=null,this.options=Object.assign({},c,t),this.minimapWrapper=this.initMinimapWrapper(),this.overlay=this.initOverlay()}static create(t){return new p(t)}init(t){if(super.init(t),!this.wavesurfer)throw Error("WaveSurfer is not initialized");if(this.options.container){let t=null;"string"==typeof this.options.container?t=document.querySelector(this.options.container):this.options.container instanceof HTMLElement&&(t=this.options.container),t?.appendChild(this.minimapWrapper)}else this.container?.insertAdjacentElement(this.options.insertPosition,this.minimapWrapper);this.subscriptions.push(this.wavesurfer.on("decode",(()=>{this.initMinimap()})))}initMinimapWrapper(){const t=document.createElement("div");return t.style.position="relative",t}initOverlay(){const t=document.createElement("div");return t.setAttribute("style","position: absolute; z-index: 2; left: 0; top: 0; bottom: 0;"),t.style.backgroundColor=this.options.overlayColor,this.minimapWrapper.appendChild(t),t}initMinimap(){if(!this.wavesurfer||!this.wrapper)return;const t=this.wavesurfer.getDecodedData(),e=this.wavesurfer.getMediaElement();if(!t||!e)return;this.miniWavesurfer=d.create({...this.options,container:this.minimapWrapper,minPxPerSec:1,fillParent:!0,media:e,peaks:[t.getChannelData(0)],duration:t.duration});const i=Math.round(this.minimapWrapper.clientWidth/this.wrapper.clientWidth*100);this.overlay.style.width=`${i}%`,this.subscriptions.push(this.wavesurfer.on("timeupdate",(({currentTime:e})=>{const s=Math.max(0,Math.min(e/t.duration*100-i/2,100-i)).toFixed(2);this.overlay.style.left=`${s}%`}))),this.subscriptions.push(this.miniWavesurfer.on("interaction",(()=>{this.wavesurfer&&this.miniWavesurfer&&this.wavesurfer.setTime(this.miniWavesurfer.getCurrentTime()),this.container&&(this.container.scrollLeft=this.minimapWrapper.scrollLeft/this.minimapWrapper.scrollWidth*this.container.scrollWidth),this.emit("interaction")})),this.miniWavesurfer.on("ready",(()=>{this.emit("ready")})))}destroy(){this.miniWavesurfer?.destroy(),this.minimapWrapper.remove(),super.destroy()}}const u=p;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()}(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:()=>m});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}init(t){this.wavesurfer=t.wavesurfer,this.container=t.container,this.wrapper=t.wrapper}destroy(){this.subscriptions.forEach((t=>t()))}},n={decode:async function(t){let e;try{e=new AudioContext({sampleRate:3e3})}catch(t){e=new AudioContext({sampleRate:8e3})}const i=e.decodeAudioData(t);return i.finally((()=>e.close())),i},createBuffer:function(t,e){if("number"==typeof t[0]&&(t=[t]),t[0].some((t=>t>1||t<-1))){const e=Math.max(...t[0]);t=t.map((t=>t.map((t=>t/e))))}return{length:t[0].length,duration:e,numberOfChannels:t.length,sampleRate:t[0].length/e,getChannelData:e=>t?.[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}};class r extends i{constructor(t,e){super(),this.options={height:0},this.timeout=null,this.isScrolling=!1,this.channelData=null,this.duration=null,this.resizeObserver=null,this.options={...e};let i=null;if("string"==typeof t.container?i=document.querySelector(t.container):t.container instanceof HTMLElement&&(i=t.container),!i)throw new Error("Container not found");const[s,n]=this.initHtml();i.appendChild(s),this.container=s,this.scrollContainer=n.querySelector(".scroll"),this.wrapper=n.querySelector(".wrapper"),this.canvasWrapper=n.querySelector(".canvases"),this.progressWrapper=n.querySelector(".progress"),this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.resizeObserver=new ResizeObserver((()=>{this.delay((()=>this.reRender()),100)})),this.resizeObserver.observe(this.scrollContainer)}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 box-sizing: border-box;\n }\n </style>\n\n <div class="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getContainer(){return this.scrollContainer}getWrapper(){return this.wrapper}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?this.options.barWidth*s:1,o=null!=this.options.barGap?this.options.barGap*s:this.options.barWidth?n/2:0,a=this.options.barRadius??0,h=t[0],l=h.length,d=Math.floor(e/(n+o))/l,c=i/2,p=1===t.length,u=p?h:t[1],m=p&&u.some((t=>t<0)),g=(t,i)=>{let r=0,p=0,g=0;const y=document.createElement("canvas");y.width=Math.round(e*(i-t)/l),y.height=this.options.height,y.style.width=`${Math.floor(y.width/s)}px`,y.style.height=`${this.options.height}px`,y.style.left=`${Math.floor(t*e/s/l)}px`,this.canvasWrapper.appendChild(y);const f=y.getContext("2d",{desynchronized:!0});f.beginPath(),f.fillStyle=this.options.waveColor??"",f.roundRect||(f.roundRect=f.fillRect);for(let e=t;e<i;e++){const i=Math.round((e-t)*d);if(i>r){const t=Math.round(p*c),e=Math.round(g*c);f.roundRect(r*(n+o),c-t,n,t+e||1,a),r=i,p=0,g=0}const s=m?h[e]:Math.abs(h[e]),l=m?u[e]:Math.abs(u[e]);s>p&&(p=s),(m?l<-g:l>g)&&(g=l<0?-l:l)}f.fill(),f.closePath();const v=y.cloneNode();this.progressWrapper.appendChild(v);const b=v.getContext("2d",{desynchronized:!0});y.width>0&&y.height>0&&b.drawImage(y,0,0),b.globalCompositeOperation="source-in",b.fillStyle=this.options.progressColor??"",b.fillRect(0,0,y.width,y.height)};this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="";const{scrollLeft:y,scrollWidth:f,clientWidth:v}=this.scrollContainer,b=l/f;let w=Math.min(r.MAX_CANVAS_WIDTH,v);w-=w%((n+o)/s);const C=Math.floor(Math.abs(y)*b),W=Math.ceil(C+w*b);g(C,W);const M=W-C;for(let t=W;t<l;t+=M)await this.delay((()=>{g(t,Math.min(l,t+M))}));for(let t=C-1;t>=0;t-=M)await this.delay((()=>{g(Math.max(0,t-M),t)}))}render(t,e){const i=window.devicePixelRatio||1,s=this.scrollContainer.clientWidth,n=Math.ceil(e*(this.options.minPxPerSec||0));this.isScrolling=n>s;const r=this.options.fillParent&&!this.isScrolling,o=(r?s:n)*i,{height:a}=this.options;this.wrapper.style.width=r?"100%":`${n}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.progressWrapper.style.borderRightStyle="solid",this.progressWrapper.style.borderRightColor=`${this.options.cursorColor||this.options.progressColor}`,this.progressWrapper.style.borderRightWidth=`${this.options.cursorWidth}px`,this.canvasWrapper.style.height=`${this.options.height}px`,this.renderPeaks(t,o,a,i),this.channelData=t,this.duration=e}reRender(){if(!this.channelData||!this.duration)return;const t=this.progressWrapper.clientWidth;this.render(this.channelData,this.duration);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}renderProgress(t,e=!1){if(!isNaN(t)&&(this.progressWrapper.style.width=100*t+"%",this.isScrolling&&this.options.autoCenter)){const{clientWidth:i,scrollLeft:s,scrollWidth:n}=this.scrollContainer,r=n*t,o=i/2,a=o/20;(r>s+(e?o:i)||r<s)&&(r-(s+o)>=a&&r<s+i?this.scrollContainer.scrollLeft+=a:this.scrollContainer.scrollLeft=r-o)}}}r.MAX_CANVAS_WIDTH=4e3;const o=r,a=class extends i{constructor(t){super(),this.subscriptions=[],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})}loadUrl(t){this.media.src=t}destroy(){this.media.pause(),this.subscriptions.forEach((t=>t())),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)}},h=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()}},l={height:128,waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoCenter:!0};class d extends a{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.canPlay=!1,this.options=Object.assign({},l,t),this.fetcher=new class{async load(t){return fetch(t).then((t=>t.arrayBuffer()))}},this.timer=new h,this.renderer=new o({container:this.options.container},this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initReadyEvent(),this.initPlugins();const e=this.options.url||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)}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.getCurrentTime()>=this.getDuration()&&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"))})))}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({wavesurfer:this,container:this.renderer.getContainer(),wrapper:this.renderer.getWrapper()}),this.plugins.push(t),t}getActivePlugins(){return this.plugins}async load(t,e,i){if(this.decodedData=null,this.canPlay=!1,this.loadUrl(t),this.emit("load",t),e)i||(i=await new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getMediaElement().duration)))}))||0),this.decodedData=n.createBuffer(e,i);else{const e=await this.fetcher.load(t);this.decodedData=await n.decode(e)}this.renderAudio(),this.emit("decode",this.getDuration()),this.emit("redraw")}renderAudio(){if(!this.decodedData)return;const t=[this.decodedData.getChannelData(0)];this.decodedData.numberOfChannels>1&&t.push(this.decodedData.getChannelData(1)),this.renderer.render(t,this.decodedData.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(){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.plugins.forEach((t=>t.destroy())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}const c=d,p={height:50,overlayColor:"rgba(100, 100, 100, 0.1)",insertPosition:"afterend"};class u extends s{constructor(t){super(t),this.miniWavesurfer=null,this.options=Object.assign({},p,t),this.minimapWrapper=this.initMinimapWrapper(),this.overlay=this.initOverlay()}static create(t){return new u(t)}init(t){if(super.init(t),!this.wavesurfer)throw Error("WaveSurfer is not initialized");if(this.options.container){let t=null;"string"==typeof this.options.container?t=document.querySelector(this.options.container):this.options.container instanceof HTMLElement&&(t=this.options.container),t?.appendChild(this.minimapWrapper)}else this.container?.insertAdjacentElement(this.options.insertPosition,this.minimapWrapper);this.subscriptions.push(this.wavesurfer.on("decode",(()=>{this.initMinimap()})))}initMinimapWrapper(){const t=document.createElement("div");return t.style.position="relative",t}initOverlay(){const t=document.createElement("div");return t.setAttribute("style","position: absolute; z-index: 2; left: 0; top: 0; bottom: 0;"),t.style.backgroundColor=this.options.overlayColor,this.minimapWrapper.appendChild(t),t}initMinimap(){if(!this.wavesurfer||!this.wrapper)return;const t=this.wavesurfer.getDecodedData(),e=this.wavesurfer.getMediaElement();if(!t||!e)return;this.miniWavesurfer=c.create({...this.options,container:this.minimapWrapper,minPxPerSec:1,fillParent:!0,media:e,peaks:[t.getChannelData(0)],duration:t.duration});const i=Math.round(this.minimapWrapper.clientWidth/this.wrapper.clientWidth*100);this.overlay.style.width=`${i}%`,this.subscriptions.push(this.wavesurfer.on("timeupdate",(e=>{const s=Math.max(0,Math.min(e/t.duration*100-i/2,100-i)).toFixed(2);this.overlay.style.left=`${s}%`}))),this.subscriptions.push(this.miniWavesurfer.on("interaction",(()=>{this.wavesurfer&&this.miniWavesurfer&&this.wavesurfer.setTime(this.miniWavesurfer.getCurrentTime()),this.container&&(this.container.scrollLeft=this.minimapWrapper.scrollLeft/this.minimapWrapper.scrollWidth*this.container.scrollWidth),this.emit("interaction")})),this.miniWavesurfer.on("ready",(()=>{this.emit("ready")})))}destroy(){this.miniWavesurfer?.destroy(),this.minimapWrapper.remove(),super.destroy()}}const m=u;return e.default})()));
@@ -36,38 +36,38 @@ export type MultitrackOptions = {
36
36
  envelopeOptions?: EnvelopePluginOptions;
37
37
  };
38
38
  export type MultitrackEvents = {
39
- canplay: void;
40
- 'start-position-change': {
39
+ canplay: [];
40
+ 'start-position-change': [{
41
41
  id: TrackId;
42
42
  startPosition: number;
43
- };
44
- 'start-cue-change': {
43
+ }];
44
+ 'start-cue-change': [{
45
45
  id: TrackId;
46
46
  startCue: number;
47
- };
48
- 'end-cue-change': {
47
+ }];
48
+ 'end-cue-change': [{
49
49
  id: TrackId;
50
50
  endCue: number;
51
- };
52
- 'fade-in-change': {
51
+ }];
52
+ 'fade-in-change': [{
53
53
  id: TrackId;
54
54
  fadeInEnd: number;
55
- };
56
- 'fade-out-change': {
55
+ }];
56
+ 'fade-out-change': [{
57
57
  id: TrackId;
58
58
  fadeOutStart: number;
59
- };
60
- 'volume-change': {
59
+ }];
60
+ 'volume-change': [{
61
61
  id: TrackId;
62
62
  volume: number;
63
- };
64
- 'intro-end-change': {
63
+ }];
64
+ 'intro-end-change': [{
65
65
  id: TrackId;
66
66
  endTime: number;
67
- };
68
- drop: {
67
+ }];
68
+ drop: [{
69
69
  id: TrackId;
70
- };
70
+ }];
71
71
  };
72
72
  export type MultitrackTracks = Array<TrackOptions>;
73
73
  declare class MultiTrack extends EventEmitter<MultitrackEvents> {