Check how to deal with the issue of Wavesurfer.js that prevents the waveform from appearing when the container is initially hidden.

A couple of days ago, i needed to use the well known library WaveSurfer.js, a customizable audio waveform visualization, built on top of Web Audio API and HTML5 Canvas. As always, the initialization is pretty straightforward and i never faced any problem with it. However, i noticed an interesting behaviour when working with this inside a Bootstrap 4 Tab. In Bootstrap 4, only the primary tab is visible, the rest are initially hidden. So, when i initialized a WaveSurfer instance inside one of those hidden tabs, the wave simply wasn't there. However, when i initialized the wave in the same page, but inside a visible container, the waveform appeared without issue.

WaveSurfer has this problem, when the container or parent container where the waveform should be drawn, isn't visible and therefore it doesn't have defined dimensions (width and height), so when WaveSurfer is initialized with the fillParent property set to true, the waveform is of course drawn, but with 0px as width as it cannot determine the width of the container !

In this short article, we will explain you how to draw the wave from an audio using WaveSurfer when the container is initially hidden.

A. Force container to be visible and hide it again

The first solution, that may be problematic for some people, is to make the div visible shortly, while the waveform is drawn and then hide it short after that. This ensures that the problematic of the hidden div with no dimensions dissapears as the div will be drawn and therefore it will have the dimensions specified by the browser and Wavesurfer will be able to determine the waveform width automatically.

For example, given the following markup, where the container of the waveform is hidden:

<div id="hidden-container" style="display: none;">
  <div id="waveform"></div>
</div>

We should be able to render properly the waveform even when the container is initially hidden with the following JavaScript:

// Initialize a simple instance of WaveSurfer
var wavesurfer = WaveSurfer.create({
    container: '#waveform'
});

// Load an audio file
wavesurfer.load('/myaudio.mp3');

// Attach on ready listener to WaveSurfer
wavesurfer.on('ready', function () {
    // Make the container temporarily visible
    document.getElementById("hidden-container").style.display = '';

    // Draw the waves
    wavesurfer.drawBuffer();

    // Hide the container once again ! Now WaveSurfer should have been rendered normally
    document.getElementById("hidden-container").style.display = 'none';
});

B. Specify width of waveform manually

As mentioned, the problem happens when the container or the waveform itself is initially hidden when the wavesurfer instance is initialized. So, if you don't want to apply the first solution, you can choose this one, that solves the problem specifying the width of the waveform manually. This can be done setting the fillParent property to false during the initialization and specifying a minimum width in pixels for every second rendered on the wave through the minPxPerSec property.

This method has the disadvantage of the lost of the responsiveness offered by the plugin:

// Initialize a simple instance of WaveSurfer
var wavesurfer = WaveSurfer.create({
    container: '#waveform',
    // Prevent autosize
    fillParent: false,
    // Define a minimum amount of pixels that should be used
    // to draw a single second of the sound. This defines a
    // specific width to the 
    minPxPerSec: 10
});

// Load an audio file
wavesurfer.load('/myaudio.mp3');

Using any of the mentioned solutions will guarantee the rendering of the waveform even when the container or the element itself is hidden.

Happy coding !


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors