Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/afkcodes/react-native-audio-pro/llms.txt

Use this file to discover all available pages before exploring further.

The native layer is the sole authority on playback state in React Native Audio Pro. State transitions are determined by the Swift (iOS) and Kotlin (Android) implementations and communicated to TypeScript exclusively through STATE_CHANGED events. The TypeScript layer never infers, derives, or manufactures a playback state on its own — it only reflects what native reports.
Native emits every state change. TypeScript never infers or emits state. If you observe a state value, it was placed there by a native STATE_CHANGED event — not by any JS-side logic.

States

IDLE

The player has no track loaded and no active media session. This is the implicit default when the app starts — it is never emitted on startup. It is only emitted when the native player fully tears down after a stop on an empty queue or after a critical error clears all state. Transitions into IDLE: native full teardown (e.g. after an unrecoverable error clears all player state).

STOPPED

A track is loaded and the media session is still active, but playback is not running. Position is reset to 0. Duration is preserved. The notification / lock screen controls remain visible. This state occurs after calling stop() or when a track reaches its natural end. Transitions into STOPPED: calling stop(), or when a track ends (TRACK_ENDED).

LOADING

The player is fetching or buffering a track. This state is entered immediately after calling play() and may also occur mid-playback if the network stalls. When buffering occurs mid-playback, LOADING does not mean the user paused — it means the player is waiting for data. Transitions into LOADING: calling play(), or a mid-track network buffer event.

PLAYING

Audio is actively playing. The native rate is greater than zero. Progress events are emitted at the configured progressIntervalMs interval during this state. Transitions into PLAYING: after LOADING completes successfully, or after calling AudioPro.play() while paused.

PAUSED

Audio is paused and the current track is retained in memory. Position is preserved. The player can resume from this state. This state is entered after calling pause() or after play({ autoPlay: false }). Transitions into PAUSED: calling pause(), or starting playback with autoPlay: false.

ERROR

An unrecoverable failure has occurred. The player state is fully cleared — all track and position data is reset. Both STATE_CHANGED: ERROR and a PLAYBACK_ERROR event are emitted. You should handle errors by inspecting the PLAYBACK_ERROR payload and deciding whether to retry. Transitions into ERROR: native onError() when a critical failure occurs.
PLAYBACK_ERROR events and the ERROR state are not the same thing. A PLAYBACK_ERROR event may be emitted independently (for recoverable errors) without the player entering the ERROR state. Native will always emit STATE_CHANGED: ERROR explicitly when the player enters an unrecoverable failure.

State Transition Table

Method / TriggerResulting StateEvents Emitted
App startIDLE (implicit, no event)
configure()No change
play()LOADING → PLAYINGSTATE_CHANGED: LOADING, STATE_CHANGED: PLAYING
play({ autoPlay: false })LOADING → PAUSEDSTATE_CHANGED: LOADING, STATE_CHANGED: PAUSED
pause()PAUSEDSTATE_CHANGED: PAUSED
play() (while paused)PLAYINGSTATE_CHANGED: PLAYING
stop()STOPPEDSTATE_CHANGED: STOPPED
Track reaches endSTOPPEDTRACK_ENDED, STATE_CHANGED: STOPPED
Network stall mid-playbackLOADINGSTATE_CHANGED: LOADING
Unrecoverable native errorERRORSTATE_CHANGED: ERROR, PLAYBACK_ERROR
seekTo() / seekBy()No changeSEEK_COMPLETE

Reading State

Imperatively

Use AudioPro.getPlaybackState() to read the current state synchronously at any time:
import { AudioPro, AudioProState } from 'react-native-audio-pro';

const state = AudioPro.getPlaybackState();

if (state === AudioProState.PLAYING) {
  AudioPro.pause();
} else if (state === AudioProState.PAUSED) {
  AudioPro.play();
}

Reactively in Components

Use the useAudioPro() hook to subscribe to state changes in React components. The hook re-renders only when the selected state changes:
import { useAudioPro, AudioProState } from 'react-native-audio-pro';

function PlaybackControls() {
  const { state } = useAudioPro();

  return (
    <View>
      {state === AudioProState.PLAYING && (
        <Button title="Pause" onPress={() => AudioPro.pause()} />
      )}
      {state === AudioProState.PAUSED && (
        <Button title="Resume" onPress={() => AudioPro.play()} />
      )}
      {state === AudioProState.LOADING && (
        <ActivityIndicator />
      )}
      {state === AudioProState.ERROR && (
        <Text>Playback failed. Please try again.</Text>
      )}
    </View>
  );
}

Buffering vs. User-Intended Pause

LOADING mid-playback is distinct from a user-initiated PAUSED state. Native is responsible for telling them apart:
  • User pauses → native transitions to PAUSED and emits STATE_CHANGED: PAUSED
  • Network stalls → native transitions to LOADING and emits STATE_CHANGED: LOADING. When buffering recovers, native transitions back to PLAYING automatically
You can use this distinction to show a buffering indicator without hiding or changing your play/pause button:
import { useAudioPro, AudioProState } from 'react-native-audio-pro';

function PlayerStatus() {
  const { state } = useAudioPro();

  const isBuffering = state === AudioProState.LOADING;
  const isPaused = state === AudioProState.PAUSED;
  const isPlaying = state === AudioProState.PLAYING;

  return (
    <View>
      {/* Overlay a spinner during buffering without changing the play/pause icon */}
      {isBuffering && <ActivityIndicator style={styles.overlay} />}
      <TouchableOpacity onPress={isPlaying ? AudioPro.pause : AudioPro.play}>
        <Icon name={isPlaying || isBuffering ? 'pause' : 'play'} />
      </TouchableOpacity>
    </View>
  );
}

Build docs developers (and LLMs) love