> ## Documentation Index
> Fetch the complete documentation index at: https://api.fanvue.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# AudioPlayer

> A compact playback control for a single audio clip: a play/pause toggle, a static amplitude waveform that doubles as a seek scrubber, and elapsed/total timestamps.

```tsx theme={null}
import { AudioPlayer } from "@fanvue/ui";
import type { AudioPlayerProps, AudioPlayerSize } from "@fanvue/ui";
```

## Examples

## Unknown Duration

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-audioplayer--unknown-duration&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="AudioPlayer — Unknown Duration" />
</Frame>

```tsx theme={null}
import { AudioPlayer } from "@fanvue/ui";

const SILENT_CLIP_5S = "https://example.com/sample.wav";

<AudioPlayer src="data:audio/wav;base64,bm90LXJlYWwtYXVkaW8=" />
```

## Idle

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-audioplayer--idle&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="AudioPlayer — Idle" />
</Frame>

```tsx theme={null}
import { AudioPlayer } from "@fanvue/ui";

const SILENT_CLIP_5S = "https://example.com/sample.wav";

<AudioPlayer src={SILENT_CLIP_5S} duration={5} />
```

## On Media Card

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-audioplayer--on-media-card&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="AudioPlayer — On Media Card" />
</Frame>

```tsx theme={null}
import { AudioPlayer } from "@fanvue/ui";

const SILENT_CLIP_5S = "https://example.com/sample.wav";

<div
  className="dark relative flex h-[361px] w-[255px] items-end rounded-2xl bg-center bg-cover p-4"
  style={{
    backgroundImage:
      "linear-gradient(0deg, rgba(0,0,0,0.55), rgba(0,0,0,0.15)), url(https://images.unsplash.com/photo-1494203484021-3c454daf695d?w=400&h=600&fit=crop)",
  }}
>
  <AudioPlayer src={SILENT_CLIP_5S} duration={5} className="w-[184px]" />
</div>
```

## Generated Audio Row

<Frame>
  <iframe src={"https://main--697a1b6dd4dad73ee9c0e5f5.chromatic.com/iframe.html?id=components-audioplayer--generated-audio-row&viewMode=story&shortcuts=false&singleStory=true&globals=theme:light"} width="100%" height="220" style={{border: "none", borderRadius: "8px"}} loading="lazy" title="AudioPlayer — Generated Audio Row" />
</Frame>

```tsx theme={null}
import { AudioPlayer } from "@fanvue/ui";

const SILENT_CLIP_5S = "https://example.com/sample.wav";

<div className="w-[424px] rounded-xl border border-border-primary bg-surface-primary p-4">
  <p className="typography-body-small-14px-regular mb-2 text-content-primary">
    Generated Audio
  </p>
  <AudioPlayer src={SILENT_CLIP_5S} duration={5} />
</div>
```

## Props

## AudioPlayer

A compact playback control for a single audio clip: a play/pause toggle, a static amplitude waveform that doubles as a seek scrubber, and elapsed/total timestamps. Designed to sit as an overlay on media thumbnails (Vault cards) as well as inline rows (the AI Voice Message "Generated Audio" row).

The waveform is seeded from the decoded audio when possible, falling back to a deterministic (not random) placeholder derived from `src` so the result is stable across renders, SSR, and Chromatic snapshots.

<ParamField path="src" type="string" required>
  URL of the audio file to play.
</ParamField>

<ParamField path="defaultPlaying" type="boolean" default="false">
  Initial playback state (uncontrolled).
</ParamField>

<ParamField path="duration" type="number">
  Total duration in seconds, used to render the timestamp before the media's own metadata has loaded (and as a fallback if it never does).
</ParamField>

<ParamField path="onEnded" type="(() => void)">
  Called when playback reaches the end of the media.
</ParamField>

<ParamField path="onPause" type="(() => void)">
  Called when playback is paused.
</ParamField>

<ParamField path="onPlay" type="(() => void)">
  Called when playback starts.
</ParamField>

<ParamField path="playing" type="boolean">
  Whether playback is active (controlled). Note: once `onEnded` fires, the browser has already stopped native playback. To loop or replay under controlled usage, toggle this prop `false` then `true` (rather than leaving it `true`) — the sync effect only calls `play()` again when this value actually changes.
</ParamField>

<ParamField path="size" type="&#x22;40&#x22;" default="40">
  Height of the player row, in pixels.
</ParamField>

## Exported types

Also exported from `@fanvue/ui`: `AudioPlayerProps`, `AudioPlayerSize`.

***

**Setup:** [Installation](/docs/ui/installation) · [Theming](/docs/ui/theming)
