An audio waveform you can seek through: loudness peaks drawn as rounded bars that rise in from the middle on load, the played part tinted in full, the part under the pointer previewed in a lighter tint with a time bubble above, and a thin playhead on hover. It resamples any number of peaks to the bars that fit the width, keeps its own clock with an optional play button so it plays on its own, or follows a real audio element. Drag, click and keys seek (arrows 5 seconds, Shift 1, Page keys a tenth, Home and End), Space or K plays and pauses, and a native range input carries it for assistive technology.
The import and the props worth knowing about, in one place.
import { PlayerWaveform, resamplePeaks } from "@/components/beste/component/player-waveform";
// Plays on its own, with a button and times
<PlayerWaveform
peaks={peaks} // numbers from 0 to 1, any length
duration={214}
defaultPlaying
loop
showPlay
showTime
/>
// Follows an audio element: controlled value and playing state
<PlayerWaveform
peaks={peaks}
duration={audio.duration}
value={currentTime}
playing={isPlaying}
onPlayingChange={(next) => console.log(next ? "play" : "pause")}
onValueCommit={(seconds) => console.log("seek to", seconds)}
barWidth={2} // px
gap={1} // px
tone="muted" // "muted" | "outline" | "ghost" (default)
size="lg" // "sm" | "default" | "lg"
/>Every one of these is in the component already. They are listed because a props table cannot mention a gesture, so nothing else on this page can tell you they exist.
| Left / Right | Seek back or forward 5 seconds. |
|---|---|
| Shift + Arrow | Seek 1 second, for fine placement. |
| Page Up / Page Down | A tenth of the duration. |
| Home / End | Jump to the start or the end. |
| Space / K | Play or pause, with the play button shown. |
| Drag | The playhead follows the pointer and seeks once on release. |
Read from the component's own type, so this cannot drift from what it accepts.
| Prop | Type | Default | Description |
|---|---|---|---|
peaks* | number[] | — | Loudness samples from 0 to 1, any length. They are resampled to the bars that fit. |
duration* | number | — | Length of the audio, in seconds. |
value | number | — | Playhead position in seconds, controlled. |
defaultValue | number | — | Starting playhead position in seconds, uncontrolled. |
onValueChange | (seconds: number) => void | — | Every drag frame, clock tick and key press, with the new time in seconds. |
onValueCommit | (seconds: number) => void | — | Once per gesture: on release, or after a key press. Seek the media here. |
playing | boolean | — | Whether the playhead runs, controlled. With an uncontrolled value the waveform keeps its own clock. |
defaultPlaying | boolean | — | Whether it starts running, uncontrolled. |
onPlayingChange | (playing: boolean) => void | — | |
loop | boolean | — | Start over at the end instead of stopping. |
rate | number | — | Playback speed of the built-in clock, 1 is real time. |
showPlay | boolean | — | A play and pause button before the waveform. |
showTime | boolean | — | Elapsed time on the left and remaining time on the right. |
barWidth | number | — | Width of one bar in px. |
gap | number | — | Space between bars in px. |
radius | number | — | Corner radius of a bar in px. Defaults to half the bar width, a pill. |
tone | "muted" | "outline" | "ghost" | — | |
size | "sm" | "default" | "lg" | — | |
disabled | boolean | — | |
name | string | — | Form name for the underlying range input. |
aria-label | string | — | Accessible name. Defaults to "Seek". |
className | string | — |