wavesurfer.js 6.6.1 → 6.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/plugin/wavesurfer.cursor.js +1 -1
  2. package/dist/plugin/wavesurfer.cursor.min.js +1 -1
  3. package/dist/plugin/wavesurfer.elan.js +1 -1
  4. package/dist/plugin/wavesurfer.elan.min.js +1 -1
  5. package/dist/plugin/wavesurfer.markers.js +1 -1
  6. package/dist/plugin/wavesurfer.markers.min.js +1 -1
  7. package/dist/plugin/wavesurfer.mediasession.js +1 -1
  8. package/dist/plugin/wavesurfer.mediasession.min.js +1 -1
  9. package/dist/plugin/wavesurfer.microphone.js +1 -1
  10. package/dist/plugin/wavesurfer.microphone.min.js +1 -1
  11. package/dist/plugin/wavesurfer.minimap.js +1 -1
  12. package/dist/plugin/wavesurfer.minimap.min.js +1 -1
  13. package/dist/plugin/wavesurfer.playhead.js +1 -1
  14. package/dist/plugin/wavesurfer.playhead.min.js +1 -1
  15. package/dist/plugin/wavesurfer.regions.js +1 -1
  16. package/dist/plugin/wavesurfer.regions.min.js +1 -1
  17. package/dist/plugin/wavesurfer.spectrogram.js +34 -128
  18. package/dist/plugin/wavesurfer.spectrogram.js.map +1 -1
  19. package/dist/plugin/wavesurfer.spectrogram.min.js +2 -2
  20. package/dist/plugin/wavesurfer.spectrogram.min.js.map +1 -1
  21. package/dist/plugin/wavesurfer.timeline.js +1 -1
  22. package/dist/plugin/wavesurfer.timeline.min.js +1 -1
  23. package/dist/wavesurfer-html-init.js +1 -1
  24. package/dist/wavesurfer-html-init.min.js +1 -1
  25. package/dist/wavesurfer.js +6 -160
  26. package/dist/wavesurfer.js.map +1 -1
  27. package/dist/wavesurfer.min.js +2 -2
  28. package/dist/wavesurfer.min.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/drawer.canvasentry.js +0 -43
  31. package/src/drawer.js +4 -0
  32. package/src/drawer.multicanvas.js +1 -71
  33. package/src/plugin/spectrogram/index.js +30 -121
  34. package/src/wavesurfer.js +0 -33
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wavesurfer.js",
3
- "version": "6.6.1",
3
+ "version": "6.6.2",
4
4
  "description": "Interactive navigable audio visualization using Web Audio and Canvas",
5
5
  "main": "dist/wavesurfer.js",
6
6
  "directories": {
@@ -66,11 +66,6 @@ export default class CanvasEntry {
66
66
  * @type {object}
67
67
  */
68
68
  this.canvasContextAttributes = {};
69
- /**
70
- * The Timeout id used to track this canvas entry.
71
- */
72
- this.drawTimeout = null;
73
-
74
69
  }
75
70
 
76
71
  /**
@@ -130,27 +125,21 @@ export default class CanvasEntry {
130
125
  */
131
126
  clearWave() {
132
127
  // wave
133
- this.waveCtx.save();
134
- this.waveCtx.setTransform(1, 0, 0, 1, 0, 0);
135
128
  this.waveCtx.clearRect(
136
129
  0,
137
130
  0,
138
131
  this.waveCtx.canvas.width,
139
132
  this.waveCtx.canvas.height
140
133
  );
141
- this.waveCtx.restore();
142
134
 
143
135
  // progress
144
136
  if (this.hasProgressCanvas) {
145
- this.progressCtx.save();
146
- this.progressCtx.setTransform(1, 0, 0, 1, 0, 0);
147
137
  this.progressCtx.clearRect(
148
138
  0,
149
139
  0,
150
140
  this.progressCtx.canvas.width,
151
141
  this.progressCtx.canvas.height
152
142
  );
153
- this.progressCtx.restore();
154
143
  }
155
144
  }
156
145
 
@@ -435,36 +424,4 @@ export default class CanvasEntry {
435
424
  return this.wave.toDataURL(format, quality);
436
425
  }
437
426
  }
