wavesurfer.js 7.0.0-beta.15 → 7.0.0-beta.16

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 (68) hide show
  1. package/README.md +2 -2
  2. package/dist/draggable.js +0 -5
  3. package/dist/plugins/base-plugin.d.ts +16 -0
  4. package/dist/plugins/decoder.d.ts +9 -0
  5. package/dist/plugins/draggable.d.ts +1 -0
  6. package/dist/plugins/envelope.cjs +1 -0
  7. package/dist/plugins/envelope.d.ts +1 -1
  8. package/dist/plugins/envelope.esm.js +1 -0
  9. package/dist/plugins/envelope.js +1 -1
  10. package/dist/plugins/envelope.min.js +1 -0
  11. package/dist/plugins/event-emitter.d.ts +19 -0
  12. package/dist/plugins/fetcher.d.ts +5 -0
  13. package/dist/plugins/hover.cjs +1 -0
  14. package/dist/plugins/hover.d.ts +1 -1
  15. package/dist/plugins/hover.esm.js +1 -0
  16. package/dist/plugins/hover.js +1 -1
  17. package/dist/plugins/hover.min.js +1 -0
  18. package/dist/plugins/minimap.cjs +1 -0
  19. package/dist/plugins/minimap.d.ts +1 -1
  20. package/dist/plugins/minimap.esm.js +1 -0
  21. package/dist/plugins/minimap.js +1 -1
  22. package/dist/plugins/minimap.min.js +1 -0
  23. package/dist/plugins/player.d.ts +45 -0
  24. package/dist/plugins/plugins/envelope.d.ts +79 -0
  25. package/dist/plugins/plugins/hover.d.ts +35 -0
  26. package/dist/plugins/plugins/minimap.d.ts +39 -0
  27. package/dist/plugins/plugins/record.d.ts +28 -0
  28. package/dist/plugins/plugins/regions.d.ts +115 -0
  29. package/dist/plugins/plugins/spectrogram.d.ts +76 -0
  30. package/dist/plugins/plugins/timeline.d.ts +47 -0
  31. package/dist/plugins/record.cjs +1 -0
  32. package/dist/plugins/record.d.ts +1 -1
  33. package/dist/plugins/record.esm.js +1 -0
  34. package/dist/plugins/record.js +1 -1
  35. package/dist/plugins/record.min.js +1 -0
  36. package/dist/plugins/regions.cjs +1 -0
  37. package/dist/plugins/regions.d.ts +2 -2
  38. package/dist/plugins/regions.esm.js +1 -0
  39. package/dist/plugins/regions.js +2 -2
  40. package/dist/plugins/regions.min.js +1 -0
  41. package/dist/plugins/renderer.d.ts +44 -0
  42. package/dist/plugins/spectrogram.cjs +1 -0
  43. package/dist/plugins/spectrogram.d.ts +1 -1
  44. package/dist/plugins/spectrogram.esm.js +1 -0
  45. package/dist/plugins/spectrogram.js +1 -1
  46. package/dist/plugins/spectrogram.min.js +1 -0
  47. package/dist/plugins/timeline.cjs +1 -0
  48. package/dist/plugins/timeline.d.ts +1 -1
  49. package/dist/plugins/timeline.esm.js +1 -0
  50. package/dist/plugins/timeline.js +8 -5
  51. package/dist/plugins/timeline.min.js +1 -0
  52. package/dist/plugins/timer.d.ts +11 -0
  53. package/dist/plugins/wavesurfer.d.ts +156 -0
  54. package/dist/renderer.js +1 -0
  55. package/dist/wavesurfer.cjs +1 -0
  56. package/dist/wavesurfer.d.ts +1 -1
  57. package/dist/wavesurfer.esm.js +1 -0
  58. package/dist/wavesurfer.js +1 -1
  59. package/dist/wavesurfer.min.js +1 -0
  60. package/package.json +13 -14
  61. package/dist/plugins/envelope.min.cjs +0 -1
  62. package/dist/plugins/hover.min.cjs +0 -1
  63. package/dist/plugins/minimap.min.cjs +0 -1
  64. package/dist/plugins/record.min.cjs +0 -1
  65. package/dist/plugins/regions.min.cjs +0 -1
  66. package/dist/plugins/spectrogram.min.cjs +0 -1
  67. package/dist/plugins/timeline.min.cjs +0 -1
  68. package/dist/wavesurfer.min.cjs +0 -1
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Record audio from the microphone, render a waveform and download the audio.
3
+ */
4
+ import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
5
+ export type RecordPluginOptions = {
6
+ realtimeWaveColor?: string;
7
+ lineWidth?: number;
8
+ mimeType?: MediaRecorderOptions['mimeType'];
9
+ audioBitsPerSecond?: MediaRecorderOptions['audioBitsPerSecond'];
10
+ };
11
+ export type RecordPluginEvents = BasePluginEvents & {
12
+ startRecording: [];
13
+ stopRecording: [];
14
+ };
15
+ declare class RecordPlugin extends BasePlugin<RecordPluginEvents, RecordPluginOptions> {
16
+ private mediaRecorder;
17
+ private recordedUrl;
18
+ static create(options?: RecordPluginOptions): RecordPlugin;
19
+ private loadBlob;
20
+ render(stream: MediaStream): () => void;
21
+ private cleanUp;
22
+ startRecording(): Promise<void>;
23
+ isRecording(): boolean;
24
+ stopRecording(): void;
25
+ getRecordedUrl(): string;
26
+ destroy(): void;
27
+ }
28
+ export default RecordPlugin;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Regions are visual overlays on the waveform that can be used to mark segments of audio.
3
+ * Regions can be clicked on, dragged and resized.
4
+ * You can set the color and content of each region, as well as their HTML content.
5
+ */
6
+ import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
7
+ import EventEmitter from '../event-emitter.js';
8
+ export type RegionsPluginOptions = undefined;
9
+ export type RegionsPluginEvents = BasePluginEvents & {
10
+ 'region-created': [region: Region];
11
+ 'region-updated': [region: Region];
12
+ 'region-clicked': [region: Region, e: MouseEvent];
13
+ 'region-double-clicked': [region: Region, e: MouseEvent];
14
+ };
15
+ export type RegionEvents = {
16
+ /** Before the region is removed */
17
+ remove: [];
18
+ /** When the region's parameters are being updated */
19
+ update: [];
20
+ /** When dragging or resizing is finished */
21
+ 'update-end': [];
22
+ /** On play */
23
+ play: [];
24
+ /** On mouse click */
25
+ click: [event: MouseEvent];
26
+ /** Double click */
27
+ dblclick: [event: MouseEvent];
28
+ /** Mouse over */
29
+ over: [event: MouseEvent];
30
+ /** Mouse leave */
31
+ leave: [event: MouseEvent];
32
+ };
33
+ export type RegionParams = {
34
+ /** The id of the region, any string */
35
+ id?: string;
36
+ /** The start position of the region (in seconds) */
37
+ start: number;
38
+ /** The end position of the region (in seconds) */
39
+ end?: number;
40
+ /** Allow/dissallow dragging the region */
41
+ drag?: boolean;
42
+ /** Allow/dissallow resizing the region */
43
+ resize?: boolean;
44
+ /** The color of the region (CSS color) */
45
+ color?: string;
46
+ /** Content string or HTML element */
47
+ content?: string | HTMLElement;
48
+ /** Min length when resizing (in seconds) */
49
+ minLength?: number;
50
+ /** Max length when resizing (in seconds) */
51
+ maxLength?: number;
52
+ };
53
+ declare class Region extends EventEmitter<RegionEvents> {
54
+ private totalDuration;
55
+ element: HTMLElement;
56
+ id: string;
57
+ start: number;
58
+ end: number;
59
+ drag: boolean;
60
+ resize: boolean;
61
+ color: string;
62
+ content?: HTMLElement;
63
+ minLength: number;
64
+ maxLength: number;
65
+ constructor(params: RegionParams, totalDuration: number);
66
+ private initElement;
67
+ private renderPosition;
68
+ private initMouseEvents;
69
+ private onStartMoving;
70
+ private onEndMoving;
71
+ _onUpdate(dx: number, side?: 'start' | 'end'): void;
72
+ private onMove;
73
+ private onResize;
74
+ private onEndResizing;
75
+ _setTotalDuration(totalDuration: number): void;
76
+ /** Play the region from start to end */
77
+ play(): void;
78
+ /** Update the region's options */
79
+ setOptions(options: {
80
+ color?: string;
81
+ drag?: boolean;
82
+ resize?: boolean;
83
+ start?: number;
84
+ end?: number;
85
+ }): void;
86
+ /** Remove the region */
87
+ remove(): void;
88
+ }
89
+ declare class RegionsPlugin extends BasePlugin<RegionsPluginEvents, RegionsPluginOptions> {
90
+ private regions;
91
+ private regionsContainer;
92
+ /** Create an instance of RegionsPlugin */
93
+ constructor(options?: RegionsPluginOptions);
94
+ /** Create an instance of RegionsPlugin */
95
+ static create(options?: RegionsPluginOptions): RegionsPlugin;
96
+ /** Called by wavesurfer, don't call manually */
97
+ onInit(): void;
98
+ private initRegionsContainer;
99
+ /** Get all created regions */
100
+ getRegions(): Region[];
101
+ private avoidOverlapping;
102
+ private saveRegion;
103
+ /** Create a region with given parameters */
104
+ addRegion(options: RegionParams): Region;
105
+ /**
106
+ * Enable creation of regions by dragging on an empty space on the waveform.
107
+ * Returns a function to disable the drag selection.
108
+ */
109
+ enableDragSelection(options: Omit<RegionParams, 'start' | 'end'>): () => void;
110
+ /** Remove all regions */
111
+ clearRegions(): void;
112
+ /** Destroy the plugin and clean up */
113
+ destroy(): void;
114
+ }
115
+ export default RegionsPlugin;
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Spectrogram plugin
3
+ *
4
+ * Render a spectrogram visualisation of the audio.
5
+ *
6
+ * @author Pavel Denisov (https://github.com/akreal)
7
+ * @see https://github.com/wavesurfer-js/wavesurfer.js/pull/337
8
+ *
9
+ * @example
10
+ * // ... initialising wavesurfer with the plugin
11
+ * var wavesurfer = WaveSurfer.create({
12
+ * // wavesurfer options ...
13
+ * plugins: [
14
+ * SpectrogramPlugin.create({
15
+ * // plugin options ...
16
+ * })
17
+ * ]
18
+ * });
19
+ */
20
+ /**
21
+ * Spectrogram plugin for wavesurfer.
22
+ */
23
+ import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
24
+ export type SpectrogramPluginOptions = {
25
+ /** Selector of element or element in which to render */
26
+ container: string | HTMLElement;
27
+ /** Number of samples to fetch to FFT. Must be a power of 2. */
28
+ fftSamples?: number;
29
+ /** Height of the spectrogram view in CSS pixels */
30
+ height?: number;
31
+ /** Set to true to display frequency labels. */
32
+ labels?: boolean;
33
+ labelsBackground?: string;
34
+ labelsColor?: string;
35
+ labelsHzColor?: string;
36
+ /** Size of the overlapping window. Must be < fftSamples. Auto deduced from canvas size by default. */
37
+ noverlap?: number;
38
+ /** The window function to be used. */
39
+ windowFunc?: 'bartlett' | 'bartlettHann' | 'blackman' | 'cosine' | 'gauss' | 'hamming' | 'hann' | 'lanczoz' | 'rectangular' | 'triangular';
40
+ /** Some window functions have this extra value. (Between 0 and 1) */
41
+ alpha?: number;
42
+ /** Min frequency to scale spectrogram. */
43
+ frequencyMin?: number;
44
+ /** Max frequency to scale spectrogram. Set this to samplerate/2 to draw whole range of spectrogram. */
45
+ frequencyMax?: number;
46
+ /**
47
+ * A 256 long array of 4-element arrays. Each entry should contain a float between 0 and 1 and specify r, g, b, and alpha.
48
+ * Each entry should contain a float between 0 and 1 and specify r, g, b, and alpha.
49
+ */
50
+ colorMap?: number[][];
51
+ };
52
+ export type SpectrogramPluginEvents = BasePluginEvents & {
53
+ ready: [];
54
+ click: [relativeX: number];
55
+ };
56
+ declare class SpectrogramPlugin extends BasePlugin<SpectrogramPluginEvents, SpectrogramPluginOptions> {
57
+ static create(options?: SpectrogramPluginOptions): SpectrogramPlugin;
58
+ utils: {
59
+ style: (el: HTMLElement, styles: Record<string, string>) => CSSStyleDeclaration & Record<string, string>;
60
+ };
61
+ constructor(options: SpectrogramPluginOptions);
62
+ onInit(): void;
63
+ destroy(): void;
64
+ createWrapper(): void;
65
+ _wrapperClickHandler(event: any): void;
66
+ createCanvas(): void;
67
+ render(): void;
68
+ drawSpectrogram: (frequenciesData: any) => void;
69
+ getFrequencies(callback: any): void;
70
+ loadFrequenciesData(url: any): Promise<void>;
71
+ freqType(freq: any): string | number;
72
+ unitType(freq: any): "KHz" | "Hz";
73
+ loadLabels(bgFill: any, fontSizeFreq: any, fontSizeUnit: any, fontType: any, textColorFreq: any, textColorUnit: any, textAlign: any, container: any): void;
74
+ resample(oldMatrix: any): Uint8Array[];
75
+ }
76
+ export default SpectrogramPlugin;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The Timeline plugin adds timestamps and notches under the waveform.
3
+ */
4
+ import BasePlugin, { type BasePluginEvents } from '../base-plugin.js';
5
+ export type TimelinePluginOptions = {
6
+ /** The height of the timeline in pixels, defaults to 20 */
7
+ height?: number;
8
+ /** HTML container for the timeline, defaults to wavesufer's container */
9
+ container?: HTMLElement;
10
+ /** Pass 'beforebegin' to insert the timeline on top of the waveform */
11
+ insertPosition?: InsertPosition;
12
+ /** The duration of the timeline in seconds, defaults to wavesurfer's duration */
13
+ duration?: number;
14
+ /** Interval between ticks in seconds */
15
+ timeInterval?: number;
16
+ /** Interval between numeric labels */
17
+ primaryLabelInterval?: number;
18
+ /** Interval between secondary numeric labels */
19
+ secondaryLabelInterval?: number;
20
+ /** Custom inline style to apply to the container */
21
+ style?: Partial<CSSStyleDeclaration> | string;
22
+ /** Turn the time into a suitable label for the time. */
23
+ formatTimeCallback?: (seconds: number) => string;
24
+ };
25
+ declare const defaultOptions: {
26
+ height: number;
27
+ formatTimeCallback: (seconds: number) => string;
28
+ };
29
+ export type TimelinePluginEvents = BasePluginEvents & {
30
+ ready: [];
31
+ };
32
+ declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, TimelinePluginOptions> {
33
+ private timelineWrapper;
34
+ protected options: TimelinePluginOptions & typeof defaultOptions;
35
+ constructor(options?: TimelinePluginOptions);
36
+ static create(options?: TimelinePluginOptions): TimelinePlugin;
37
+ /** Called by wavesurfer, don't call manually */
38
+ onInit(): void;
39
+ /** Unmount */
40
+ destroy(): void;
41
+ private initTimelineWrapper;
42
+ private defaultTimeInterval;
43
+ private defaultPrimaryLabelInterval;
44
+ private defaultSecondaryLabelInterval;
45
+ private initTimeline;
46
+ }
47
+ export default TimelinePlugin;
@@ -0,0 +1 @@
1
+ "use strict";function e(e,t,r,i){return new(r||(r=Promise))((function(s,n){function o(e){try{a(i.next(e))}catch(e){n(e)}}function d(e){try{a(i.throw(e))}catch(e){n(e)}}function a(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,d)}a((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const r=this.on(e,t),i=this.on(e,(()=>{r(),i()}));return r}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}}class r extends t{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((e=>e()))}}const i=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class s extends r{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new s(e||{})}loadBlob(e,t){var r;const i=new Blob(e,{type:t});this.recordedUrl=URL.createObjectURL(i),null===(r=this.wavesurfer)||void 0===r||r.load(this.recordedUrl)}render(e){if(!this.wavesurfer)return()=>{};const t=this.wavesurfer.getWrapper(),r=document.createElement("canvas");r.width=t.clientWidth,r.height=t.clientHeight,r.style.zIndex="10",t.appendChild(r);const i=r.getContext("2d"),s=new AudioContext,n=s.createMediaStreamSource(e),o=s.createAnalyser();let d;n.connect(o);const a=()=>{var e;if(!i)return;i.clearRect(0,0,r.width,r.height);const t=o.frequencyBinCount,s=new Uint8Array(t);o.getByteTimeDomainData(s),i.lineWidth=this.options.lineWidth||2;const n=this.options.realtimeWaveColor||(null===(e=this.wavesurfer)||void 0===e?void 0:e.options.waveColor)||"";i.strokeStyle=Array.isArray(n)?n[0]:n,i.beginPath();const c=1*r.width/t;let h=0;for(let e=0;e<t;e++){const t=s[e]/128*r.height/2;0===e?i.moveTo(h,t):i.lineTo(h,t),h+=c}i.lineTo(r.width,r.height/2),i.stroke(),d=requestAnimationFrame(a)};return a(),()=>{d&&cancelAnimationFrame(d),n&&(n.disconnect(),n.mediaStream.getTracks().forEach((e=>e.stop()))),s&&s.close(),null==r||r.remove()}}cleanUp(){var e;this.stopRecording(),null===(e=this.wavesurfer)||void 0===e||e.empty(),this.recordedUrl&&(URL.revokeObjectURL(this.recordedUrl),this.recordedUrl="")}startRecording(){return e(this,void 0,void 0,(function*(){let e;this.cleanUp();try{e=yield navigator.mediaDevices.getUserMedia({audio:!0})}catch(e){throw new Error("Error accessing the microphone: "+e.message)}const t=this.render(e),r=new MediaRecorder(e,{mimeType:this.options.mimeType||i.find((e=>MediaRecorder.isTypeSupported(e))),audioBitsPerSecond:this.options.audioBitsPerSecond}),s=[];r.addEventListener("dataavailable",(e=>{e.data.size>0&&s.push(e.data)})),r.addEventListener("stop",(()=>{t(),this.loadBlob(s,r.mimeType),this.emit("stopRecording")})),r.start(),this.emit("startRecording"),this.mediaRecorder=r}))}isRecording(){var e;return"recording"===(null===(e=this.mediaRecorder)||void 0===e?void 0:e.state)}stopRecording(){var e;this.isRecording()&&(null===(e=this.mediaRecorder)||void 0===e||e.stop())}getRecordedUrl(){return this.recordedUrl}destroy(){super.destroy(),this.cleanUp()}}module.exports=s;
@@ -12,7 +12,7 @@ export type RecordPluginEvents = BasePluginEvents & {
12
12
  startRecording: [];
13
13
  stopRecording: [];
14
14
  };
15
- export declare class RecordPlugin extends BasePlugin<RecordPluginEvents, RecordPluginOptions> {
15
+ declare class RecordPlugin extends BasePlugin<RecordPluginEvents, RecordPluginOptions> {
16
16
  private mediaRecorder;
17
17
  private recordedUrl;
18
18
  static create(options?: RecordPluginOptions): RecordPlugin;
@@ -0,0 +1 @@
1
+ function e(e,t,r,i){return new(r||(r=Promise))((function(s,n){function o(e){try{d(i.next(e))}catch(e){n(e)}}function a(e){try{d(i.throw(e))}catch(e){n(e)}}function d(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,a)}d((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const r=this.on(e,t),i=this.on(e,(()=>{r(),i()}));return r}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}}class r extends t{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((e=>e()))}}const i=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class s extends r{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new s(e||{})}loadBlob(e,t){var r;const i=new Blob(e,{type:t});this.recordedUrl=URL.createObjectURL(i),null===(r=this.wavesurfer)||void 0===r||r.load(this.recordedUrl)}render(e){if(!this.wavesurfer)return()=>{};const t=this.wavesurfer.getWrapper(),r=document.createElement("canvas");r.width=t.clientWidth,r.height=t.clientHeight,r.style.zIndex="10",t.appendChild(r);const i=r.getContext("2d"),s=new AudioContext,n=s.createMediaStreamSource(e),o=s.createAnalyser();let a;n.connect(o);const d=()=>{var e;if(!i)return;i.clearRect(0,0,r.width,r.height);const t=o.frequencyBinCount,s=new Uint8Array(t);o.getByteTimeDomainData(s),i.lineWidth=this.options.lineWidth||2;const n=this.options.realtimeWaveColor||(null===(e=this.wavesurfer)||void 0===e?void 0:e.options.waveColor)||"";i.strokeStyle=Array.isArray(n)?n[0]:n,i.beginPath();const c=1*r.width/t;let h=0;for(let e=0;e<t;e++){const t=s[e]/128*r.height/2;0===e?i.moveTo(h,t):i.lineTo(h,t),h+=c}i.lineTo(r.width,r.height/2),i.stroke(),a=requestAnimationFrame(d)};return d(),()=>{a&&cancelAnimationFrame(a),n&&(n.disconnect(),n.mediaStream.getTracks().forEach((e=>e.stop()))),s&&s.close(),null==r||r.remove()}}cleanUp(){var e;this.stopRecording(),null===(e=this.wavesurfer)||void 0===e||e.empty(),this.recordedUrl&&(URL.revokeObjectURL(this.recordedUrl),this.recordedUrl="")}startRecording(){return e(this,void 0,void 0,(function*(){let e;this.cleanUp();try{e=yield navigator.mediaDevices.getUserMedia({audio:!0})}catch(e){throw new Error("Error accessing the microphone: "+e.message)}const t=this.render(e),r=new MediaRecorder(e,{mimeType:this.options.mimeType||i.find((e=>MediaRecorder.isTypeSupported(e))),audioBitsPerSecond:this.options.audioBitsPerSecond}),s=[];r.addEventListener("dataavailable",(e=>{e.data.size>0&&s.push(e.data)})),r.addEventListener("stop",(()=>{t(),this.loadBlob(s,r.mimeType),this.emit("stopRecording")})),r.start(),this.emit("startRecording"),this.mediaRecorder=r}))}isRecording(){var e;return"recording"===(null===(e=this.mediaRecorder)||void 0===e?void 0:e.state)}stopRecording(){var e;this.isRecording()&&(null===(e=this.mediaRecorder)||void 0===e||e.stop())}getRecordedUrl(){return this.recordedUrl}destroy(){super.destroy(),this.cleanUp()}}export{s as default};
@@ -13,7 +13,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
13
13
  import BasePlugin from '../base-plugin.js';
14
14
  const MIME_TYPES = ['audio/webm', 'audio/wav', 'audio/mpeg', 'audio/mp4', 'audio/mp3'];
15
15
  const findSupportedMimeType = () => MIME_TYPES.find((mimeType) => MediaRecorder.isTypeSupported(mimeType));
16
- export class RecordPlugin extends BasePlugin {
16
+ class RecordPlugin extends BasePlugin {
17
17
  constructor() {
18
18
  super(...arguments);
19
19
  this.mediaRecorder = null;
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).WaveSurfer=e.WaveSurfer||{},e.WaveSurfer.Record=t())}(this,(function(){"use strict";function e(e,t,r,i){return new(r||(r=Promise))((function(s,n){function o(e){try{a(i.next(e))}catch(e){n(e)}}function d(e){try{a(i.throw(e))}catch(e){n(e)}}function a(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,d)}a((i=i.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class t{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const r=this.on(e,t),i=this.on(e,(()=>{r(),i()}));return r}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}}class r extends t{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((e=>e()))}}const i=["audio/webm","audio/wav","audio/mpeg","audio/mp4","audio/mp3"];class s extends r{constructor(){super(...arguments),this.mediaRecorder=null,this.recordedUrl=""}static create(e){return new s(e||{})}loadBlob(e,t){var r;const i=new Blob(e,{type:t});this.recordedUrl=URL.createObjectURL(i),null===(r=this.wavesurfer)||void 0===r||r.load(this.recordedUrl)}render(e){if(!this.wavesurfer)return()=>{};const t=this.wavesurfer.getWrapper(),r=document.createElement("canvas");r.width=t.clientWidth,r.height=t.clientHeight,r.style.zIndex="10",t.appendChild(r);const i=r.getContext("2d"),s=new AudioContext,n=s.createMediaStreamSource(e),o=s.createAnalyser();let d;n.connect(o);const a=()=>{var e;if(!i)return;i.clearRect(0,0,r.width,r.height);const t=o.frequencyBinCount,s=new Uint8Array(t);o.getByteTimeDomainData(s),i.lineWidth=this.options.lineWidth||2;const n=this.options.realtimeWaveColor||(null===(e=this.wavesurfer)||void 0===e?void 0:e.options.waveColor)||"";i.strokeStyle=Array.isArray(n)?n[0]:n,i.beginPath();const c=1*r.width/t;let l=0;for(let e=0;e<t;e++){const t=s[e]/128*r.height/2;0===e?i.moveTo(l,t):i.lineTo(l,t),l+=c}i.lineTo(r.width,r.height/2),i.stroke(),d=requestAnimationFrame(a)};return a(),()=>{d&&cancelAnimationFrame(d),n&&(n.disconnect(),n.mediaStream.getTracks().forEach((e=>e.stop()))),s&&s.close(),null==r||r.remove()}}cleanUp(){var e;this.stopRecording(),null===(e=this.wavesurfer)||void 0===e||e.empty(),this.recordedUrl&&(URL.revokeObjectURL(this.recordedUrl),this.recordedUrl="")}startRecording(){return e(this,void 0,void 0,(function*(){let e;this.cleanUp();try{e=yield navigator.mediaDevices.getUserMedia({audio:!0})}catch(e){throw new Error("Error accessing the microphone: "+e.message)}const t=this.render(e),r=new MediaRecorder(e,{mimeType:this.options.mimeType||i.find((e=>MediaRecorder.isTypeSupported(e))),audioBitsPerSecond:this.options.audioBitsPerSecond}),s=[];r.addEventListener("dataavailable",(e=>{e.data.size>0&&s.push(e.data)})),r.addEventListener("stop",(()=>{t(),this.loadBlob(s,r.mimeType),this.emit("stopRecording")})),r.start(),this.emit("startRecording"),this.mediaRecorder=r}))}isRecording(){var e;return"recording"===(null===(e=this.mediaRecorder)||void 0===e?void 0:e.state)}stopRecording(){var e;this.isRecording()&&(null===(e=this.mediaRecorder)||void 0===e||e.stop())}getRecordedUrl(){return this.recordedUrl}destroy(){super.destroy(),this.cleanUp()}}return s}));
@@ -0,0 +1 @@
1
+ "use strict";class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function i(t,e,i,n,s=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let l=o.clientX,a=o.clientY,h=!1;const d=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(h||Math.abs(r-l)>=s||Math.abs(o-a)>=s){const{left:n,top:s}=t.getBoundingClientRect();h||(h=!0,null==i||i(l-n,a-s)),e(r-l,o-a,r-n,o-s),l=r,a=o}},u=t=>{h&&(t.preventDefault(),t.stopPropagation())},c=()=>{h&&(null==n||n()),r()};document.addEventListener("pointermove",d),document.addEventListener("pointerup",c),document.addEventListener("pointerleave",c),document.addEventListener("click",u,!0),r=()=>{document.removeEventListener("pointermove",d),document.removeEventListener("pointerup",c),document.removeEventListener("pointerleave",c),setTimeout((()=>{document.removeEventListener("click",u,!0)}),10)}};return t.addEventListener("pointerdown",o),()=>{r(),t.removeEventListener("pointerdown",o)}}class n extends t{constructor(t,e){var i,n,s,r,o,l;super(),this.totalDuration=e,this.minLength=0,this.maxLength=1/0,this.id=t.id||`region-${Math.random().toString(32).slice(2)}`,this.start=t.start,this.end=null!==(i=t.end)&&void 0!==i?i:t.start,this.drag=null===(n=t.drag)||void 0===n||n,this.resize=null===(s=t.resize)||void 0===s||s,this.color=null!==(r=t.color)&&void 0!==r?r:"rgba(0, 0, 0, 0.1)",this.minLength=null!==(o=t.minLength)&&void 0!==o?o:this.minLength,this.maxLength=null!==(l=t.maxLength)&&void 0!==l?l:this.maxLength,this.element=this.initElement(t.content),this.renderPosition(),this.initMouseEvents()}initElement(t){const e=document.createElement("div"),i=this.start===this.end;if(e.setAttribute("part",`${i?"marker":"region"} ${this.id}`),e.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n `),t&&("string"==typeof t?(this.content=document.createElement("div"),this.content.style.padding=`0.2em ${i?.2:.4}em`,this.content.textContent=t):this.content=t,this.content.setAttribute("part","region-content"),e.appendChild(this.content)),!i){const t=document.createElement("div");t.setAttribute("data-resize","left"),t.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),t.setAttribute("part","region-handle region-handle-left");const i=t.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),e.appendChild(t),e.appendChild(i)}return e}renderPosition(){const t=this.start/this.totalDuration,e=(this.totalDuration-this.end)/this.totalDuration;this.element.style.left=100*t+"%",this.element.style.right=100*e+"%"}initMouseEvents(){const{element:t}=this;if(!t)return;t.addEventListener("click",(t=>this.emit("click",t))),t.addEventListener("mouseenter",(t=>this.emit("over",t))),t.addEventListener("mouseleave",(t=>this.emit("leave",t))),t.addEventListener("dblclick",(t=>this.emit("dblclick",t))),i(t,(t=>this.onMove(t)),(()=>this.onStartMoving()),(()=>this.onEndMoving()));i(t.querySelector('[data-resize="left"]'),(t=>this.onResize(t,"start")),(()=>null),(()=>this.onEndResizing()),1),i(t.querySelector('[data-resize="right"]'),(t=>this.onResize(t,"end")),(()=>null),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(t,e){if(!this.element.parentElement)return;const i=t/this.element.parentElement.clientWidth*this.totalDuration,n=e&&"start"!==e?this.start:this.start+i,s=e&&"end"!==e?this.end:this.end+i,r=s-n;n>0&&s<this.totalDuration&&n<=s&&r>=this.minLength&&r<=this.maxLength&&(this.start=n,this.end=s,this.renderPosition(),this.emit("update"))}onMove(t){this.drag&&this._onUpdate(t)}onResize(t,e){this.resize&&this._onUpdate(t,e)}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(t){this.totalDuration=t,this.renderPosition()}play(){this.emit("play")}setOptions(t){var e,i;t.color&&(this.color=t.color,this.element.style.backgroundColor=this.color),void 0!==t.drag&&(this.drag=t.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==t.resize&&(this.resize=t.resize,this.element.querySelectorAll("[data-resize]").forEach((t=>{t.style.cursor=this.resize?"ew-resize":"default"}))),void 0===t.start&&void 0===t.end||(this.start=null!==(e=t.start)&&void 0!==e?e:this.start,this.end=null!==(i=t.end)&&void 0!==i?i:this.end,this.renderPosition())}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class s extends e{constructor(t){super(t),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(t){return new s(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer)}initRegionsContainer(){const t=document.createElement("div");return t.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),t}getRegions(){return this.regions}avoidOverlapping(t){if(!t.content)return;const e=t.content,i=e.getBoundingClientRect().left,n=t.element.scrollWidth,s=this.regions.filter((e=>{if(e===t||!e.content)return!1;const s=e.content.getBoundingClientRect().left,r=e.element.scrollWidth;return i<s+r&&s<i+n})).map((t=>{var e;return(null===(e=t.content)||void 0===e?void 0:e.getBoundingClientRect().height)||0})).reduce(((t,e)=>t+e),0);e.style.marginTop=`${s}px`}saveRegion(t){this.regionsContainer.appendChild(t.element),this.avoidOverlapping(t),this.regions.push(t),this.emit("region-created",t);const e=[t.on("update-end",(()=>{this.avoidOverlapping(t),this.emit("region-updated",t)})),t.on("play",(()=>{var e,i;null===(e=this.wavesurfer)||void 0===e||e.play(),null===(i=this.wavesurfer)||void 0===i||i.setTime(t.start)})),t.on("click",(e=>{this.emit("region-clicked",t,e)})),t.on("dblclick",(e=>{this.emit("region-double-clicked",t,e)})),t.once("remove",(()=>{e.forEach((t=>t())),this.regions=this.regions.filter((e=>e!==t))}))];this.subscriptions.push(...e)}addRegion(t){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=this.wavesurfer.getDuration(),i=new n(t,e);return e?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(t=>{i._setTotalDuration(t),this.saveRegion(i)}))),i}enableDragSelection(t){var e,s;const r=null===(s=null===(e=this.wavesurfer)||void 0===e?void 0:e.getWrapper())||void 0===s?void 0:s.querySelector("div");if(!r)return()=>{};let o=null,l=0;return i(r,((t,e,i)=>{o&&o._onUpdate(t,i>l?"end":"start")}),(e=>{if(l=e,!this.wavesurfer)return;const i=this.wavesurfer.getDuration(),s=this.wavesurfer.getWrapper().clientWidth,r=e/s*i,a=(e+5)/s*i;o=new n(Object.assign(Object.assign({},t),{start:r,end:a}),i),this.regionsContainer.appendChild(o.element)}),(()=>{o&&(this.saveRegion(o),o=null)}))}clearRegions(){this.regions.forEach((t=>t.remove()))}destroy(){this.clearRegions(),super.destroy()}}module.exports=s;
@@ -50,7 +50,7 @@ export type RegionParams = {
50
50
  /** Max length when resizing (in seconds) */
51
51
  maxLength?: number;
52
52
  };
53
- export declare class Region extends EventEmitter<RegionEvents> {
53
+ declare class Region extends EventEmitter<RegionEvents> {
54
54
  private totalDuration;
55
55
  element: HTMLElement;
56
56
  id: string;
@@ -86,7 +86,7 @@ export declare class Region extends EventEmitter<RegionEvents> {
86
86
  /** Remove the region */
87
87
  remove(): void;
88
88
  }
89
- export declare class RegionsPlugin extends BasePlugin<RegionsPluginEvents, RegionsPluginOptions> {
89
+ declare class RegionsPlugin extends BasePlugin<RegionsPluginEvents, RegionsPluginOptions> {
90
90
  private regions;
91
91
  private regionsContainer;
92
92
  /** Create an instance of RegionsPlugin */
@@ -0,0 +1 @@
1
+ class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function i(t,e,i,n,s=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let l=o.clientX,a=o.clientY,h=!1;const d=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(h||Math.abs(r-l)>=s||Math.abs(o-a)>=s){const{left:n,top:s}=t.getBoundingClientRect();h||(h=!0,null==i||i(l-n,a-s)),e(r-l,o-a,r-n,o-s),l=r,a=o}},u=t=>{h&&(t.preventDefault(),t.stopPropagation())},c=()=>{h&&(null==n||n()),r()};document.addEventListener("pointermove",d),document.addEventListener("pointerup",c),document.addEventListener("pointerleave",c),document.addEventListener("click",u,!0),r=()=>{document.removeEventListener("pointermove",d),document.removeEventListener("pointerup",c),document.removeEventListener("pointerleave",c),setTimeout((()=>{document.removeEventListener("click",u,!0)}),10)}};return t.addEventListener("pointerdown",o),()=>{r(),t.removeEventListener("pointerdown",o)}}class n extends t{constructor(t,e){var i,n,s,r,o,l;super(),this.totalDuration=e,this.minLength=0,this.maxLength=1/0,this.id=t.id||`region-${Math.random().toString(32).slice(2)}`,this.start=t.start,this.end=null!==(i=t.end)&&void 0!==i?i:t.start,this.drag=null===(n=t.drag)||void 0===n||n,this.resize=null===(s=t.resize)||void 0===s||s,this.color=null!==(r=t.color)&&void 0!==r?r:"rgba(0, 0, 0, 0.1)",this.minLength=null!==(o=t.minLength)&&void 0!==o?o:this.minLength,this.maxLength=null!==(l=t.maxLength)&&void 0!==l?l:this.maxLength,this.element=this.initElement(t.content),this.renderPosition(),this.initMouseEvents()}initElement(t){const e=document.createElement("div"),i=this.start===this.end;if(e.setAttribute("part",`${i?"marker":"region"} ${this.id}`),e.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n `),t&&("string"==typeof t?(this.content=document.createElement("div"),this.content.style.padding=`0.2em ${i?.2:.4}em`,this.content.textContent=t):this.content=t,this.content.setAttribute("part","region-content"),e.appendChild(this.content)),!i){const t=document.createElement("div");t.setAttribute("data-resize","left"),t.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),t.setAttribute("part","region-handle region-handle-left");const i=t.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),e.appendChild(t),e.appendChild(i)}return e}renderPosition(){const t=this.start/this.totalDuration,e=(this.totalDuration-this.end)/this.totalDuration;this.element.style.left=100*t+"%",this.element.style.right=100*e+"%"}initMouseEvents(){const{element:t}=this;if(!t)return;t.addEventListener("click",(t=>this.emit("click",t))),t.addEventListener("mouseenter",(t=>this.emit("over",t))),t.addEventListener("mouseleave",(t=>this.emit("leave",t))),t.addEventListener("dblclick",(t=>this.emit("dblclick",t))),i(t,(t=>this.onMove(t)),(()=>this.onStartMoving()),(()=>this.onEndMoving()));i(t.querySelector('[data-resize="left"]'),(t=>this.onResize(t,"start")),(()=>null),(()=>this.onEndResizing()),1),i(t.querySelector('[data-resize="right"]'),(t=>this.onResize(t,"end")),(()=>null),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(t,e){if(!this.element.parentElement)return;const i=t/this.element.parentElement.clientWidth*this.totalDuration,n=e&&"start"!==e?this.start:this.start+i,s=e&&"end"!==e?this.end:this.end+i,r=s-n;n>0&&s<this.totalDuration&&n<=s&&r>=this.minLength&&r<=this.maxLength&&(this.start=n,this.end=s,this.renderPosition(),this.emit("update"))}onMove(t){this.drag&&this._onUpdate(t)}onResize(t,e){this.resize&&this._onUpdate(t,e)}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(t){this.totalDuration=t,this.renderPosition()}play(){this.emit("play")}setOptions(t){var e,i;t.color&&(this.color=t.color,this.element.style.backgroundColor=this.color),void 0!==t.drag&&(this.drag=t.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==t.resize&&(this.resize=t.resize,this.element.querySelectorAll("[data-resize]").forEach((t=>{t.style.cursor=this.resize?"ew-resize":"default"}))),void 0===t.start&&void 0===t.end||(this.start=null!==(e=t.start)&&void 0!==e?e:this.start,this.end=null!==(i=t.end)&&void 0!==i?i:this.end,this.renderPosition())}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class s extends e{constructor(t){super(t),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(t){return new s(t)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer)}initRegionsContainer(){const t=document.createElement("div");return t.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),t}getRegions(){return this.regions}avoidOverlapping(t){if(!t.content)return;const e=t.content,i=e.getBoundingClientRect().left,n=t.element.scrollWidth,s=this.regions.filter((e=>{if(e===t||!e.content)return!1;const s=e.content.getBoundingClientRect().left,r=e.element.scrollWidth;return i<s+r&&s<i+n})).map((t=>{var e;return(null===(e=t.content)||void 0===e?void 0:e.getBoundingClientRect().height)||0})).reduce(((t,e)=>t+e),0);e.style.marginTop=`${s}px`}saveRegion(t){this.regionsContainer.appendChild(t.element),this.avoidOverlapping(t),this.regions.push(t),this.emit("region-created",t);const e=[t.on("update-end",(()=>{this.avoidOverlapping(t),this.emit("region-updated",t)})),t.on("play",(()=>{var e,i;null===(e=this.wavesurfer)||void 0===e||e.play(),null===(i=this.wavesurfer)||void 0===i||i.setTime(t.start)})),t.on("click",(e=>{this.emit("region-clicked",t,e)})),t.on("dblclick",(e=>{this.emit("region-double-clicked",t,e)})),t.once("remove",(()=>{e.forEach((t=>t())),this.regions=this.regions.filter((e=>e!==t))}))];this.subscriptions.push(...e)}addRegion(t){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=this.wavesurfer.getDuration(),i=new n(t,e);return e?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(t=>{i._setTotalDuration(t),this.saveRegion(i)}))),i}enableDragSelection(t){var e,s;const r=null===(s=null===(e=this.wavesurfer)||void 0===e?void 0:e.getWrapper())||void 0===s?void 0:s.querySelector("div");if(!r)return()=>{};let o=null,l=0;return i(r,((t,e,i)=>{o&&o._onUpdate(t,i>l?"end":"start")}),(e=>{if(l=e,!this.wavesurfer)return;const i=this.wavesurfer.getDuration(),s=this.wavesurfer.getWrapper().clientWidth,r=e/s*i,a=(e+5)/s*i;o=new n(Object.assign(Object.assign({},t),{start:r,end:a}),i),this.regionsContainer.appendChild(o.element)}),(()=>{o&&(this.saveRegion(o),o=null)}))}clearRegions(){this.regions.forEach((t=>t.remove()))}destroy(){this.clearRegions(),super.destroy()}}export{s as default};
@@ -6,7 +6,7 @@
6
6
  import BasePlugin from '../base-plugin.js';
7
7
  import { makeDraggable } from '../draggable.js';
8
8
  import EventEmitter from '../event-emitter.js';
9
- export class Region extends EventEmitter {
9
+ class Region extends EventEmitter {
10
10
  constructor(params, totalDuration) {
11
11
  var _a, _b, _c, _d, _e, _f;
12
12
  super();
@@ -189,7 +189,7 @@ export class Region extends EventEmitter {
189
189
  this.element = null;
190
190
  }
191
191
  }
192
- export class RegionsPlugin extends BasePlugin {
192
+ class RegionsPlugin extends BasePlugin {
193
193
  /** Create an instance of RegionsPlugin */
194
194
  constructor(options) {
195
195
  super(options);
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):((e="undefined"!=typeof globalThis?globalThis:e||self).WaveSurfer=e.WaveSurfer||{},e.WaveSurfer.Regions=t())}(this,(function(){"use strict";class e{constructor(){this.listeners={}}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.un(e,t)}once(e,t){const i=this.on(e,t),n=this.on(e,(()=>{i(),n()}));return i}un(e,t){this.listeners[e]&&(t?this.listeners[e].delete(t):delete this.listeners[e])}unAll(){this.listeners={}}emit(e,...t){this.listeners[e]&&this.listeners[e].forEach((e=>e(...t)))}}class t extends e{constructor(e){super(),this.subscriptions=[],this.options=e}onInit(){}init(e){this.wavesurfer=e,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((e=>e()))}}function i(e,t,i,n,s=5){let r=()=>{};if(!e)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let l=o.clientX,a=o.clientY,d=!1;const h=n=>{n.preventDefault(),n.stopPropagation();const r=n.clientX,o=n.clientY;if(d||Math.abs(r-l)>=s||Math.abs(o-a)>=s){const{left:n,top:s}=e.getBoundingClientRect();d||(d=!0,null==i||i(l-n,a-s)),t(r-l,o-a,r-n,o-s),l=r,a=o}},u=e=>{d&&(e.preventDefault(),e.stopPropagation())},c=()=>{d&&(null==n||n()),r()};document.addEventListener("pointermove",h),document.addEventListener("pointerup",c),document.addEventListener("pointerleave",c),document.addEventListener("click",u,!0),r=()=>{document.removeEventListener("pointermove",h),document.removeEventListener("pointerup",c),document.removeEventListener("pointerleave",c),setTimeout((()=>{document.removeEventListener("click",u,!0)}),10)}};return e.addEventListener("pointerdown",o),()=>{r(),e.removeEventListener("pointerdown",o)}}class n extends e{constructor(e,t){var i,n,s,r,o,l;super(),this.totalDuration=t,this.minLength=0,this.maxLength=1/0,this.id=e.id||`region-${Math.random().toString(32).slice(2)}`,this.start=e.start,this.end=null!==(i=e.end)&&void 0!==i?i:e.start,this.drag=null===(n=e.drag)||void 0===n||n,this.resize=null===(s=e.resize)||void 0===s||s,this.color=null!==(r=e.color)&&void 0!==r?r:"rgba(0, 0, 0, 0.1)",this.minLength=null!==(o=e.minLength)&&void 0!==o?o:this.minLength,this.maxLength=null!==(l=e.maxLength)&&void 0!==l?l:this.maxLength,this.element=this.initElement(e.content),this.renderPosition(),this.initMouseEvents()}initElement(e){const t=document.createElement("div"),i=this.start===this.end;if(t.setAttribute("part",`${i?"marker":"region"} ${this.id}`),t.setAttribute("style",`\n position: absolute;\n height: 100%;\n background-color: ${i?"none":this.color};\n border-left: ${i?"2px solid "+this.color:"none"};\n border-radius: 2px;\n box-sizing: border-box;\n transition: background-color 0.2s ease;\n cursor: ${this.drag?"grab":"default"};\n pointer-events: all;\n `),e&&("string"==typeof e?(this.content=document.createElement("div"),this.content.style.padding=`0.2em ${i?.2:.4}em`,this.content.textContent=e):this.content=e,this.content.setAttribute("part","region-content"),t.appendChild(this.content)),!i){const e=document.createElement("div");e.setAttribute("data-resize","left"),e.setAttribute("style",`\n position: absolute;\n z-index: 2;\n width: 6px;\n height: 100%;\n top: 0;\n left: 0;\n border-left: 2px solid rgba(0, 0, 0, 0.5);\n border-radius: 2px 0 0 2px;\n cursor: ${this.resize?"ew-resize":"default"};\n word-break: keep-all;\n `),e.setAttribute("part","region-handle region-handle-left");const i=e.cloneNode();i.setAttribute("data-resize","right"),i.style.left="",i.style.right="0",i.style.borderRight=i.style.borderLeft,i.style.borderLeft="",i.style.borderRadius="0 2px 2px 0",i.setAttribute("part","region-handle region-handle-right"),t.appendChild(e),t.appendChild(i)}return t}renderPosition(){const e=this.start/this.totalDuration,t=(this.totalDuration-this.end)/this.totalDuration;this.element.style.left=100*e+"%",this.element.style.right=100*t+"%"}initMouseEvents(){const{element:e}=this;if(!e)return;e.addEventListener("click",(e=>this.emit("click",e))),e.addEventListener("mouseenter",(e=>this.emit("over",e))),e.addEventListener("mouseleave",(e=>this.emit("leave",e))),e.addEventListener("dblclick",(e=>this.emit("dblclick",e))),i(e,(e=>this.onMove(e)),(()=>this.onStartMoving()),(()=>this.onEndMoving()));i(e.querySelector('[data-resize="left"]'),(e=>this.onResize(e,"start")),(()=>null),(()=>this.onEndResizing()),1),i(e.querySelector('[data-resize="right"]'),(e=>this.onResize(e,"end")),(()=>null),(()=>this.onEndResizing()),1)}onStartMoving(){this.drag&&(this.element.style.cursor="grabbing")}onEndMoving(){this.drag&&(this.element.style.cursor="grab",this.emit("update-end"))}_onUpdate(e,t){if(!this.element.parentElement)return;const i=e/this.element.parentElement.clientWidth*this.totalDuration,n=t&&"start"!==t?this.start:this.start+i,s=t&&"end"!==t?this.end:this.end+i,r=s-n;n>0&&s<this.totalDuration&&n<=s&&r>=this.minLength&&r<=this.maxLength&&(this.start=n,this.end=s,this.renderPosition(),this.emit("update"))}onMove(e){this.drag&&this._onUpdate(e)}onResize(e,t){this.resize&&this._onUpdate(e,t)}onEndResizing(){this.resize&&this.emit("update-end")}_setTotalDuration(e){this.totalDuration=e,this.renderPosition()}play(){this.emit("play")}setOptions(e){var t,i;e.color&&(this.color=e.color,this.element.style.backgroundColor=this.color),void 0!==e.drag&&(this.drag=e.drag,this.element.style.cursor=this.drag?"grab":"default"),void 0!==e.resize&&(this.resize=e.resize,this.element.querySelectorAll("[data-resize]").forEach((e=>{e.style.cursor=this.resize?"ew-resize":"default"}))),void 0===e.start&&void 0===e.end||(this.start=null!==(t=e.start)&&void 0!==t?t:this.start,this.end=null!==(i=e.end)&&void 0!==i?i:this.end,this.renderPosition())}remove(){this.emit("remove"),this.element.remove(),this.element=null}}class s extends t{constructor(e){super(e),this.regions=[],this.regionsContainer=this.initRegionsContainer()}static create(e){return new s(e)}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.wavesurfer.getWrapper().appendChild(this.regionsContainer)}initRegionsContainer(){const e=document.createElement("div");return e.setAttribute("style","\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 3;\n pointer-events: none;\n "),e}getRegions(){return this.regions}avoidOverlapping(e){if(!e.content)return;const t=e.content,i=t.getBoundingClientRect().left,n=e.element.scrollWidth,s=this.regions.filter((t=>{if(t===e||!t.content)return!1;const s=t.content.getBoundingClientRect().left,r=t.element.scrollWidth;return i<s+r&&s<i+n})).map((e=>{var t;return(null===(t=e.content)||void 0===t?void 0:t.getBoundingClientRect().height)||0})).reduce(((e,t)=>e+t),0);t.style.marginTop=`${s}px`}saveRegion(e){this.regionsContainer.appendChild(e.element),this.avoidOverlapping(e),this.regions.push(e),this.emit("region-created",e);const t=[e.on("update-end",(()=>{this.avoidOverlapping(e),this.emit("region-updated",e)})),e.on("play",(()=>{var t,i;null===(t=this.wavesurfer)||void 0===t||t.play(),null===(i=this.wavesurfer)||void 0===i||i.setTime(e.start)})),e.on("click",(t=>{this.emit("region-clicked",e,t)})),e.on("dblclick",(t=>{this.emit("region-double-clicked",e,t)})),e.once("remove",(()=>{t.forEach((e=>e())),this.regions=this.regions.filter((t=>t!==e))}))];this.subscriptions.push(...t)}addRegion(e){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const t=this.wavesurfer.getDuration(),i=new n(e,t);return t?this.saveRegion(i):this.subscriptions.push(this.wavesurfer.once("ready",(e=>{i._setTotalDuration(e),this.saveRegion(i)}))),i}enableDragSelection(e){var t,s;const r=null===(s=null===(t=this.wavesurfer)||void 0===t?void 0:t.getWrapper())||void 0===s?void 0:s.querySelector("div");if(!r)return()=>{};let o=null,l=0;return i(r,((e,t,i)=>{o&&o._onUpdate(e,i>l?"end":"start")}),(t=>{if(l=t,!this.wavesurfer)return;const i=this.wavesurfer.getDuration(),s=this.wavesurfer.getWrapper().clientWidth,r=t/s*i,a=(t+5)/s*i;o=new n(Object.assign(Object.assign({},e),{start:r,end:a}),i),this.regionsContainer.appendChild(o.element)}),(()=>{o&&(this.saveRegion(o),o=null)}))}clearRegions(){this.regions.forEach((e=>e.remove()))}destroy(){this.clearRegions(),super.destroy()}}return s}));
@@ -0,0 +1,44 @@
1
+ import EventEmitter from './event-emitter.js';
2
+ import type { WaveSurferOptions } from './wavesurfer.js';
3
+ type RendererEvents = {
4
+ click: [relativeX: number];
5
+ drag: [relativeX: number];
6
+ scroll: [relativeStart: number, relativeEnd: number];
7
+ render: [];
8
+ };
9
+ declare class Renderer extends EventEmitter<RendererEvents> {
10
+ private static MAX_CANVAS_WIDTH;
11
+ private options;
12
+ private parent;
13
+ private container;
14
+ private scrollContainer;
15
+ private wrapper;
16
+ private canvasWrapper;
17
+ private progressWrapper;
18
+ private cursor;
19
+ private timeouts;
20
+ private isScrolling;
21
+ private audioData;
22
+ private resizeObserver;
23
+ private isDragging;
24
+ constructor(options: WaveSurferOptions);
25
+ private initEvents;
26
+ private initDrag;
27
+ private getHeight;
28
+ private initHtml;
29
+ setOptions(options: WaveSurferOptions): void;
30
+ getWrapper(): HTMLElement;
31
+ getScroll(): number;
32
+ destroy(): void;
33
+ private createDelay;
34
+ private convertColorValues;
35
+ private renderBars;
36
+ private renderSingleCanvas;
37
+ private renderWaveform;
38
+ render(audioData: AudioBuffer): void;
39
+ reRender(): void;
40
+ zoom(minPxPerSec: number): void;
41
+ private scrollIntoView;
42
+ renderProgress(progress: number, isPlaying?: boolean): void;
43
+ }
44
+ export default Renderer;
@@ -0,0 +1 @@
1
+ "use strict";class t{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 s=this.on(t,e),i=this.on(t,(()=>{s(),i()}));return s}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)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function s(t,e,s,i){switch(this.bufferSize=t,this.sampleRate=e,this.bandwidth=2/t*(e/2),this.sinTable=new Float32Array(t),this.cosTable=new Float32Array(t),this.windowValues=new Float32Array(t),this.reverseTable=new Uint32Array(t),this.peakBand=0,this.peak=0,s){case"bartlett":for(a=0;a<t;a++)this.windowValues[a]=2/(t-1)*((t-1)/2-Math.abs(a-(t-1)/2));break;case"bartlettHann":for(a=0;a<t;a++)this.windowValues[a]=.62-.48*Math.abs(a/(t-1)-.5)-.38*Math.cos(2*Math.PI*a/(t-1));break;case"blackman":for(i=i||.16,a=0;a<t;a++)this.windowValues[a]=(1-i)/2-.5*Math.cos(2*Math.PI*a/(t-1))+i/2*Math.cos(4*Math.PI*a/(t-1));break;case"cosine":for(a=0;a<t;a++)this.windowValues[a]=Math.cos(Math.PI*a/(t-1)-Math.PI/2);break;case"gauss":for(i=i||.25,a=0;a<t;a++)this.windowValues[a]=Math.pow(Math.E,-.5*Math.pow((a-(t-1)/2)/(i*(t-1)/2),2));break;case"hamming":for(a=0;a<t;a++)this.windowValues[a]=.54-.46*Math.cos(2*Math.PI*a/(t-1));break;case"hann":case void 0:for(a=0;a<t;a++)this.windowValues[a]=.5*(1-Math.cos(2*Math.PI*a/(t-1)));break;case"lanczoz":for(a=0;a<t;a++)this.windowValues[a]=Math.sin(Math.PI*(2*a/(t-1)-1))/(Math.PI*(2*a/(t-1)-1));break;case"rectangular":for(a=0;a<t;a++)this.windowValues[a]=1;break;case"triangular":for(a=0;a<t;a++)this.windowValues[a]=2/t*(t/2-Math.abs(a-(t-1)/2));break;default:throw Error("No such window function '"+s+"'")}for(var a,r=1,h=t>>1;r<t;){for(a=0;a<r;a++)this.reverseTable[a+r]=this.reverseTable[a]+h;r<<=1,h>>=1}for(a=0;a<t;a++)this.sinTable[a]=Math.sin(-Math.PI/a),this.cosTable[a]=Math.cos(-Math.PI/a);this.calculateSpectrum=function(t){var e,s,i,a=this.bufferSize,r=this.cosTable,h=this.sinTable,n=this.reverseTable,l=new Float32Array(a),o=new Float32Array(a),c=2/this.bufferSize,f=Math.sqrt,p=new Float32Array(a/2),u=Math.floor(Math.log(a)/Math.LN2);if(Math.pow(2,u)!==a)throw"Invalid buffer size, must be a power of 2.";if(a!==t.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+a+" Buffer Size: "+t.length;for(var d,w,M,b,g,m,y,v,x=1,k=0;k<a;k++)l[k]=t[n[k]]*this.windowValues[n[k]],o[k]=0;for(;x<a;){d=r[x],w=h[x],M=1,b=0;for(var q=0;q<x;q++){for(k=q;k<a;)m=M*l[g=k+x]-b*o[g],y=M*o[g]+b*l[g],l[g]=l[k]-m,o[g]=o[k]-y,l[k]+=m,o[k]+=y,k+=x<<1;M=(v=M)*d-b*w,b=v*w+b*d}x<<=1}k=0;for(var S=a/2;k<S;k++)(i=c*f((e=l[k])*e+(s=o[k])*s))>this.peak&&(this.peakBand=k,this.peak=i),p[k]=i;return p}}class i extends e{static create(t){return new i(t||{})}constructor(t){if(super(t),this.utils={style:(t,e)=>Object.assign(t.style,e)},this.drawSpectrogram=t=>{isNaN(t[0][0])||(t=[t]);const e=this.spectrCc,s=this.height,i=this.width,a=this.buffer.sampleRate/2,r=this.frequencyMin,h=this.frequencyMax;if(e){for(let n=0;n<t.length;n++){const l=this.resample(t[n]),o=new ImageData(i,s);for(let t=0;t<l.length;t++)for(let e=0;e<l[t].length;e++){const a=this.colorMap[l[t][e]],r=4*((s-e)*i+t);o.data[r]=255*a[0],o.data[r+1]=255*a[1],o.data[r+2]=255*a[2],o.data[r+3]=255*a[3]}createImageBitmap(o).then((t=>{e.drawImage(t,0,s*(1-h/a),i,s*(h-r)/a,0,s*n,i,s)}))}this.emit("ready")}},this.frequenciesDataUrl=t.frequenciesDataUrl,this.container="string"==typeof t.container?document.querySelector(t.container):t.container,t.colorMap){if(t.colorMap.length<256)throw new Error("Colormap must contain 256 elements");for(let e=0;e<t.colorMap.length;e++){if(4!==t.colorMap[e].length)throw new Error("ColorMap entries must contain 4 values")}this.colorMap=t.colorMap}else{this.colorMap=[];for(let t=0;t<256;t++){const e=(255-t)/256;this.colorMap.push([e,e,e,1])}}this.fftSamples=t.fftSamples||512,this.height=t.height||this.fftSamples/2,this.noverlap=t.noverlap,this.windowFunc=t.windowFunc,this.alpha=t.alpha,this.channels=1,this.frequencyMin=t.frequencyMin||0,this.frequencyMax=t.frequencyMax||0,this.createWrapper(),this.createCanvas()}onInit(){this.container=this.container||this.wavesurfer.getWrapper(),this.container.appendChild(this.wrapper),this.wavesurfer.options.fillParent&&this.utils.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.width=this.wavesurfer.getWrapper().offsetWidth,this.subscriptions.push(this.wavesurfer.on("redraw",(()=>this.render())))}destroy(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("redraw",this._onRender),this.wavesurfer=null,this.util=null,this.options=null,this.wrapper&&(this.wrapper.remove(),this.wrapper=null),super.destroy()}createWrapper(){if(this.wrapper=document.createElement("div"),this.utils.style(this.wrapper,{display:"block",position:"relative",userSelect:"none",webkitUserSelect:"none",height:this.height*this.channels+"px"}),this.options.labels){const t=document.createElement("canvas");t.setAttribute("part","spec-labels"),t.classList.add("spec-labels"),this.utils.style(t,{position:"absolute",zIndex:9,width:"55px",height:"100%"}),this.wrapper.appendChild(t),this.labelsEl=t}this.wrapper.addEventListener("click",this._onWrapperClick)}_wrapperClickHandler(t){t.preventDefault();const e="offsetX"in t?t.offsetX:t.layerX;this.emit("click",e/this.width||0)}createCanvas(){const t=document.createElement("canvas");this.wrapper.appendChild(t),this.spectrCc=t.getContext("2d"),this.utils.style(t,{position:"absolute",left:0,top:0,width:"100%",height:"100%",zIndex:4}),this.canvas=t}render(){this.canvas.width=this.width,this.canvas.height=this.height,this.frequenciesDataUrl?this.loadFrequenciesData(this.frequenciesDataUrl):this.getFrequencies(this.drawSpectrogram),this.loadLabels(this.options.labelsBackground,"12px","12px","",this.options.labelsColor,this.options.labelsHzColor||this.options.labelsColor,"center","#specLabels")}getFrequencies(t){const e=this.fftSamples,i=this.wavesurfer.getDecodedData(),a=this.channels;if(this.frequencyMax=this.frequencyMax||i.sampleRate/2,!i)return;this.buffer=i;const r=i.sampleRate,h=[];let n=this.noverlap;if(!n){const t=i.length/this.canvas.width;n=Math.max(0,Math.round(e-t))}const l=new s(e,r,this.windowFunc,this.alpha);for(let t=0;t<a;t++){const s=i.getChannelData(t),a=[];let r=0;for(;r+e<s.length;){const t=s.slice(r,r+e),i=l.calculateSpectrum(t),h=new Uint8Array(e/2);let o;for(o=0;o<e/2;o++)h[o]=Math.max(-255,45*Math.log10(i[o]));a.push(h),r+=e-n}h.push(a)}t(h,this)}loadFrequenciesData(t){return fetch(t).then((t=>t.json())).then(this.drawSpectrogram)}freqType(t){return t>=1e3?(t/1e3).toFixed(1):Math.round(t)}unitType(t){return t>=1e3?"KHz":"Hz"}loadLabels(t,e,s,i,a,r,h,n){t=t||"rgba(68,68,68,0)",e=e||"12px",s=s||"12px",i=i||"Helvetica",a=a||"#fff",r=r||"#fff",h=h||"center";const l=this.height||512,o=l/256*5,c=this.frequencyMin,f=(this.frequencyMax-c)/o,p=this.labelsEl.getContext("2d"),u=window.devicePixelRatio;if(this.labelsEl.height=this.height*this.channels*u,this.labelsEl.width=55*u,p.scale(u,u),p)for(let n=0;n<this.channels;n++){let u;for(p.fillStyle=t,p.fillRect(0,n*l,55,(1+n)*l),p.fill(),u=0;u<=o;u++){p.textAlign=h,p.textBaseline="middle";const t=c+f*u,o=this.freqType(t),d=this.unitType(t),w=16;let M;M=0==u?(1+n)*l+u-10:(1+n)*l-50*u+2,p.fillStyle=r,p.font=s+" "+i,p.fillText(d,w+24,M),p.fillStyle=a,p.font=e+" "+i,p.fillText(o,w,M)}}}resample(t){const e=this.width,s=[],i=1/t.length,a=1/e;let r;for(r=0;r<e;r++){const e=new Array(t[0].length);let h;for(h=0;h<t.length;h++){const s=h*i,n=s+i,l=r*a,o=l+a,c=n<=l||o<=s?0:Math.min(Math.max(n,l),Math.max(o,s))-Math.max(Math.min(n,l),Math.min(o,s));let f;if(c>0)for(f=0;f<t[0].length;f++)null==e[f]&&(e[f]=0),e[f]+=c/a*t[h][f]}const n=new Uint8Array(t[0].length);let l;for(l=0;l<t[0].length;l++)n[l]=e[l];s.push(n)}return s}}module.exports=i;
@@ -53,7 +53,7 @@ export type SpectrogramPluginEvents = BasePluginEvents & {
53
53
  ready: [];
54
54
  click: [relativeX: number];
55
55
  };
56
- export declare class SpectrogramPlugin extends BasePlugin<SpectrogramPluginEvents, SpectrogramPluginOptions> {
56
+ declare class SpectrogramPlugin extends BasePlugin<SpectrogramPluginEvents, SpectrogramPluginOptions> {
57
57
  static create(options?: SpectrogramPluginOptions): SpectrogramPlugin;
58
58
  utils: {
59
59
  style: (el: HTMLElement, styles: Record<string, string>) => CSSStyleDeclaration & Record<string, string>;
@@ -0,0 +1 @@
1
+ class t{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 s=this.on(t,e),i=this.on(t,(()=>{s(),i()}));return s}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)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function s(t,e,s,i){switch(this.bufferSize=t,this.sampleRate=e,this.bandwidth=2/t*(e/2),this.sinTable=new Float32Array(t),this.cosTable=new Float32Array(t),this.windowValues=new Float32Array(t),this.reverseTable=new Uint32Array(t),this.peakBand=0,this.peak=0,s){case"bartlett":for(a=0;a<t;a++)this.windowValues[a]=2/(t-1)*((t-1)/2-Math.abs(a-(t-1)/2));break;case"bartlettHann":for(a=0;a<t;a++)this.windowValues[a]=.62-.48*Math.abs(a/(t-1)-.5)-.38*Math.cos(2*Math.PI*a/(t-1));break;case"blackman":for(i=i||.16,a=0;a<t;a++)this.windowValues[a]=(1-i)/2-.5*Math.cos(2*Math.PI*a/(t-1))+i/2*Math.cos(4*Math.PI*a/(t-1));break;case"cosine":for(a=0;a<t;a++)this.windowValues[a]=Math.cos(Math.PI*a/(t-1)-Math.PI/2);break;case"gauss":for(i=i||.25,a=0;a<t;a++)this.windowValues[a]=Math.pow(Math.E,-.5*Math.pow((a-(t-1)/2)/(i*(t-1)/2),2));break;case"hamming":for(a=0;a<t;a++)this.windowValues[a]=.54-.46*Math.cos(2*Math.PI*a/(t-1));break;case"hann":case void 0:for(a=0;a<t;a++)this.windowValues[a]=.5*(1-Math.cos(2*Math.PI*a/(t-1)));break;case"lanczoz":for(a=0;a<t;a++)this.windowValues[a]=Math.sin(Math.PI*(2*a/(t-1)-1))/(Math.PI*(2*a/(t-1)-1));break;case"rectangular":for(a=0;a<t;a++)this.windowValues[a]=1;break;case"triangular":for(a=0;a<t;a++)this.windowValues[a]=2/t*(t/2-Math.abs(a-(t-1)/2));break;default:throw Error("No such window function '"+s+"'")}for(var a,r=1,h=t>>1;r<t;){for(a=0;a<r;a++)this.reverseTable[a+r]=this.reverseTable[a]+h;r<<=1,h>>=1}for(a=0;a<t;a++)this.sinTable[a]=Math.sin(-Math.PI/a),this.cosTable[a]=Math.cos(-Math.PI/a);this.calculateSpectrum=function(t){var e,s,i,a=this.bufferSize,r=this.cosTable,h=this.sinTable,n=this.reverseTable,l=new Float32Array(a),o=new Float32Array(a),c=2/this.bufferSize,f=Math.sqrt,p=new Float32Array(a/2),u=Math.floor(Math.log(a)/Math.LN2);if(Math.pow(2,u)!==a)throw"Invalid buffer size, must be a power of 2.";if(a!==t.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+a+" Buffer Size: "+t.length;for(var d,w,M,b,g,m,y,v,x=1,k=0;k<a;k++)l[k]=t[n[k]]*this.windowValues[n[k]],o[k]=0;for(;x<a;){d=r[x],w=h[x],M=1,b=0;for(var q=0;q<x;q++){for(k=q;k<a;)m=M*l[g=k+x]-b*o[g],y=M*o[g]+b*l[g],l[g]=l[k]-m,o[g]=o[k]-y,l[k]+=m,o[k]+=y,k+=x<<1;M=(v=M)*d-b*w,b=v*w+b*d}x<<=1}k=0;for(var S=a/2;k<S;k++)(i=c*f((e=l[k])*e+(s=o[k])*s))>this.peak&&(this.peakBand=k,this.peak=i),p[k]=i;return p}}class i extends e{static create(t){return new i(t||{})}constructor(t){if(super(t),this.utils={style:(t,e)=>Object.assign(t.style,e)},this.drawSpectrogram=t=>{isNaN(t[0][0])||(t=[t]);const e=this.spectrCc,s=this.height,i=this.width,a=this.buffer.sampleRate/2,r=this.frequencyMin,h=this.frequencyMax;if(e){for(let n=0;n<t.length;n++){const l=this.resample(t[n]),o=new ImageData(i,s);for(let t=0;t<l.length;t++)for(let e=0;e<l[t].length;e++){const a=this.colorMap[l[t][e]],r=4*((s-e)*i+t);o.data[r]=255*a[0],o.data[r+1]=255*a[1],o.data[r+2]=255*a[2],o.data[r+3]=255*a[3]}createImageBitmap(o).then((t=>{e.drawImage(t,0,s*(1-h/a),i,s*(h-r)/a,0,s*n,i,s)}))}this.emit("ready")}},this.frequenciesDataUrl=t.frequenciesDataUrl,this.container="string"==typeof t.container?document.querySelector(t.container):t.container,t.colorMap){if(t.colorMap.length<256)throw new Error("Colormap must contain 256 elements");for(let e=0;e<t.colorMap.length;e++){if(4!==t.colorMap[e].length)throw new Error("ColorMap entries must contain 4 values")}this.colorMap=t.colorMap}else{this.colorMap=[];for(let t=0;t<256;t++){const e=(255-t)/256;this.colorMap.push([e,e,e,1])}}this.fftSamples=t.fftSamples||512,this.height=t.height||this.fftSamples/2,this.noverlap=t.noverlap,this.windowFunc=t.windowFunc,this.alpha=t.alpha,this.channels=1,this.frequencyMin=t.frequencyMin||0,this.frequencyMax=t.frequencyMax||0,this.createWrapper(),this.createCanvas()}onInit(){this.container=this.container||this.wavesurfer.getWrapper(),this.container.appendChild(this.wrapper),this.wavesurfer.options.fillParent&&this.utils.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.width=this.wavesurfer.getWrapper().offsetWidth,this.subscriptions.push(this.wavesurfer.on("redraw",(()=>this.render())))}destroy(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("redraw",this._onRender),this.wavesurfer=null,this.util=null,this.options=null,this.wrapper&&(this.wrapper.remove(),this.wrapper=null),super.destroy()}createWrapper(){if(this.wrapper=document.createElement("div"),this.utils.style(this.wrapper,{display:"block",position:"relative",userSelect:"none",webkitUserSelect:"none",height:this.height*this.channels+"px"}),this.options.labels){const t=document.createElement("canvas");t.setAttribute("part","spec-labels"),t.classList.add("spec-labels"),this.utils.style(t,{position:"absolute",zIndex:9,width:"55px",height:"100%"}),this.wrapper.appendChild(t),this.labelsEl=t}this.wrapper.addEventListener("click",this._onWrapperClick)}_wrapperClickHandler(t){t.preventDefault();const e="offsetX"in t?t.offsetX:t.layerX;this.emit("click",e/this.width||0)}createCanvas(){const t=document.createElement("canvas");this.wrapper.appendChild(t),this.spectrCc=t.getContext("2d"),this.utils.style(t,{position:"absolute",left:0,top:0,width:"100%",height:"100%",zIndex:4}),this.canvas=t}render(){this.canvas.width=this.width,this.canvas.height=this.height,this.frequenciesDataUrl?this.loadFrequenciesData(this.frequenciesDataUrl):this.getFrequencies(this.drawSpectrogram),this.loadLabels(this.options.labelsBackground,"12px","12px","",this.options.labelsColor,this.options.labelsHzColor||this.options.labelsColor,"center","#specLabels")}getFrequencies(t){const e=this.fftSamples,i=this.wavesurfer.getDecodedData(),a=this.channels;if(this.frequencyMax=this.frequencyMax||i.sampleRate/2,!i)return;this.buffer=i;const r=i.sampleRate,h=[];let n=this.noverlap;if(!n){const t=i.length/this.canvas.width;n=Math.max(0,Math.round(e-t))}const l=new s(e,r,this.windowFunc,this.alpha);for(let t=0;t<a;t++){const s=i.getChannelData(t),a=[];let r=0;for(;r+e<s.length;){const t=s.slice(r,r+e),i=l.calculateSpectrum(t),h=new Uint8Array(e/2);let o;for(o=0;o<e/2;o++)h[o]=Math.max(-255,45*Math.log10(i[o]));a.push(h),r+=e-n}h.push(a)}t(h,this)}loadFrequenciesData(t){return fetch(t).then((t=>t.json())).then(this.drawSpectrogram)}freqType(t){return t>=1e3?(t/1e3).toFixed(1):Math.round(t)}unitType(t){return t>=1e3?"KHz":"Hz"}loadLabels(t,e,s,i,a,r,h,n){t=t||"rgba(68,68,68,0)",e=e||"12px",s=s||"12px",i=i||"Helvetica",a=a||"#fff",r=r||"#fff",h=h||"center";const l=this.height||512,o=l/256*5,c=this.frequencyMin,f=(this.frequencyMax-c)/o,p=this.labelsEl.getContext("2d"),u=window.devicePixelRatio;if(this.labelsEl.height=this.height*this.channels*u,this.labelsEl.width=55*u,p.scale(u,u),p)for(let n=0;n<this.channels;n++){let u;for(p.fillStyle=t,p.fillRect(0,n*l,55,(1+n)*l),p.fill(),u=0;u<=o;u++){p.textAlign=h,p.textBaseline="middle";const t=c+f*u,o=this.freqType(t),d=this.unitType(t),w=16;let M;M=0==u?(1+n)*l+u-10:(1+n)*l-50*u+2,p.fillStyle=r,p.font=s+" "+i,p.fillText(d,w+24,M),p.fillStyle=a,p.font=e+" "+i,p.fillText(o,w,M)}}}resample(t){const e=this.width,s=[],i=1/t.length,a=1/e;let r;for(r=0;r<e;r++){const e=new Array(t[0].length);let h;for(h=0;h<t.length;h++){const s=h*i,n=s+i,l=r*a,o=l+a,c=n<=l||o<=s?0:Math.min(Math.max(n,l),Math.max(o,s))-Math.max(Math.min(n,l),Math.min(o,s));let f;if(c>0)for(f=0;f<t[0].length;f++)null==e[f]&&(e[f]=0),e[f]+=c/a*t[h][f]}const n=new Uint8Array(t[0].length);let l;for(l=0;l<t[0].length;l++)n[l]=e[l];s.push(n)}return s}}export{i as default};
@@ -171,7 +171,7 @@ function FFT(bufferSize, sampleRate, windowFunc, alpha) {
171
171
  * Spectrogram plugin for wavesurfer.
172
172
  */
173
173
  import BasePlugin from '../base-plugin.js';
174
- export class SpectrogramPlugin extends BasePlugin {
174
+ class SpectrogramPlugin extends BasePlugin {
175
175
  static create(options) {
176
176
  return new SpectrogramPlugin(options || {});
177
177
  }
@@ -0,0 +1 @@
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):((t="undefined"!=typeof globalThis?globalThis:t||self).WaveSurfer=t.WaveSurfer||{},t.WaveSurfer.Spectrogram=e())}(this,(function(){"use strict";class t{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 s=this.on(t,e),i=this.on(t,(()=>{s(),i()}));return s}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)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}function s(t,e,s,i){switch(this.bufferSize=t,this.sampleRate=e,this.bandwidth=2/t*(e/2),this.sinTable=new Float32Array(t),this.cosTable=new Float32Array(t),this.windowValues=new Float32Array(t),this.reverseTable=new Uint32Array(t),this.peakBand=0,this.peak=0,s){case"bartlett":for(a=0;a<t;a++)this.windowValues[a]=2/(t-1)*((t-1)/2-Math.abs(a-(t-1)/2));break;case"bartlettHann":for(a=0;a<t;a++)this.windowValues[a]=.62-.48*Math.abs(a/(t-1)-.5)-.38*Math.cos(2*Math.PI*a/(t-1));break;case"blackman":for(i=i||.16,a=0;a<t;a++)this.windowValues[a]=(1-i)/2-.5*Math.cos(2*Math.PI*a/(t-1))+i/2*Math.cos(4*Math.PI*a/(t-1));break;case"cosine":for(a=0;a<t;a++)this.windowValues[a]=Math.cos(Math.PI*a/(t-1)-Math.PI/2);break;case"gauss":for(i=i||.25,a=0;a<t;a++)this.windowValues[a]=Math.pow(Math.E,-.5*Math.pow((a-(t-1)/2)/(i*(t-1)/2),2));break;case"hamming":for(a=0;a<t;a++)this.windowValues[a]=.54-.46*Math.cos(2*Math.PI*a/(t-1));break;case"hann":case void 0:for(a=0;a<t;a++)this.windowValues[a]=.5*(1-Math.cos(2*Math.PI*a/(t-1)));break;case"lanczoz":for(a=0;a<t;a++)this.windowValues[a]=Math.sin(Math.PI*(2*a/(t-1)-1))/(Math.PI*(2*a/(t-1)-1));break;case"rectangular":for(a=0;a<t;a++)this.windowValues[a]=1;break;case"triangular":for(a=0;a<t;a++)this.windowValues[a]=2/t*(t/2-Math.abs(a-(t-1)/2));break;default:throw Error("No such window function '"+s+"'")}for(var a,r=1,n=t>>1;r<t;){for(a=0;a<r;a++)this.reverseTable[a+r]=this.reverseTable[a]+n;r<<=1,n>>=1}for(a=0;a<t;a++)this.sinTable[a]=Math.sin(-Math.PI/a),this.cosTable[a]=Math.cos(-Math.PI/a);this.calculateSpectrum=function(t){var e,s,i,a=this.bufferSize,r=this.cosTable,n=this.sinTable,h=this.reverseTable,l=new Float32Array(a),o=new Float32Array(a),c=2/this.bufferSize,f=Math.sqrt,u=new Float32Array(a/2),p=Math.floor(Math.log(a)/Math.LN2);if(Math.pow(2,p)!==a)throw"Invalid buffer size, must be a power of 2.";if(a!==t.length)throw"Supplied buffer is not the same size as defined FFT. FFT Size: "+a+" Buffer Size: "+t.length;for(var d,w,b,M,g,m,y,v,x=1,S=0;S<a;S++)l[S]=t[h[S]]*this.windowValues[h[S]],o[S]=0;for(;x<a;){d=r[x],w=n[x],b=1,M=0;for(var k=0;k<x;k++){for(S=k;S<a;)m=b*l[g=S+x]-M*o[g],y=b*o[g]+M*l[g],l[g]=l[S]-m,o[g]=o[S]-y,l[S]+=m,o[S]+=y,S+=x<<1;b=(v=b)*d-M*w,M=v*w+M*d}x<<=1}S=0;for(var q=a/2;S<q;S++)(i=c*f((e=l[S])*e+(s=o[S])*s))>this.peak&&(this.peakBand=S,this.peak=i),u[S]=i;return u}}class i extends e{static create(t){return new i(t||{})}constructor(t){if(super(t),this.utils={style:(t,e)=>Object.assign(t.style,e)},this.drawSpectrogram=t=>{isNaN(t[0][0])||(t=[t]);const e=this.spectrCc,s=this.height,i=this.width,a=this.buffer.sampleRate/2,r=this.frequencyMin,n=this.frequencyMax;if(e){for(let h=0;h<t.length;h++){const l=this.resample(t[h]),o=new ImageData(i,s);for(let t=0;t<l.length;t++)for(let e=0;e<l[t].length;e++){const a=this.colorMap[l[t][e]],r=4*((s-e)*i+t);o.data[r]=255*a[0],o.data[r+1]=255*a[1],o.data[r+2]=255*a[2],o.data[r+3]=255*a[3]}createImageBitmap(o).then((t=>{e.drawImage(t,0,s*(1-n/a),i,s*(n-r)/a,0,s*h,i,s)}))}this.emit("ready")}},this.frequenciesDataUrl=t.frequenciesDataUrl,this.container="string"==typeof t.container?document.querySelector(t.container):t.container,t.colorMap){if(t.colorMap.length<256)throw new Error("Colormap must contain 256 elements");for(let e=0;e<t.colorMap.length;e++){if(4!==t.colorMap[e].length)throw new Error("ColorMap entries must contain 4 values")}this.colorMap=t.colorMap}else{this.colorMap=[];for(let t=0;t<256;t++){const e=(255-t)/256;this.colorMap.push([e,e,e,1])}}this.fftSamples=t.fftSamples||512,this.height=t.height||this.fftSamples/2,this.noverlap=t.noverlap,this.windowFunc=t.windowFunc,this.alpha=t.alpha,this.channels=1,this.frequencyMin=t.frequencyMin||0,this.frequencyMax=t.frequencyMax||0,this.createWrapper(),this.createCanvas()}onInit(){this.container=this.container||this.wavesurfer.getWrapper(),this.container.appendChild(this.wrapper),this.wavesurfer.options.fillParent&&this.utils.style(this.wrapper,{width:"100%",overflowX:"hidden",overflowY:"hidden"}),this.width=this.wavesurfer.getWrapper().offsetWidth,this.subscriptions.push(this.wavesurfer.on("redraw",(()=>this.render())))}destroy(){this.unAll(),this.wavesurfer.un("ready",this._onReady),this.wavesurfer.un("redraw",this._onRender),this.wavesurfer=null,this.util=null,this.options=null,this.wrapper&&(this.wrapper.remove(),this.wrapper=null),super.destroy()}createWrapper(){if(this.wrapper=document.createElement("div"),this.utils.style(this.wrapper,{display:"block",position:"relative",userSelect:"none",webkitUserSelect:"none",height:this.height*this.channels+"px"}),this.options.labels){const t=document.createElement("canvas");t.setAttribute("part","spec-labels"),t.classList.add("spec-labels"),this.utils.style(t,{position:"absolute",zIndex:9,width:"55px",height:"100%"}),this.wrapper.appendChild(t),this.labelsEl=t}this.wrapper.addEventListener("click",this._onWrapperClick)}_wrapperClickHandler(t){t.preventDefault();const e="offsetX"in t?t.offsetX:t.layerX;this.emit("click",e/this.width||0)}createCanvas(){const t=document.createElement("canvas");this.wrapper.appendChild(t),this.spectrCc=t.getContext("2d"),this.utils.style(t,{position:"absolute",left:0,top:0,width:"100%",height:"100%",zIndex:4}),this.canvas=t}render(){this.canvas.width=this.width,this.canvas.height=this.height,this.frequenciesDataUrl?this.loadFrequenciesData(this.frequenciesDataUrl):this.getFrequencies(this.drawSpectrogram),this.loadLabels(this.options.labelsBackground,"12px","12px","",this.options.labelsColor,this.options.labelsHzColor||this.options.labelsColor,"center","#specLabels")}getFrequencies(t){const e=this.fftSamples,i=this.wavesurfer.getDecodedData(),a=this.channels;if(this.frequencyMax=this.frequencyMax||i.sampleRate/2,!i)return;this.buffer=i;const r=i.sampleRate,n=[];let h=this.noverlap;if(!h){const t=i.length/this.canvas.width;h=Math.max(0,Math.round(e-t))}const l=new s(e,r,this.windowFunc,this.alpha);for(let t=0;t<a;t++){const s=i.getChannelData(t),a=[];let r=0;for(;r+e<s.length;){const t=s.slice(r,r+e),i=l.calculateSpectrum(t),n=new Uint8Array(e/2);let o;for(o=0;o<e/2;o++)n[o]=Math.max(-255,45*Math.log10(i[o]));a.push(n),r+=e-h}n.push(a)}t(n,this)}loadFrequenciesData(t){return fetch(t).then((t=>t.json())).then(this.drawSpectrogram)}freqType(t){return t>=1e3?(t/1e3).toFixed(1):Math.round(t)}unitType(t){return t>=1e3?"KHz":"Hz"}loadLabels(t,e,s,i,a,r,n,h){t=t||"rgba(68,68,68,0)",e=e||"12px",s=s||"12px",i=i||"Helvetica",a=a||"#fff",r=r||"#fff",n=n||"center";const l=this.height||512,o=l/256*5,c=this.frequencyMin,f=(this.frequencyMax-c)/o,u=this.labelsEl.getContext("2d"),p=window.devicePixelRatio;if(this.labelsEl.height=this.height*this.channels*p,this.labelsEl.width=55*p,u.scale(p,p),u)for(let h=0;h<this.channels;h++){let p;for(u.fillStyle=t,u.fillRect(0,h*l,55,(1+h)*l),u.fill(),p=0;p<=o;p++){u.textAlign=n,u.textBaseline="middle";const t=c+f*p,o=this.freqType(t),d=this.unitType(t),w=16;let b;b=0==p?(1+h)*l+p-10:(1+h)*l-50*p+2,u.fillStyle=r,u.font=s+" "+i,u.fillText(d,w+24,b),u.fillStyle=a,u.font=e+" "+i,u.fillText(o,w,b)}}}resample(t){const e=this.width,s=[],i=1/t.length,a=1/e;let r;for(r=0;r<e;r++){const e=new Array(t[0].length);let n;for(n=0;n<t.length;n++){const s=n*i,h=s+i,l=r*a,o=l+a,c=h<=l||o<=s?0:Math.min(Math.max(h,l),Math.max(o,s))-Math.max(Math.min(h,l),Math.min(o,s));let f;if(c>0)for(f=0;f<t[0].length;f++)null==e[f]&&(e[f]=0),e[f]+=c/a*t[n][f]}const h=new Uint8Array(t[0].length);let l;for(l=0;l<t[0].length;l++)h[l]=e[l];s.push(h)}return s}}return i}));
@@ -0,0 +1 @@
1
+ "use strict";class t{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)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}const i={height:20,formatTimeCallback:t=>{if(t/60>1){return`${Math.floor(t/60)}:${`${(t=Math.round(t%60))<10?"0":""}${t}`}`}return`${Math.round(1e3*t)/1e3}`}};class s extends e{constructor(t){super(t||{}),this.options=Object.assign({},i,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new s(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=null!==(t=this.options.container)&&void 0!==t?t:this.wavesurfer.getWrapper();this.options.insertPosition?(e.firstElementChild||e).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):e.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;this.initTimeline((null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration())||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){var e,i,s;const n=this.timelineWrapper.scrollWidth/t,r=null!==(e=this.options.timeInterval)&&void 0!==e?e:this.defaultTimeInterval(n),o=null!==(i=this.options.primaryLabelInterval)&&void 0!==i?i:this.defaultPrimaryLabelInterval(n),l=null!==(s=this.options.secondaryLabelInterval)&&void 0!==s?s:this.defaultSecondaryLabelInterval(n),a="beforebegin"===this.options.insertPosition,h=document.createElement("div");if(h.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n position: relative;\n `),a){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";h.setAttribute("style",h.getAttribute("style")+t)}"string"==typeof this.options.style?h.setAttribute("style",h.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(h.style,this.options.style);const p=document.createElement("div");p.setAttribute("part","timeline-notch"),p.setAttribute("style",`\n width: 0;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${a?"flex-start":"flex-end"};\n ${a?"top: 0;":"bottom: 0;"}\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n position: absolute;\n z-index: 1;\n `);for(let e=0;e<t;e+=r){const t=p.cloneNode(),i=Math.round(100*e)/100%o==0,s=Math.round(100*e)/100%l==0;(i||s)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.options.formatTimeCallback(e),i&&(t.style.opacity="1")),t.style.left=e*n+"px",h.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(h),this.emit("ready")}}module.exports=s;
@@ -29,7 +29,7 @@ declare const defaultOptions: {
29
29
  export type TimelinePluginEvents = BasePluginEvents & {
30
30
  ready: [];
31
31
  };
32
- export declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, TimelinePluginOptions> {
32
+ declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, TimelinePluginOptions> {
33
33
  private timelineWrapper;
34
34
  protected options: TimelinePluginOptions & typeof defaultOptions;
35
35
  constructor(options?: TimelinePluginOptions);
@@ -0,0 +1 @@
1
+ class t{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}}class e extends t{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}}const i={height:20,formatTimeCallback:t=>{if(t/60>1){return`${Math.floor(t/60)}:${`${(t=Math.round(t%60))<10?"0":""}${t}`}`}return`${Math.round(1e3*t)/1e3}`}};class n extends e{constructor(t){super(t||{}),this.options=Object.assign({},i,t),this.timelineWrapper=this.initTimelineWrapper()}static create(t){return new n(t)}onInit(){var t;if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const e=null!==(t=this.options.container)&&void 0!==t?t:this.wavesurfer.getWrapper();this.options.insertPosition?(e.firstElementChild||e).insertAdjacentElement(this.options.insertPosition,this.timelineWrapper):e.appendChild(this.timelineWrapper),this.options.duration?this.initTimeline(this.options.duration):this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;this.initTimeline((null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration())||0)})))}destroy(){this.timelineWrapper.remove(),super.destroy()}initTimelineWrapper(){const t=document.createElement("div");return t.setAttribute("part","timeline"),t}defaultTimeInterval(t){return t>=25?1:5*t>=25?5:15*t>=25?15:60*Math.ceil(.5/t)}defaultPrimaryLabelInterval(t){return t>=25?10:5*t>=25?6:4}defaultSecondaryLabelInterval(t){return t>=25?5:2}initTimeline(t){var e,i,n;const s=this.timelineWrapper.scrollWidth/t,r=null!==(e=this.options.timeInterval)&&void 0!==e?e:this.defaultTimeInterval(s),o=null!==(i=this.options.primaryLabelInterval)&&void 0!==i?i:this.defaultPrimaryLabelInterval(s),l=null!==(n=this.options.secondaryLabelInterval)&&void 0!==n?n:this.defaultSecondaryLabelInterval(s),a="beforebegin"===this.options.insertPosition,h=document.createElement("div");if(h.setAttribute("style",`\n height: ${this.options.height}px;\n overflow: hidden;\n font-size: ${this.options.height/2}px;\n white-space: nowrap;\n position: relative;\n `),a){const t="\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n z-index: 2;\n ";h.setAttribute("style",h.getAttribute("style")+t)}"string"==typeof this.options.style?h.setAttribute("style",h.getAttribute("style")+this.options.style):"object"==typeof this.options.style&&Object.assign(h.style,this.options.style);const p=document.createElement("div");p.setAttribute("part","timeline-notch"),p.setAttribute("style",`\n width: 0;\n height: 50%;\n display: flex;\n flex-direction: column;\n justify-content: ${a?"flex-start":"flex-end"};\n ${a?"top: 0;":"bottom: 0;"}\n overflow: visible;\n border-left: 1px solid currentColor;\n opacity: 0.25;\n position: absolute;\n z-index: 1;\n `);for(let e=0;e<t;e+=r){const t=p.cloneNode(),i=Math.round(100*e)/100%o==0,n=Math.round(100*e)/100%l==0;(i||n)&&(t.style.height="100%",t.style.textIndent="3px",t.textContent=this.options.formatTimeCallback(e),i&&(t.style.opacity="1")),t.style.left=e*s+"px",h.appendChild(t)}this.timelineWrapper.innerHTML="",this.timelineWrapper.appendChild(h),this.emit("ready")}}export{n as default};