How to convert mp3 to the sound wave image using javascript

Viewed 2637

I have a requirement in my project to convert mp3 audio to an image containing the waves for that mp3. Something like

enter image description here

Can I do this using javascript(specially nodejs)? Kindly help

3 Answers

Here is a short JavaScript program I wrote. When you input a mp3 file, it decodes it, and displays the amplitudes of the waveform on a canvas. The canvas looks a bit squished for longer files, but that could be changed later with css. Try a smaller file for best results (like 5-10 second duration audio file).

Note: This works in the browser, and I don't know about Node. This uses the built-in browser features HTML Canvas Element, and the Web Audio API. I expect Node has comparable features, or you could find a library that makes an image file with commands similar to the HTML Canvas 2d Context. Good luck!

const margin = 10;
const chunkSize = 50;



const input = document.querySelector("input");
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
const ac = new AudioContext();
const {width, height} = canvas;
const centerHeight = Math.ceil(height / 2);
const scaleFactor = (height - margin * 2) / 2;

async function drawToCanvas() {
  const buffer = await input.files[0].arrayBuffer();
  const audioBuffer = await ac.decodeAudioData(buffer);
  const float32Array = audioBuffer.getChannelData(0);

  const array = [];

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

  canvas.width = Math.ceil(float32Array.length / chunkSize + margin * 2);

  for (let index in array) {
    ctx.strokeStyle = "black";
    ctx.beginPath();
    ctx.moveTo(margin + Number(index), centerHeight - array[index] * scaleFactor);
    ctx.lineTo(margin + Number(index), centerHeight + array[index] * scaleFactor);
    ctx.stroke();
  }
}


input.addEventListener("input", drawToCanvas);
canvas {
  width: 90%;
  height: 400px;
}
<input type="file" accept="audio/mp3">
<br>
<canvas height="1000"></canvas>

You could use wavesurfer.js library that makes waves out of all different kinds of audio formats. I added an example with an mp3 file of how to implement it with HTML and JS:

If you want to add it with npm have a look at this documentation: wavesurfer.js npm doc.

var wavesurfer = WaveSurfer.create({
    container: '#waveform',
    waveColor: 'pink',
    progressColor: 'lightgreen'
});

wavesurfer.load('https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3');
<div id="waveform"></div>

<script src="https://unpkg.com/wavesurfer.js"></script>

Check this npm package waveplayer.

Load an audio file and play it

Create a waveplayer.js instance and pass in some (optional) options:

import WavePlayer from 'waveplayer';
 
var wavePlayer = new WavePlayer({
    container: '#waveform',
    barWidth: 4,
    barGap: 1,
    height: 128
});

Load an audio file from a URL and start playback when loading has finished:

wavePlayer.load('url-to-some-audio-file.mp3')
    .then(() => waveplayer.play());
Related