438
-
439
- /**
440
- * Stretches existing canvas
441
- * @param {Number} newTotalWidth total width of wave in pixels
442
- */
443
- stretchCanvas(newTotalWidth) {
444
- //Calculate the start and width of this canvas
445
- let start = Math.round(this.start * newTotalWidth);
446
- let width = Math.round(this.end * newTotalWidth - start);
447
-
448
- //Stretch canvas
449
- let elementSize = { width: width + 'px' };
450
- let elementStart = {left: start + 'px'};
451
- style(this.wave, elementSize);
452
- style(this.wave, elementStart);
453
- if (this.hasProgressCanvas) {
454
- style(this.progress, elementSize);
455
- style(this.progress, elementStart);
456
- }
457
- }
458
-
459
- /**
460
- * Set the left offset of the canvas
461
- * @param {Number} position in px for the canvas to start
462
- */
463
- setLeft(position) {
464
- let elementStart = {left: position + 'px'};
465
- style(this.wave, elementStart);
466
- if (this.hasProgressCanvas) {
467
- style(this.progress, elementStart);
468
- }
469
- }
470
427
  }
package/src/drawer.js CHANGED
@@ -272,6 +272,10 @@ export default class Drawer extends util.Observer {
272
272
  * @return {boolean} Whether the width of the container was updated or not
273
273
  */
274
274
  setWidth(width) {
275
+ if (this.width == width) {
276
+ return false;
277
+ }
278
+
275
279
  this.width = width;
276
280
 
277
281
  if (this.params.fillParent || this.params.scrollParent) {
@@ -89,14 +89,6 @@ export default class MultiCanvas extends Drawer {
89
89
  * @type {boolean}
90
90
  */
91
91
  this.vertical = params.vertical;
92
-
93
- /**
94
- * Whether to use the optimsized zoom rendering
95
- * Automatically toggles to true if stretchCanvases() function is called
96
- *
97
- * @type {boolean}
98
- */
99
- this.optimiseZoom = false;
100
92
  }
101
93
 
102
94
  /**
@@ -165,16 +157,10 @@ export default class MultiCanvas extends Drawer {
165
157
 
166
158
  let canvasWidth = this.maxCanvasWidth + this.overlap;
167
159
  const lastCanvas = this.canvases.length - 1;
168
- let leftOffset = 0;
169
160
  this.canvases.forEach((entry, i) => {
170
161
  if (i == lastCanvas) {
171
162
  canvasWidth = this.width - this.maxCanvasWidth * lastCanvas;
172
163
  }
173
-
174
- //Set left offset and add to next entry
175
- entry.setLeft(leftOffset);
176
- leftOffset += canvasWidth / this.params.pixelRatio;
177
-
178
164
  this.updateDimensions(entry, canvasWidth, this.height);
179
165
 
180
166
  entry.clearWave();
@@ -424,39 +410,7 @@ export default class MultiCanvas extends Drawer {
424
410
  this.canvases.forEach((entry, i) => {
425
411
  this.setFillStyles(entry, waveColor, progressColor);
426
412
  this.applyCanvasTransforms(entry, this.params.vertical);
427
-
428
- if (this.optimiseZoom) {
429
- //Optimising zoom functionality
430
- //If there's a wrapper, optimise for the view
431
- let priority = 0;
432
- if (this.wrapper) {
433
- let canvasRect = entry.wave.getBoundingClientRect();
434
- let wrapperRect = this.wrapper.getBoundingClientRect();
435
-
436
- //Determine whether canvas is in viewframe or not and assign priority
437
- if (Math.floor(canvasRect['left']) > Math.ceil(wrapperRect['right'])) {
438
- //Canvas is to the right of view window
439
- let distance = canvasRect['left'] - wrapperRect['right'];
440
- priority = Math.ceil(distance / wrapperRect['width']);
441
- } else if (Math.ceil(canvasRect['right']) < Math.floor(wrapperRect['left'])) {
442
- //Canvas is to the left of the view window
443
- let distance = wrapperRect['left'] - canvasRect['right'];
444
- priority = Math.ceil(distance / wrapperRect['width']);
445
- }
446
- } else {
447
- //Everything is equal priority
448
- }
449
-
450
- //This staggers the drawing of canvases so they don't all draw at once
451
- entry.clearWave();
452
- clearTimeout(entry.drawTimeout);
453
- entry.drawTimeout = setTimeout(function(){
454
- entry.drawLines(peaks, absmax, halfH, offsetY, start, end);
455
- entry.drawTimeout = null;
456
- }, 25 * priority);
457
- } else {
458
- entry.drawLines(peaks, absmax, halfH, offsetY, start, end);
459
- }
413
+ entry.drawLines(peaks, absmax, halfH, offsetY, start, end);
460
414
  });
461
415
  }
462
416
 
@@ -652,30 +606,6 @@ export default class MultiCanvas extends Drawer {
652
606
  }
653
607
  }
654
608
 
655
- /**
656
- * Stretches the canvases to mimic zoom without recalculation
657
- *
658
- * @param {Number} desiredWidth new width of the wave display
659
- * @param {Number} progress Value between 0 and 1 for wave progress
660
- */
661
- stretchCanvases(desiredWidth, progress) {
662
- if (!this.optimiseZoom) {
663
- //Enable optimsed zooming
664
- this.optimiseZoom = true;
665
- }
666
- let totalCanvasWidth = Math.round(desiredWidth / this.params.pixelRatio);
667
- this.width = desiredWidth;
668
-
669
- for (let i = 0; i < this.canvases.length; i++) {
670
- this.canvases[i].stretchCanvas(totalCanvasWidth);
671
- }
672
-
673
- //Update progress
674
- let progressPos = progress * totalCanvasWidth;
675
- this.updateProgress(progressPos);
676
- this.recenterOnPosition(progressPos, true);
677
- }
678
-
679
609
  /**
680
610
  * Render the new progress
681
611
  *
@@ -92,9 +92,6 @@ export default class SpectrogramPlugin {
92
92
  this._onRender = () => {
93
93
  this.render();
94
94
  };
95
- this._onZoom = () => {
96
- this.stretchCanvases();
97
- };
98
95
  this._onWrapperClick = e => {
99
96
  this._wrapperClickHandler(e);
100
97
  };
@@ -139,9 +136,6 @@ export default class SpectrogramPlugin {
139
136
  this.alpha = params.alpha;
140
137
  this.splitChannels = params.splitChannels;
141
138
  this.channels = this.splitChannels ? ws.backend.buffer.numberOfChannels : 1;
142
- this.canvases = [];
143
- this.canvasesTimeouts = [];
144
- this.scrollLeftTracker = 0; //Tracks the desired scrollLeft value
145
139
 
146
140
  // Getting file's original samplerate is difficult(#1248).
147
141
  // So set 12kHz default to render like wavesurfer.js 5.x.
@@ -149,11 +143,10 @@ export default class SpectrogramPlugin {
149
143
  this.frequencyMax = params.frequencyMax || 12000;
150
144
 
151
145
  this.createWrapper();
152
- this.addCanvas();
146
+ this.createCanvas();
153
147
  this.render();
154
148
 
155
149
  drawer.wrapper.addEventListener('scroll', this._onScroll);
156
- ws.on('zoom', this._onZoom);
157
150
  ws.on('redraw', this._onRender);
158
151
  };
159
152
  }
@@ -238,49 +231,17 @@ export default class SpectrogramPlugin {
238
231
  this.fireEvent('click', relX / this.width || 0);
239
232
  }
240
233
 
241
- /**
242
- * Add a canvas to this.canvases
243
- */
244
- addCanvas() {
245
- const canvas = (this.wrapper.appendChild(
234
+ createCanvas() {
235
+ const canvas = (this.canvas = this.wrapper.appendChild(
246
236
  document.createElement('canvas')
247
237
  ));
248
238
 
239
+ this.spectrCc = canvas.getContext('2d');
240
+
249
241
  this.util.style(canvas, {
250
242
  position: 'absolute',
251
243
  zIndex: 4
252
244
  });
253
-
254
- this.canvases.push(canvas);
255
- this.canvasesTimeouts.push(null);
256
- }
257
-
258
- /**
259
- * Remove a canvas from this.canvases
260
- */
261
- removeCanvas() {
262
- //Stop drawing (if drawing)
263
- clearTimeout(this.canvasesTimeouts[this.canvasesTimeouts.length - 1]);
264
-
265
- let lastEntry = this.canvases[this.canvases.length - 1];
266
- lastEntry.parentElement.removeChild(lastEntry);
267
-
268
- this.canvases.pop();
269
- this.canvasesTimeouts.pop();
270
- }
271
-
272
- /**
273
- * Ensure the correct number of canvases for the size of the spectrogram
274
- */
275
- updateCanvases() {
276
- let canvasesRequired = Math.ceil(this.width / 4000);
277
-
278
- while (this.canvases.length < canvasesRequired) {
279
- this.addCanvas();
280
- }
281
- while (this.canvases.length > canvasesRequired) {
282
- this.removeCanvas();
283
- }
284
245
  }
285
246
 
286
247
  render() {
@@ -294,14 +255,11 @@ export default class SpectrogramPlugin {
294
255
  }
295
256
 
296
257
  updateCanvasStyle() {
297
- this.updateCanvases();
298
- //width per canvas
299
- for (let i = 0; i < this.canvases.length; i++) {
300
- this.canvases[i].width = Math.round(this.width / this.canvases.length);
301
- this.canvases[i].height = this.fftSamples / 2 * this.channels;
302
- this.canvases[i].style.width = Math.round(this.canvases[i].width / this.pixelRatio) + 'px';
303
- this.canvases[i].style.height = this.height + 'px';
304
- }
258
+ const width = Math.round(this.width / this.pixelRatio) + 'px';
259
+ this.canvas.width = this.width;
260
+ this.canvas.height = this.fftSamples / 2 * this.channels;
261
+ this.canvas.style.width = width;
262
+ this.canvas.style.height = this.height + 'px';
305
263
  }
306
264
 
307
265
  drawSpectrogram(frequenciesData, my) {
@@ -310,61 +268,25 @@ export default class SpectrogramPlugin {
310
268
  frequenciesData = [frequenciesData];
311
269
  }
312
270
 
313
- my.updateCanvasStyle();
314
-
315
- //Stop canvases still being drawn
316
- for (let i = 0; i < my.canvasesTimeouts.length; i++) {
317
- clearTimeout(my.canvasesTimeouts[i]);
318
- }
319
-
320
- const view = [my.scrollLeftTracker, my.scrollLeftTracker + my.wrapper.clientWidth];
321
-
322
- for (let canvasNum = 0; canvasNum < my.canvases.length; canvasNum++) {
323
- const canvasLeft = canvasNum * Math.floor(my.width / my.canvases.length / my.pixelRatio);
324
- const canvasRight = (canvasNum + 1) * Math.floor(my.width / my.canvases.length / my.pixelRatio);
325
- const canvasBound = [canvasLeft, canvasRight];
326
- my.canvases[canvasNum].style['left'] = canvasLeft + 'px';
327
-
328
- //Optimise drawing for the view
329
- let priority = 0;
330
- if (canvasBound[0] > view[1]) {
331
- //Canvas is to the right of view window
332
- let distance = canvasBound[0] - view[1];
333
- priority = Math.ceil(distance / (view[1] - view[0]));
334
- } else if (canvasBound[1] < view[0]) {
335
- //Canvas is to the left of the view window
336
- let distance = view[0] - canvasBound[1];
337
- priority = Math.ceil(distance / (view[1] - view[0]));
338
- }
339
-
340
- //delay = 25ms * number of viewport widths away the canvas is
341
- my.canvasesTimeouts[canvasNum] = setTimeout(my.drawToCanvas, 25 * priority, frequenciesData, my, canvasNum);
342
- }
343
- }
344
-
345
- /**
346
- * Draw spectrogram channel to a specific canvas
347
- * @param {[Number, Number, Number]} frequenciesData spectrogram data in [channel, sample, freq] format
348
- * @param {SpectrogramPlugin} my variable with 'this' in it
349
- * @param {Number} canvasNum Canvas to draw to
350
- */
351
- drawToCanvas(frequenciesData, my, canvasNum) {
271
+ const spectrCc = my.spectrCc;
352
272
  const height = my.fftSamples / 2;
273
+ const width = my.width;
353
274
  const freqFrom = my.buffer.sampleRate / 2;
354
275
  const freqMin = my.frequencyMin;
355
276
  const freqMax = my.frequencyMax;
356
277
 
357
- for (let channel = 0; channel < frequenciesData.length; channel++) {
278
+ if (!spectrCc) {
279
+ return;
280
+ }
358
281
 
359
- //Get pixels from frequency data and apply to image
360
- const relevantFreqs = frequenciesData[channel].slice(canvasNum * Math.round(frequenciesData[channel].length / my.canvases.length), (canvasNum + 1) * Math.round(frequenciesData[channel].length / my.canvases.length));
361
- const pixels = my.resample(relevantFreqs);
362
- const imageData = new ImageData(pixels.length, height);
282
+ for (let c = 0; c < frequenciesData.length; c++) { // for each channel
283
+ const pixels = my.resample(frequenciesData[c]);
284
+ const imageData = new ImageData(width, height);
363
285
 
364
286
  for (let i = 0; i < pixels.length; i++) {
365
287
  for (let j = 0; j < pixels[i].length; j++) {
366
288
  const colorMap = my.colorMap[pixels[i][j]];
367
- const redIndex = ((height - j) * imageData.width + i) * 4;
289
+ const redIndex = ((height - j) * width + i) * 4;
368
290
  imageData.data[redIndex] = colorMap[0] * 255;
369
291
  imageData.data[redIndex + 1] = colorMap[1] * 255;
370
292
  imageData.data[redIndex + 2] = colorMap[2] * 255;
@@ -372,20 +294,16 @@ export default class SpectrogramPlugin {
372
294
  }
373
295
  }
374
296
 
375
- //Draw image to canvas
376
- createImageBitmap(imageData).then(renderer => {
377
- if (my.canvases[canvasNum]) { //Check canvas still exists after creating image
378
- my.canvases[canvasNum].getContext('2d').drawImage(renderer,
379
- 0, height * (1 - freqMax / freqFrom), // source x, y
380
- imageData.width, height * (freqMax - freqMin) / freqFrom, // source width, height
381
- 0, height * channel, // destination x, y
382
- my.canvases[canvasNum].width, height // destination width, height
383
- );
384
- }
385
- });
297
+ // scale and stack spectrograms
298
+ createImageBitmap(imageData).then(renderer =>
299
+ spectrCc.drawImage(renderer,
300
+ 0, height * (1 - freqMax / freqFrom), // source x, y
301
+ width, height * (freqMax - freqMin) / freqFrom, // source width, height
302
+ 0, height * c, // destination x, y
303
+ width, height // destination width, height
304
+ )
305
+ );
386
306
  }
387
- //Drawing is finished
388
- my.canvasesTimeouts[canvasNum] = null;
389
307
  }
390
308
 
391
309
  getFrequencies(callback) {
@@ -404,7 +322,7 @@ export default class SpectrogramPlugin {
404
322
 
405
323
  let noverlap = this.noverlap;
406
324
  if (!noverlap) {
407
- const uniqueSamplesPerPx = buffer.length / this.width;
325
+ const uniqueSamplesPerPx = buffer.length / this.canvas.width;
408
326
  noverlap = Math.max(0, Math.round(fftSamples - uniqueSamplesPerPx));
409
327
  }
410
328
 
@@ -543,13 +461,12 @@ export default class SpectrogramPlugin {
543
461
 
544
462
  updateScroll(e) {
545
463
  if (this.wrapper) {
546
- this.scrollLeftTracker = e.target.scrollLeft;
547
464
  this.wrapper.scrollLeft = e.target.scrollLeft;
548
465
  }
549
466
  }
550
467
 
551
468
  resample(oldMatrix) {
552
- const columnsNumber = oldMatrix.length;
469
+ const columnsNumber = this.width;
553
470
  const newMatrix = [];
554
471
 
555
472
  const oldPiece = 1 / oldMatrix.length;
@@ -602,12 +519,4 @@ export default class SpectrogramPlugin {
602
519
 
603
520
  return newMatrix;
604
521
  }
605
-
606
- stretchCanvases() {
607
- for (let i = 0; i < this.canvases.length; i++) {
608
- this.canvases[i].style.width = Math.round(this.drawer.width / this.canvases.length / this.pixelRatio) + 'px';
609
- const canvasLeft = i * Math.floor(this.drawer.width / this.canvases.length / this.pixelRatio);
610
- this.canvases[i].style['left'] = canvasLeft + 'px';
611
- }
612
- }
613
522
  }
package/src/wavesurfer.js CHANGED
@@ -1275,21 +1275,6 @@ export default class WaveSurfer extends util.Observer {
1275
1275
  this.drawBuffer();
1276
1276
  }
1277
1277
 
1278
- /**
1279
- * Calls getPeaks() and drawPeaks()
1280
- * @param {WaveSurfer} wavesurfer the Wavesurfer to get/draw peaks from/to
1281
- * @param {number} width The width of the area that should be drawn
1282
- * @param {number} start The x-offset of the beginning of the area that
1283
- * should be rendered
1284
- * @param {number} end The x-offset of the end of the area that should be
1285
- * rendered
1286
- */
1287
- getAndDrawPeaks(wavesurfer, width, start, end) {
1288
- let peaks;
1289
- peaks = wavesurfer.backend.getPeaks(width, start, end);
1290
- wavesurfer.drawer.drawPeaks(peaks, width, start, end);
1291
- }
1292
-
1293
1278
  /**
1294
1279
  * Get the correct peaks for current wave view-port and render wave
1295
1280
  *
@@ -1371,24 +1356,6 @@ export default class WaveSurfer extends util.Observer {
1371
1356
  this.fireEvent('zoom', pxPerSec);
1372
1357
  }
1373
1358
 
1374
- /**
1375
- * Call this function while moving the zoom slider to stretch the canvases
1376
- * of the wave without recalculating
1377
- *
1378
- * @param {Number} pxPerSec value returned from the zoom slider
1379
- */
1380
- zooming(pxPerSec) {
1381
- //Calculate the new width, this cannot be smaller than the parent container width
1382
- let desiredWidth = Math.round(this.getDuration() * pxPerSec * this.params.pixelRatio);
1383
- let parentWidth = this.drawer.getWidth();
1384
- desiredWidth = Math.max(parentWidth, desiredWidth);
1385
-
1386
- //Stretch canvases
1387
- this.drawer.stretchCanvases(desiredWidth, this.backend.getPlayedPercents());
1388
-
1389
- this.fireEvent('zoom', pxPerSec);
1390
- }
1391
-
1392
1359
  /**
1393
1360
  * Decode buffer and load
1394
1361
  *