
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@arraypress/waveform-player
Advanced tools
Lightweight, customizable audio player with waveform visualization
A lightweight, customizable audio player with waveform visualization. Under 8KB gzipped.
Live Demo | Documentation | * NPM Package*

data-waveform-player to any div. No JavaScript required.For detailed release notes, see the Changelog.
Simplest possible usage:
<!-- Just this. That's it. -->
<div data-waveform-player data-url="song.mp3"></div>
npm install @arraypress/waveform-player
<link rel="stylesheet" href="https://unpkg.com/@arraypress/waveform-player@latest/dist/waveform-player.css">
<script src="https://unpkg.com/@arraypress/waveform-player@latest/dist/waveform-player.min.js"></script>
<link rel="stylesheet" href="waveform-player.css">
<script src="waveform-player.js"></script>
A persistent bottom-bar audio player with queue, favorites, cart, volume popup, DJ mode with markers, and cross-page session persistence:
<div data-wb-play
data-url="song.mp3"
data-title="My Track"
data-artist="Artist"
data-bpm="128"
data-key="Am">
</div>
<script>
WaveformBar.init();
</script>
Add playlist and chapter support with zero JavaScript:
<div data-waveform-playlist data-continuous="true">
<div data-track data-url="song1.mp3" data-title="Track 1">
<div data-chapter data-time="0:00">Intro</div>
<div data-chapter data-time="2:30">Verse</div>
</div>
<div data-track data-url="song2.mp3" data-title="Track 2"></div>
</div>
Track meaningful audio engagement:
WaveformTracker.init({
endpoint: '/api/analytics',
events: {
listen: 30 // Track after 30 seconds of listening
}
});
| Feature | WaveformPlayer | WaveSurfer.js | Amplitude.js |
|---|---|---|---|
| Size (gzipped) | ~8KB | 40KB+ | 35KB+ |
| Zero Config | ✅ | ❌ | ❌ |
| Dependencies | None | None | None |
| Waveform Styles | 6 | 3 | N/A |
| Setup Time | 30 seconds | 5+ minutes | 5+ minutes |
| Real Waveforms | ✅ | ✅ | ❌ |
| Keyboard Controls | ✅ | ✅ | ❌ |
| Media Session API | ✅ | ❌ | ❌ |
| Speed Control | ✅ | ✅ | ❌ |
<div data-waveform-player
data-url="audio.mp3"
data-title="My Song"
data-subtitle="Artist Name"
data-waveform-style="mirror"
data-show-playback-speed="true"
data-markers='[{"time": 30, "label": "Chorus"}]'>
</div>
<!-- Hide built-in controls for custom UI integration -->
<div data-waveform-player
data-url="audio.mp3"
data-show-controls="false"
data-show-info="false">
</div>
import WaveformPlayer from '@arraypress/waveform-player';
const player = new WaveformPlayer('#player', {
url: 'audio.mp3',
waveformStyle: 'mirror',
height: 80,
barWidth: 2,
barSpacing: 1,
markers: [
{time: 30, label: 'Verse', color: '#4ade80'},
{time: 60, label: 'Chorus', color: '#f59e0b'}
]
});
Choose from 6 built-in styles:
| Option | Type | Default | Description |
|---|---|---|---|
url | string | '' | Audio file URL |
waveformStyle | string | 'bars' | Visual style: bars, mirror, line, blocks, dots, seekbar |
height | number | 60 | Waveform height in pixels |
barWidth | number | 3 | Width of waveform bars |
barSpacing | number | 1 | Space between bars |
samples | number | 200 | Number of waveform samples |
waveformColor | string | 'rgba(255,255,255,0.3)' | Waveform color |
progressColor | string | 'rgba(255,255,255,0.9)' | Progress color |
buttonColor | string | 'rgba(255,255,255,0.9)' | Play button color |
showControls | boolean | true | Show play/pause button |
showInfo | boolean | true | Show title, subtitle, time, and metadata |
showTime | boolean | true | Show time display |
showBPM | boolean | false | Enable BPM detection |
showPlaybackSpeed | boolean | false | Show speed control menu |
playbackRate | number | 1 | Initial playback speed (0.5-2) |
autoplay | boolean | false | Autoplay on load |
title | string | '' | Track title |
subtitle | string | '' | Track subtitle |
artwork | string | '' | Album artwork URL |
markers | array | [] | Chapter markers array |
waveform | array | null | Pre-generated waveform data |
enableMediaSession | boolean | true | Enable system media controls |
// Control playback
player.play();
player.pause();
player.togglePlay();
// Seek
player.seekTo(30); // Seek to 30 seconds
player.seekToPercent(0.5); // Seek to 50%
// Volume
player.setVolume(0.8); // 80% volume
// Speed
player.setPlaybackRate(1.5); // 1.5x speed
// Dynamic loading
await player.loadTrack('new-song.mp3', 'New Title', 'New Artist', {
markers: [{time: 30, label: 'Chorus'}],
artwork: 'cover.jpg',
waveform: [0.2, 0.5, 0.8, 0.3] // Optional pre-generated data
});
// Destroy
player.destroy();
new WaveformPlayer('#player', {
url: 'audio.mp3',
onLoad: (player) => console.log('Loaded'),
onPlay: (player) => console.log('Playing'),
onPause: (player) => console.log('Paused'),
onEnd: (player) => console.log('Ended'),
onTimeUpdate: (current, total, player) => {
console.log(`${current}/${total}`);
}
});
When a player is focused (click on it):
Space - Play/pause←/→ - Seek backward/forward 5 seconds↑/↓ - Volume up/downM - Mute/unmute0-9 - Jump to 0%-90% of trackFor better performance, generate waveform data server-side:
// Generate waveform data once
const waveformData = await WaveformPlayer.generateWaveformData('audio.mp3');
// Use pre-generated data for instant display
new WaveformPlayer('#player', {
url: 'audio.mp3',
waveform: waveformData // Bypass client-side processing
});
// Get all instances
const players = WaveformPlayer.getAllInstances();
// Find specific player
const player = WaveformPlayer.getInstance('my-player');
// Destroy all players
WaveformPlayer.destroyAll();
.waveform-player {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-radius: 12px;
}
.waveform-btn {
border-color: #fff;
}
import {useEffect, useRef} from 'react';
import WaveformPlayer from '@arraypress/waveform-player';
function AudioPlayer({url}) {
const playerRef = useRef();
useEffect(() => {
const player = new WaveformPlayer(playerRef.current, {url});
return () => player.destroy();
}, [url]);
return <div ref={playerRef}/>;
}
<template>
<div ref="player"></div>
</template>
<script>
import WaveformPlayer from '@arraypress/waveform-player';
export default {
mounted() {
this.player = new WaveformPlayer(this.$refs.player, {
url: this.audioUrl
});
},
beforeDestroy() {
this.player?.destroy();
}
}
</script>
See the live demo for:
# Install dependencies
npm install
# Development mode
npm run dev
# Build
npm run build
# Check size
npm run size
MIT © ArrayPress
Created by David Sherlock
FAQs
Lightweight, customizable audio player with waveform visualization
The npm package @arraypress/waveform-player receives a total of 10,949 weekly downloads. As such, @arraypress/waveform-player popularity was classified as popular.
We found that @arraypress/waveform-player demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.