Wavesurfer incorrectly destroyed / recreated (RangeError: invalid array length)
grudus opened this issue · 4 comments
Bug description
Hi
I have problem with wavesurfer after I destroy it and recreate on a page. Consider the following scenario:
- User clicks the button to start recording (record plugin) -> initializing: WaveSurfer.create and RecordPlugin.create
- User clicks the button to stop recording -> calling waveSurfer.destroy and recordPlugin.destroy
- User clicks the button to start recording again -> initializing: WaveSurfer.create and RecordPlugin.create.
Now what happens: When I reacreate the wavesurfer and try to draw it (3) I got RangeError: invalid array length
exception in the renderMultiCanvas.draw
function and the page freezes.
After some debugging I found out there is a problematic code:
// renderMultiCanvas function
const numCanvases = Math.ceil(totalWidth / singleCanvasWidth);
// Render all canvases if the waveform doesn't scroll
if (!this.isScrollable) {
for (let i = 0; i < numCanvases; i++) {
draw(i);
}
return;
}
For some reason singleCanvasWidth
is 0 so it draws infinitely. I can temporarily fix my use case by doing const numCanvases = Math.ceil(totalWidth / singleCanvasWidth || 1);
but I know that's not the root case.
Additionally, if I add console log
inside the renderMultiCanvas
I can see it is invoked constantly even when I destroy the wavesurfer instance.
Environment
- Browser: Chrome
- Next js (12.2.5)
- wavesurfer.js (7.8.4)
Minimal code snippet
(Some code omitted to make it clearer)
const visualisationRef = React.useRef<HTMLElement>(null)
const waveSurfer = React.useRef<WaveSurfer>()
const recordPlugin = React.useRef<RecordPlugin>()
const cleanup = () => {
if (recordPlugin.current) {
if (recordPlugin.current.isRecording()) {
recordPlugin.current.stopRecording()
}
recordPlugin.current.stopMic()
recordPlugin.current.unAll()
recordPlugin.current.destroy()
recordPlugin.current = undefined
}
if (waveSurfer.current) {
waveSurfer.current.empty()
waveSurfer.current.unAll()
waveSurfer.current.destroy()
waveSurfer.current = undefined
}
}
const initialize = () => {
cleanup()
waveSurfer.current = WaveSurfer.create({
container: visualisationRef.current,
barAlign: 'bottom',
barWidth: 5,
barRadius: 6,
waveColor: '#fff',
height: 48,
cursorWidth: 0,
barHeight: 4,
barGap: 2,
fillParent: true,
hideScrollbar: true,
interact: false,
autoplay: false,
mediaControls: false,
})
recordPlugin.current = waveSurfer.current.registerPlugin(
RecordPlugin.create({
renderRecordedAudio: false,
})
)
}
const startVisualisation = () => {
initialize()
recordPlugin.current?.startRecording()
}
Expected result
Library and plugin is correctly unmounted and it is possible to clean and rerun the initialization