wavesurfer.js 7.8.4-beta.1 → 7.8.4
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.js +1 -3
- package/dist/decoder.js +16 -5
- package/dist/dom.js +1 -1
- package/dist/draggable.js +2 -2
- package/dist/event-emitter.js +6 -3
- package/dist/fetcher.js +50 -37
- package/dist/player.js +14 -4
- package/dist/plugins/envelope.js +1 -355
- package/dist/plugins/hover.js +1 -106
- package/dist/plugins/record.cjs +1 -1
- package/dist/plugins/record.esm.js +1 -1
- package/dist/plugins/record.js +1 -1
- package/dist/plugins/record.min.js +1 -1
- package/dist/renderer.js +108 -88
- package/dist/timer.js +4 -1
- package/dist/wavesurfer.js +95 -76
- package/dist/webaudio.js +50 -33
- package/package.json +1 -1
package/dist/wavesurfer.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import BasePlugin from './base-plugin.js';
|
|
2
11
|
import Decoder from './decoder.js';
|
|
3
12
|
import * as dom from './dom.js';
|
|
@@ -19,16 +28,6 @@ const defaultOptions = {
|
|
|
19
28
|
sampleRate: 8000,
|
|
20
29
|
};
|
|
21
30
|
class WaveSurfer extends Player {
|
|
22
|
-
options;
|
|
23
|
-
renderer;
|
|
24
|
-
timer;
|
|
25
|
-
plugins = [];
|
|
26
|
-
decodedData = null;
|
|
27
|
-
subscriptions = [];
|
|
28
|
-
mediaSubscriptions = [];
|
|
29
|
-
abortController = null;
|
|
30
|
-
static BasePlugin = BasePlugin;
|
|
31
|
-
static dom = dom;
|
|
32
31
|
/** Create a new WaveSurfer instance */
|
|
33
32
|
static create(options) {
|
|
34
33
|
return new WaveSurfer(options);
|
|
@@ -43,6 +42,11 @@ class WaveSurfer extends Player {
|
|
|
43
42
|
autoplay: options.autoplay,
|
|
44
43
|
playbackRate: options.audioRate,
|
|
45
44
|
});
|
|
45
|
+
this.plugins = [];
|
|
46
|
+
this.decodedData = null;
|
|
47
|
+
this.subscriptions = [];
|
|
48
|
+
this.mediaSubscriptions = [];
|
|
49
|
+
this.abortController = null;
|
|
46
50
|
this.options = Object.assign({}, defaultOptions, options);
|
|
47
51
|
this.timer = new Timer();
|
|
48
52
|
const audioElement = media ? undefined : this.getMediaElement();
|
|
@@ -168,7 +172,8 @@ class WaveSurfer extends Player {
|
|
|
168
172
|
}
|
|
169
173
|
}
|
|
170
174
|
initPlugins() {
|
|
171
|
-
|
|
175
|
+
var _a;
|
|
176
|
+
if (!((_a = this.options.plugins) === null || _a === void 0 ? void 0 : _a.length))
|
|
172
177
|
return;
|
|
173
178
|
this.options.plugins.forEach((plugin) => {
|
|
174
179
|
this.registerPlugin(plugin);
|
|
@@ -224,73 +229,80 @@ class WaveSurfer extends Player {
|
|
|
224
229
|
getActivePlugins() {
|
|
225
230
|
return this.plugins;
|
|
226
231
|
}
|
|
227
|
-
|
|
228
|
-
this
|
|
229
|
-
|
|
230
|
-
this.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (
|
|
236
|
-
this.
|
|
237
|
-
|
|
232
|
+
loadAudio(url, blob, channelData, duration) {
|
|
233
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
234
|
+
var _a;
|
|
235
|
+
this.emit('load', url);
|
|
236
|
+
if (!this.options.media && this.isPlaying())
|
|
237
|
+
this.pause();
|
|
238
|
+
this.decodedData = null;
|
|
239
|
+
// Fetch the entire audio as a blob if pre-decoded data is not provided
|
|
240
|
+
if (!blob && !channelData) {
|
|
241
|
+
const fetchParams = this.options.fetchParams || {};
|
|
242
|
+
if (window.AbortController && !fetchParams.signal) {
|
|
243
|
+
this.abortController = new AbortController();
|
|
244
|
+
fetchParams.signal = (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal;
|
|
245
|
+
}
|
|
246
|
+
const onProgress = (percentage) => this.emit('loading', percentage);
|
|
247
|
+
blob = yield Fetcher.fetchBlob(url, onProgress, fetchParams);
|
|
238
248
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
// Set the mediaelement source
|
|
250
|
+
this.setSrc(url, blob);
|
|
251
|
+
// Wait for the audio duration
|
|
252
|
+
const audioDuration = yield new Promise((resolve) => {
|
|
253
|
+
const staticDuration = duration || this.getDuration();
|
|
254
|
+
if (staticDuration) {
|
|
255
|
+
resolve(staticDuration);
|
|
256
|
+
}
|
|
257
|
+
else {
|
|
258
|
+
this.mediaSubscriptions.push(this.onMediaEvent('loadedmetadata', () => resolve(this.getDuration()), { once: true }));
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
// Set the duration if the player is a WebAudioPlayer without a URL
|
|
262
|
+
if (!url && !blob) {
|
|
263
|
+
const media = this.getMediaElement();
|
|
264
|
+
if (media instanceof WebAudioPlayer) {
|
|
265
|
+
media.duration = audioDuration;
|
|
266
|
+
}
|
|
249
267
|
}
|
|
250
|
-
|
|
251
|
-
|
|
268
|
+
// Decode the audio data or use user-provided peaks
|
|
269
|
+
if (channelData) {
|
|
270
|
+
this.decodedData = Decoder.createBuffer(channelData, audioDuration || 0);
|
|
252
271
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const media = this.getMediaElement();
|
|
257
|
-
if (media instanceof WebAudioPlayer) {
|
|
258
|
-
media.duration = audioDuration;
|
|
272
|
+
else if (blob) {
|
|
273
|
+
const arrayBuffer = yield blob.arrayBuffer();
|
|
274
|
+
this.decodedData = yield Decoder.decode(arrayBuffer, this.options.sampleRate);
|
|
259
275
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
const arrayBuffer = await blob.arrayBuffer();
|
|
267
|
-
this.decodedData = await Decoder.decode(arrayBuffer, this.options.sampleRate);
|
|
268
|
-
}
|
|
269
|
-
if (this.decodedData) {
|
|
270
|
-
this.emit('decode', this.getDuration());
|
|
271
|
-
this.renderer.render(this.decodedData);
|
|
272
|
-
}
|
|
273
|
-
this.emit('ready', this.getDuration());
|
|
276
|
+
if (this.decodedData) {
|
|
277
|
+
this.emit('decode', this.getDuration());
|
|
278
|
+
this.renderer.render(this.decodedData);
|
|
279
|
+
}
|
|
280
|
+
this.emit('ready', this.getDuration());
|
|
281
|
+
});
|
|
274
282
|
}
|
|
275
283
|
/** Load an audio file by URL, with optional pre-decoded audio data */
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
+
load(url, channelData, duration) {
|
|
285
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
286
|
+
try {
|
|
287
|
+
return yield this.loadAudio(url, undefined, channelData, duration);
|
|
288
|
+
}
|
|
289
|
+
catch (err) {
|
|
290
|
+
this.emit('error', err);
|
|
291
|
+
throw err;
|
|
292
|
+
}
|
|
293
|
+
});
|
|
284
294
|
}
|
|
285
295
|
/** Load an audio blob */
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
296
|
+
loadBlob(blob, channelData, duration) {
|
|
297
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
+
try {
|
|
299
|
+
return yield this.loadAudio('', blob, channelData, duration);
|
|
300
|
+
}
|
|
301
|
+
catch (err) {
|
|
302
|
+
this.emit('error', err);
|
|
303
|
+
throw err;
|
|
304
|
+
}
|
|
305
|
+
});
|
|
294
306
|
}
|
|
295
307
|
/** Zoom the waveform by a given pixels-per-second factor */
|
|
296
308
|
zoom(minPxPerSec) {
|
|
@@ -305,7 +317,7 @@ class WaveSurfer extends Player {
|
|
|
305
317
|
return this.decodedData;
|
|
306
318
|
}
|
|
307
319
|
/** Get decoded peaks */
|
|
308
|
-
exportPeaks({ channels = 2, maxLength = 8000, precision =
|
|
320
|
+
exportPeaks({ channels = 2, maxLength = 8000, precision = 10000 } = {}) {
|
|
309
321
|
if (!this.decodedData) {
|
|
310
322
|
throw new Error('The audio has not been decoded yet');
|
|
311
323
|
}
|
|
@@ -354,8 +366,10 @@ class WaveSurfer extends Player {
|
|
|
354
366
|
this.setTime(time);
|
|
355
367
|
}
|
|
356
368
|
/** Play or pause the audio */
|
|
357
|
-
|
|
358
|
-
return this
|
|
369
|
+
playPause() {
|
|
370
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
371
|
+
return this.isPlaying() ? this.pause() : this.play();
|
|
372
|
+
});
|
|
359
373
|
}
|
|
360
374
|
/** Stop the audio and go to the beginning */
|
|
361
375
|
stop() {
|
|
@@ -376,13 +390,16 @@ class WaveSurfer extends Player {
|
|
|
376
390
|
super.setMediaElement(element);
|
|
377
391
|
this.initPlayerEvents();
|
|
378
392
|
}
|
|
379
|
-
|
|
380
|
-
return this
|
|
393
|
+
exportImage() {
|
|
394
|
+
return __awaiter(this, arguments, void 0, function* (format = 'image/png', quality = 1, type = 'dataURL') {
|
|
395
|
+
return this.renderer.exportImage(format, quality, type);
|
|
396
|
+
});
|
|
381
397
|
}
|
|
382
398
|
/** Unmount wavesurfer */
|
|
383
399
|
destroy() {
|
|
400
|
+
var _a;
|
|
384
401
|
this.emit('destroy');
|
|
385
|
-
this.abortController
|
|
402
|
+
(_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
|
|
386
403
|
this.plugins.forEach((plugin) => plugin.destroy());
|
|
387
404
|
this.subscriptions.forEach((unsubscribe) => unsubscribe());
|
|
388
405
|
this.unsubscribePlayerEvents();
|
|
@@ -391,4 +408,6 @@ class WaveSurfer extends Player {
|
|
|
391
408
|
super.destroy();
|
|
392
409
|
}
|
|
393
410
|
}
|
|
411
|
+
WaveSurfer.BasePlugin = BasePlugin;
|
|
412
|
+
WaveSurfer.dom = dom;
|
|
394
413
|
export default WaveSurfer;
|
package/dist/webaudio.js
CHANGED
|
@@ -1,34 +1,43 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
import EventEmitter from './event-emitter.js';
|
|
2
11
|
/**
|
|
3
12
|
* A Web Audio buffer player emulating the behavior of an HTML5 Audio element.
|
|
4
13
|
*/
|
|
5
14
|
class WebAudioPlayer extends EventEmitter {
|
|
6
|
-
audioContext;
|
|
7
|
-
gainNode;
|
|
8
|
-
bufferNode = null;
|
|
9
|
-
playStartTime = 0;
|
|
10
|
-
playedDuration = 0;
|
|
11
|
-
_muted = false;
|
|
12
|
-
_playbackRate = 1;
|
|
13
|
-
_duration = undefined;
|
|
14
|
-
buffer = null;
|
|
15
|
-
currentSrc = '';
|
|
16
|
-
paused = true;
|
|
17
|
-
crossOrigin = null;
|
|
18
|
-
seeking = false;
|
|
19
|
-
autoplay = false;
|
|
20
15
|
constructor(audioContext = new AudioContext()) {
|
|
21
16
|
super();
|
|
17
|
+
this.bufferNode = null;
|
|
18
|
+
this.playStartTime = 0;
|
|
19
|
+
this.playedDuration = 0;
|
|
20
|
+
this._muted = false;
|
|
21
|
+
this._playbackRate = 1;
|
|
22
|
+
this._duration = undefined;
|
|
23
|
+
this.buffer = null;
|
|
24
|
+
this.currentSrc = '';
|
|
25
|
+
this.paused = true;
|
|
26
|
+
this.crossOrigin = null;
|
|
27
|
+
this.seeking = false;
|
|
28
|
+
this.autoplay = false;
|
|
29
|
+
/** Subscribe to an event. Returns an unsubscribe function. */
|
|
30
|
+
this.addEventListener = this.on;
|
|
31
|
+
/** Unsubscribe from an event */
|
|
32
|
+
this.removeEventListener = this.un;
|
|
22
33
|
this.audioContext = audioContext;
|
|
23
34
|
this.gainNode = this.audioContext.createGain();
|
|
24
35
|
this.gainNode.connect(this.audioContext.destination);
|
|
25
36
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
async load() {
|
|
31
|
-
return;
|
|
37
|
+
load() {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
return;
|
|
40
|
+
});
|
|
32
41
|
}
|
|
33
42
|
get src() {
|
|
34
43
|
return this.currentSrc;
|
|
@@ -64,10 +73,11 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
64
73
|
});
|
|
65
74
|
}
|
|
66
75
|
_play() {
|
|
76
|
+
var _a;
|
|
67
77
|
if (!this.paused)
|
|
68
78
|
return;
|
|
69
79
|
this.paused = false;
|
|
70
|
-
this.bufferNode
|
|
80
|
+
(_a = this.bufferNode) === null || _a === void 0 ? void 0 : _a.disconnect();
|
|
71
81
|
this.bufferNode = this.audioContext.createBufferSource();
|
|
72
82
|
if (this.buffer) {
|
|
73
83
|
this.bufferNode.buffer = this.buffer;
|
|
@@ -89,15 +99,18 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
89
99
|
};
|
|
90
100
|
}
|
|
91
101
|
_pause() {
|
|
102
|
+
var _a;
|
|
92
103
|
this.paused = true;
|
|
93
|
-
this.bufferNode
|
|
104
|
+
(_a = this.bufferNode) === null || _a === void 0 ? void 0 : _a.stop();
|
|
94
105
|
this.playedDuration += this.audioContext.currentTime - this.playStartTime;
|
|
95
106
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
play() {
|
|
108
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
109
|
+
if (!this.paused)
|
|
110
|
+
return;
|
|
111
|
+
this._play();
|
|
112
|
+
this.emit('play');
|
|
113
|
+
});
|
|
101
114
|
}
|
|
102
115
|
pause() {
|
|
103
116
|
if (this.paused)
|
|
@@ -106,16 +119,19 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
106
119
|
this.emit('pause');
|
|
107
120
|
}
|
|
108
121
|
stopAt(timeSeconds) {
|
|
122
|
+
var _a, _b;
|
|
109
123
|
const delay = timeSeconds - this.currentTime;
|
|
110
|
-
this.bufferNode
|
|
111
|
-
this.bufferNode
|
|
124
|
+
(_a = this.bufferNode) === null || _a === void 0 ? void 0 : _a.stop(this.audioContext.currentTime + delay);
|
|
125
|
+
(_b = this.bufferNode) === null || _b === void 0 ? void 0 : _b.addEventListener('ended', () => {
|
|
112
126
|
this.bufferNode = null;
|
|
113
127
|
this.pause();
|
|
114
128
|
}, { once: true });
|
|
115
129
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
130
|
+
setSinkId(deviceId) {
|
|
131
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
132
|
+
const ac = this.audioContext;
|
|
133
|
+
return ac.setSinkId(deviceId);
|
|
134
|
+
});
|
|
119
135
|
}
|
|
120
136
|
get playbackRate() {
|
|
121
137
|
return this._playbackRate;
|
|
@@ -141,7 +157,8 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
141
157
|
this.emit('timeupdate');
|
|
142
158
|
}
|
|
143
159
|
get duration() {
|
|
144
|
-
|
|
160
|
+
var _a, _b;
|
|
161
|
+
return (_a = this._duration) !== null && _a !== void 0 ? _a : (((_b = this.buffer) === null || _b === void 0 ? void 0 : _b.duration) || 0);
|
|
145
162
|
}
|
|
146
163
|
set duration(value) {
|
|
147
164
|
this._duration = value;
|