A fully composable audio player component system. Build custom audio interfaces by combining individual control components.
Installation
pnpm dlx shadcn@latest add @audio/player
Setup
AudioProvider Required: Wrap your app with
AudioProvider at the root level. This provides the audio context
to all components. The provider manages audio playback state, handles events,
manages error retries, and preloads tracks.
First, wrap your app with AudioProvider at the root level:
// app/layout.tsx or _app.tsx
import { AudioProvider } from "@/components/audio/provider";
export default function RootLayout({ children }) {
return (
<html>
<body>
<AudioProvider tracks={initialTracks}>{children}</AudioProvider>
</body>
</html>
);
}Usage
Import the components you need:
import {
AudioPlayer,
AudioPlayerControlBar,
AudioPlayerControlGroup,
AudioPlayerPlay,
AudioPlayerSkipBack,
AudioPlayerSkipForward,
AudioPlayerRewind,
AudioPlayerFastForward,
AudioPlayerSeekBar,
AudioPlayerTimeDisplay,
AudioPlayerVolume,
} from "@/components/audio/player";<AudioPlayer>
<AudioPlayerControlBar>
<AudioPlayerControlGroup>
<AudioPlayerRewind />
<AudioPlayerSkipBack />
<AudioPlayerPlay />
<AudioPlayerSkipForward />
<AudioPlayerFastForward />
<AudioPlayerTimeDisplay />
<AudioPlayerSeekBar />
<AudioPlayerTimeDisplay remaining />
<AudioPlayerVolume />
</AudioPlayerControlGroup>
</AudioPlayerControlBar>
</AudioPlayer>Stacked Layout
A player with stacked variant, showing time displays above and below the seek bar.
Player with Queue
A full-featured player with queue management, shuffle, and repeat controls. Uses AudioPlayerControlGroup for flexible layout management.
For more queue management options, see the Audio Queue documentation.
API Reference
AudioPlayer
A styled container component for audio controls. This is a presentational wrapper that provides consistent styling. All audio components are self-contained and read state from the global store.
Props
Inherits all props from HTMLDivElement.
Example
<AudioPlayer>{/* Your audio controls */}</AudioPlayer>AudioPlayerControlBar
A container component that holds audio player controls. Use it to wrap your control components.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "compact" | "stacked" | "compact" | Layout variant for the control bar. |
className | string | - | Additional CSS classes. |
Example
<AudioPlayerControlBar>
<AudioPlayerPlay />
<AudioPlayerSeekBar />
<AudioPlayerTimeDisplay />
</AudioPlayerControlBar>Stacked Layout
<AudioPlayerControlBar variant="stacked">
<AudioPlayerControlGroup>
<AudioPlayerTimeDisplay />
<AudioPlayerSeekBar />
<AudioPlayerTimeDisplay remaining />
</AudioPlayerControlGroup>
</AudioPlayerControlBar>AudioPlayerControlGroup
A flexible wrapper component for grouping audio controls and managing flex layouts. Useful for creating custom layouts with flex-col, justify-between, etc.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes. |
Example
<AudioPlayerControlBar variant="stacked">
<AudioPlayerControlGroup>
<AudioPlayerTimeDisplay />
<AudioPlayerSeekBar />
<AudioPlayerTimeDisplay remaining />
</AudioPlayerControlGroup>
<AudioPlayerControlGroup className="justify-between">
<AudioPlayerControlGroup>
<AudioPlayerSkipBack />
<AudioPlayerPlay />
<AudioPlayerSkipForward />
</AudioPlayerControlGroup>
<AudioPlayerVolume />
</AudioPlayerControlGroup>
</AudioPlayerControlBar>AudioPlayerPlay
A button that toggles play/pause state. Shows a loading spinner when buffering or loading, and automatically handles keyboard shortcuts (Space bar to play/pause).
Inherits all props from AudioPlayerButton (which extends shadcn/ui's Button component).
Keyboard Shortcuts: The AudioPlayerPlay
component automatically handles the Space bar keyboard shortcut for
play/pause. This works when the focus is on the document body.
AudioPlayerSkipBack
A button that navigates to the previous track.
Inherits all props from AudioPlayerButton (which extends shadcn/ui's Button component).
AudioPlayerSkipForward
A button that navigates to the next track.
Inherits all props from AudioPlayerButton (which extends shadcn/ui's Button component).
AudioPlayerRewind
A button that seeks backward by 10 seconds.
Inherits all props from AudioPlayerButton (which extends shadcn/ui's Button component).
AudioPlayerFastForward
A button that seeks forward by 10 seconds.
Inherits all props from AudioPlayerButton (which extends shadcn/ui's Button component).
AudioPlayerSeekBar
A slider component that shows playback progress and allows seeking. Automatically syncs with the current track's playback position.
Inherits all props from Slider component (except value, onValueChange, min, max, bufferValue).
AudioPlayerTimeDisplay
Displays the current playback time or remaining time.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
remaining | boolean | false | Display remaining time instead of current time. |
className | string | - | Additional CSS classes. |
AudioPlayerVolume
A dropdown menu button with a slider to control volume. Click to open the volume control menu.
Inherits all props from DropdownMenu component.
Notes
- Component Architecture: All audio components are self-contained and read state directly from the global store. The audio player uses the HTML5 audio element under the hood.
- AudioProvider Role: The
AudioProvidercomponent manages the audio element lifecycle using theuseAudio()hook to access thehtmlAudiosingleton, handles playback events, manages error retries (up to 3 retries with exponential backoff), preloads next tracks, and synchronizes audio state with the Zustand store. It's required for all audio components to function correctly. - Previous Button Behavior: The previous button restarts the track if it has been played for more than 3 seconds, otherwise it navigates to the previous track in the queue.
Live Stream Limitations: Live streams disable seeking, rewind, and fast-forward controls. The seek bar is disabled and shows 100% progress for live streams.
Changelog
2025-12-24 useAudio integration and improvements
- Changed: Provider now uses
useAudio()hook to accesshtmlAudiosingleton - Improved: Better state synchronization between audio element and Zustand store
- Fixed: Slider synchronization when pausing and resuming playback
- Improved: Event listener management using
AbortControllerfor cleaner cleanup
Last updated 12/24/2025
On This Page