BBC Waveform Data Example
This example demonstrates fast waveform loading using BBC's pre-computed peaks format. Waveforms appear almost instantly while audio loads in the background.
Loading...
About BBC Waveform Data
BBC's audiowaveform tool generates pre-computed peak data from audio files. This enables:
- Instant waveform display - peaks files are ~50KB vs ~3MB for audio
- Reduced server load - no need to decode audio for visualization
- Consistent rendering - same peaks regardless of browser/platform
- Progressive loading - show waveforms while audio loads in background
Generating BBC Peaks Files
# Install audiowaveform (macOS) brew install audiowaveform # Generate binary .dat file at 256 samples per pixel audiowaveform -i audio.mp3 -o peaks.dat -z 256 -b 8 # Generate with different zoom levels audiowaveform -i audio.mp3 -o peaks-30.dat -z 30 -b 8 # ~30 SPP # Generate 16-bit for higher precision audiowaveform -i audio.mp3 -o peaks-16bit.dat -z 256 -b 16
Fully Progressive Loading
import React, { useState, useEffect, useMemo } from 'react';
import type WaveformData from 'waveform-data';
import {
WaveformPlaylistProvider,
Waveform,
PlayButton,
PauseButton,
StopButton,
useAudioTracks,
loadWaveformData,
} from '@waveform-playlist/browser';
const trackConfigs = [
{ name: 'Kick', audioSrc: '/audio/kick.opus', peaksSrc: '/peaks/kick.dat' },
{ name: 'Bass', audioSrc: '/audio/bass.opus', peaksSrc: '/peaks/bass.dat' },
];
function WaveformDataExample() {
const [peaksMap, setPeaksMap] = useState<Map<string, WaveformData>>(new Map());
// 1. Load peaks PROGRESSIVELY - each track appears as its peaks load!
useEffect(() => {
trackConfigs.forEach(async (config) => {
const waveformData = await loadWaveformData(config.peaksSrc);
// Update state for THIS track immediately - triggers re-render
setPeaksMap(prev => new Map(prev).set(config.name, waveformData));
});
}, []);
// 2. Build configs - only include tracks that have peaks ready
const audioConfigs = useMemo(() =>
trackConfigs
.filter(config => peaksMap.has(config.name))
.map(config => ({
src: config.audioSrc,
name: config.name,
waveformData: peaksMap.get(config.name), // Pre-computed peaks!
})),
[peaksMap]);
// 3. Load audio progressively - tracks appear as they load!
const { tracks, loading, loadedCount, totalCount } = useAudioTracks(
audioConfigs, // Configs added progressively as peaks arrive
{ progressive: true }
);
// Tracks render immediately as each one loads - no waiting!
return (
<WaveformPlaylistProvider tracks={tracks} samplesPerPixel={1024}>
{loading && <div>Loading: {loadedCount} / {totalCount}</div>}
<PlayButton /> <PauseButton /> <StopButton />
<Waveform />
</WaveformPlaylistProvider>
);
}Audio Credits: "Ubiquitous" by Albert Kader — Minimal Techno stems from the Cambridge Music Technology multitrack library. Licensed under CC BY 4.0.
