wavesurfer.js 6.4.0 → 6.5.0
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/LICENSE +1 -1
- package/README.md +36 -48
- package/dist/plugin/wavesurfer.cursor.js +19 -8
- package/dist/plugin/wavesurfer.cursor.js.map +1 -1
- package/dist/plugin/wavesurfer.cursor.min.js +2 -2
- package/dist/plugin/wavesurfer.cursor.min.js.map +1 -1
- package/dist/plugin/wavesurfer.elan.js +6 -3
- package/dist/plugin/wavesurfer.elan.js.map +1 -1
- package/dist/plugin/wavesurfer.elan.min.js +2 -2
- package/dist/plugin/wavesurfer.elan.min.js.map +1 -1
- package/dist/plugin/wavesurfer.markers.js +6 -3
- package/dist/plugin/wavesurfer.markers.js.map +1 -1
- package/dist/plugin/wavesurfer.markers.min.js +2 -2
- package/dist/plugin/wavesurfer.markers.min.js.map +1 -1
- package/dist/plugin/wavesurfer.mediasession.js +4 -2
- package/dist/plugin/wavesurfer.mediasession.js.map +1 -1
- package/dist/plugin/wavesurfer.mediasession.min.js +2 -2
- package/dist/plugin/wavesurfer.mediasession.min.js.map +1 -1
- package/dist/plugin/wavesurfer.microphone.js +5 -2
- package/dist/plugin/wavesurfer.microphone.js.map +1 -1
- package/dist/plugin/wavesurfer.microphone.min.js +2 -2
- package/dist/plugin/wavesurfer.microphone.min.js.map +1 -1
- package/dist/plugin/wavesurfer.minimap.js +5 -2
- package/dist/plugin/wavesurfer.minimap.js.map +1 -1
- package/dist/plugin/wavesurfer.minimap.min.js +2 -2
- package/dist/plugin/wavesurfer.minimap.min.js.map +1 -1
- package/dist/plugin/wavesurfer.playhead.js +5 -2
- package/dist/plugin/wavesurfer.playhead.js.map +1 -1
- package/dist/plugin/wavesurfer.playhead.min.js +2 -2
- package/dist/plugin/wavesurfer.playhead.min.js.map +1 -1
- package/dist/plugin/wavesurfer.regions.js +106 -9
- package/dist/plugin/wavesurfer.regions.js.map +1 -1
- package/dist/plugin/wavesurfer.regions.min.js +2 -2
- package/dist/plugin/wavesurfer.regions.min.js.map +1 -1
- package/dist/plugin/wavesurfer.spectrogram.js +5 -2
- package/dist/plugin/wavesurfer.spectrogram.js.map +1 -1
- package/dist/plugin/wavesurfer.spectrogram.min.js +2 -2
- package/dist/plugin/wavesurfer.spectrogram.min.js.map +1 -1
- package/dist/plugin/wavesurfer.timeline.js +13 -5
- package/dist/plugin/wavesurfer.timeline.js.map +1 -1
- package/dist/plugin/wavesurfer.timeline.min.js +2 -2
- package/dist/plugin/wavesurfer.timeline.min.js.map +1 -1
- package/dist/wavesurfer-html-init.js +4 -2
- package/dist/wavesurfer-html-init.js.map +1 -1
- package/dist/wavesurfer-html-init.min.js +2 -2
- package/dist/wavesurfer-html-init.min.js.map +1 -1
- package/dist/wavesurfer.js +77 -27
- package/dist/wavesurfer.js.map +1 -1
- package/dist/wavesurfer.min.js +2 -2
- package/dist/wavesurfer.min.js.map +1 -1
- package/package.json +8 -8
- package/src/mediaelement.js +3 -0
- package/src/plugin/cursor/index.js +1 -1
- package/src/plugin/markers/index.js +1 -1
- package/src/plugin/regions/index.js +4 -0
- package/src/plugin/regions/region.js +76 -1
- package/src/util/silence-mode.js +7 -0
- package/src/wavesurfer.js +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wavesurfer.js",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.0",
|
|
4
4
|
"description": "Interactive navigable audio visualization using Web Audio and Canvas",
|
|
5
5
|
"main": "dist/wavesurfer.js",
|
|
6
6
|
"directories": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
},
|
|
36
36
|
"repository": {
|
|
37
37
|
"type": "git",
|
|
38
|
-
"url": "git
|
|
38
|
+
"url": "git@github.com:wavesurfer-js/wavesurfer.js.git"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"registry": "https://registry.npmjs.org"
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"author": "",
|
|
44
44
|
"license": "BSD-3-Clause",
|
|
45
45
|
"bugs": {
|
|
46
|
-
"url": "https://github.com/
|
|
46
|
+
"url": "https://github.com/wavesurfer-js/wavesurfer.js/issues"
|
|
47
47
|
},
|
|
48
48
|
"keywords": [
|
|
49
49
|
"waveform",
|
|
@@ -55,13 +55,13 @@
|
|
|
55
55
|
"visualization"
|
|
56
56
|
],
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@babel/core": "^7.20.
|
|
58
|
+
"@babel/core": "^7.20.12",
|
|
59
59
|
"@babel/eslint-parser": "^7.19.1",
|
|
60
60
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
61
61
|
"@babel/preset-env": "^7.20.2",
|
|
62
62
|
"@babel/register": "^7.18.9",
|
|
63
63
|
"@chiragrupani/karma-chromium-edge-launcher": "^2.2.2",
|
|
64
|
-
"babel-loader": "^9.1.
|
|
64
|
+
"babel-loader": "^9.1.2",
|
|
65
65
|
"babel-plugin-add-module-exports": "^1.0.4",
|
|
66
66
|
"babel-plugin-istanbul": "^6.1.1",
|
|
67
67
|
"date-fns": "^2.29.3",
|
|
@@ -85,11 +85,11 @@
|
|
|
85
85
|
"karma-jasmine-matchers": "5.0.0",
|
|
86
86
|
"karma-verbose-reporter": "0.0.8",
|
|
87
87
|
"karma-webpack": "^5.0.0",
|
|
88
|
-
"lint-staged": "^13.0
|
|
88
|
+
"lint-staged": "^13.1.0",
|
|
89
89
|
"load-script": "^2.0.0",
|
|
90
90
|
"pre-commit": "^1.2.2",
|
|
91
|
-
"webpack": "^5.
|
|
92
|
-
"webpack-cli": "^
|
|
91
|
+
"webpack": "^5.75.0",
|
|
92
|
+
"webpack-cli": "^5.0.1",
|
|
93
93
|
"webpack-dev-server": "^4.11.1",
|
|
94
94
|
"webpack-merge": "^5.8.0"
|
|
95
95
|
},
|
package/src/mediaelement.js
CHANGED
|
@@ -65,6 +65,9 @@ export default class MediaElement extends WebAudio {
|
|
|
65
65
|
this.mediaListeners.error = () => {
|
|
66
66
|
this.fireEvent('error', 'Error loading media element');
|
|
67
67
|
};
|
|
68
|
+
this.mediaListeners.waiting = () => {
|
|
69
|
+
this.fireEvent('waiting');
|
|
70
|
+
};
|
|
68
71
|
this.mediaListeners.canplay = () => {
|
|
69
72
|
this.fireEvent('canplay');
|
|
70
73
|
};
|
|
@@ -274,7 +274,7 @@ export default class MarkersPlugin {
|
|
|
274
274
|
labelEl.innerText = label;
|
|
275
275
|
labelEl.setAttribute('title', tooltip);
|
|
276
276
|
this.style(labelEl, {
|
|
277
|
-
"font-family": "
|
|
277
|
+
"font-family": "inherit",
|
|
278
278
|
"font-size": "90%"
|
|
279
279
|
});
|
|
280
280
|
labelDiv.appendChild(labelEl);
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* @typedef {Object} RegionsPluginParams
|
|
5
5
|
* @property {?boolean} dragSelection Enable creating regions by dragging with
|
|
6
6
|
* the mouse
|
|
7
|
+
* @property {?boolean} contentEditable=false Allow/disallow editing content of the region
|
|
8
|
+
* @property {?boolean} removeButton=false adds remove region button
|
|
7
9
|
* @property {?RegionParams[]} regions Regions that should be added upon
|
|
8
10
|
* initialisation
|
|
9
11
|
* @property {number} slop=2 The sensitivity of the mouse dragging
|
|
@@ -203,6 +205,8 @@ export default class RegionsPlugin {
|
|
|
203
205
|
|
|
204
206
|
params = {
|
|
205
207
|
edgeScrollWidth: this.params.edgeScrollWidth || this.defaultEdgeScrollWidth,
|
|
208
|
+
contentEditable: this.params.contentEditable,
|
|
209
|
+
removeButton: this.params.removeButton,
|
|
206
210
|
...params
|
|
207
211
|
};
|
|
208
212
|
|
|
@@ -28,6 +28,8 @@ export class Region {
|
|
|
28
28
|
this.resize =
|
|
29
29
|
params.resize === undefined ? true : Boolean(params.resize);
|
|
30
30
|
this.drag = params.drag === undefined ? true : Boolean(params.drag);
|
|
31
|
+
this.contentEditable = Boolean(params.contentEditable);
|
|
32
|
+
this.removeButton = Boolean(params.removeButton);
|
|
31
33
|
// reflect resize and drag state of region for region-updated listener
|
|
32
34
|
this.isResizing = false;
|
|
33
35
|
this.isDragging = false;
|
|
@@ -196,6 +198,40 @@ export class Region {
|
|
|
196
198
|
top: this.marginTop
|
|
197
199
|
});
|
|
198
200
|
|
|
201
|
+
/* Button Remove Region */
|
|
202
|
+
if (this.removeButton){
|
|
203
|
+
const removeButtonEl = document.createElement('div');
|
|
204
|
+
removeButtonEl.className = 'remove-region-button';
|
|
205
|
+
removeButtonEl.innerText = 'x';
|
|
206
|
+
this.removeButtonEl = this.element.appendChild(removeButtonEl);
|
|
207
|
+
const css = {
|
|
208
|
+
zIndex: 4,
|
|
209
|
+
position: 'absolute',
|
|
210
|
+
bottom: 0,
|
|
211
|
+
right: 0,
|
|
212
|
+
cursor:'pointer',
|
|
213
|
+
marginRight: '3px',
|
|
214
|
+
fontSize: '80%',
|
|
215
|
+
color: 'grey',
|
|
216
|
+
height: '14px'
|
|
217
|
+
};
|
|
218
|
+
this.style(this.removeButtonEl, css);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Edit content */
|
|
222
|
+
if (this.contentEditable){
|
|
223
|
+
const contentEl = document.createElement('div');
|
|
224
|
+
contentEl.className = 'region-content';
|
|
225
|
+
contentEl.contentEditable = true;
|
|
226
|
+
contentEl.innerText = this.data.text || '';
|
|
227
|
+
this.contentEl = this.element.appendChild(contentEl);
|
|
228
|
+
const css = {
|
|
229
|
+
zIndex: 4,
|
|
230
|
+
padding: '2px 5px',
|
|
231
|
+
cursor:'text'};
|
|
232
|
+
this.style(this.contentEl, css);
|
|
233
|
+
}
|
|
234
|
+
|
|
199
235
|
/* Resize handles */
|
|
200
236
|
if (this.resize) {
|
|
201
237
|
this.handleLeftEl = this.util.withOrientation(
|
|
@@ -404,6 +440,22 @@ export class Region {
|
|
|
404
440
|
if (this.drag || this.resize) {
|
|
405
441
|
this.bindDragEvents();
|
|
406
442
|
}
|
|
443
|
+
|
|
444
|
+
/* Edit content */
|
|
445
|
+
if (this.contentEditable){
|
|
446
|
+
this.contentEl.addEventListener('blur', this.onContentBlur.bind(this));
|
|
447
|
+
this.contentEl.addEventListener('click', this.onContentClick.bind(this));
|
|
448
|
+
}
|
|
449
|
+
/* Remove button */
|
|
450
|
+
if (this.removeButton){
|
|
451
|
+
this.removeButtonEl.addEventListener('click', this.onRemove.bind(this));
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
this.on('remove', () => {
|
|
455
|
+
this.contentEl.removeEventListener('blur', this.onContentBlur.bind(this));
|
|
456
|
+
this.contentEl.removeEventListener('click', this.onContentClick.bind(this));
|
|
457
|
+
this.removeButtonEl.removeEventListener('click', this.onRemove.bind(this));
|
|
458
|
+
});
|
|
407
459
|
}
|
|
408
460
|
|
|
409
461
|
bindDragEvents() {
|
|
@@ -586,6 +638,7 @@ export class Region {
|
|
|
586
638
|
const onMove = (event) => {
|
|
587
639
|
const duration = this.wavesurfer.getDuration();
|
|
588
640
|
let orientedEvent = this.util.withOrientation(event, this.vertical);
|
|
641
|
+
let delta = null;
|
|
589
642
|
|
|
590
643
|
if (event.touches && event.touches.length > 1) {
|
|
591
644
|
return;
|
|
@@ -632,7 +685,9 @@ export class Region {
|
|
|
632
685
|
}
|
|
633
686
|
} else if (resize === 'end') {
|
|
634
687
|
if (time < this.start + minLength) {
|
|
688
|
+
// Calculate the end time based on the min length of the region.
|
|
635
689
|
time = this.start + minLength;
|
|
690
|
+
delta = time - (this.end + (time - startTime));
|
|
636
691
|
}
|
|
637
692
|
|
|
638
693
|
if (time > duration) {
|
|
@@ -641,7 +696,10 @@ export class Region {
|
|
|
641
696
|
}
|
|
642
697
|
}
|
|
643
698
|
|
|
644
|
-
|
|
699
|
+
if (!delta) {
|
|
700
|
+
delta = time - startTime;
|
|
701
|
+
}
|
|
702
|
+
|
|
645
703
|
startTime = time;
|
|
646
704
|
|
|
647
705
|
// Drag
|
|
@@ -794,6 +852,23 @@ export class Region {
|
|
|
794
852
|
}
|
|
795
853
|
}
|
|
796
854
|
|
|
855
|
+
onContentBlur(event){
|
|
856
|
+
const {text: oldText} = this.data || {};
|
|
857
|
+
const text = event.target.innerText;
|
|
858
|
+
const data = {...this.data, text };
|
|
859
|
+
const eventParams = {action: 'contentEdited', oldText, text};
|
|
860
|
+
this.update({data}, eventParams);
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
onContentClick(event){
|
|
864
|
+
event.stopPropagation();
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
onRemove(event){
|
|
868
|
+
event.stopPropagation();
|
|
869
|
+
this.remove();
|
|
870
|
+
}
|
|
871
|
+
|
|
797
872
|
updateHandlesResize(resize) {
|
|
798
873
|
let cursorStyle;
|
|
799
874
|
if (resize) {
|
package/src/util/silence-mode.js
CHANGED
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
* @since 5.2.0
|
|
11
11
|
*/
|
|
12
12
|
export default function ignoreSilenceMode() {
|
|
13
|
+
// Set webaudio context with 1 second silent audio 44100 bit rate buffer to allow playing audio even if silent switch is on the device
|
|
14
|
+
const silentAC = new AudioContext();
|
|
15
|
+
const silentBS = silentAC.createBufferSource();
|
|
16
|
+
silentBS.buffer = silentAC.createBuffer(1, 1, 44100);
|
|
17
|
+
silentBS.connect(silentAC.destination);
|
|
18
|
+
silentBS.start();
|
|
19
|
+
|
|
13
20
|
// Set the src to a short bit of url encoded as a silent mp3
|
|
14
21
|
// NOTE The silence MP3 must be high quality, when web audio sounds are played
|
|
15
22
|
// in parallel the web audio sound is mixed to match the bitrate of the html sound
|
package/src/wavesurfer.js
CHANGED
|
@@ -1004,6 +1004,10 @@ export default class WaveSurfer extends util.Observer {
|
|
|
1004
1004
|
* @emits WaveSurfer#volume
|
|
1005
1005
|
*/
|
|
1006
1006
|
setVolume(newVolume) {
|
|
1007
|
+
if (this.isMuted === true) {
|
|
1008
|
+
this.savedVolume = newVolume;
|
|
1009
|
+
return;
|
|
1010
|
+
}
|
|
1007
1011
|
this.backend.setVolume(newVolume);
|
|
1008
1012
|
this.fireEvent('volume', newVolume);
|
|
1009
1013
|
}
|