Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / multimedia / audio

Build Custom Audio Player with Waveform in JavaScript

5.00/5 (2 votes)
4 Aug 2022CPOL4 min read 14.1K  
Simple Audio Player to browse any song with Play / Pause, Stop options & a waveform generated using CanvasJS charts
This tip is about a simple Audio Player that can be used to browse any song with Play / Pause, Stop options and waveform generated using CanvasJS charts.

Introduction

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. You can build a simple audio player app in JavaScript using Web Audio API. API lets you extract frequency, waveform and other data from the audio file. The extracted data can be used to visualize by generating waves. When you are working with large data that audio waveform generates, drawing waves smoother & faster without any lag in the web-page is important. As a developer, I prefer to keep the page faster irrespective of loads of content in the page. If we try to draw waveform in the page, performance has to be kept in mind & build some simple library to achieve it. Instead, I'm using CanvasJS chart to visualize the waveform that can draw millions of datapoints in few milliseconds.

The underlying techniques were built in JavaScript using Web Audio API & CanvasJS. However, it works fine with Angular, React or any other JavaScript frameworks.

Audio Player Waveform using CanvasJS

Step by Step Instructions

To play or visualize the waveform of the audio, audio file is necessary. Let's add an input field that lets user browse MP3 files from their machine. To keep it simple, I've restricted it to allow user to browse just MP3 files. However, web audio API supports WAV, MP3, AAC, OGG & other formats.

HTML
<input type="file" class="file-input" id="mp3-input" accept="audio/mp3">

Read Audio File

In Web Audio API, we need to get an ArrayBuffer of audio data and pass it to a BufferSource to fetch the audio. Using AudioContext.decodeAudioData method gets the audio buffer of the sound. The decoded AudioBuffer is resampled to the AudioContext's sampling rate, then passed to a callback or promise.

JavaScript
let margin = 10,
        chunkSize = 500,
        height = chart.get("height"),
scaleFactor = (height - margin * 2) / 2;

audioContext = new AudioContext();

let buffer = await file.arrayBuffer(),
        audioBuffer = await audioContext.decodeAudioData(buffer),
        float32Array = audioBuffer.getChannelData(0);

let array = [], i = 0, length = float32Array.length;

while (i < length) {
    array.push(
        float32Array.slice(i, i += chunkSize).reduce(function (total, value) {
            return Math.max(total, Math.abs(value));
        })
    );
}

Add Play / Pause & Stop Buttons

Let's add two buttons, one to control play / pause & another to stop. Generally icons / text in the button should show the action that user can do. When the audio is being played, show 'Pause' text / icon & 'Play' text / icon when the audio is paused. You can easily toggle between play & pause states to achieve that. In Web Audio API, you can check for state of the audio-context and based on the current state, either resume the audio or suspend it.

HTML
<button class="button" id="play-pause-btn" 
title="Play / Pause"><span class="pp-icon"></span></button>
<button class="button" id="stop-btn" 
title="Stop"><span class="stop-icon"></span></button>
JavaScript
if(audioContext.state === 'running') {
    audioContext.suspend().then(() => {
        playPauseBtn.classList.toggle('is-play');
    });
}
else if(audioContext.state === 'suspended') {
    audioContext.resume().then(() => {
        playPauseBtn.classList.toggle('is-play');
    });
}

Stopping the audio is pretty simple. Web Audio API has the option to stop the source by calling stop() method.

JavaScript
source.stop();

Generate Datapoints from the Audio Data

CanvasJS supports many chart types like line, area, pie, range, financial charts, etc. for different sets of data & use-cases. In this case range-area suits well - as it looks like audio waves. The only task for us is to generate datapoints from the audio file, pass it to chart. And CanvasJS draws wave graph for you like a charm.

JavaScript
let dps = []
for (let index in array) {
    dps.push({ x: margin + Number(index), 
    y: [50 - array[index] * scaleFactor, 50 + array[index] * scaleFactor]});
}

chart.options.data[0].dataPoints = dps;
chart.render();

Add Audio Playing Effect to the Wave

When the audio starts playing, it's a good option to shade the region that has already been played in the waveform. Add stripline to show shaded region in the chart & keep updating it every few milliseconds or 1 second. And stop updating it once the audio stops playing.

JavaScript
source.onended = () => {
    chart.axisX[0].stripLines[0].set("endValue", chart.axisX[0].get("maximum"));
    clearInterval(intervalId);
}
let intervalId = setInterval(() => {
    chart.axisX[0].stripLines[0].set
    ("endValue", audioContext.currentTime * 
    (chart.data[0].dataPoints.length / audioBuffer.duration));
}, 250);

Yippee! You just built a custom audio-player with play, pause & stop options along with the audio waveform generated using CanvasJS range-area chart. You can even use column chart, range-column chart do show waves differently. You can even customize the look & feel of the audio player using simple CSS properties & match the same with the waveform by changing CanvasJS chart properties.

This waveform generated by CanvasJS chart can be integrated with audio / video player to make it appealing to the user. Library has more customization options to change the look & feel - this gives you more flexibility to customize the chart look & feel to match with your website / player theme. In this tutorial, I have disabled chart interactivity so as to showcase just the waveform. However, CanvasJS supports interactivity where it shows tooltip & highlights when you hover chart. Check this JSFiddle for live code.

Sample Code

Points of Interest

You will learn how interesting it is to play around with web audio API & CanvasJS API. When it comes to CanvasJS, you will learn & enjoy how to customize colors & updating chart dynamically to make waveform more appealing to the user.

Sample Code: JSFiddle

History

  • 4th August, 2022: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)