# Audio Playback

As of `stream-chat-react-native@8.11.0`, you can build audio players using:

- `AudioPlayerProvider` React component
- `useAudioPlayerControl` hook
- `useActiveAudioPlayer` hook

## Best Practices

- Wrap audio UI in `AudioPlayerProvider` to keep playback stable in lists.
- Use `useStateStore` selectors to avoid re-rendering on unrelated audio state.
- Prefer single-playback mode unless your UX clearly needs concurrency.
- Reuse the shared player pool instead of creating per-row players.
- Test playback when items unmount to confirm continuity.

The old `useAudioPlayer` hook is deprecated; most functionality is now in `AudioPlayer`.

<admonition type="info">

Before `stream-chat-react-native@8.10.0`, audio used `useAudioController` and lived inside the UI component, which broke playback in virtualized lists. `useAudioPlayerControl` uses a central pool, so playback continues even if the message component unmounts.

</admonition>

Audio playback is controlled via `AudioPlayerProvider` and `useAudioPlayerControl`. The provider maintains a pool of `AudioPlayer` instances; access them with `useAudioPlayerControl`.

By default, `Channel` renders `AudioPlayerProvider`, so its children share a single pool.

## Audio Playback mode

Choose between single or concurrent playback:

**Single-playback mode**: only one audio at a time (default in `Channel`).
**Concurrent-playback mode**: multiple audios can play at once.

Enable concurrent playback by setting `allowConcurrentPlayback` in `AudioPlayerProvider`’s `value`.

## Building Audio Components

To build audio components outside `Channel`:

1. Have a top-level component render `AudioPlayerProvider`

```tsx
const TopLevelComponent = ({ children }) => {
  return (
    <AudioPlayerProvider value={{ allowConcurrentPlayback: false }}>
      {children}
    </AudioPlayerProvider>
  );
};
```

2. Render the audio player in a child component

```tsx
import {
  AudioPlayerState,
  useAudioPlayerControl,
  useStateStore,
} from "stream-chat-react-native";

const audioPlayerSelector = (state: AudioPlayerState) => ({
  currentPlaybackRate: state.currentPlaybackRate,
  duration: state.duration,
  isPlaying: state.isPlaying,
  position: state.position,
  progress: state.progress,
});

const AudioPlayerComponent = () => {
  const audioPlayer = useAudioPlayerControl({
    duration: item.duration ?? 0,
    mimeType: item.mime_type ?? "",
    requester: "audio-player-component",
    type: isVoiceRecording ? "voiceRecording" : "audio",
    uri: item.asset_url ?? "",
  });
  // You can use the following state to build your own audio player UI
  const { duration, isPlaying, position, progress, currentPlaybackRate } =
    useStateStore(audioPlayer.state, audioPlayerSelector);
};
```

3. Get the active audio player

In single-playback mode, a global player UI can show the active audio even if the user scrolls away.

Note: This is relevant only for single-playback mode.

```tsx
import { useActiveAudioPlayer } from "stream-chat-react-native";

const activeAudioPlayer = useActiveAudioPlayer();
```

## Audio Player API

Use the following `AudioPlayer` methods to build a UI:

### Getters

| Method                | Description                                                               |
| --------------------- | ------------------------------------------------------------------------- |
| `isPlaying`           | Get the current playing state of the audio, whether it is playing or not. |
| `duration`            | Get the duration of the audio in milliseconds.                            |
| `progress`            | Get progress as a percentage (0-1).                                       |
| `position`            | Get the current position of the audio in milliseconds.                    |
| `currentPlaybackRate` | Get the current playback rate.                                            |
| `playbackRates`       | Get available playback rates.                                             |
| `id`                  | Get the audio player ID.                                                  |

### Setters

| Method      | Description                                                            |
| ----------- | ---------------------------------------------------------------------- |
| `duration`  | Set the duration of the audio in milliseconds.                         |
| `position`  | Set the position of the audio in milliseconds and update the progress. |
| `progress`  | Set progress (0-1) and update the position.                            |
| `isPlaying` | Set the playing state of the audio.                                    |

### Methods

**_play_** - plays the audio.

| Type         | Description      |
| ------------ | ---------------- |
| `() => void` | Plays the audio. |

```tsx
audioPlayer.play();
```

**_pause_** - pauses the audio.

| Type         | Description       |
| ------------ | ----------------- |
| `() => void` | Pauses the audio. |

```tsx
audioPlayer.pause();
```

**_toggle_** - toggles the playing state of the audio.

| Type         | Description                             |
| ------------ | --------------------------------------- |
| `() => void` | Toggles the playing state of the audio. |

```tsx
audioPlayer.toggle();
```

**_seek_** - seeks to a specific position in the audio.

| Type                                           | Description                                |
| ---------------------------------------------- | ------------------------------------------ |
| `(positionInSeconds: number) => Promise<void>` | Seeks to a specific position in the audio. |

```tsx
await audioPlayer.seek(positionInSeconds);
```

**_stop_** - stops the audio.

| Type                  | Description      |
| --------------------- | ---------------- |
| `() => Promise<void>` | Stops the audio. |

```tsx
await audioPlayer.stop();
```

**_changePlaybackRate_** - changes the playback rate of the audio.

| Type                  | Description                             |
| --------------------- | --------------------------------------- |
| `() => Promise<void>` | Changes the playback rate of the audio. |

```tsx
await audioPlayer.changePlaybackRate(playbackRate);
```

**_initPlayer_** - initializes the audio player using the provided URL or provided player reference.

| Type                                                                          | Description                                                                                                                                                                                   |
| ----------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `({url?: string, playerRef?: React.RefObject<AudioPlayer>}) => Promise<void>` | Initializes the audio player using the provided URL or provided player reference. For Expo, we pass the URL while for audio playing using `react-native-video`, we pass the player reference. |

```tsx
await audioPlayer.initPlayer({ url: "https://example.com/audio.mp3" });
```


---

This page was last updated at 2026-04-17T17:33:45.651Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react-native/v8/guides/audio-playback/](https://getstream.io/chat/docs/sdk/react-native/v8/guides/audio-playback/).