Audio Player

PreviousNext

A customizable audio player with progress controls and playback management for music, podcasts, and voice content.

Installation

pnpm dlx @elevenlabs/agents-cli@latest components add audio-player

Usage

import {
  AudioPlayerButton,
  AudioPlayerDuration,
  AudioPlayerProgress,
  AudioPlayerProvider,
  AudioPlayerTime,
  useAudioPlayer,
  useAudioPlayerTime,
} from "@/components/ui/audio-player"

Basic Player

<AudioPlayerProvider>
  <div className="flex items-center gap-4">
    <AudioPlayerButton />
    <AudioPlayerProgress className="flex-1" />
    <AudioPlayerTime />
    <span>/</span>
    <AudioPlayerDuration />
  </div>
</AudioPlayerProvider>

Playing a Specific Track

const track = {
  id: "track-1",
  src: "/audio/song.mp3",
  data: { title: "My Song", artist: "Artist Name" }
}
 
<AudioPlayerProvider>
  <AudioPlayerButton item={track} />
  <AudioPlayerProgress />
</AudioPlayerProvider>

Multiple Tracks

const tracks = [
  { id: "1", src: "/audio/track1.mp3", data: { title: "Track 1" } },
  { id: "2", src: "/audio/track2.mp3", data: { title: "Track 2" } },
  { id: "3", src: "/audio/track3.mp3", data: { title: "Track 3" } },
]
 
<AudioPlayerProvider>
  <div className="space-y-4">
    {tracks.map((track) => (
      <div key={track.id} className="flex items-center gap-4">
        <AudioPlayerButton item={track} />
        <span className="text-sm">{track.data.title}</span>
      </div>
    ))}
    <AudioPlayerProgress className="w-full" />
    <div className="flex gap-2 text-sm">
      <AudioPlayerTime />
      <span>/</span>
      <AudioPlayerDuration />
    </div>
  </div>
</AudioPlayerProvider>

API Reference

AudioPlayerProvider

The provider component that manages audio state and playback. Must wrap all audio player components.

<AudioPlayerProvider>{children}</AudioPlayerProvider>

AudioPlayerButton

A play/pause button that controls playback. Shows a loading spinner when buffering.

Props

PropTypeDescription
itemAudioPlayerItem<TData>Optional. The audio item to play. If not provided, controls the current track
...propsButtonPropsAll standard Button component props

AudioPlayerItem Type

interface AudioPlayerItem<TData = unknown> {
  id: string | number
  src: string
  data?: TData
}

AudioPlayerProgress

A slider that shows playback progress and allows seeking. Pauses during seeking and resumes after.

Props

PropTypeDescription
...propsSliderPropsAll Radix UI Slider props except min, max, and value

AudioPlayerTime

Displays the current playback time in formatted time (e.g., "1:30").

Props

PropTypeDescription
classNamestringOptional CSS classes
...propsHTMLSpanElementAll standard span element props

AudioPlayerDuration

Displays the total duration of the current track or "--:--" when unavailable.

Props

PropTypeDescription
classNamestringOptional CSS classes
...propsHTMLSpanElementAll standard span element props

useAudioPlayer Hook

Access the audio player context to control playback programmatically.

const {
  ref, // RefObject<HTMLAudioElement>
  activeItem, // Current playing item
  duration, // Track duration in seconds
  error, // MediaError if any
  isPlaying, // Playing state
  isBuffering, // Buffering state
  isItemActive, // Check if an item is active
  setActiveItem, // Set the active item
  play, // Play audio
  pause, // Pause audio
  seek, // Seek to time
} = useAudioPlayer<TData>()

Example Usage

function PlaylistController() {
  const { play, pause, isPlaying, activeItem } = useAudioPlayer()
 
  const handlePlayNext = () => {
    const nextTrack = getNextTrack(activeItem?.id)
    if (nextTrack) {
      play(nextTrack)
    }
  }
 
  return <button onClick={handlePlayNext}>Next Track</button>
}

useAudioPlayerTime Hook

Get the current playback time (updates every frame using requestAnimationFrame).

const time = useAudioPlayerTime() // Current time in seconds

Example Usage

function CustomTimeDisplay() {
  const time = useAudioPlayerTime()
  const { duration } = useAudioPlayer()
 
  const percentage = duration ? (time / duration) * 100 : 0
 
  return <div>Progress: {percentage.toFixed(1)}%</div>
}

Advanced Examples

Custom Controls

function CustomAudioPlayer() {
  const { play, pause, isPlaying, seek, duration } = useAudioPlayer()
 
  return (
    <div className="space-y-4">
      <button onClick={() => (isPlaying ? pause() : play())}>
        {isPlaying ? "Pause" : "Play"}
      </button>
 
      <button onClick={() => seek(0)}>Restart</button>
 
      <button onClick={() => duration && seek(duration * 0.5)}>
        Jump to 50%
      </button>
    </div>
  )
}

Error Handling

function AudioPlayerWithError() {
  const { error, activeItem } = useAudioPlayer()
 
  if (error) {
    return (
      <div className="text-red-500">
        Failed to load: {activeItem?.src}
        <br />
        Error: {error.message}
      </div>
    )
  }
 
  return <AudioPlayerButton />
}

Notes

  • The audio player uses the HTML5 audio element under the hood
  • Progress updates are synchronized using requestAnimationFrame for smooth UI updates
  • The player handles buffering states and network errors automatically
  • Space bar triggers play/pause when the progress slider is focused
  • The component includes TypeScript support with generic data types
  • Audio state is managed globally within the provider context