wavesurfer.js
wavesurfer.js copied to clipboard
Failed to set the 'currentTime' property on 'HTMLMediaElement' error when using MediaElement backend
Wavesurfer.js version(s):
3.3.3
Browser and operating system version(s):
latest Chrome (v83), Windows 10
Use behaviour needed to reproduce the issue:
This is the code:
playerRef.current = WaveSurfer.create({
barWidth: 3,
cursorWidth: 1,
container: '#waveform',
// see https://github.com/katspaugh/wavesurfer.js#can-the-audio-start-playing-before-the-waveform-is-drawn
backend: 'MediaElement',
height: 60,
progressColor: '#2D5BFF',
responsive: true,
waveColor: '#EFEFEF',
cursorColor: 'transparent',
});
// Called when a song is buffered and ready to play
playerRef.current.on('ready', function () {
playerRef.current!.play();
setLoading(false);
});
Try to load an .mp3 while one is playing, but the waveform is not loaded yet, it will result in the exception. This is the stack trace:
TypeError: Failed to set the 'currentTime' property on 'HTMLMediaElement': The provided double value is non-finite.
WaveSurfer/src/mediaelement.js:275
272 | */
273 | seekTo(start) {
274 | if (start != null) {
> 275 | this.media.currentTime = start;
| ^
276 | }
277 | this.clearPlayEnd();
278 | }
WaveSurfer.seekTo
WaveSurfer/src/wavesurfer.js:906
903 | // avoid small scrolls while paused seeking
904 | const oldScrollParent = this.params.scrollParent;
905 | this.params.scrollParent = false;
> 906 | this.backend.seekTo(progress * this.getDuration());
| ^
907 | this.drawer.progress(progress);
908 |
909 | if (!paused) {
WaveSurfer.stop
WaveSurfer/src/wavesurfer.js:923
920 | */
921 | stop() {
922 | this.pause();
> 923 | this.seekTo(0);
| ^
924 | this.drawer.progress(0);
925 | }
After some debugging the issue is in mediaelement.js
's getDuration()
method:
getDuration() {
if (this.explicitDuration) {
return this.explicitDuration;
}
let duration = (this.buffer || this.media).duration;
if (duration >= Infinity) {
// streaming audio
duration = this.media.seekable.end(0); // <- This returns Infinity!!
}
return duration;
}
A workaround is to call pause()
before loading a new mp3.
the solution is to edit the function like this:
if (start != null && !isNaN(start)) { this.media.currentTime = start; }
[workaround]
Loading Wavesurfer on loadedmetadata
event of video might fix the issue.