Audio Waveform
A static, width-explicit waveform for timelines. Decodes audio (URL / Blob / AudioBuffer) into normalized peaks — or takes precomputed peaks — and renders mirrored canvas bars at any pixel width, with optional played-progress coloring. Backs the waveform-player.
A static waveform built for timelines. It decodes an audio source (URL,
Blob, or an already-decoded AudioBuffer) into normalized peaks — or
takes a precomputed peaks array — and renders mirrored bars onto a
canvas at an explicit pixel width. Decoding happens once; changing the
width (e.g. on zoom) only re-draws, resampling the cached peaks. An
optional progress fraction colors the played portion.
Decode once and draw at any pixel width — it's built for a zoomable,
horizontally-scrollable editor timeline track, not a fixed container. It
also backs waveform-player, where the played portion is
colored via progress and the bar doubles as a seek scrubber.
Installation
One-time setup: add the @ikui registry to your components.json.
{
"registries": {
"@ikui": "https://ik-ui.pages.dev/r/{name}.json"
}
}Then install the component:
pnpm dlx shadcn@latest add @ikui/audio-waveformUsage
import { AudioWaveform } from "@/components/audio-waveform";<AudioWaveform
audioUrl={url}
width={duration * pixelsPerSecond * zoom}
height={48}
progress={currentTime / duration}
barColor="rgba(255,255,255,0.45)"
barPlayedColor="rgba(255,255,255,0.95)"
/>Decode once and reuse the peaks across re-renders (or share them with
another view) via onDecoded:
const [peaks, setPeaks] = useState<number[]>()
// first mount decodes; later renders pass `peaks` to skip decoding
<AudioWaveform audioUrl={url} height={48} onDecoded={setPeaks} />
{peaks && <AudioWaveform peaks={peaks} width={1200} height={48} />}Examples
Zoomable timeline track
The component is built for timelines: it decodes once, then draws at an
explicit pixel width. Zoom widens the canvas and scrolls instead of
re-fitting, reusing the cached peaks; click to move the progress split.
Custom bars
Tune the bar geometry and colors: barWidth and gap set the bar shape,
rounded toggles the caps, and barColor / barPlayedColor color the
unplayed and played sides of the progress split.
Props
| Prop | Type | Default |
|---|---|---|
audioUrl | string | - |
blob | Blob | - |
audioBuffer | AudioBuffer | - |
peaks | number[] | - |
width | number | - |
height | number | - |
barWidth | number | 2 |
gap | number | 1 |
minBarHeight | number | 2 |
backgroundColor | string | "transparent" |
barColor | string | "rgb(184, 184, 184)" |
barPlayedColor | string | - |
progress | number | 0 |
rounded | boolean | true |
onDecoded | (peaks: number[]) => void | - |
className | string | - |
style | React.CSSProperties | - |