Command Palette

Search for a command to run...

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.

components.json
{
  "registries": {
    "@ikui": "https://ik-ui.pages.dev/r/{name}.json"
  }
}

Then install the component:

pnpm dlx shadcn@latest add @ikui/audio-waveform

Usage

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

PropTypeDefault
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
-