Learn how to generate a dynamic and interactive audio spectrum from an audio file using the awesome Wavesurfer.js library.


"A sound wave is the pattern of disturbance caused by the movement of energy traveling through a medium such as air". Just kidding, we aren't so technical! If you are working on some platform that needs to play some audio to an user, for example to sell some Audio file, it's pretty awesome to show its wave form so the user will be impressed about the structure of the Audio and of what your platform can do. Willing to make it in the browser? Then Wavesurfer.js is the right tool for you.

With wavesurfer.js you can create anything from an HTML5 audio player to a sophisticated DJ application, but in this case we'll only show you how to create a basic wave form viewer and an easy audio player with 3 single buttons namely play, pause and stop.

1. Download and include Wavesurfer.js

Wavesurfer.js is a customizable audio waveform visualization, built on top of Web Audio API and HTML5 Canvas. According to the way you work, you can load this library in 2 ways. The first one is by simply including the script in your document from a CDN or a local copy:

<!-- Load using a free CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/1.3.7/wavesurfer.min.js"></script>

<!-- Or load it from a local copy -->
<script src="./path-to/wavesurfer.min.js"></script>

If you want to use a module bundler like browserify, webpack etc, then you will need to use the version that supports this approach. You will need to install the module in your project using the following command:

npm install [email protected]

Then you will be able to require the module using require("wavesurfer.js");. For more information about this library, please visit the official website or the official repository at Github here.

2. Using the library

Waversurfer is really easy to use. With the introducition of the version 2.0, now you can use it with bundlers and not only directly in the window:

With VanillaJS in the browser

The method of your interest is the create method. The only required parameter is container. It can be either a unique CSS3 selector, or a DOM element. However, you can also pass any number of options. After creating an instance you can load the audio file to create its waveform using the load method. The audio URL expects to be from your own domain or the URL from a song in another domain that supports CORS headers:

<!-- a div where the div will be placed -->
<div id="audio-spectrum"></div>

<script>
    // Create an instance of wave surfer with its configuration
    var Spectrum = WaveSurfer.create({
        container: '#audio-spectrum',
        // Add some color to the audio spectrum
        progressColor: "#03a9f4"
    });
    
    Spectrum.on("ready", function(){
        // Do something when the file has been loaded
        
        // Do whatever you need to do with the player
        Spectrum.play();
        Spectrum.pause();
        Spectrum.stop();
    });

    // Load the audio file from your own domain !
    Spectrum.load('audio-file.mp3');
</script>

The plugin exposes the global variable WaveSurfer in the browser, so you can simply use it once the script is loaded.

Using a module bundler

Wavesurfer is easy to use too with webpack, browserify etc. just require the module instead of using the global variable:

<!-- a div where the div will be placed -->
<div id="audio-spectrum"></div>

<script>
    // Require the wavesurfer module
    var WaveSurfer = require("wavesurfer.js");

    // Create an instance of wave surfer with its configuration
    var Spectrum = WaveSurfer.create({
        container: '#audio-spectrum',
        // Add some color to the audio spectrum
        progressColor: "#03a9f4"
    });
    
    Spectrum.on("ready", function(){
        // Do something when the file has been loaded

        // Do whatever you need to do with the player
        Spectrum.play();
        Spectrum.pause();
        Spectrum.stop();
    });

    // Load the audio file from your own domain !
    Spectrum.load('audio-file.mp3');
</script>

Final example

The following document is ready to be tested and you only need to provide a valid audio file. In this case, we have a simple responsive audio spectrum that will be rendered in the browser and 3 controls namely play, pause and stop. The core file of Wavesurfer is included through the CDN:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>AudioSpectrum in JavaScript</title>
    </head>
    <body>
        <!-- Create a div where the audio waves will be shown --> 
        <div id="audio-spectrum"></div>

        <!-- Create action buttons -->
        <input type="button" id="btn-play" value="Play" disabled="disabled"/>
        <input type="button" id="btn-pause" value="Pause" disabled="disabled"/>
        <input type="button" id="btn-stop" value="Stop" disabled="disabled" />

        <!-- Load the wavesurferscript , in this case from a CDN -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/wavesurfer.js/1.3.7/wavesurfer.min.js"></script>

        <script>
            // Store the 3 buttons in some object
            var buttons = {
                play: document.getElementById("btn-play"),
                pause: document.getElementById("btn-pause"),
                stop: document.getElementById("btn-stop")
            };

            // Create an instance of wave surfer with its configuration
            var Spectrum = WaveSurfer.create({
                container: '#audio-spectrum',
                progressColor: "#03a9f4"
            });

            // Handle Play button
            buttons.play.addEventListener("click", function(){
                Spectrum.play();

                // Enable/Disable respectively buttons
                buttons.stop.disabled = false;
                buttons.pause.disabled = false;
                buttons.play.disabled = true;
            }, false);

            // Handle Pause button
            buttons.pause.addEventListener("click", function(){
                Spectrum.pause();

                // Enable/Disable respectively buttons
                buttons.pause.disabled = true;
                buttons.play.disabled = false;
            }, false);


            // Handle Stop button
            buttons.stop.addEventListener("click", function(){
                Spectrum.stop();

                // Enable/Disable respectively buttons
                buttons.pause.disabled = true;
                buttons.play.disabled = false;
                buttons.stop.disabled = true;
            }, false);


            // Add a listener to enable the play button once it's ready
            Spectrum.on('ready', function () {
                buttons.play.disabled = false;
            });
            
            // If you want a responsive mode (so when the user resizes the window)
            // the spectrum will be still playable
            window.addEventListener("resize", function(){
                // Get the current progress according to the cursor position
                var currentProgress = Spectrum.getCurrentTime() / Spectrum.getDuration();

                // Reset graph
                Spectrum.empty();
                Spectrum.drawBuffer();
                // Set original position
                Spectrum.seekTo(currentProgress);

                // Enable/Disable respectively buttons
                buttons.pause.disabled = true;
                buttons.play.disabled = false;
                buttons.stop.disabled = false;
            }, false);

            // Load the audio file from your domain !
            Spectrum.load('audio-file.mp3');
        </script>
    </body>
</html>                                                                                                                                                                                                                                                                                                        

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