A javascript library to create a squiggly SVG waveform from audio data. Inspired by the podcast player by Megaphone.
I decided to split the squiggl functionality into 3 parts (one async, two sync) so that the audio data can be read once, then re-formatted and re-rendered multiple times without too much I/O. This way, the waveform can be re-rendered in response to changing screen widths.
Via <script>
tag (example):
<script src="https://unpkg.com/squiggl/dist/index.js"></script>
Via npm i squiggl
:
const squiggl = require('squiggl');
// or
import squiggl from 'squiggl';
The squiggl object consists of 3 functions:
- extractVolumeData
- formatVolumeData
- createElement
These functions are used in tandem to:
- Extract the useful bits of data we need from an audio file.
- Format the data into a shape that we can use.
- Create an SVG element that is the visualization of the data.
// Step 0.1: Define squiggly SVG element's parent container.
var container = document.querySelector( '#waveform-container' );
// Step 0.2: Define options.
const options = {
svg: {
id: 'squigglSvg',
width: 810,
height: 60
},
path: {
arcRadius: 2.25, // recommended
stroke: '#eaeaef',
strokeWidth: 1.2 // recommended
}
};
fetch( '/radiolab.mp3' )
// Step 0.3: Retrieve an audio file.
.then( res => res.arrayBuffer() )
// Step 1: Extract the useful bits of data we need.
.then( audioData => squiggl.extractVolumeData( audioData ) )
.then( volumeData => {
// Step 2: Format the data into a shape that we can use.
const formattedVolumeData = squiggl.formatVolumeData( volumeData, options.svg.width, options.path.arcRadius );
// Step 3: Create an SVG element that is the visualization of the data.
const svgElement = squiggl.createElement( formatVolumeData, options );
container.appendChild( svgElement );
});
squiggl requires you to define certain attributes of its internal <svg>
and <path>
elements through the options
parameter. This allows you to dynamically define certain visual properties of the waveform.
// Example
const options = {
svg: {
id: 'squigglSvg',
width: 810,
height: 60
},
path: {
arcRadius: 2.25, // recommended
stroke: '#eaeaef',
strokeWidth: 1.2 // recommended
}
};
Parameter | Type | Description |
---|---|---|
audioData |
ArrayBuffer | This is decoded using the decodeAudioData function from either window.AudioContext or window.webkitAudioContext (whichever is available). We can then call getChannelData(0) from the resulting buffer to pull out the volume data. |
Returns |
---|
Array of Numbers between -1.0 and 1.0 |
This function doesn't care where you get your audio data from (HTTP request, file input, etc...) as long as it's compatible with the AudioContext API.
Parameter | Type | Description |
---|---|---|
volumeData |
Array of Numbers between -1.0 and 1.0 | Ideally generated from the extractVolumeData function. |
width |
Number | The desired width of your SVG. Used to determine how many squiggles to draw. |
arcRadius |
Number | The radius of each turn in the waveform. Used to determine how many squiggles to draw. |
Returns |
---|
Array of Numbers between 0.0 and 1.0 |
This function formats the audio data into a smaller set of numbers that models the number of squiggles in the waveform, and their magnitudes.
Parameter | Type | Description |
---|---|---|
volumeData |
Array of Numbers between 0.0 and 1.0 | Ideally generated from the formatVolumeData function. |
options |
Object | See above. |
Returns |
---|
An <svg> Element that is ready to be added to the DOM. |