Audio Player

Media

Audio player with playback controls and progress.

Preview

Sample Audio Track

Usage

example.jsx
import { AudioPlayer } from "@/components/ui/audio-player";

export default function Example() {
  return <AudioPlayer />;
}

Source Code

Copy this file into components/ui/audio-player.jsx in your project.

audio-player.jsx
"use client";

import { forwardRef, useRef, useState } from "react";
import { cn } from "@/lib/utils";

const AudioPlayer = forwardRef(({ className, src, title, ...props }, ref) => {
  const audioRef = useRef(null);
  const [playing, setPlaying] = useState(false);
  const [progress, setProgress] = useState(0);

  const toggle = () => {
    if (!audioRef.current) return;
    if (playing) audioRef.current.pause();
    else audioRef.current.play();
  };

  const onTimeUpdate = () => {
    if (!audioRef.current) return;
    setProgress((audioRef.current.currentTime / audioRef.current.duration) * 100 || 0);
  };

  return (
    <div ref={ref} className={cn("flex items-center gap-3 rounded-lg border bg-background p-3", className)} {...props}>
      <audio ref={audioRef} src={src}
        onPlay={() => setPlaying(true)} onPause={() => setPlaying(false)}
        onEnded={() => setPlaying(false)} onTimeUpdate={onTimeUpdate}
      />
      <button onClick={toggle} className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground">
        {playing ? (
          <svg className="h-4 w-4" fill="currentColor" viewBox="0 0 24 24"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z" /></svg>
        ) : (
          <svg className="ml-0.5 h-4 w-4" fill="currentColor" viewBox="0 0 24 24"><path d="M8 5v14l11-7z" /></svg>
        )}
      </button>
      <div className="flex-1 min-w-0">
        {title && <div className="truncate text-sm font-medium">{title}</div>}
        <div className="mt-1 h-1.5 w-full overflow-hidden rounded-full bg-muted">
          <div className="h-full rounded-full bg-primary transition-all" style={{ width: `${progress}%` }} />
        </div>
      </div>
    </div>
  );
});
AudioPlayer.displayName = "AudioPlayer";

export { AudioPlayer };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge