wavesurfer.js 7.0.0-beta.14 → 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.
- package/README.md +2 -2
- package/dist/draggable.js +3 -5
- package/dist/plugins/base-plugin.d.ts +16 -0
- package/dist/plugins/decoder.d.ts +9 -0
- package/dist/plugins/draggable.d.ts +1 -0
- package/dist/plugins/envelope.cjs +1 -0
- package/dist/plugins/envelope.d.ts +1 -1
- package/dist/plugins/envelope.esm.js +1 -0
- package/dist/plugins/envelope.js +1 -1
- package/dist/plugins/envelope.min.js +1 -0
- package/dist/plugins/event-emitter.d.ts +19 -0
- package/dist/plugins/fetcher.d.ts +5 -0
- package/dist/plugins/hover.cjs +1 -0
- package/dist/plugins/hover.d.ts +1 -1
- package/dist/plugins/hover.esm.js +1 -0
- package/dist/plugins/hover.js +1 -1
- package/dist/plugins/hover.min.js +1 -0
- package/dist/plugins/minimap.cjs +1 -0
- package/dist/plugins/minimap.d.ts +1 -1
- package/dist/plugins/minimap.esm.js +1 -0
- package/dist/plugins/minimap.js +1 -1
- package/dist/plugins/minimap.min.js +1 -0
- package/dist/plugins/player.d.ts +45 -0
- package/dist/plugins/plugins/envelope.d.ts +79 -0
- package/dist/plugins/plugins/hover.d.ts +35 -0
- package/dist/plugins/plugins/minimap.d.ts +39 -0
- package/dist/plugins/plugins/record.d.ts +28 -0
- package/dist/plugins/plugins/regions.d.ts +115 -0
- package/dist/plugins/plugins/spectrogram.d.ts +76 -0
- package/dist/plugins/plugins/timeline.d.ts +47 -0
- package/dist/plugins/record.cjs +1 -0
- package/dist/plugins/record.d.ts +1 -1
- package/dist/plugins/record.esm.js +1 -0
- package/dist/plugins/record.js +1 -1
- package/dist/plugins/record.min.js +1 -0
- package/dist/plugins/regions.cjs +1 -0
- package/dist/plugins/regions.d.ts +2 -2
- package/dist/plugins/regions.esm.js +1 -0
- package/dist/plugins/regions.js +4 -4
- package/dist/plugins/regions.min.js +1 -0
- package/dist/plugins/renderer.d.ts +44 -0
- package/dist/plugins/spectrogram.cjs +1 -0
- package/dist/plugins/spectrogram.d.ts +1 -1
- package/dist/plugins/spectrogram.esm.js +1 -0
- package/dist/plugins/spectrogram.js +1 -1
- package/dist/plugins/spectrogram.min.js +1 -0
- package/dist/plugins/timeline.cjs +1 -0
- package/dist/plugins/timeline.d.ts +4 -2
- package/dist/plugins/timeline.esm.js +1 -0
- package/dist/plugins/timeline.js +20 -17
- package/dist/plugins/timeline.min.js +1 -0
- package/dist/plugins/timer.d.ts +11 -0
- package/dist/plugins/wavesurfer.d.ts +156 -0
- package/dist/renderer.js +3 -1
- package/dist/wavesurfer.cjs +1 -0
- package/dist/wavesurfer.d.ts +1 -1
- package/dist/wavesurfer.esm.js +1 -0
- package/dist/wavesurfer.js +1 -1
- package/dist/wavesurfer.min.js +1 -0
- package/package.json +13 -14
- package/dist/plugins/envelope.min.cjs +0 -1
- package/dist/plugins/hover.min.cjs +0 -1
- package/dist/plugins/minimap.min.cjs +0 -1
- package/dist/plugins/record.min.cjs +0 -1
- package/dist/plugins/regions.min.cjs +0 -1
- package/dist/plugins/spectrogram.min.cjs +0 -1
- package/dist/plugins/timeline.min.cjs +0 -1
- package/dist/wavesurfer.min.cjs +0 -1
|
@@ -19,14 +19,17 @@ export type TimelinePluginOptions = {
|
|
|
19
19
|
secondaryLabelInterval?: number;
|
|
20
20
|
/** Custom inline style to apply to the container */
|
|
21
21
|
style?: Partial<CSSStyleDeclaration> | string;
|
|
22
|
+
/** Turn the time into a suitable label for the time. */
|
|
23
|
+
formatTimeCallback?: (seconds: number) => string;
|
|
22
24
|
};
|
|
23
25
|
declare const defaultOptions: {
|
|
24
26
|
height: number;
|
|
27
|
+
formatTimeCallback: (seconds: number) => string;
|
|
25
28
|
};
|
|
26
29
|
export type TimelinePluginEvents = BasePluginEvents & {
|
|
27
30
|
ready: [];
|
|
28
31
|
};
|
|
29
|
-
|
|
32
|
+
declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, TimelinePluginOptions> {
|
|
30
33
|
private timelineWrapper;
|
|
31
34
|
protected options: TimelinePluginOptions & typeof defaultOptions;
|
|
32
35
|
constructor(options?: TimelinePluginOptions);
|
|
@@ -36,7 +39,6 @@ export declare class TimelinePlugin extends BasePlugin<TimelinePluginEvents, Tim
|
|
|
36
39
|
/** Unmount */
|
|
37
40
|
destroy(): void;
|
|
38
41
|
private initTimelineWrapper;
|
|
39
|
-
private formatTime;
|
|
40
42
|
private defaultTimeInterval;
|
|
41
43
|
private defaultPrimaryLabelInterval;
|
|
42
44
|
private defaultSecondaryLabelInterval;
|
|
@@ -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};
|
package/dist/plugins/timeline.js
CHANGED
|
@@ -4,8 +4,19 @@
|
|
|
4
4
|
import BasePlugin from '../base-plugin.js';
|
|
5
5
|
const defaultOptions = {
|
|
6
6
|
height: 20,
|
|
7
|
+
formatTimeCallback: (seconds) => {
|
|
8
|
+
if (seconds / 60 > 1) {
|
|
9
|
+
// calculate minutes and seconds from seconds count
|
|
10
|
+
const minutes = Math.floor(seconds / 60);
|
|
11
|
+
seconds = Math.round(seconds % 60);
|
|
12
|
+
const paddedSeconds = `${seconds < 10 ? '0' : ''}${seconds}`;
|
|
13
|
+
return `${minutes}:${paddedSeconds}`;
|
|
14
|
+
}
|
|
15
|
+
const rounded = Math.round(seconds * 1000) / 1000;
|
|
16
|
+
return `${rounded}`;
|
|
17
|
+
},
|
|
7
18
|
};
|
|
8
|
-
|
|
19
|
+
class TimelinePlugin extends BasePlugin {
|
|
9
20
|
constructor(options) {
|
|
10
21
|
super(options || {});
|
|
11
22
|
this.options = Object.assign({}, defaultOptions, options);
|
|
@@ -48,17 +59,6 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
48
59
|
div.setAttribute('part', 'timeline');
|
|
49
60
|
return div;
|
|
50
61
|
}
|
|
51
|
-
formatTime(seconds) {
|
|
52
|
-
if (seconds / 60 > 1) {
|
|
53
|
-
// calculate minutes and seconds from seconds count
|
|
54
|
-
const minutes = Math.floor(seconds / 60);
|
|
55
|
-
seconds = Math.round(seconds % 60);
|
|
56
|
-
const paddedSeconds = `${seconds < 10 ? '0' : ''}${seconds}`;
|
|
57
|
-
return `${minutes}:${paddedSeconds}`;
|
|
58
|
-
}
|
|
59
|
-
const rounded = Math.round(seconds * 1000) / 1000;
|
|
60
|
-
return `${rounded}`;
|
|
61
|
-
}
|
|
62
62
|
// Return how many seconds should be between each notch
|
|
63
63
|
defaultTimeInterval(pxPerSec) {
|
|
64
64
|
if (pxPerSec >= 25) {
|
|
@@ -109,11 +109,9 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
109
109
|
timeline.setAttribute('style', `
|
|
110
110
|
height: ${this.options.height}px;
|
|
111
111
|
overflow: hidden;
|
|
112
|
-
display: flex;
|
|
113
|
-
justify-content: space-between;
|
|
114
|
-
align-items: ${isTop ? 'flex-start' : 'flex-end'};
|
|
115
112
|
font-size: ${this.options.height / 2}px;
|
|
116
113
|
white-space: nowrap;
|
|
114
|
+
position: relative;
|
|
117
115
|
`);
|
|
118
116
|
if (isTop) {
|
|
119
117
|
const topStyle = `
|
|
@@ -132,15 +130,19 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
132
130
|
Object.assign(timeline.style, this.options.style);
|
|
133
131
|
}
|
|
134
132
|
const notchEl = document.createElement('div');
|
|
133
|
+
notchEl.setAttribute('part', 'timeline-notch');
|
|
135
134
|
notchEl.setAttribute('style', `
|
|
136
|
-
width:
|
|
135
|
+
width: 0;
|
|
137
136
|
height: 50%;
|
|
138
137
|
display: flex;
|
|
139
138
|
flex-direction: column;
|
|
140
139
|
justify-content: ${isTop ? 'flex-start' : 'flex-end'};
|
|
140
|
+
${isTop ? 'top: 0;' : 'bottom: 0;'}
|
|
141
141
|
overflow: visible;
|
|
142
142
|
border-left: 1px solid currentColor;
|
|
143
143
|
opacity: 0.25;
|
|
144
|
+
position: absolute;
|
|
145
|
+
z-index: 1;
|
|
144
146
|
`);
|
|
145
147
|
for (let i = 0; i < duration; i += timeInterval) {
|
|
146
148
|
const notch = notchEl.cloneNode();
|
|
@@ -149,10 +151,11 @@ export class TimelinePlugin extends BasePlugin {
|
|
|
149
151
|
if (isPrimary || isSecondary) {
|
|
150
152
|
notch.style.height = '100%';
|
|
151
153
|
notch.style.textIndent = '3px';
|
|
152
|
-
notch.textContent = this.
|
|
154
|
+
notch.textContent = this.options.formatTimeCallback(i);
|
|
153
155
|
if (isPrimary)
|
|
154
156
|
notch.style.opacity = '1';
|
|
155
157
|
}
|
|
158
|
+
notch.style.left = `${i * pxPerSec}px`;
|
|
156
159
|
timeline.appendChild(notch);
|
|
157
160
|
}
|
|
158
161
|
this.timelineWrapper.innerHTML = '';
|
|
@@ -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.Timeline=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 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")}}return n}));
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { GenericPlugin } from './base-plugin.js';
|
|
2
|
+
import Player from './player.js';
|
|
3
|
+
export type WaveSurferOptions = {
|
|
4
|
+
/** HTML element or CSS selector */
|
|
5
|
+
container: HTMLElement | string;
|
|
6
|
+
/** The height of the waveform in pixels, or "auto" to fill the container height */
|
|
7
|
+
height?: number | 'auto';
|
|
8
|
+
/** The color of the waveform */
|
|
9
|
+
waveColor?: string | string[] | CanvasGradient;
|
|
10
|
+
/** The color of the progress mask */
|
|
11
|
+
progressColor?: string | string[] | CanvasGradient;
|
|
12
|
+
/** The color of the playpack cursor */
|
|
13
|
+
cursorColor?: string;
|
|
14
|
+
/** The cursor width */
|
|
15
|
+
cursorWidth?: number;
|
|
16
|
+
/** Render the waveform with bars like this: ▁ ▂ ▇ ▃ ▅ ▂ */
|
|
17
|
+
barWidth?: number;
|
|
18
|
+
/** Spacing between bars in pixels */
|
|
19
|
+
barGap?: number;
|
|
20
|
+
/** Rounded borders for bars */
|
|
21
|
+
barRadius?: number;
|
|
22
|
+
/** A vertical scaling factor for the waveform */
|
|
23
|
+
barHeight?: number;
|
|
24
|
+
/** Vertical bar alignment */
|
|
25
|
+
barAlign?: 'top' | 'bottom';
|
|
26
|
+
/** Minimum pixels per second of audio (i.e. zoom level) */
|
|
27
|
+
minPxPerSec?: number;
|
|
28
|
+
/** Stretch the waveform to fill the container, true by default */
|
|
29
|
+
fillParent?: boolean;
|
|
30
|
+
/** Audio URL */
|
|
31
|
+
url?: string;
|
|
32
|
+
/** Pre-computed audio data */
|
|
33
|
+
peaks?: Array<Float32Array | number[]>;
|
|
34
|
+
/** Pre-computed duration */
|
|
35
|
+
duration?: number;
|
|
36
|
+
/** Use an existing media element instead of creating one */
|
|
37
|
+
media?: HTMLMediaElement;
|
|
38
|
+
/** Play the audio on load */
|
|
39
|
+
autoplay?: boolean;
|
|
40
|
+
/** Pass false to disable clicks on the waveform */
|
|
41
|
+
interact?: boolean;
|
|
42
|
+
/** Hide the scrollbar */
|
|
43
|
+
hideScrollbar?: boolean;
|
|
44
|
+
/** Audio rate */
|
|
45
|
+
audioRate?: number;
|
|
46
|
+
/** Automatically scroll the container to keep the current position in viewport */
|
|
47
|
+
autoScroll?: boolean;
|
|
48
|
+
/** If autoScroll is enabled, keep the cursor in the center of the waveform during playback */
|
|
49
|
+
autoCenter?: boolean;
|
|
50
|
+
/** Decoding sample rate. Doesn't affect the playback. Defaults to 8000 */
|
|
51
|
+
sampleRate?: number;
|
|
52
|
+
/** Render each audio channel as a separate waveform */
|
|
53
|
+
splitChannels?: WaveSurferOptions[];
|
|
54
|
+
/** Stretch the waveform to the full height */
|
|
55
|
+
normalize?: boolean;
|
|
56
|
+
/** The list of plugins to initialize on start */
|
|
57
|
+
plugins?: GenericPlugin[];
|
|
58
|
+
/** Custom render function */
|
|
59
|
+
renderFunction?: (peaks: Array<Float32Array | number[]>, ctx: CanvasRenderingContext2D) => void;
|
|
60
|
+
/** Options to pass to the fetch method */
|
|
61
|
+
fetchParams?: RequestInit;
|
|
62
|
+
};
|
|
63
|
+
declare const defaultOptions: {
|
|
64
|
+
waveColor: string;
|
|
65
|
+
progressColor: string;
|
|
66
|
+
cursorWidth: number;
|
|
67
|
+
minPxPerSec: number;
|
|
68
|
+
fillParent: boolean;
|
|
69
|
+
interact: boolean;
|
|
70
|
+
autoScroll: boolean;
|
|
71
|
+
autoCenter: boolean;
|
|
72
|
+
sampleRate: number;
|
|
73
|
+
};
|
|
74
|
+
export type WaveSurferEvents = {
|
|
75
|
+
/** When audio starts loading */
|
|
76
|
+
load: [url: string];
|
|
77
|
+
/** When the audio has been decoded */
|
|
78
|
+
decode: [duration: number];
|
|
79
|
+
/** When the audio is both decoded and can play */
|
|
80
|
+
ready: [duration: number];
|
|
81
|
+
/** When a waveform is drawn */
|
|
82
|
+
redraw: [];
|
|
83
|
+
/** When the audio starts playing */
|
|
84
|
+
play: [];
|
|
85
|
+
/** When the audio pauses */
|
|
86
|
+
pause: [];
|
|
87
|
+
/** When the audio finishes playing */
|
|
88
|
+
finish: [];
|
|
89
|
+
/** On audio position change, fires continuously during playback */
|
|
90
|
+
timeupdate: [currentTime: number];
|
|
91
|
+
/** An alias of timeupdate but only when the audio is playing */
|
|
92
|
+
audioprocess: [currentTime: number];
|
|
93
|
+
/** When the user seeks to a new position */
|
|
94
|
+
seeking: [currentTime: number];
|
|
95
|
+
/** When the user interacts with the waveform (i.g. clicks or drags on it) */
|
|
96
|
+
interaction: [newTime: number];
|
|
97
|
+
/** When the user clicks on the waveform */
|
|
98
|
+
click: [relativeX: number];
|
|
99
|
+
/** When the user drags the cursor */
|
|
100
|
+
drag: [relativeX: number];
|
|
101
|
+
/** When the waveform is scrolled (panned) */
|
|
102
|
+
scroll: [visibleStartTime: number, visibleEndTime: number];
|
|
103
|
+
/** When the zoom level changes */
|
|
104
|
+
zoom: [minPxPerSec: number];
|
|
105
|
+
/** Just before the waveform is destroyed so you can clean up your events */
|
|
106
|
+
destroy: [];
|
|
107
|
+
};
|
|
108
|
+
declare class WaveSurfer extends Player<WaveSurferEvents> {
|
|
109
|
+
options: WaveSurferOptions & typeof defaultOptions;
|
|
110
|
+
private renderer;
|
|
111
|
+
private timer;
|
|
112
|
+
private plugins;
|
|
113
|
+
private decodedData;
|
|
114
|
+
private duration;
|
|
115
|
+
protected subscriptions: Array<() => void>;
|
|
116
|
+
/** Create a new WaveSurfer instance */
|
|
117
|
+
static create(options: WaveSurferOptions): WaveSurfer;
|
|
118
|
+
/** Create a new WaveSurfer instance */
|
|
119
|
+
constructor(options: WaveSurferOptions);
|
|
120
|
+
setOptions(options: Partial<WaveSurferOptions>): void;
|
|
121
|
+
private initTimerEvents;
|
|
122
|
+
private initPlayerEvents;
|
|
123
|
+
private initRendererEvents;
|
|
124
|
+
private initPlugins;
|
|
125
|
+
/** Register a wavesurfer.js plugin */
|
|
126
|
+
registerPlugin<T extends GenericPlugin>(plugin: T): T;
|
|
127
|
+
/** For plugins only: get the waveform wrapper div */
|
|
128
|
+
getWrapper(): HTMLElement;
|
|
129
|
+
/** Get the current scroll position in pixels */
|
|
130
|
+
getScroll(): number;
|
|
131
|
+
/** Get all registered plugins */
|
|
132
|
+
getActivePlugins(): GenericPlugin[];
|
|
133
|
+
/** Load an audio file by URL, with optional pre-decoded audio data */
|
|
134
|
+
load(url: string, channelData?: WaveSurferOptions['peaks'], duration?: number): Promise<void>;
|
|
135
|
+
/** Zoom the waveform by a given pixels-per-second factor */
|
|
136
|
+
zoom(minPxPerSec: number): void;
|
|
137
|
+
/** Get the decoded audio data */
|
|
138
|
+
getDecodedData(): AudioBuffer | null;
|
|
139
|
+
/** Get the duration of the audio in seconds */
|
|
140
|
+
getDuration(): number;
|
|
141
|
+
/** Toggle if the waveform should react to clicks */
|
|
142
|
+
toggleInteraction(isInteractive: boolean): void;
|
|
143
|
+
/** Seek to a percentage of audio as [0..1] (0 = beginning, 1 = end) */
|
|
144
|
+
seekTo(progress: number): void;
|
|
145
|
+
/** Play or pause the audio */
|
|
146
|
+
playPause(): Promise<void>;
|
|
147
|
+
/** Stop the audio and go to the beginning */
|
|
148
|
+
stop(): void;
|
|
149
|
+
/** Skip N or -N seconds from the current position */
|
|
150
|
+
skip(seconds: number): void;
|
|
151
|
+
/** Empty the waveform by loading a tiny silent audio */
|
|
152
|
+
empty(): void;
|
|
153
|
+
/** Unmount wavesurfer */
|
|
154
|
+
destroy(): void;
|
|
155
|
+
}
|
|
156
|
+
export default WaveSurfer;
|
package/dist/renderer.js
CHANGED
|
@@ -88,6 +88,7 @@ class Renderer extends EventEmitter {
|
|
|
88
88
|
overflow-y: hidden;
|
|
89
89
|
width: 100%;
|
|
90
90
|
position: relative;
|
|
91
|
+
touch-action: none;
|
|
91
92
|
}
|
|
92
93
|
:host .noScrollbar {
|
|
93
94
|
scrollbar-color: transparent;
|
|
@@ -216,6 +217,7 @@ class Renderer extends EventEmitter {
|
|
|
216
217
|
}
|
|
217
218
|
}
|
|
218
219
|
const vScale = (halfHeight / max) * barHeight;
|
|
220
|
+
const rectFn = barRadius && 'roundRect' in ctx ? 'roundRect' : 'rect';
|
|
219
221
|
ctx.beginPath();
|
|
220
222
|
let prevX = 0;
|
|
221
223
|
let maxTop = 0;
|
|
@@ -232,7 +234,7 @@ class Renderer extends EventEmitter {
|
|
|
232
234
|
y = 0;
|
|
233
235
|
else if (options.barAlign === 'bottom')
|
|
234
236
|
y = height - barHeight;
|
|
235
|
-
ctx
|
|
237
|
+
ctx[rectFn](prevX * (barWidth + barGap), y, barWidth, barHeight, barRadius);
|
|
236
238
|
prevX = x;
|
|
237
239
|
maxTop = 0;
|
|
238
240
|
maxBottom = 0;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";function t(t,e,i,s){return new(i||(i=Promise))((function(n,r){function o(t){try{h(s.next(t))}catch(t){r(t)}}function a(t){try{h(s.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(o,a)}h((s=s.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const e={decode:function(e,i){return t(this,void 0,void 0,(function*(){const t=new AudioContext({sampleRate:i}),s=t.decodeAudioData(e);return s.finally((()=>t.close())),s}))},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>null==t?void 0:t[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}};const i={fetchBlob:function(e,i){return t(this,void 0,void 0,(function*(){return fetch(e,i).then((t=>t.blob()))}))}};class s{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 n extends s{constructor(t){super(),t.media?this.media=t.media:this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}getSrc(){return this.media.currentSrc||this.media.src||""}revokeSrc(){const t=this.getSrc();t.startsWith("blob:")&&URL.revokeObjectURL(t)}setSrc(t,e){if(this.getSrc()===t)return;this.revokeSrc();const i=e instanceof Blob?URL.createObjectURL(e):t;this.media.src=i,this.media.load()}destroy(){this.media.pause(),this.revokeSrc(),this.media.src="",this.media.load()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}}class r extends s{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");this.parent=e;const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,n=(t+i)/e;this.emit("scroll",s,n)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){!function(t,e,i,s,n=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let a=o.clientX,h=o.clientY,l=!1;const c=s=>{s.preventDefault(),s.stopPropagation();const r=s.clientX,o=s.clientY;if(l||Math.abs(r-a)>=n||Math.abs(o-h)>=n){const{left:s,top:n}=t.getBoundingClientRect();l||(l=!0,null==i||i(a-s,h-n)),e(r-a,o-h,r-s,o-n),a=r,h=o}},d=t=>{l&&(t.preventDefault(),t.stopPropagation())},u=()=>{l&&(null==s||s()),r()};document.addEventListener("pointermove",c),document.addEventListener("pointerup",u),document.addEventListener("pointerleave",u),document.addEventListener("click",d,!0),r=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",u),document.removeEventListener("pointerleave",u),setTimeout((()=>{document.removeEventListener("click",d,!0)}),10)}};t.addEventListener("pointerdown",o)}(this.wrapper,((t,e,i)=>{this.emit("drag",Math.max(0,Math.min(1,i/this.wrapper.clientWidth)))}),(()=>this.isDragging=!0),(()=>this.isDragging=!1))}getHeight(){return null==this.options.height?128:isNaN(Number(this.options.height))?"auto"===this.options.height&&this.parent.clientHeight||128:Number(this.options.height)}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n touch-action: none;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.getHeight()}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress" part="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){var t;this.container.remove(),null===(t=this.resizeObserver)||void 0===t||t.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return t[0]||"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const n=e*s;i.addColorStop(n,t)})),i}renderBars(t,e,i){if(i.fillStyle=this.convertColorValues(e.waveColor),e.renderFunction)return void e.renderFunction(t,i);const s=t[0],n=t[1]||t[0],r=s.length,o=window.devicePixelRatio||1,{width:a,height:h}=i.canvas,l=h/2,c=e.barHeight||1,d=e.barWidth?e.barWidth*o:1,u=e.barGap?e.barGap*o:e.barWidth?d/2:0,p=e.barRadius||0,m=a/(d+u)/r;let g=1;if(e.normalize){g=0;for(let t=0;t<r;t++){const e=Math.abs(s[t]);e>g&&(g=e)}}const v=l/g*c,f=p&&"roundRect"in i?"roundRect":"rect";i.beginPath();let b=0,y=0,C=0;for(let t=0;t<=r;t++){const r=Math.round(t*m);if(r>b){const t=Math.round(y*v),s=t+Math.round(C*v)||1;let n=l-t;"top"===e.barAlign?n=0:"bottom"===e.barAlign&&(n=h-s),i[f](b*(d+u),n,d,s,p),b=r,y=0,C=0}const o=Math.abs(s[t]||0),a=Math.abs(n[t]||0);o>y&&(y=o),a>C&&(C=a)}i.fill(),i.closePath()}renderSingleCanvas(t,e,i,s,n,r,o,a){const h=window.devicePixelRatio||1,l=document.createElement("canvas"),c=t[0].length;l.width=Math.round(i*(r-n)/c),l.height=s*h,l.style.width=`${Math.floor(l.width/h)}px`,l.style.height=`${s}px`,l.style.left=`${Math.floor(n*i/h/c)}px`,o.appendChild(l);const d=l.getContext("2d");this.renderBars(t.map((t=>t.slice(n,r))),e,d);const u=l.cloneNode();a.appendChild(u);const p=u.getContext("2d");l.width>0&&l.height>0&&p.drawImage(l,0,0),p.globalCompositeOperation="source-in",p.fillStyle=this.convertColorValues(e.progressColor),p.fillRect(0,0,l.width,l.height)}renderWaveform(t,e,i){const s=document.createElement("div"),n=this.getHeight();s.style.height=`${n}px`,this.canvasWrapper.style.minHeight=`${n}px`,this.canvasWrapper.appendChild(s);const o=s.cloneNode();this.progressWrapper.appendChild(o);const{scrollLeft:a,scrollWidth:h,clientWidth:l}=this.scrollContainer,c=t[0].length,d=c/h;let u=Math.min(r.MAX_CANVAS_WIDTH,l);if(e.barWidth||e.barGap){const t=e.barWidth||.5,i=t+(e.barGap||t/2);u%i!=0&&(u=Math.floor(u/i)*i)}const p=Math.floor(Math.abs(a)*d),m=Math.floor(p+u*d),g=m-p,v=(r,a)=>{this.renderSingleCanvas(t,e,i,n,Math.max(0,r),Math.min(a,c),s,o)},f=this.createDelay(),b=this.createDelay(),y=(t,e)=>{v(t,e),t>0&&f((()=>{y(t-g,e-g)}))},C=(t,e)=>{v(t,e),e<c&&b((()=>{C(t+g,e+g)}))};y(p,m),m<c&&C(m,m+g)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[],this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.wrapper.style.width="";const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const n=this.options.fillParent&&!this.isScrolling,r=(n?i:s)*e;if(this.wrapper.style.width=n?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i=Object.assign(Object.assign({},this.options),this.options.splitChannels[e]);this.renderWaveform([t.getChannelData(e)],i,r)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,r)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:n}=this.scrollContainer,r=n*t,o=i/2;if(r>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||r<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;r-(s+o)>=t&&r<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=r-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=r<s?r-t:r-i+t}else this.scrollContainer.scrollLeft=r;{const{scrollLeft:t}=this.scrollContainer,e=t/n,s=(t+i)/n;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}r.MAX_CANVAS_WIDTH=4e3;class o extends s{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}}const a={waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class h extends n{static create(t){return new h(t)}constructor(t){var e,i;super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.duration=null,this.subscriptions=[],this.options=Object.assign({},a,t),this.timer=new o,this.renderer=new r(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const s=this.options.url||(null===(e=this.options.media)||void 0===e?void 0:e.currentSrc)||(null===(i=this.options.media)||void 0===i?void 0:i.src);s&&this.load(s,this.options.peaks,this.options.duration)}setOptions(t){this.options=Object.assign({},this.options,t),this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction",this.getCurrentTime()),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction",e*this.getDuration()),this.emit("drag",e))})))}}initPlugins(){var t;(null===(t=this.options.plugins)||void 0===t?void 0:t.length)&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),this.subscriptions.push(t.once("destroy",(()=>{this.plugins=this.plugins.filter((e=>e!==t))}))),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}load(s,n,r){return t(this,void 0,void 0,(function*(){this.isPlaying()&&this.pause(),this.decodedData=null,this.duration=null,this.emit("load",s);const t=n?void 0:yield i.fetchBlob(s,this.options.fetchParams);if(this.setSrc(s,t),this.duration=r||this.getDuration()||(yield new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getDuration())))})))||0,n)this.decodedData=e.createBuffer(n,this.duration);else if(t){const i=yield t.arrayBuffer();this.decodedData=yield e.decode(i,this.options.sampleRate),0!==this.duration&&this.duration!==1/0||(this.duration=this.decodedData.duration)}this.emit("decode",this.duration),this.decodedData&&this.renderer.render(this.decodedData),this.emit("ready",this.duration)}))}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){return null!==this.duration?this.duration:super.getDuration()}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return t(this,void 0,void 0,(function*(){return this.isPlaying()?this.pause():this.play()}))}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.plugins.forEach((t=>t.destroy())),this.subscriptions.forEach((t=>t())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}module.exports=h;
|
package/dist/wavesurfer.d.ts
CHANGED
|
@@ -105,7 +105,7 @@ export type WaveSurferEvents = {
|
|
|
105
105
|
/** Just before the waveform is destroyed so you can clean up your events */
|
|
106
106
|
destroy: [];
|
|
107
107
|
};
|
|
108
|
-
|
|
108
|
+
declare class WaveSurfer extends Player<WaveSurferEvents> {
|
|
109
109
|
options: WaveSurferOptions & typeof defaultOptions;
|
|
110
110
|
private renderer;
|
|
111
111
|
private timer;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function t(t,e,i,s){return new(i||(i=Promise))((function(n,r){function o(t){try{h(s.next(t))}catch(t){r(t)}}function a(t){try{h(s.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(o,a)}h((s=s.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const e={decode:function(e,i){return t(this,void 0,void 0,(function*(){const t=new AudioContext({sampleRate:i}),s=t.decodeAudioData(e);return s.finally((()=>t.close())),s}))},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>null==t?void 0:t[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}};const i={fetchBlob:function(e,i){return t(this,void 0,void 0,(function*(){return fetch(e,i).then((t=>t.blob()))}))}};class s{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 n extends s{constructor(t){super(),t.media?this.media=t.media:this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}getSrc(){return this.media.currentSrc||this.media.src||""}revokeSrc(){const t=this.getSrc();t.startsWith("blob:")&&URL.revokeObjectURL(t)}setSrc(t,e){if(this.getSrc()===t)return;this.revokeSrc();const i=e instanceof Blob?URL.createObjectURL(e):t;this.media.src=i,this.media.load()}destroy(){this.media.pause(),this.revokeSrc(),this.media.src="",this.media.load()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}}class r extends s{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");this.parent=e;const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,n=(t+i)/e;this.emit("scroll",s,n)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){!function(t,e,i,s,n=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let a=o.clientX,h=o.clientY,l=!1;const c=s=>{s.preventDefault(),s.stopPropagation();const r=s.clientX,o=s.clientY;if(l||Math.abs(r-a)>=n||Math.abs(o-h)>=n){const{left:s,top:n}=t.getBoundingClientRect();l||(l=!0,null==i||i(a-s,h-n)),e(r-a,o-h,r-s,o-n),a=r,h=o}},d=t=>{l&&(t.preventDefault(),t.stopPropagation())},u=()=>{l&&(null==s||s()),r()};document.addEventListener("pointermove",c),document.addEventListener("pointerup",u),document.addEventListener("pointerleave",u),document.addEventListener("click",d,!0),r=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",u),document.removeEventListener("pointerleave",u),setTimeout((()=>{document.removeEventListener("click",d,!0)}),10)}};t.addEventListener("pointerdown",o)}(this.wrapper,((t,e,i)=>{this.emit("drag",Math.max(0,Math.min(1,i/this.wrapper.clientWidth)))}),(()=>this.isDragging=!0),(()=>this.isDragging=!1))}getHeight(){return null==this.options.height?128:isNaN(Number(this.options.height))?"auto"===this.options.height&&this.parent.clientHeight||128:Number(this.options.height)}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n touch-action: none;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.getHeight()}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress" part="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){var t;this.container.remove(),null===(t=this.resizeObserver)||void 0===t||t.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return t[0]||"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const n=e*s;i.addColorStop(n,t)})),i}renderBars(t,e,i){if(i.fillStyle=this.convertColorValues(e.waveColor),e.renderFunction)return void e.renderFunction(t,i);const s=t[0],n=t[1]||t[0],r=s.length,o=window.devicePixelRatio||1,{width:a,height:h}=i.canvas,l=h/2,c=e.barHeight||1,d=e.barWidth?e.barWidth*o:1,u=e.barGap?e.barGap*o:e.barWidth?d/2:0,p=e.barRadius||0,m=a/(d+u)/r;let g=1;if(e.normalize){g=0;for(let t=0;t<r;t++){const e=Math.abs(s[t]);e>g&&(g=e)}}const v=l/g*c,f=p&&"roundRect"in i?"roundRect":"rect";i.beginPath();let b=0,y=0,C=0;for(let t=0;t<=r;t++){const r=Math.round(t*m);if(r>b){const t=Math.round(y*v),s=t+Math.round(C*v)||1;let n=l-t;"top"===e.barAlign?n=0:"bottom"===e.barAlign&&(n=h-s),i[f](b*(d+u),n,d,s,p),b=r,y=0,C=0}const o=Math.abs(s[t]||0),a=Math.abs(n[t]||0);o>y&&(y=o),a>C&&(C=a)}i.fill(),i.closePath()}renderSingleCanvas(t,e,i,s,n,r,o,a){const h=window.devicePixelRatio||1,l=document.createElement("canvas"),c=t[0].length;l.width=Math.round(i*(r-n)/c),l.height=s*h,l.style.width=`${Math.floor(l.width/h)}px`,l.style.height=`${s}px`,l.style.left=`${Math.floor(n*i/h/c)}px`,o.appendChild(l);const d=l.getContext("2d");this.renderBars(t.map((t=>t.slice(n,r))),e,d);const u=l.cloneNode();a.appendChild(u);const p=u.getContext("2d");l.width>0&&l.height>0&&p.drawImage(l,0,0),p.globalCompositeOperation="source-in",p.fillStyle=this.convertColorValues(e.progressColor),p.fillRect(0,0,l.width,l.height)}renderWaveform(t,e,i){const s=document.createElement("div"),n=this.getHeight();s.style.height=`${n}px`,this.canvasWrapper.style.minHeight=`${n}px`,this.canvasWrapper.appendChild(s);const o=s.cloneNode();this.progressWrapper.appendChild(o);const{scrollLeft:a,scrollWidth:h,clientWidth:l}=this.scrollContainer,c=t[0].length,d=c/h;let u=Math.min(r.MAX_CANVAS_WIDTH,l);if(e.barWidth||e.barGap){const t=e.barWidth||.5,i=t+(e.barGap||t/2);u%i!=0&&(u=Math.floor(u/i)*i)}const p=Math.floor(Math.abs(a)*d),m=Math.floor(p+u*d),g=m-p,v=(r,a)=>{this.renderSingleCanvas(t,e,i,n,Math.max(0,r),Math.min(a,c),s,o)},f=this.createDelay(),b=this.createDelay(),y=(t,e)=>{v(t,e),t>0&&f((()=>{y(t-g,e-g)}))},C=(t,e)=>{v(t,e),e<c&&b((()=>{C(t+g,e+g)}))};y(p,m),m<c&&C(m,m+g)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[],this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.wrapper.style.width="";const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const n=this.options.fillParent&&!this.isScrolling,r=(n?i:s)*e;if(this.wrapper.style.width=n?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i=Object.assign(Object.assign({},this.options),this.options.splitChannels[e]);this.renderWaveform([t.getChannelData(e)],i,r)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,r)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:n}=this.scrollContainer,r=n*t,o=i/2;if(r>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||r<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;r-(s+o)>=t&&r<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=r-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=r<s?r-t:r-i+t}else this.scrollContainer.scrollLeft=r;{const{scrollLeft:t}=this.scrollContainer,e=t/n,s=(t+i)/n;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}r.MAX_CANVAS_WIDTH=4e3;class o extends s{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}}const a={waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class h extends n{static create(t){return new h(t)}constructor(t){var e,i;super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.duration=null,this.subscriptions=[],this.options=Object.assign({},a,t),this.timer=new o,this.renderer=new r(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const s=this.options.url||(null===(e=this.options.media)||void 0===e?void 0:e.currentSrc)||(null===(i=this.options.media)||void 0===i?void 0:i.src);s&&this.load(s,this.options.peaks,this.options.duration)}setOptions(t){this.options=Object.assign({},this.options,t),this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction",this.getCurrentTime()),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction",e*this.getDuration()),this.emit("drag",e))})))}}initPlugins(){var t;(null===(t=this.options.plugins)||void 0===t?void 0:t.length)&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),this.subscriptions.push(t.once("destroy",(()=>{this.plugins=this.plugins.filter((e=>e!==t))}))),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}load(s,n,r){return t(this,void 0,void 0,(function*(){this.isPlaying()&&this.pause(),this.decodedData=null,this.duration=null,this.emit("load",s);const t=n?void 0:yield i.fetchBlob(s,this.options.fetchParams);if(this.setSrc(s,t),this.duration=r||this.getDuration()||(yield new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getDuration())))})))||0,n)this.decodedData=e.createBuffer(n,this.duration);else if(t){const i=yield t.arrayBuffer();this.decodedData=yield e.decode(i,this.options.sampleRate),0!==this.duration&&this.duration!==1/0||(this.duration=this.decodedData.duration)}this.emit("decode",this.duration),this.decodedData&&this.renderer.render(this.decodedData),this.emit("ready",this.duration)}))}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){return null!==this.duration?this.duration:super.getDuration()}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return t(this,void 0,void 0,(function*(){return this.isPlaying()?this.pause():this.play()}))}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.plugins.forEach((t=>t.destroy())),this.subscriptions.forEach((t=>t())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}export{h as default};
|
package/dist/wavesurfer.js
CHANGED
|
@@ -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=e()}(this,(function(){"use strict";function t(t,e,i,s){return new(i||(i=Promise))((function(n,r){function o(t){try{h(s.next(t))}catch(t){r(t)}}function a(t){try{h(s.throw(t))}catch(t){r(t)}}function h(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(o,a)}h((s=s.apply(t,e||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const e={decode:function(e,i){return t(this,void 0,void 0,(function*(){const t=new AudioContext({sampleRate:i}),s=t.decodeAudioData(e);return s.finally((()=>t.close())),s}))},createBuffer:function(t,e){return"number"==typeof t[0]&&(t=[t]),function(t){const e=t[0];if(e.some((t=>t>1||t<-1))){const i=e.length;let s=0;for(let t=0;t<i;t++){const i=Math.abs(e[t]);i>s&&(s=i)}for(const e of t)for(let t=0;t<i;t++)e[t]/=s}}(t),{duration:e,length:t[0].length,sampleRate:t[0].length/e,numberOfChannels:t.length,getChannelData:e=>null==t?void 0:t[e],copyFromChannel:AudioBuffer.prototype.copyFromChannel,copyToChannel:AudioBuffer.prototype.copyToChannel}}};const i={fetchBlob:function(e,i){return t(this,void 0,void 0,(function*(){return fetch(e,i).then((t=>t.blob()))}))}};class s{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 n extends s{constructor(t){super(),t.media?this.media=t.media:this.media=document.createElement("audio"),t.autoplay&&(this.media.autoplay=!0),null!=t.playbackRate&&(this.media.playbackRate=t.playbackRate)}onMediaEvent(t,e,i){return this.media.addEventListener(t,e,i),()=>this.media.removeEventListener(t,e)}onceMediaEvent(t,e){return this.onMediaEvent(t,e,{once:!0})}getSrc(){return this.media.currentSrc||this.media.src||""}revokeSrc(){const t=this.getSrc();t.startsWith("blob:")&&URL.revokeObjectURL(t)}setSrc(t,e){if(this.getSrc()===t)return;this.revokeSrc();const i=e instanceof Blob?URL.createObjectURL(e):t;this.media.src=i,this.media.load()}destroy(){this.media.pause(),this.revokeSrc(),this.media.src="",this.media.load()}play(){return this.media.play()}pause(){this.media.pause()}isPlaying(){return this.media.currentTime>0&&!this.media.paused&&!this.media.ended}setTime(t){this.media.currentTime=t}getDuration(){return this.media.duration}getCurrentTime(){return this.media.currentTime}getVolume(){return this.media.volume}setVolume(t){this.media.volume=t}getMuted(){return this.media.muted}setMuted(t){this.media.muted=t}getPlaybackRate(){return this.media.playbackRate}setPlaybackRate(t,e){null!=e&&(this.media.preservesPitch=e),this.media.playbackRate=t}getMediaElement(){return this.media}setSinkId(t){return this.media.setSinkId(t)}}class r extends s{constructor(t){let e;if(super(),this.timeouts=[],this.isScrolling=!1,this.audioData=null,this.resizeObserver=null,this.isDragging=!1,this.options=t,"string"==typeof t.container?e=document.querySelector(t.container):t.container instanceof HTMLElement&&(e=t.container),!e)throw new Error("Container not found");this.parent=e;const[i,s]=this.initHtml();e.appendChild(i),this.container=i,this.scrollContainer=s.querySelector(".scroll"),this.wrapper=s.querySelector(".wrapper"),this.canvasWrapper=s.querySelector(".canvases"),this.progressWrapper=s.querySelector(".progress"),this.cursor=s.querySelector(".cursor"),this.initEvents()}initEvents(){this.wrapper.addEventListener("click",(t=>{const e=this.wrapper.getBoundingClientRect(),i=(t.clientX-e.left)/e.width;this.emit("click",i)})),this.initDrag(),this.scrollContainer.addEventListener("scroll",(()=>{const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer,s=t/e,n=(t+i)/e;this.emit("scroll",s,n)}));const t=this.createDelay(100);this.resizeObserver=new ResizeObserver((()=>{t((()=>this.reRender()))})),this.resizeObserver.observe(this.scrollContainer)}initDrag(){!function(t,e,i,s,n=5){let r=()=>{};if(!t)return r;const o=o=>{if(2===o.button)return;o.preventDefault(),o.stopPropagation();let a=o.clientX,h=o.clientY,l=!1;const c=s=>{s.preventDefault(),s.stopPropagation();const r=s.clientX,o=s.clientY;if(l||Math.abs(r-a)>=n||Math.abs(o-h)>=n){const{left:s,top:n}=t.getBoundingClientRect();l||(l=!0,null==i||i(a-s,h-n)),e(r-a,o-h,r-s,o-n),a=r,h=o}},d=t=>{l&&(t.preventDefault(),t.stopPropagation())},u=()=>{l&&(null==s||s()),r()};document.addEventListener("pointermove",c),document.addEventListener("pointerup",u),document.addEventListener("pointerleave",u),document.addEventListener("click",d,!0),r=()=>{document.removeEventListener("pointermove",c),document.removeEventListener("pointerup",u),document.removeEventListener("pointerleave",u),setTimeout((()=>{document.removeEventListener("click",d,!0)}),10)}};t.addEventListener("pointerdown",o)}(this.wrapper,((t,e,i)=>{this.emit("drag",Math.max(0,Math.min(1,i/this.wrapper.clientWidth)))}),(()=>this.isDragging=!0),(()=>this.isDragging=!1))}getHeight(){return null==this.options.height?128:isNaN(Number(this.options.height))?"auto"===this.options.height&&this.parent.clientHeight||128:Number(this.options.height)}initHtml(){const t=document.createElement("div"),e=t.attachShadow({mode:"open"});return e.innerHTML=`\n <style>\n :host {\n user-select: none;\n }\n :host .scroll {\n overflow-x: auto;\n overflow-y: hidden;\n width: 100%;\n position: relative;\n touch-action: none;\n }\n :host .noScrollbar {\n scrollbar-color: transparent;\n scrollbar-width: none;\n }\n :host .noScrollbar::-webkit-scrollbar {\n display: none;\n -webkit-appearance: none;\n }\n :host .wrapper {\n position: relative;\n overflow: visible;\n z-index: 2;\n }\n :host .canvases {\n min-height: ${this.getHeight()}px;\n }\n :host .canvases > div {\n position: relative;\n }\n :host canvas {\n display: block;\n position: absolute;\n top: 0;\n image-rendering: pixelated;\n }\n :host .progress {\n pointer-events: none;\n position: absolute;\n z-index: 2;\n top: 0;\n left: 0;\n width: 0;\n height: 100%;\n overflow: hidden;\n }\n :host .progress > div {\n position: relative;\n }\n :host .cursor {\n pointer-events: none;\n position: absolute;\n z-index: 5;\n top: 0;\n left: 0;\n height: 100%;\n border-radius: 2px;\n }\n </style>\n\n <div class="scroll" part="scroll">\n <div class="wrapper">\n <div class="canvases"></div>\n <div class="progress" part="progress"></div>\n <div class="cursor" part="cursor"></div>\n </div>\n </div>\n `,[t,e]}setOptions(t){this.options=t,this.reRender()}getWrapper(){return this.wrapper}getScroll(){return this.scrollContainer.scrollLeft}destroy(){var t;this.container.remove(),null===(t=this.resizeObserver)||void 0===t||t.disconnect()}createDelay(t=10){const e={};return this.timeouts.push(e),i=>{e.timeout&&clearTimeout(e.timeout),e.timeout=setTimeout(i,t)}}convertColorValues(t){if(!Array.isArray(t))return t||"";if(t.length<2)return t[0]||"";const e=document.createElement("canvas"),i=e.getContext("2d").createLinearGradient(0,0,0,e.height),s=1/(t.length-1);return t.forEach(((t,e)=>{const n=e*s;i.addColorStop(n,t)})),i}renderBars(t,e,i){if(i.fillStyle=this.convertColorValues(e.waveColor),e.renderFunction)return void e.renderFunction(t,i);const s=t[0],n=t[1]||t[0],r=s.length,o=window.devicePixelRatio||1,{width:a,height:h}=i.canvas,l=h/2,c=e.barHeight||1,d=e.barWidth?e.barWidth*o:1,u=e.barGap?e.barGap*o:e.barWidth?d/2:0,p=e.barRadius||0,m=a/(d+u)/r;let g=1;if(e.normalize){g=0;for(let t=0;t<r;t++){const e=Math.abs(s[t]);e>g&&(g=e)}}const v=l/g*c,f=p&&"roundRect"in i?"roundRect":"rect";i.beginPath();let b=0,y=0,C=0;for(let t=0;t<=r;t++){const r=Math.round(t*m);if(r>b){const t=Math.round(y*v),s=t+Math.round(C*v)||1;let n=l-t;"top"===e.barAlign?n=0:"bottom"===e.barAlign&&(n=h-s),i[f](b*(d+u),n,d,s,p),b=r,y=0,C=0}const o=Math.abs(s[t]||0),a=Math.abs(n[t]||0);o>y&&(y=o),a>C&&(C=a)}i.fill(),i.closePath()}renderSingleCanvas(t,e,i,s,n,r,o,a){const h=window.devicePixelRatio||1,l=document.createElement("canvas"),c=t[0].length;l.width=Math.round(i*(r-n)/c),l.height=s*h,l.style.width=`${Math.floor(l.width/h)}px`,l.style.height=`${s}px`,l.style.left=`${Math.floor(n*i/h/c)}px`,o.appendChild(l);const d=l.getContext("2d");this.renderBars(t.map((t=>t.slice(n,r))),e,d);const u=l.cloneNode();a.appendChild(u);const p=u.getContext("2d");l.width>0&&l.height>0&&p.drawImage(l,0,0),p.globalCompositeOperation="source-in",p.fillStyle=this.convertColorValues(e.progressColor),p.fillRect(0,0,l.width,l.height)}renderWaveform(t,e,i){const s=document.createElement("div"),n=this.getHeight();s.style.height=`${n}px`,this.canvasWrapper.style.minHeight=`${n}px`,this.canvasWrapper.appendChild(s);const o=s.cloneNode();this.progressWrapper.appendChild(o);const{scrollLeft:a,scrollWidth:h,clientWidth:l}=this.scrollContainer,c=t[0].length,d=c/h;let u=Math.min(r.MAX_CANVAS_WIDTH,l);if(e.barWidth||e.barGap){const t=e.barWidth||.5,i=t+(e.barGap||t/2);u%i!=0&&(u=Math.floor(u/i)*i)}const p=Math.floor(Math.abs(a)*d),m=Math.floor(p+u*d),g=m-p,v=(r,a)=>{this.renderSingleCanvas(t,e,i,n,Math.max(0,r),Math.min(a,c),s,o)},f=this.createDelay(),b=this.createDelay(),y=(t,e)=>{v(t,e),t>0&&f((()=>{y(t-g,e-g)}))},C=(t,e)=>{v(t,e),e<c&&b((()=>{C(t+g,e+g)}))};y(p,m),m<c&&C(m,m+g)}render(t){this.timeouts.forEach((t=>t.timeout&&clearTimeout(t.timeout))),this.timeouts=[],this.canvasWrapper.innerHTML="",this.progressWrapper.innerHTML="",this.wrapper.style.width="";const e=window.devicePixelRatio||1,i=this.scrollContainer.clientWidth,s=Math.ceil(t.duration*(this.options.minPxPerSec||0));this.isScrolling=s>i;const n=this.options.fillParent&&!this.isScrolling,r=(n?i:s)*e;if(this.wrapper.style.width=n?"100%":`${s}px`,this.scrollContainer.style.overflowX=this.isScrolling?"auto":"hidden",this.scrollContainer.classList.toggle("noScrollbar",!!this.options.hideScrollbar),this.cursor.style.backgroundColor=`${this.options.cursorColor||this.options.progressColor}`,this.cursor.style.width=`${this.options.cursorWidth}px`,this.options.splitChannels)for(let e=0;e<t.numberOfChannels;e++){const i=Object.assign(Object.assign({},this.options),this.options.splitChannels[e]);this.renderWaveform([t.getChannelData(e)],i,r)}else{const e=[t.getChannelData(0)];t.numberOfChannels>1&&e.push(t.getChannelData(1)),this.renderWaveform(e,this.options,r)}this.audioData=t,this.emit("render")}reRender(){if(!this.audioData)return;const t=this.progressWrapper.clientWidth;this.render(this.audioData);const e=this.progressWrapper.clientWidth;this.scrollContainer.scrollLeft+=e-t}zoom(t){this.options.minPxPerSec=t,this.reRender()}scrollIntoView(t,e=!1){const{clientWidth:i,scrollLeft:s,scrollWidth:n}=this.scrollContainer,r=n*t,o=i/2;if(r>s+(e&&this.options.autoCenter&&!this.isDragging?o:i)||r<s)if(this.options.autoCenter&&!this.isDragging){const t=o/20;r-(s+o)>=t&&r<s+i?this.scrollContainer.scrollLeft+=t:this.scrollContainer.scrollLeft=r-o}else if(this.isDragging){const t=10;this.scrollContainer.scrollLeft=r<s?r-t:r-i+t}else this.scrollContainer.scrollLeft=r;{const{scrollLeft:t}=this.scrollContainer,e=t/n,s=(t+i)/n;this.emit("scroll",e,s)}}renderProgress(t,e){isNaN(t)||(this.progressWrapper.style.width=100*t+"%",this.cursor.style.left=100*t+"%",this.cursor.style.marginLeft=100===Math.round(100*t)?`-${this.options.cursorWidth}px`:"",this.isScrolling&&this.options.autoScroll&&this.scrollIntoView(t,e))}}r.MAX_CANVAS_WIDTH=4e3;class o extends s{constructor(){super(...arguments),this.unsubscribe=()=>{}}start(){this.unsubscribe=this.on("tick",(()=>{requestAnimationFrame((()=>{this.emit("tick")}))})),this.emit("tick")}stop(){this.unsubscribe()}destroy(){this.unsubscribe()}}const a={waveColor:"#999",progressColor:"#555",cursorWidth:1,minPxPerSec:0,fillParent:!0,interact:!0,autoScroll:!0,autoCenter:!0,sampleRate:8e3};class h extends n{static create(t){return new h(t)}constructor(t){var e,i;super({media:t.media,autoplay:t.autoplay,playbackRate:t.audioRate}),this.plugins=[],this.decodedData=null,this.duration=null,this.subscriptions=[],this.options=Object.assign({},a,t),this.timer=new o,this.renderer=new r(this.options),this.initPlayerEvents(),this.initRendererEvents(),this.initTimerEvents(),this.initPlugins();const s=this.options.url||(null===(e=this.options.media)||void 0===e?void 0:e.currentSrc)||(null===(i=this.options.media)||void 0===i?void 0:i.src);s&&this.load(s,this.options.peaks,this.options.duration)}setOptions(t){this.options=Object.assign({},this.options,t),this.renderer.setOptions(this.options),t.audioRate&&this.setPlaybackRate(t.audioRate)}initTimerEvents(){this.subscriptions.push(this.timer.on("tick",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),!0),this.emit("timeupdate",t),this.emit("audioprocess",t)})))}initPlayerEvents(){this.subscriptions.push(this.onMediaEvent("timeupdate",(()=>{const t=this.getCurrentTime();this.renderer.renderProgress(t/this.getDuration(),this.isPlaying()),this.emit("timeupdate",t)})),this.onMediaEvent("play",(()=>{this.emit("play"),this.timer.start()})),this.onMediaEvent("pause",(()=>{this.emit("pause"),this.timer.stop()})),this.onMediaEvent("ended",(()=>{this.emit("finish")})),this.onMediaEvent("seeking",(()=>{this.emit("seeking",this.getCurrentTime())})))}initRendererEvents(){this.subscriptions.push(this.renderer.on("click",(t=>{this.options.interact&&(this.seekTo(t),this.emit("interaction",this.getCurrentTime()),this.emit("click",t))})),this.renderer.on("scroll",((t,e)=>{const i=this.getDuration();this.emit("scroll",t*i,e*i)})),this.renderer.on("render",(()=>{this.emit("redraw")})));{let t;this.subscriptions.push(this.renderer.on("drag",(e=>{this.options.interact&&(this.renderer.renderProgress(e),clearTimeout(t),t=setTimeout((()=>{this.seekTo(e)}),this.isPlaying()?0:200),this.emit("interaction",e*this.getDuration()),this.emit("drag",e))})))}}initPlugins(){var t;(null===(t=this.options.plugins)||void 0===t?void 0:t.length)&&this.options.plugins.forEach((t=>{this.registerPlugin(t)}))}registerPlugin(t){return t.init(this),this.plugins.push(t),this.subscriptions.push(t.once("destroy",(()=>{this.plugins=this.plugins.filter((e=>e!==t))}))),t}getWrapper(){return this.renderer.getWrapper()}getScroll(){return this.renderer.getScroll()}getActivePlugins(){return this.plugins}load(s,n,r){return t(this,void 0,void 0,(function*(){this.isPlaying()&&this.pause(),this.decodedData=null,this.duration=null,this.emit("load",s);const t=n?void 0:yield i.fetchBlob(s,this.options.fetchParams);if(this.setSrc(s,t),this.duration=r||this.getDuration()||(yield new Promise((t=>{this.onceMediaEvent("loadedmetadata",(()=>t(this.getDuration())))})))||0,n)this.decodedData=e.createBuffer(n,this.duration);else if(t){const i=yield t.arrayBuffer();this.decodedData=yield e.decode(i,this.options.sampleRate),0!==this.duration&&this.duration!==1/0||(this.duration=this.decodedData.duration)}this.emit("decode",this.duration),this.decodedData&&this.renderer.render(this.decodedData),this.emit("ready",this.duration)}))}zoom(t){if(!this.decodedData)throw new Error("No audio loaded");this.renderer.zoom(t),this.emit("zoom",t)}getDecodedData(){return this.decodedData}getDuration(){return null!==this.duration?this.duration:super.getDuration()}toggleInteraction(t){this.options.interact=t}seekTo(t){const e=this.getDuration()*t;this.setTime(e)}playPause(){return t(this,void 0,void 0,(function*(){return this.isPlaying()?this.pause():this.play()}))}stop(){this.pause(),this.setTime(0)}skip(t){this.setTime(this.getCurrentTime()+t)}empty(){this.load("",[[0]],.001)}destroy(){this.emit("destroy"),this.plugins.forEach((t=>t.destroy())),this.subscriptions.forEach((t=>t())),this.timer.destroy(),this.renderer.destroy(),super.destroy()}}return h}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wavesurfer.js",
|
|
3
|
-
"version": "7.0.0-beta.
|
|
3
|
+
"version": "7.0.0-beta.16",
|
|
4
4
|
"license": "BSD-3-Clause",
|
|
5
5
|
"author": "katspaugh",
|
|
6
6
|
"description": "Navigable audio waveform player",
|
|
@@ -21,20 +21,20 @@
|
|
|
21
21
|
"files": [
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
|
-
"main": "./dist/wavesurfer.js",
|
|
25
|
-
"module": "./dist/wavesurfer.js",
|
|
24
|
+
"main": "./dist/wavesurfer.esm.js",
|
|
25
|
+
"module": "./dist/wavesurfer.esm.js",
|
|
26
|
+
"browser": "./dist/wavesurfer.esm.js",
|
|
26
27
|
"types": "./dist/wavesurfer.d.ts",
|
|
27
|
-
"browser": "./dist/wavesurfer.js",
|
|
28
28
|
"exports": {
|
|
29
29
|
".": {
|
|
30
|
-
"import": "./dist/wavesurfer.js",
|
|
30
|
+
"import": "./dist/wavesurfer.esm.js",
|
|
31
31
|
"types": "./dist/wavesurfer.d.ts",
|
|
32
|
-
"require": "./dist/wavesurfer.
|
|
32
|
+
"require": "./dist/wavesurfer.cjs"
|
|
33
33
|
},
|
|
34
34
|
"./dist/plugins/*.js": {
|
|
35
|
-
"import": "./dist/plugins/*.js",
|
|
35
|
+
"import": "./dist/plugins/*.esm.js",
|
|
36
36
|
"types": "./dist/plugins/*.d.ts",
|
|
37
|
-
"require": "./dist/plugins/*.
|
|
37
|
+
"require": "./dist/plugins/*.cjs"
|
|
38
38
|
},
|
|
39
39
|
"./dist/*": {
|
|
40
40
|
"import": "./dist/*"
|
|
@@ -42,9 +42,7 @@
|
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build:dev": "tsc -w --target ESNext",
|
|
45
|
-
"build
|
|
46
|
-
"build:umd:plugins": "webpack --config webpack.config.plugins.js",
|
|
47
|
-
"build": "rm -rf dist && tsc && npm run build:umd && npm run build:umd:plugins",
|
|
45
|
+
"build": "rm -rf dist && tsc && rollup -c",
|
|
48
46
|
"deploy": "yarn build && yarn docs",
|
|
49
47
|
"prepublishOnly": "npm run build",
|
|
50
48
|
"docs": "typedoc --titleLink '/' src/wavesurfer.ts src/plugins/*.ts --out docs",
|
|
@@ -58,6 +56,8 @@
|
|
|
58
56
|
"start": "npm run build:dev & npm run serve"
|
|
59
57
|
},
|
|
60
58
|
"devDependencies": {
|
|
59
|
+
"@rollup/plugin-terser": "^0.4.3",
|
|
60
|
+
"@rollup/plugin-typescript": "^11.1.2",
|
|
61
61
|
"@typescript-eslint/eslint-plugin": "^5.57.0",
|
|
62
62
|
"@typescript-eslint/parser": "^5.57.0",
|
|
63
63
|
"cypress": "^12.9.0",
|
|
@@ -66,10 +66,9 @@
|
|
|
66
66
|
"eslint-config-prettier": "^8.8.0",
|
|
67
67
|
"eslint-plugin-prettier": "^4.2.1",
|
|
68
68
|
"prettier": "^2.8.7",
|
|
69
|
+
"rollup": "^3.26.2",
|
|
69
70
|
"ts-loader": "^9.4.2",
|
|
70
71
|
"typedoc": "^0.24.6",
|
|
71
|
-
"typescript": "^5.0.4"
|
|
72
|
-
"webpack": "^5.77.0",
|
|
73
|
-
"webpack-cli": "^5.0.1"
|
|
72
|
+
"typescript": "^5.0.4"
|
|
74
73
|
}
|
|
75
74
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Envelope=e():t.Envelope=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,i)=>{for(var n in i)t.o(i,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:i[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>a});const i=class{constructor(){this.listeners={}}on(t,e){return this.listeners[t]||(this.listeners[t]=new Set),this.listeners[t].add(e),()=>this.un(t,e)}once(t,e){const i=this.on(t,e),n=this.on(t,(()=>{i(),n()}));return i}un(t,e){this.listeners[t]&&(e?this.listeners[t].delete(e):delete this.listeners[t])}unAll(){this.listeners={}}emit(t,...e){this.listeners[t]&&this.listeners[t].forEach((t=>t(...e)))}},n=class extends i{constructor(t){super(),this.subscriptions=[],this.options=t}onInit(){}init(t){this.wavesurfer=t,this.onInit()}destroy(){this.emit("destroy"),this.subscriptions.forEach((t=>t()))}},s={fadeInStart:0,fadeOutEnd:0,fadeInEnd:0,fadeOutStart:0,lineWidth:4,lineColor:"rgba(0, 0, 255, 0.5)",dragPointSize:10,dragPointFill:"rgba(255, 255, 255, 0.8)",dragPointStroke:"rgba(255, 255, 255, 0.8)"};class o extends i{constructor(t,e){super(),this.top=0,this.padding=t.dragPointSize/2+1;const i=document.createElementNS("http://www.w3.org/2000/svg","svg");i.setAttribute("width","100%"),i.setAttribute("height","100%"),i.setAttribute("viewBox","0 0 0 0"),i.setAttribute("preserveAspectRatio","none"),i.setAttribute("style","position: absolute; left: 0; top: 0; z-index: 4; pointer-events: none;"),i.setAttribute("part","envelope"),this.svg=i;const n=document.createElementNS("http://www.w3.org/2000/svg","polyline");n.setAttribute("points","0,0 0,0 0,0 0,0"),n.setAttribute("stroke",t.lineColor),n.setAttribute("stroke-width",t.lineWidth),n.setAttribute("fill","none"),n.setAttribute("style","pointer-events: none;"),n.setAttribute("part","polyline"),i.appendChild(n);const s=document.createElementNS("http://www.w3.org/2000/svg","line");s.setAttribute("stroke","transparent"),s.setAttribute("stroke-width",(3*t.lineWidth).toString()),s.setAttribute("style","cursor: ns-resize; pointer-events: all;"),s.setAttribute("part","line"),i.appendChild(s),[0,1].forEach((()=>{const e=document.createElementNS("http://www.w3.org/2000/svg","circle");e.setAttribute("r",(t.dragPointSize/2).toString()),e.setAttribute("fill",t.dragPointFill),e.setAttribute("stroke",t.dragPointStroke||t.dragPointFill),e.setAttribute("stroke-width","2"),e.setAttribute("style","cursor: ew-resize; pointer-events: all;"),e.setAttribute("part","circle"),i.appendChild(e)})),e.appendChild(i);{const t=t=>{const e=this.top+t,{height:n}=i.viewBox.baseVal;if(e<-.5||e>n)return;const s=Math.min(1,Math.max(0,(n-e)/n));this.emit("line-move",s)},e=(t,e)=>{const s=n.points.getItem(t).x+e,{width:o}=i.viewBox.baseVal;this.emit("point-move",t,s/o)};this.makeDraggable(s,((e,i)=>t(i)));const o=this.svg.querySelectorAll("circle");Array.from(o).forEach(((t,i)=>{this.makeDraggable(t,(t=>e(i+1,t)))}))}}makeDraggable(t,e){!function(t,e,i,n,s=5){let o=()=>{};if(!t)return o;t.addEventListener("pointerdown",(r=>{r.preventDefault(),r.stopPropagation();let a=r.clientX,d=r.clientY,u=!1;const l=n=>{n.preventDefault(),n.stopPropagation();const o=n.clientX,r=n.clientY;if(u||Math.abs(o-a)>=s||Math.abs(r-d)>=s){const{left:n,top:s}=t.getBoundingClientRect();u||(u=!0,null==i||i(a-n,d-s)),e(o-a,r-d,o-n,r-s),a=o,d=r}},h=t=>{u&&(t.preventDefault(),t.stopPropagation())},p=()=>{u&&(null==n||n()),o()},c=t=>t.preventDefault(),g={passive:!1};document.addEventListener("touchmove",c,g),document.addEventListener("pointermove",l),document.addEventListener("pointerup",p),document.addEventListener("pointerleave",p),document.addEventListener("click",h,!0),o=()=>{document.removeEventListener("touchmove",c,g),document.removeEventListener("pointermove",l),document.removeEventListener("pointerup",p),document.removeEventListener("pointerleave",p),setTimeout((()=>{document.removeEventListener("click",h,!0)}),10)}}))}(t,e)}update({x1:t,x2:e,x3:i,x4:n,y:s}){const o=this.svg.clientWidth,r=this.svg.clientHeight;this.top=r-s*r;const a=Math.max(this.padding,Math.min(this.top,r-this.padding));this.svg.setAttribute("viewBox",`0 0 ${o} ${r}`);const d=this.svg.querySelector("polyline"),{points:u}=d;u.getItem(0).x=t*o,u.getItem(0).y=r,u.getItem(1).x=e*o,u.getItem(1).y=a,u.getItem(2).x=i*o,u.getItem(2).y=a,u.getItem(3).x=n*o,u.getItem(3).y=r;const l=this.svg.querySelector("line");l.setAttribute("x1",u.getItem(1).x.toString()),l.setAttribute("x2",u.getItem(2).x.toString()),l.setAttribute("y1",a.toString()),l.setAttribute("y2",a.toString());const h=this.svg.querySelectorAll("circle");Array.from(h).forEach(((t,e)=>{const i=u.getItem(e+1);t.setAttribute("cx",i.x.toString()),t.setAttribute("cy",i.y.toString())}))}destroy(){this.svg.remove()}}class r extends n{constructor(t){var e;super(t),this.polyline=null,this.audioContext=null,this.gainNode=null,this.volume=1,this.isFadingIn=!1,this.isFadingOut=!1,this.naturalVolumeExponent=1.5,this.options=Object.assign({},s,t),this.options.lineColor=this.options.lineColor||s.lineColor,this.options.dragPointFill=this.options.dragPointFill||s.dragPointFill,this.options.dragPointStroke=this.options.dragPointStroke||s.dragPointStroke,this.volume=null!==(e=this.options.volume)&&void 0!==e?e:1}static create(t){return new r(t)}destroy(){var t;null===(t=this.polyline)||void 0===t||t.destroy(),super.destroy()}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");this.initWebAudio(),this.initSvg(),this.initFadeEffects(),this.subscriptions.push(this.wavesurfer.on("redraw",(()=>{var t;const e=null===(t=this.wavesurfer)||void 0===t?void 0:t.getDuration();e&&(this.options.fadeInStart=this.options.fadeInStart||0,this.options.fadeOutEnd=this.options.fadeOutEnd||e,this.options.fadeInEnd=this.options.fadeInEnd||this.options.fadeInStart,this.options.fadeOutStart=this.options.fadeOutStart||this.options.fadeOutEnd,this.renderPolyline())})))}initSvg(){if(!this.wavesurfer)return;const t=this.wavesurfer.getWrapper();this.polyline=new o(this.options,t),this.subscriptions.push(this.polyline.on("line-move",(t=>{this.setVolume(this.naturalVolume(t))})),this.polyline.on("point-move",((t,e)=>{var i;const n=e*((null===(i=this.wavesurfer)||void 0===i?void 0:i.getDuration())||0);if(1===t){if(n<this.options.fadeInStart||n>this.options.fadeOutStart)return;this.options.fadeInEnd=n,this.emit("fade-in-change",n)}else if(2===t){if(n>this.options.fadeOutEnd||n<this.options.fadeInEnd)return;this.options.fadeOutStart=n,this.emit("fade-out-change",n)}this.renderPolyline()})))}renderPolyline(){if(!this.polyline||!this.wavesurfer)return;const t=this.wavesurfer.getDuration();t&&this.polyline.update({x1:this.options.fadeInStart/t,x2:this.options.fadeInEnd/t,x3:this.options.fadeOutStart/t,x4:this.options.fadeOutEnd/t,y:this.invertNaturalVolume(this.volume)})}initWebAudio(){var t,e;const i=null===(t=this.wavesurfer)||void 0===t?void 0:t.getMediaElement();if(!i)return null;this.volume=null!==(e=this.options.volume)&&void 0!==e?e:i.volume;const n=new window.AudioContext;this.gainNode=n.createGain(),this.setGainValue(),n.createMediaElementSource(i).connect(this.gainNode),this.gainNode.connect(n.destination),this.audioContext=n}invertNaturalVolume(t){return Math.pow((t-1e-4)/.9999,1/this.naturalVolumeExponent)}naturalVolume(t){return 1e-4+.9999*Math.pow(t,this.naturalVolumeExponent)}setGainValue(){this.gainNode&&(this.gainNode.gain.value=this.volume)}initFadeEffects(){if(!this.audioContext||!this.wavesurfer)return;const t=this.wavesurfer.on("timeupdate",(t=>{var e;if(!this.audioContext||!this.gainNode)return;if(!(null===(e=this.wavesurfer)||void 0===e?void 0:e.isPlaying()))return;if("suspended"===this.audioContext.state&&this.audioContext.resume(),!this.isFadingIn&&t>=this.options.fadeInStart&&t<=this.options.fadeInEnd)return this.isFadingIn=!0,this.gainNode.gain.setValueAtTime(0,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(this.volume,this.audioContext.currentTime+(this.options.fadeInEnd-t));if(!this.isFadingOut&&t>=this.options.fadeOutStart&&t<=this.options.fadeOutEnd)return this.isFadingOut=!0,this.gainNode.gain.setValueAtTime(this.volume,this.audioContext.currentTime),void this.gainNode.gain.linearRampToValueAtTime(0,this.audioContext.currentTime+(this.options.fadeOutEnd-t));let i=!1;this.isFadingIn&&(t<this.options.fadeInStart||t>this.options.fadeInEnd)&&(this.isFadingIn=!1,i=!0),this.isFadingOut&&(t<this.options.fadeOutStart||t>=this.options.fadeOutEnd)&&(this.isFadingOut=!1,i=!0),i&&(this.gainNode.gain.cancelScheduledValues(this.audioContext.currentTime),this.setGainValue())}));this.subscriptions.push(t)}getCurrentVolume(){return this.gainNode?this.gainNode.gain.value:this.volume}setStartTime(t,e=!1){if(e){const e=this.options.fadeInEnd-this.options.fadeInStart;this.options.fadeInEnd=t+e}this.options.fadeInStart=t,this.renderPolyline()}setEndTime(t,e=!1){if(e){const e=this.options.fadeOutEnd-this.options.fadeOutStart;this.options.fadeOutStart=t-e}this.options.fadeOutEnd=t,this.renderPolyline()}setFadeInEnd(t){this.options.fadeInEnd=t,this.renderPolyline()}setFadeOutStart(t){this.options.fadeOutStart=t,this.renderPolyline()}setVolume(t){this.volume=t,this.setGainValue(),this.renderPolyline(),this.emit("volume-change",t)}}const a=r;return e.default})()));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Hover=e():t.Hover=e()}("undefined"!=typeof WaveSurfer?WaveSurfer:this,(()=>(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e)},e={};t.d(e,{default:()=>n});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 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)))}},i=class extends s{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()))}},r={lineWidth:1,labelSize:11};class o extends i{constructor(t){super(t||{}),this.unsubscribe=()=>{},this.onPointerMove=t=>{if(!this.wavesurfer)return;const e=this.wavesurfer.getWrapper().clientWidth,{offsetX:s}=t,i=Math.min(1,Math.max(0,s/e)),r=Math.min(e-this.options.lineWidth-1,s);this.wrapper.style.transform=`translateX(${r}px)`,this.wrapper.style.opacity="1";const o=this.wavesurfer.getDuration()||0;this.label.textContent=this.formatTime(o*i);const n=this.label.offsetWidth;this.label.style.transform=r+n>e?`translateX(-${n+this.options.lineWidth}px)`:"",this.emit("hover",i)},this.onPointerLeave=()=>{this.wrapper.style.opacity="0"},this.options=Object.assign({},r,t),this.wrapper=document.createElement("div"),this.label=document.createElement("span"),this.wrapper.appendChild(this.label)}static create(t){return new o(t)}addUnits(t){return`${t}${"number"==typeof t?"px":""}`}onInit(){if(!this.wavesurfer)throw Error("WaveSurfer is not initialized");const t=this.wavesurfer.options,e=this.options.lineColor||t.cursorColor||t.progressColor;this.wrapper.setAttribute("part","hover"),Object.assign(this.wrapper.style,{position:"absolute",zIndex:10,left:0,top:0,height:"100%",pointerEvents:"none",borderLeft:`${this.addUnits(this.options.lineWidth)} solid ${e}`,transition:"opacity .1s ease-in"}),this.label.setAttribute("part","hover-label"),Object.assign(this.label.style,{display:"block",backgroundColor:this.options.labelBackground,color:this.options.labelColor,fontSize:`${this.addUnits(this.options.labelSize)}`,transition:"transform .1s ease-in",padding:"2px 3px"});const s=this.wavesurfer.getWrapper();s.appendChild(this.wrapper),s.addEventListener("pointermove",this.onPointerMove),s.addEventListener("pointerleave",this.onPointerLeave),this.unsubscribe=()=>{s.removeEventListener("pointermove",this.onPointerMove),s.removeEventListener("pointerleave",this.onPointerLeave)}}formatTime(t){return`${Math.floor(t/60)}:${("0"+Math.round(t)%60).slice(-2)}`}destroy(){super.destroy(),this.unsubscribe(),this.wrapper.remove()}}const n=o;return e.default})()));
|