wavesurfer.js 7.0.0-alpha.22 → 7.0.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/base-plugin.d.ts +6 -5
- package/dist/base-plugin.js +4 -2
- package/dist/index.d.ts +18 -35
- package/dist/index.js +48 -102
- package/dist/player.d.ts +26 -9
- package/dist/player.js +38 -18
- package/dist/plugins/envelope.d.ts +4 -2
- package/dist/plugins/envelope.js +21 -11
- package/dist/plugins/minimap.d.ts +6 -4
- package/dist/plugins/minimap.js +18 -7
- package/dist/plugins/multitrack.d.ts +1 -2
- package/dist/plugins/multitrack.js +15 -17
- package/dist/plugins/regions.d.ts +5 -2
- package/dist/plugins/regions.js +26 -10
- package/dist/plugins/timeline.d.ts +4 -2
- package/dist/plugins/timeline.js +13 -4
- package/dist/renderer.d.ts +3 -1
- package/dist/renderer.js +26 -13
- package/dist/wavesurfer.Minimap.min.js +1 -1
- package/dist/wavesurfer.Multitrack.min.js +1 -1
- package/dist/wavesurfer.Regions.min.js +1 -1
- package/dist/wavesurfer.Timeline.min.js +1 -1
- package/dist/wavesurfer.d.ts +121 -0
- package/dist/wavesurfer.js +185 -0
- package/dist/wavesurfer.min.js +1 -1
- package/package.json +3 -3
package/dist/base-plugin.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import EventEmitter, { type GeneralEventTypes } from './event-emitter.js';
|
|
2
|
-
import WaveSurfer, { type WaveSurferPluginParams } from './
|
|
2
|
+
import WaveSurfer, { type WaveSurferPluginParams } from './wavesurfer.js';
|
|
3
3
|
export declare class BasePlugin<EventTypes extends GeneralEventTypes, Options> extends EventEmitter<EventTypes> {
|
|
4
|
-
protected wavesurfer
|
|
5
|
-
protected container
|
|
6
|
-
protected wrapper
|
|
4
|
+
protected wavesurfer?: WaveSurfer;
|
|
5
|
+
protected container?: HTMLElement;
|
|
6
|
+
protected wrapper?: HTMLElement;
|
|
7
7
|
protected subscriptions: (() => void)[];
|
|
8
8
|
protected options: Options;
|
|
9
|
-
constructor(
|
|
9
|
+
constructor(options: Options);
|
|
10
|
+
init(params: WaveSurferPluginParams): void;
|
|
10
11
|
destroy(): void;
|
|
11
12
|
}
|
|
12
13
|
export default BasePlugin;
|
package/dist/base-plugin.js
CHANGED
|
@@ -5,12 +5,14 @@ export class BasePlugin extends EventEmitter {
|
|
|
5
5
|
wrapper;
|
|
6
6
|
subscriptions = [];
|
|
7
7
|
options;
|
|
8
|
-
constructor(
|
|
8
|
+
constructor(options) {
|
|
9
9
|
super();
|
|
10
|
+
this.options = options;
|
|
11
|
+
}
|
|
12
|
+
init(params) {
|
|
10
13
|
this.wavesurfer = params.wavesurfer;
|
|
11
14
|
this.container = params.container;
|
|
12
15
|
this.wrapper = params.wrapper;
|
|
13
|
-
this.options = options;
|
|
14
16
|
}
|
|
15
17
|
destroy() {
|
|
16
18
|
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import Player from './player.js';
|
|
2
|
+
import { type GeneralEventTypes } from './event-emitter.js';
|
|
2
3
|
import BasePlugin from './base-plugin.js';
|
|
3
4
|
export type WaveSurferOptions = {
|
|
4
5
|
/** HTML element or CSS selector */
|
|
@@ -34,9 +35,15 @@ export type WaveSurferOptions = {
|
|
|
34
35
|
/** Play the audio on load */
|
|
35
36
|
autoplay?: boolean;
|
|
36
37
|
/** Is the waveform clickable? */
|
|
37
|
-
|
|
38
|
+
interact?: boolean;
|
|
38
39
|
/** Hide scrollbar **/
|
|
39
|
-
|
|
40
|
+
hideScrollbar?: boolean;
|
|
41
|
+
/** Audio rate */
|
|
42
|
+
audioRate?: number;
|
|
43
|
+
/** Keep scroll to the center of the waveform during playback */
|
|
44
|
+
autoCenter?: boolean;
|
|
45
|
+
/** Initialize plugins */
|
|
46
|
+
plugins: BasePlugin<GeneralEventTypes, unknown>[];
|
|
40
47
|
};
|
|
41
48
|
declare const defaultOptions: {
|
|
42
49
|
height: number;
|
|
@@ -45,7 +52,8 @@ declare const defaultOptions: {
|
|
|
45
52
|
cursorWidth: number;
|
|
46
53
|
minPxPerSec: number;
|
|
47
54
|
fillParent: boolean;
|
|
48
|
-
|
|
55
|
+
interact: boolean;
|
|
56
|
+
autoCenter: boolean;
|
|
49
57
|
};
|
|
50
58
|
export type WaveSurferEvents = {
|
|
51
59
|
decode: {
|
|
@@ -78,16 +86,15 @@ export type WaveSurferPluginParams = {
|
|
|
78
86
|
container: HTMLElement;
|
|
79
87
|
wrapper: HTMLElement;
|
|
80
88
|
};
|
|
81
|
-
declare class WaveSurfer extends
|
|
89
|
+
declare class WaveSurfer extends Player<WaveSurferEvents> {
|
|
82
90
|
options: WaveSurferOptions & typeof defaultOptions;
|
|
83
91
|
private fetcher;
|
|
84
92
|
private decoder;
|
|
85
93
|
private renderer;
|
|
86
|
-
private player;
|
|
87
94
|
private timer;
|
|
88
95
|
private plugins;
|
|
89
|
-
private subscriptions;
|
|
90
96
|
private decodedData;
|
|
97
|
+
private canPlay;
|
|
91
98
|
/** Create a new WaveSurfer instance */
|
|
92
99
|
static create(options: WaveSurferOptions): WaveSurfer;
|
|
93
100
|
/** Create a new WaveSurfer instance */
|
|
@@ -96,40 +103,16 @@ declare class WaveSurfer extends EventEmitter<WaveSurferEvents> {
|
|
|
96
103
|
private initRendererEvents;
|
|
97
104
|
private initTimerEvents;
|
|
98
105
|
private initReadyEvent;
|
|
106
|
+
private initPlugins;
|
|
107
|
+
/** Register a wavesurfer.js plugin */
|
|
108
|
+
registerPlugin(plugin: BasePlugin<GeneralEventTypes, unknown>): void;
|
|
99
109
|
/** Load an audio file by URL, with optional pre-decoded audio data */
|
|
100
110
|
load(url: string, channelData?: Float32Array[], duration?: number): Promise<void>;
|
|
101
111
|
/** Zoom in or out */
|
|
102
112
|
zoom(minPxPerSec: number): void;
|
|
103
|
-
/** Start playing the audio */
|
|
104
|
-
play(): void;
|
|
105
|
-
/** Pause the audio */
|
|
106
|
-
pause(): void;
|
|
107
|
-
/** Skip to a time position in seconds */
|
|
108
|
-
seekTo(time: number): void;
|
|
109
|
-
/** Check if the audio is playing */
|
|
110
|
-
isPlaying(): boolean;
|
|
111
|
-
/** Get the duration of the audio in seconds */
|
|
112
|
-
getDuration(): number;
|
|
113
|
-
/** Get the current audio position in seconds */
|
|
114
|
-
getCurrentTime(): number;
|
|
115
|
-
/** Get the audio volume */
|
|
116
|
-
getVolume(): number;
|
|
117
|
-
/** Set the audio volume */
|
|
118
|
-
setVolume(volume: number): void;
|
|
119
|
-
/** Get the audio muted state */
|
|
120
|
-
getMuted(): boolean;
|
|
121
|
-
/** Mute or unmute the audio */
|
|
122
|
-
setMuted(muted: boolean): void;
|
|
123
|
-
/** Get playback rate */
|
|
124
|
-
getPlaybackRate(): number;
|
|
125
|
-
/** Set playback rate, with an optional parameter to NOT preserve the pitch if false */
|
|
126
|
-
setPlaybackRate(rate: number, preservePitch?: boolean): void;
|
|
127
|
-
/** Register and initialize a plugin */
|
|
128
|
-
registerPlugin<T extends BasePlugin<GeneralEventTypes, Options>, Options>(CustomPlugin: new (params: WaveSurferPluginParams, options: Options) => T, options: Options): T;
|
|
129
113
|
/** Get the decoded audio data */
|
|
130
114
|
getDecodedData(): AudioBuffer | null;
|
|
131
|
-
|
|
132
|
-
getMediaElement(): HTMLMediaElement | null;
|
|
115
|
+
getDuration(): number;
|
|
133
116
|
/** Toggle if the waveform should react to clicks */
|
|
134
117
|
toggleInteractive(isInteractive: boolean): void;
|
|
135
118
|
/** Unmount wavesurfer */
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import Fetcher from './fetcher.js';
|
|
|
2
2
|
import Decoder from './decoder.js';
|
|
3
3
|
import Renderer from './renderer.js';
|
|
4
4
|
import Player from './player.js';
|
|
5
|
-
import EventEmitter from './event-emitter.js';
|
|
6
5
|
import Timer from './timer.js';
|
|
7
6
|
const defaultOptions = {
|
|
8
7
|
height: 128,
|
|
@@ -11,33 +10,33 @@ const defaultOptions = {
|
|
|
11
10
|
cursorWidth: 1,
|
|
12
11
|
minPxPerSec: 0,
|
|
13
12
|
fillParent: true,
|
|
14
|
-
|
|
13
|
+
interact: true,
|
|
14
|
+
autoCenter: true,
|
|
15
15
|
};
|
|
16
|
-
class WaveSurfer extends
|
|
16
|
+
class WaveSurfer extends Player {
|
|
17
17
|
options;
|
|
18
18
|
fetcher;
|
|
19
19
|
decoder;
|
|
20
20
|
renderer;
|
|
21
|
-
player;
|
|
22
21
|
timer;
|
|
23
22
|
plugins = [];
|
|
24
|
-
subscriptions = [];
|
|
25
23
|
decodedData = null;
|
|
24
|
+
canPlay = false;
|
|
26
25
|
/** Create a new WaveSurfer instance */
|
|
27
26
|
static create(options) {
|
|
28
27
|
return new WaveSurfer(options);
|
|
29
28
|
}
|
|
30
29
|
/** Create a new WaveSurfer instance */
|
|
31
30
|
constructor(options) {
|
|
32
|
-
super(
|
|
31
|
+
super({
|
|
32
|
+
media: options.media,
|
|
33
|
+
autoplay: options.autoplay,
|
|
34
|
+
playbackRate: options.audioRate,
|
|
35
|
+
});
|
|
33
36
|
this.options = Object.assign({}, defaultOptions, options);
|
|
34
37
|
this.fetcher = new Fetcher();
|
|
35
38
|
this.decoder = new Decoder();
|
|
36
39
|
this.timer = new Timer();
|
|
37
|
-
this.player = new Player({
|
|
38
|
-
media: this.options.media,
|
|
39
|
-
autoplay: this.options.autoplay,
|
|
40
|
-
});
|
|
41
40
|
this.renderer = new Renderer({
|
|
42
41
|
container: this.options.container,
|
|
43
42
|
height: this.options.height,
|
|
@@ -50,38 +49,40 @@ class WaveSurfer extends EventEmitter {
|
|
|
50
49
|
barWidth: this.options.barWidth,
|
|
51
50
|
barGap: this.options.barGap,
|
|
52
51
|
barRadius: this.options.barRadius,
|
|
53
|
-
|
|
52
|
+
hideScrollbar: this.options.hideScrollbar,
|
|
54
53
|
});
|
|
55
54
|
this.initPlayerEvents();
|
|
56
55
|
this.initRendererEvents();
|
|
57
56
|
this.initTimerEvents();
|
|
58
57
|
this.initReadyEvent();
|
|
58
|
+
this.initPlugins();
|
|
59
59
|
const url = this.options.url || this.options.media?.src;
|
|
60
60
|
if (url) {
|
|
61
61
|
this.load(url, this.options.peaks, this.options.duration);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
initPlayerEvents() {
|
|
65
|
-
this.subscriptions.push(this.
|
|
65
|
+
this.subscriptions.push(this.onMediaEvent('timeupdate', () => {
|
|
66
66
|
const currentTime = this.getCurrentTime();
|
|
67
|
-
this.renderer.renderProgress(currentTime / this.getDuration(), this.isPlaying());
|
|
67
|
+
this.renderer.renderProgress(currentTime / this.getDuration(), this.options.autoCenter && this.isPlaying());
|
|
68
68
|
this.emit('timeupdate', { currentTime });
|
|
69
|
-
}), this.
|
|
69
|
+
}), this.onMediaEvent('play', () => {
|
|
70
70
|
this.emit('play');
|
|
71
71
|
this.timer.start();
|
|
72
|
-
}), this.
|
|
72
|
+
}), this.onMediaEvent('pause', () => {
|
|
73
73
|
this.emit('pause');
|
|
74
74
|
this.timer.stop();
|
|
75
|
-
}), this.
|
|
75
|
+
}), this.onMediaEvent('canplay', () => {
|
|
76
|
+
this.canPlay = true;
|
|
76
77
|
this.emit('canplay', { duration: this.getDuration() });
|
|
77
|
-
}), this.
|
|
78
|
+
}), this.onMediaEvent('seeking', () => {
|
|
78
79
|
this.emit('seeking', { currentTime: this.getCurrentTime() });
|
|
79
80
|
}));
|
|
80
81
|
}
|
|
81
82
|
initRendererEvents() {
|
|
82
83
|
// Seek on click
|
|
83
84
|
this.subscriptions.push(this.renderer.on('click', ({ relativeX }) => {
|
|
84
|
-
if (this.options.
|
|
85
|
+
if (this.options.interact) {
|
|
85
86
|
const time = this.getDuration() * relativeX;
|
|
86
87
|
this.seekTo(time);
|
|
87
88
|
this.emit('seekClick', { currentTime: this.getCurrentTime() });
|
|
@@ -97,27 +98,37 @@ class WaveSurfer extends EventEmitter {
|
|
|
97
98
|
}));
|
|
98
99
|
}
|
|
99
100
|
initReadyEvent() {
|
|
100
|
-
let isDecoded = false;
|
|
101
|
-
let isPlayable = false;
|
|
102
101
|
const emitReady = () => {
|
|
103
|
-
if (
|
|
102
|
+
if (this.decodedData && this.canPlay) {
|
|
104
103
|
this.emit('ready', { duration: this.getDuration() });
|
|
105
104
|
}
|
|
106
105
|
};
|
|
107
|
-
this.subscriptions.push(this.on('decode',
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
this.subscriptions.push(this.on('decode', emitReady), this.on('canplay', emitReady));
|
|
107
|
+
}
|
|
108
|
+
initPlugins() {
|
|
109
|
+
if (!this.options.plugins?.length)
|
|
110
|
+
return;
|
|
111
|
+
this.options.plugins.forEach((plugin) => {
|
|
112
|
+
this.registerPlugin(plugin);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/** Register a wavesurfer.js plugin */
|
|
116
|
+
registerPlugin(plugin) {
|
|
117
|
+
plugin.init({
|
|
118
|
+
wavesurfer: this,
|
|
119
|
+
container: this.renderer.getContainer(),
|
|
120
|
+
wrapper: this.renderer.getWrapper(),
|
|
121
|
+
});
|
|
122
|
+
this.plugins.push(plugin);
|
|
123
|
+
plugin.once('destroy', () => {
|
|
124
|
+
this.plugins = this.plugins.filter((p) => p !== plugin);
|
|
125
|
+
});
|
|
117
126
|
}
|
|
118
127
|
/** Load an audio file by URL, with optional pre-decoded audio data */
|
|
119
128
|
async load(url, channelData, duration) {
|
|
120
|
-
this.
|
|
129
|
+
this.decodedData = null;
|
|
130
|
+
this.canPlay = false;
|
|
131
|
+
this.loadUrl(url);
|
|
121
132
|
// Fetch and decode the audio of no pre-computed audio data is provided
|
|
122
133
|
if (channelData == null) {
|
|
123
134
|
const audio = await this.fetcher.load(url);
|
|
@@ -128,9 +139,7 @@ class WaveSurfer extends EventEmitter {
|
|
|
128
139
|
if (!duration) {
|
|
129
140
|
duration =
|
|
130
141
|
(await new Promise((resolve) => {
|
|
131
|
-
this.
|
|
132
|
-
once: true,
|
|
133
|
-
});
|
|
142
|
+
this.onceMediaEvent('loadedmetadata', () => resolve(this.getDuration()));
|
|
134
143
|
})) || 0;
|
|
135
144
|
}
|
|
136
145
|
this.decodedData = {
|
|
@@ -151,88 +160,25 @@ class WaveSurfer extends EventEmitter {
|
|
|
151
160
|
this.renderer.zoom(this.decodedData, minPxPerSec);
|
|
152
161
|
this.emit('zoom', { minPxPerSec });
|
|
153
162
|
}
|
|
154
|
-
/** Start playing the audio */
|
|
155
|
-
play() {
|
|
156
|
-
this.player.play();
|
|
157
|
-
}
|
|
158
|
-
/** Pause the audio */
|
|
159
|
-
pause() {
|
|
160
|
-
this.player.pause();
|
|
161
|
-
}
|
|
162
|
-
/** Skip to a time position in seconds */
|
|
163
|
-
seekTo(time) {
|
|
164
|
-
this.player.seekTo(time);
|
|
165
|
-
}
|
|
166
|
-
/** Check if the audio is playing */
|
|
167
|
-
isPlaying() {
|
|
168
|
-
return this.player.isPlaying();
|
|
169
|
-
}
|
|
170
|
-
/** Get the duration of the audio in seconds */
|
|
171
|
-
getDuration() {
|
|
172
|
-
return this.player.getDuration() || this.decodedData?.duration || 0;
|
|
173
|
-
}
|
|
174
|
-
/** Get the current audio position in seconds */
|
|
175
|
-
getCurrentTime() {
|
|
176
|
-
return this.player.getCurrentTime();
|
|
177
|
-
}
|
|
178
|
-
/** Get the audio volume */
|
|
179
|
-
getVolume() {
|
|
180
|
-
return this.player.getVolume();
|
|
181
|
-
}
|
|
182
|
-
/** Set the audio volume */
|
|
183
|
-
setVolume(volume) {
|
|
184
|
-
this.player.setVolume(volume);
|
|
185
|
-
}
|
|
186
|
-
/** Get the audio muted state */
|
|
187
|
-
getMuted() {
|
|
188
|
-
return this.player.getMuted();
|
|
189
|
-
}
|
|
190
|
-
/** Mute or unmute the audio */
|
|
191
|
-
setMuted(muted) {
|
|
192
|
-
this.player.setMuted(muted);
|
|
193
|
-
}
|
|
194
|
-
/** Get playback rate */
|
|
195
|
-
getPlaybackRate() {
|
|
196
|
-
return this.player.getPlaybackRate();
|
|
197
|
-
}
|
|
198
|
-
/** Set playback rate, with an optional parameter to NOT preserve the pitch if false */
|
|
199
|
-
setPlaybackRate(rate, preservePitch) {
|
|
200
|
-
this.player.setPlaybackRate(rate, preservePitch);
|
|
201
|
-
}
|
|
202
|
-
/** Register and initialize a plugin */
|
|
203
|
-
registerPlugin(CustomPlugin, options) {
|
|
204
|
-
const plugin = new CustomPlugin({
|
|
205
|
-
wavesurfer: this,
|
|
206
|
-
container: this.renderer.getContainer(),
|
|
207
|
-
wrapper: this.renderer.getWrapper(),
|
|
208
|
-
}, options);
|
|
209
|
-
this.plugins.push(plugin);
|
|
210
|
-
plugin.once('destroy', () => {
|
|
211
|
-
this.plugins = this.plugins.filter((p) => p !== plugin);
|
|
212
|
-
});
|
|
213
|
-
return plugin;
|
|
214
|
-
}
|
|
215
163
|
/** Get the decoded audio data */
|
|
216
164
|
getDecodedData() {
|
|
217
165
|
return this.decodedData;
|
|
218
166
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return this.player.getMediaElement();
|
|
167
|
+
getDuration() {
|
|
168
|
+
return this.decodedData?.duration || this.getMediaElement()?.duration || 0;
|
|
222
169
|
}
|
|
223
170
|
/** Toggle if the waveform should react to clicks */
|
|
224
171
|
toggleInteractive(isInteractive) {
|
|
225
|
-
this.options.
|
|
172
|
+
this.options.interact = isInteractive;
|
|
226
173
|
}
|
|
227
174
|
/** Unmount wavesurfer */
|
|
228
175
|
destroy() {
|
|
229
176
|
this.emit('destroy');
|
|
230
|
-
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
231
177
|
this.plugins.forEach((plugin) => plugin.destroy());
|
|
232
178
|
this.timer.destroy();
|
|
233
|
-
this.player.destroy();
|
|
234
179
|
this.decoder.destroy();
|
|
235
180
|
this.renderer.destroy();
|
|
181
|
+
super.destroy();
|
|
236
182
|
}
|
|
237
183
|
}
|
|
238
184
|
export default WaveSurfer;
|
package/dist/player.d.ts
CHANGED
|
@@ -1,27 +1,44 @@
|
|
|
1
|
-
|
|
1
|
+
import EventEmitter, { type GeneralEventTypes } from './event-emitter.js';
|
|
2
|
+
type PlayerOptions = {
|
|
3
|
+
media?: HTMLMediaElement;
|
|
4
|
+
autoplay?: boolean;
|
|
5
|
+
playbackRate?: number;
|
|
6
|
+
};
|
|
7
|
+
declare class Player<T extends GeneralEventTypes> extends EventEmitter<T> {
|
|
2
8
|
protected media: HTMLMediaElement;
|
|
9
|
+
protected subscriptions: Array<() => void>;
|
|
3
10
|
private isExternalMedia;
|
|
4
11
|
private hasPlayedOnce;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
});
|
|
10
|
-
on(event: keyof HTMLMediaElementEventMap, callback: () => void, options?: AddEventListenerOptions): () => void;
|
|
12
|
+
constructor(options: PlayerOptions);
|
|
13
|
+
protected onMediaEvent(event: keyof HTMLMediaElementEventMap, callback: () => void, options?: AddEventListenerOptions): () => void;
|
|
14
|
+
protected onceMediaEvent(event: keyof HTMLMediaElementEventMap, callback: () => void): () => void;
|
|
15
|
+
protected loadUrl(src: string): void;
|
|
11
16
|
destroy(): void;
|
|
12
|
-
|
|
13
|
-
getCurrentTime(): number;
|
|
17
|
+
/** Start playing the audio */
|
|
14
18
|
play(): void;
|
|
19
|
+
/** Pause the audio */
|
|
15
20
|
pause(): void;
|
|
21
|
+
/** Check if the audio is playing */
|
|
16
22
|
isPlaying(): boolean;
|
|
23
|
+
/** Skip to a time position in seconds */
|
|
17
24
|
seekTo(time: number): void;
|
|
25
|
+
/** Get the duration of the audio in seconds */
|
|
18
26
|
getDuration(): number;
|
|
27
|
+
/** Get the current audio position in seconds */
|
|
28
|
+
getCurrentTime(): number;
|
|
29
|
+
/** Get the audio volume */
|
|
19
30
|
getVolume(): number;
|
|
31
|
+
/** Set the audio volume */
|
|
20
32
|
setVolume(volume: number): void;
|
|
33
|
+
/** Get the audio muted state */
|
|
21
34
|
getMuted(): boolean;
|
|
35
|
+
/** Mute or unmute the audio */
|
|
22
36
|
setMuted(muted: boolean): void;
|
|
37
|
+
/** Get the playback speed */
|
|
23
38
|
getPlaybackRate(): number;
|
|
39
|
+
/** Set the playback speed, pass an optional false to NOT preserve the pitch */
|
|
24
40
|
setPlaybackRate(rate: number, preservePitch?: boolean): void;
|
|
41
|
+
/** Get the HTML media element */
|
|
25
42
|
getMediaElement(): HTMLMediaElement;
|
|
26
43
|
}
|
|
27
44
|
export default Player;
|
package/dist/player.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
import EventEmitter from './event-emitter.js';
|
|
2
|
+
class Player extends EventEmitter {
|
|
2
3
|
media;
|
|
4
|
+
subscriptions = [];
|
|
3
5
|
isExternalMedia = false;
|
|
4
6
|
hasPlayedOnce = false;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
if (media) {
|
|
8
|
-
this.media = media;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
super();
|
|
9
|
+
if (options.media) {
|
|
10
|
+
this.media = options.media;
|
|
9
11
|
this.isExternalMedia = true;
|
|
10
12
|
}
|
|
11
13
|
else {
|
|
@@ -13,42 +15,48 @@ class Player {
|
|
|
13
15
|
}
|
|
14
16
|
this.subscriptions.push(
|
|
15
17
|
// Track the first play() call
|
|
16
|
-
this.
|
|
18
|
+
this.onceMediaEvent('play', () => {
|
|
17
19
|
this.hasPlayedOnce = true;
|
|
18
|
-
}
|
|
20
|
+
}));
|
|
19
21
|
// Autoplay
|
|
20
|
-
if (autoplay) {
|
|
22
|
+
if (options.autoplay) {
|
|
21
23
|
this.media.autoplay = true;
|
|
22
24
|
}
|
|
25
|
+
// Speed
|
|
26
|
+
if (options.playbackRate != null) {
|
|
27
|
+
this.media.playbackRate = options.playbackRate;
|
|
28
|
+
}
|
|
23
29
|
}
|
|
24
|
-
|
|
30
|
+
onMediaEvent(event, callback, options) {
|
|
25
31
|
this.media.addEventListener(event, callback, options);
|
|
26
32
|
return () => this.media.removeEventListener(event, callback);
|
|
27
33
|
}
|
|
34
|
+
onceMediaEvent(event, callback) {
|
|
35
|
+
return this.onMediaEvent(event, callback, { once: true });
|
|
36
|
+
}
|
|
37
|
+
loadUrl(src) {
|
|
38
|
+
this.media.src = src;
|
|
39
|
+
}
|
|
28
40
|
destroy() {
|
|
29
|
-
this.subscriptions.forEach((unsubscribe) => {
|
|
30
|
-
unsubscribe();
|
|
31
|
-
});
|
|
32
41
|
this.media.pause();
|
|
42
|
+
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
33
43
|
if (!this.isExternalMedia) {
|
|
34
44
|
this.media.remove();
|
|
35
45
|
}
|
|
36
46
|
}
|
|
37
|
-
|
|
38
|
-
this.media.src = src;
|
|
39
|
-
}
|
|
40
|
-
getCurrentTime() {
|
|
41
|
-
return this.media.currentTime;
|
|
42
|
-
}
|
|
47
|
+
/** Start playing the audio */
|
|
43
48
|
play() {
|
|
44
49
|
this.media.play();
|
|
45
50
|
}
|
|
51
|
+
/** Pause the audio */
|
|
46
52
|
pause() {
|
|
47
53
|
this.media.pause();
|
|
48
54
|
}
|
|
55
|
+
/** Check if the audio is playing */
|
|
49
56
|
isPlaying() {
|
|
50
57
|
return this.media.currentTime > 0 && !this.media.paused && !this.media.ended;
|
|
51
58
|
}
|
|
59
|
+
/** Skip to a time position in seconds */
|
|
52
60
|
seekTo(time) {
|
|
53
61
|
// iOS Safari requires a play() call before seeking
|
|
54
62
|
if (!this.hasPlayedOnce && navigator.userAgent.match(/(iPad|iPhone|iPod)/g)) {
|
|
@@ -58,24 +66,35 @@ class Player {
|
|
|
58
66
|
}
|
|
59
67
|
this.media.currentTime = time;
|
|
60
68
|
}
|
|
69
|
+
/** Get the duration of the audio in seconds */
|
|
61
70
|
getDuration() {
|
|
62
71
|
return this.media.duration;
|
|
63
72
|
}
|
|
73
|
+
/** Get the current audio position in seconds */
|
|
74
|
+
getCurrentTime() {
|
|
75
|
+
return this.media.currentTime;
|
|
76
|
+
}
|
|
77
|
+
/** Get the audio volume */
|
|
64
78
|
getVolume() {
|
|
65
79
|
return this.media.volume;
|
|
66
80
|
}
|
|
81
|
+
/** Set the audio volume */
|
|
67
82
|
setVolume(volume) {
|
|
68
83
|
this.media.volume = volume;
|
|
69
84
|
}
|
|
85
|
+
/** Get the audio muted state */
|
|
70
86
|
getMuted() {
|
|
71
87
|
return this.media.muted;
|
|
72
88
|
}
|
|
89
|
+
/** Mute or unmute the audio */
|
|
73
90
|
setMuted(muted) {
|
|
74
91
|
this.media.muted = muted;
|
|
75
92
|
}
|
|
93
|
+
/** Get the playback speed */
|
|
76
94
|
getPlaybackRate() {
|
|
77
95
|
return this.media.playbackRate;
|
|
78
96
|
}
|
|
97
|
+
/** Set the playback speed, pass an optional false to NOT preserve the pitch */
|
|
79
98
|
setPlaybackRate(rate, preservePitch) {
|
|
80
99
|
// preservePitch is true by default in most browsers
|
|
81
100
|
if (preservePitch != null) {
|
|
@@ -83,6 +102,7 @@ class Player {
|
|
|
83
102
|
}
|
|
84
103
|
this.media.playbackRate = rate;
|
|
85
104
|
}
|
|
105
|
+
/** Get the HTML media element */
|
|
86
106
|
getMediaElement() {
|
|
87
107
|
return this.media;
|
|
88
108
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import BasePlugin from '../base-plugin.js';
|
|
2
|
-
import type { WaveSurferPluginParams } from '../
|
|
2
|
+
import type { WaveSurferPluginParams } from '../wavesurfer.js';
|
|
3
3
|
export type EnvelopePluginOptions = {
|
|
4
4
|
startTime?: number;
|
|
5
5
|
endTime?: number;
|
|
@@ -42,7 +42,9 @@ declare class EnvelopePlugin extends BasePlugin<EnvelopePluginEvents, EnvelopePl
|
|
|
42
42
|
private volume;
|
|
43
43
|
private isFadingIn;
|
|
44
44
|
private isFadingOut;
|
|
45
|
-
constructor(
|
|
45
|
+
constructor(options: EnvelopePluginOptions);
|
|
46
|
+
static create(options: EnvelopePluginOptions): EnvelopePlugin;
|
|
47
|
+
init(params: WaveSurferPluginParams): void;
|
|
46
48
|
private makeDraggable;
|
|
47
49
|
private renderPolyline;
|
|
48
50
|
private initSvg;
|