Skip to content
Info:
This is documentation for Stream Chat React Native SDK v8, which is no longer actively maintained. For up-to-date documentation, see the latest version (v9).

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.

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.

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
const TopLevelComponent = ({ children }) => {
  return (
    <AudioPlayerProvider value={{ allowConcurrentPlayback: false }}>
      {children}
    </AudioPlayerProvider>
  );
};
  1. Render the audio player in a child component
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);
};
  1. 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.

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.
audioPlayer.play();

pause - pauses the audio.

Type Description
() => void Pauses the audio.
audioPlayer.pause();

toggle - toggles the playing state of the audio.

Type Description
() => void Toggles the playing state of the audio.
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.
await audioPlayer.seek(positionInSeconds);

stop - stops the audio.

Type Description
() => Promise<void> Stops the audio.
await audioPlayer.stop();

changePlaybackRate - changes the playback rate of the audio.

Type Description
() => Promise<void> Changes the playback rate of the audio.
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.
await audioPlayer.initPlayer({ url: "https://example.com/audio.mp3" });