Audio Scrubber
Waveform with travelling playhead and time labels. Install with npx remotion-ui@latest add audio-scrubber.
PrimitiveData & media
$ npx remotion-ui@latest add audio-scrubberA waveform with a travelling playhead, chapter marks and time labels.
import { AudioScrubber } from "@/remotion/primitives/audio-scrubber";
<AudioScrubber
durationInFrames={120}
marks={[{ atInFrames: 66, label: "Quote" }]}
/>Position comes from frames
Not from audio analysis. The playhead lands exactly on the frame the edit says it should, rather than wherever a detector thinks the audio is — and the scrubber can front a clip that is only being described.
The waveform is static
The colour boundary moves through it. That is the shape of a file, known before
playback; animating the bar heights would be a live spectrum, which is
audiogram-bars.
Pass measured levels as waveform, or let a deterministic envelope be generated
from seed. mirrored centres the bars the way an editor draws them; turn it
off for a baseline-anchored bar chart.
Marks
marks places rules at frame positions with optional labels — chapter points,
quotes, the cut you are about to make. They sit under the playhead, so the
playhead is never hidden behind one.
Position comes from frames rather than audio analysis, so the playhead lands on the frame the edit says it should. The waveform is static and the colour boundary moves through it — animating the heights would make it a live spectrum, which is `audiogram-bars`. Marks sit under the playhead so it is never hidden behind one.
Agent notes
Install first, then import the copied source component locally. AI guide →
@/remotion/primitives/audio-scrubber- Use when: audio-first videos, podcast clips, and waveform visuals.
- Customize: durationInFrames, waveform, barCount, width, plus copied source for timing, layout, colors, and typography.
- Rule: do not import this component from the
remotion-uinpm package; it is copied into your project.
Usage
import { AudioScrubber } from "@/remotion/primitives/audio-scrubber";
<AudioScrubber
durationInFrames={120}
marks={[{ atInFrames: 66, label: "Quote" }]}
/>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| durationInFrames | number | required | Clip length. The playhead crosses the track over exactly this. |
| waveform | number[] | generated | Bar heights 0–1. Omitted, a deterministic envelope is built from `seed`. |
| barCount | number | 96 | Bars drawn when the waveform is generated. |
| width | number | 720 | Overall width, time labels included. |
| height | number | 96 | Track height. Type scales off it. |
| playedColor | string | "#e8b86d" | Bars already played. |
| unplayedColor | string | rgba(250,250,250,0.2) | Bars not yet reached. |
| marks | { atInFrames, label? }[] | undefined | Chapter rules at frame positions. |
| mirrored | boolean | true | Centre the bars the way an editor draws them. |
| showTime | boolean | true | Elapsed and total readouts either side of the track. |
| delayInFrames | number | 0 | Frames before the playhead starts moving. |
| frame | number | undefined | Frame override — pass the parent frame inside a `<Sequence>`. |