wavesurfer.js 7.12.6 → 7.12.8
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 +12 -6
- package/dist/__tests__/dom.test.js +17 -1
- package/dist/__tests__/drag-stream.test.d.ts +1 -0
- package/dist/__tests__/drag-stream.test.js +108 -0
- package/dist/__tests__/draggable.test.js +34 -0
- package/dist/__tests__/hover.test.d.ts +1 -0
- package/dist/__tests__/hover.test.js +64 -0
- package/dist/__tests__/regions.test.js +39 -0
- package/dist/__tests__/renderer.test.js +4 -0
- package/dist/__tests__/wavesurfer.test.js +13 -0
- package/dist/__tests__/webaudio.test.d.ts +1 -0
- package/dist/__tests__/webaudio.test.js +223 -0
- package/dist/dom.d.ts +5 -0
- package/dist/dom.js +12 -0
- package/dist/draggable.js +14 -4
- package/dist/fetcher.js +31 -10
- package/dist/fft.js +5 -1
- package/dist/player.d.ts +1 -0
- package/dist/player.js +13 -4
- package/dist/plugins/envelope.cjs +1 -1
- package/dist/plugins/envelope.esm.js +1 -1
- package/dist/plugins/envelope.js +1 -1
- package/dist/plugins/envelope.min.js +1 -1
- package/dist/plugins/hover.cjs +1 -1
- package/dist/plugins/hover.d.ts +2 -0
- package/dist/plugins/hover.esm.js +1 -1
- package/dist/plugins/hover.js +1 -1
- package/dist/plugins/hover.min.js +1 -1
- package/dist/plugins/minimap.cjs +1 -1
- package/dist/plugins/minimap.esm.js +1 -1
- package/dist/plugins/minimap.js +1 -1
- package/dist/plugins/minimap.min.js +1 -1
- 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/plugins/regions.cjs +1 -1
- package/dist/plugins/regions.d.ts +1 -0
- package/dist/plugins/regions.esm.js +1 -1
- package/dist/plugins/regions.js +1 -1
- package/dist/plugins/regions.min.js +1 -1
- package/dist/plugins/spectrogram-windowed.cjs +1 -1
- package/dist/plugins/spectrogram-windowed.esm.js +1 -1
- package/dist/plugins/spectrogram-windowed.js +1 -1
- package/dist/plugins/spectrogram-windowed.min.js +1 -1
- package/dist/plugins/spectrogram.cjs +1 -1
- package/dist/plugins/spectrogram.esm.js +1 -1
- package/dist/plugins/spectrogram.js +1 -1
- package/dist/plugins/spectrogram.min.js +1 -1
- package/dist/plugins/timeline.cjs +1 -1
- package/dist/plugins/timeline.esm.js +1 -1
- package/dist/plugins/timeline.js +1 -1
- package/dist/plugins/timeline.min.js +1 -1
- package/dist/plugins/zoom.cjs +1 -1
- package/dist/plugins/zoom.d.ts +1 -0
- package/dist/plugins/zoom.esm.js +1 -1
- package/dist/plugins/zoom.js +1 -1
- package/dist/plugins/zoom.min.js +1 -1
- package/dist/reactive/drag-stream.js +14 -4
- package/dist/reactive/state-event-emitter.js +7 -0
- package/dist/renderer-utils.js +4 -2
- package/dist/renderer.d.ts +2 -0
- package/dist/renderer.js +23 -11
- package/dist/timer.js +1 -0
- package/dist/types.d.ts +18 -2
- package/dist/wavesurfer.cjs +1 -1
- package/dist/wavesurfer.d.ts +2 -0
- package/dist/wavesurfer.esm.js +1 -1
- package/dist/wavesurfer.js +35 -6
- package/dist/wavesurfer.min.js +1 -1
- package/dist/webaudio.d.ts +5 -0
- package/dist/webaudio.js +69 -6
- package/package.json +15 -14
package/dist/webaudio.js
CHANGED
|
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import EventEmitter from './event-emitter.js';
|
|
11
|
+
function setWebAudioSessionPlayback() {
|
|
12
|
+
const navigator = globalThis.navigator;
|
|
13
|
+
if (!(navigator === null || navigator === void 0 ? void 0 : navigator.audioSession))
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
navigator.audioSession.type = 'playback';
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
console.warn('Setting navigator.audioSession.type failed:', e);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
11
22
|
/**
|
|
12
23
|
* A Web Audio buffer player emulating the behavior of an HTML5 Audio element.
|
|
13
24
|
*
|
|
@@ -16,7 +27,7 @@ import EventEmitter from './event-emitter.js';
|
|
|
16
27
|
* blob URL lifecycle management automatically.
|
|
17
28
|
*/
|
|
18
29
|
class WebAudioPlayer extends EventEmitter {
|
|
19
|
-
constructor(audioContext
|
|
30
|
+
constructor(audioContext) {
|
|
20
31
|
super();
|
|
21
32
|
this.bufferNode = null;
|
|
22
33
|
this.playStartTime = 0;
|
|
@@ -34,7 +45,9 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
34
45
|
this.addEventListener = this.on;
|
|
35
46
|
/** Unsubscribe from an event */
|
|
36
47
|
this.removeEventListener = this.un;
|
|
37
|
-
this.
|
|
48
|
+
this._destroyed = false;
|
|
49
|
+
setWebAudioSessionPlayback();
|
|
50
|
+
this.audioContext = audioContext || new AudioContext();
|
|
38
51
|
this.gainNode = this.audioContext.createGain();
|
|
39
52
|
this.gainNode.connect(this.audioContext.destination);
|
|
40
53
|
}
|
|
@@ -43,6 +56,42 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
43
56
|
return;
|
|
44
57
|
});
|
|
45
58
|
}
|
|
59
|
+
/** For compatibility with HTMLMediaElement.remove(). Delegates to destroy(). */
|
|
60
|
+
remove() {
|
|
61
|
+
this.destroy();
|
|
62
|
+
}
|
|
63
|
+
/** Clean up all resources. Idempotent — safe to call multiple times. */
|
|
64
|
+
destroy() {
|
|
65
|
+
if (this._destroyed)
|
|
66
|
+
return;
|
|
67
|
+
this._destroyed = true;
|
|
68
|
+
// Clear currentSrc so any in-flight fetch/decode chains bail out
|
|
69
|
+
// via their existing `this.currentSrc !== value` guards
|
|
70
|
+
this.currentSrc = '';
|
|
71
|
+
// Stop and disconnect buffer node
|
|
72
|
+
if (this.bufferNode) {
|
|
73
|
+
this.bufferNode.onended = null;
|
|
74
|
+
try {
|
|
75
|
+
this.bufferNode.stop();
|
|
76
|
+
}
|
|
77
|
+
catch (_a) {
|
|
78
|
+
// Ignore InvalidStateError if node already stopped
|
|
79
|
+
}
|
|
80
|
+
this.bufferNode.disconnect();
|
|
81
|
+
this.bufferNode = null;
|
|
82
|
+
}
|
|
83
|
+
// Disconnect gain node
|
|
84
|
+
this.gainNode.disconnect();
|
|
85
|
+
// Close audio context (returns a promise, catch rejection if already closed)
|
|
86
|
+
// Guard with typeof check for mock environments where close may not exist
|
|
87
|
+
if (typeof this.audioContext.close === 'function') {
|
|
88
|
+
Promise.resolve(this.audioContext.close.call(this.audioContext)).catch(() => undefined);
|
|
89
|
+
}
|
|
90
|
+
// Clear buffer reference
|
|
91
|
+
this.buffer = null;
|
|
92
|
+
// Clear all event listeners
|
|
93
|
+
this.unAll();
|
|
94
|
+
}
|
|
46
95
|
get src() {
|
|
47
96
|
return this.currentSrc;
|
|
48
97
|
}
|
|
@@ -103,16 +152,24 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
103
152
|
this.bufferNode.start(this.audioContext.currentTime, currentPos);
|
|
104
153
|
this.playStartTime = this.audioContext.currentTime;
|
|
105
154
|
this.bufferNode.onended = () => {
|
|
106
|
-
if (this.
|
|
155
|
+
if (!this.paused && this.duration - this.currentTime < 0.01) {
|
|
107
156
|
this.pause();
|
|
108
157
|
this.emit('ended');
|
|
109
158
|
}
|
|
110
159
|
};
|
|
111
160
|
}
|
|
112
161
|
_pause() {
|
|
113
|
-
var _a;
|
|
114
162
|
this.paused = true;
|
|
115
|
-
|
|
163
|
+
// Clear onended before stopping to prevent spurious 'ended' event
|
|
164
|
+
if (this.bufferNode) {
|
|
165
|
+
this.bufferNode.onended = null;
|
|
166
|
+
try {
|
|
167
|
+
this.bufferNode.stop();
|
|
168
|
+
}
|
|
169
|
+
catch (_a) {
|
|
170
|
+
// Ignore InvalidStateError if node already stopped
|
|
171
|
+
}
|
|
172
|
+
}
|
|
116
173
|
this.playbackPosition += (this.audioContext.currentTime - this.playStartTime) * this._playbackRate;
|
|
117
174
|
}
|
|
118
175
|
play() {
|
|
@@ -130,13 +187,19 @@ class WebAudioPlayer extends EventEmitter {
|
|
|
130
187
|
this.emit('pause');
|
|
131
188
|
}
|
|
132
189
|
stopAt(timeSeconds) {
|
|
133
|
-
|
|
190
|
+
// The stop is scheduled on the AudioContext clock, so convert the remaining
|
|
191
|
+
// media time to real time via the playback rate
|
|
192
|
+
const delay = (timeSeconds - this.currentTime) / this._playbackRate;
|
|
134
193
|
const currentBufferNode = this.bufferNode;
|
|
135
194
|
currentBufferNode === null || currentBufferNode === void 0 ? void 0 : currentBufferNode.stop(this.audioContext.currentTime + delay);
|
|
136
195
|
currentBufferNode === null || currentBufferNode === void 0 ? void 0 : currentBufferNode.addEventListener('ended', () => {
|
|
137
196
|
if (currentBufferNode === this.bufferNode) {
|
|
138
197
|
this.bufferNode = null;
|
|
139
198
|
this.pause();
|
|
199
|
+
// The 'ended' event fires with some latency, so clamp the reported
|
|
200
|
+
// position to the exact stop time
|
|
201
|
+
this.playbackPosition = Math.min(timeSeconds, this.duration);
|
|
202
|
+
this.emit('timeupdate');
|
|
140
203
|
}
|
|
141
204
|
}, { once: true });
|
|
142
205
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wavesurfer.js",
|
|
3
|
-
"version": "7.12.
|
|
3
|
+
"version": "7.12.8",
|
|
4
4
|
"license": "BSD-3-Clause",
|
|
5
5
|
"author": "katspaugh",
|
|
6
6
|
"description": "Audio waveform player",
|
|
@@ -64,32 +64,33 @@
|
|
|
64
64
|
"make-plugin": "./scripts/plugin.sh",
|
|
65
65
|
"cypress": "cypress open --e2e",
|
|
66
66
|
"cypress:canary": "cypress open --e2e -b chrome:canary",
|
|
67
|
-
"test": "cypress run --browser
|
|
67
|
+
"test": "cypress run --browser ${CYPRESS_BROWSER:-chromium}",
|
|
68
68
|
"test:unit": "jest --coverage",
|
|
69
69
|
"serve": "npx live-server --port=9090 --no-browser --ignore='.*,src,cypress,scripts'",
|
|
70
70
|
"start": "npm run build:dev & npm run serve",
|
|
71
|
+
"dev": "npm run start",
|
|
71
72
|
"prepare": "npm run build"
|
|
72
73
|
},
|
|
73
74
|
"packageManager": "yarn@1.22.22",
|
|
74
75
|
"devDependencies": {
|
|
75
76
|
"@rollup/plugin-terser": "^0.4.4",
|
|
76
|
-
"@rollup/plugin-typescript": "^12.
|
|
77
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
77
78
|
"@types/jest": "^29.5.2",
|
|
78
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
79
|
-
"@typescript-eslint/parser": "^8.
|
|
80
|
-
"cypress": "^13.
|
|
79
|
+
"@typescript-eslint/eslint-plugin": "^8.60.1",
|
|
80
|
+
"@typescript-eslint/parser": "^8.60.1",
|
|
81
|
+
"cypress": "^13.17.0",
|
|
81
82
|
"cypress-image-snapshot": "^4.0.1",
|
|
82
|
-
"eslint": "^9.
|
|
83
|
+
"eslint": "^9.39.4",
|
|
83
84
|
"eslint-config-prettier": "^9.1.0",
|
|
84
|
-
"eslint-plugin-prettier": "^5.
|
|
85
|
-
"glob": "^11.
|
|
85
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
86
|
+
"glob": "^11.1.0",
|
|
86
87
|
"jest": "^29.7.0",
|
|
87
88
|
"jest-environment-jsdom": "^29.7.0",
|
|
88
|
-
"prettier": "^3.
|
|
89
|
-
"rollup": "^4.
|
|
90
|
-
"rollup-plugin-dts": "^6.1
|
|
89
|
+
"prettier": "^3.8.3",
|
|
90
|
+
"rollup": "^4.61.1",
|
|
91
|
+
"rollup-plugin-dts": "^6.4.1",
|
|
91
92
|
"rollup-plugin-web-worker-loader": "^1.7.0",
|
|
92
|
-
"ts-jest": "^29.
|
|
93
|
-
"typescript": "^5.9.
|
|
93
|
+
"ts-jest": "^29.4.11",
|
|
94
|
+
"typescript": "^5.9.3"
|
|
94
95
|
}
|
|
95
96
|
}
|