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.

React Native Audio Pro provides a queue API that is directly aligned with Android’s Media3 ExoPlayer interface, making the mental model familiar to Android developers and ensuring predictable behavior on both platforms. The queue holds an ordered list of AudioProTrack objects. You can add, insert, remove, reorder, and replace tracks at any time — even during active playback. Queue mutations are applied immediately by the native player without interrupting the currently playing item.
Gapless playback is enabled by default when multiple tracks are in the queue. As the current track nears its end, the native player pre-buffers the next track so there is no audible gap between items.

Track Shape

Every item in the queue is an AudioProTrack object:
type AudioProTrack = {
  id: string;          // Unique identifier for the track
  url: string;         // Remote URL (https://) or local file path
  title: string;       // Display title shown in lock screen / notification
  artwork: string;     // URL or local path to the album art image
  album?: string;      // Optional album name
  artist?: string;     // Optional artist name
  [key: string]: unknown; // Any additional custom properties
};
Custom properties (e.g., duration, genre, podcastId) can be stored on the track object and will be passed through in event payloads as-is. The native layer ignores unknown keys.

Queue Methods

addMediaItems(items)

Appends one or more tracks to the end of the queue. Accepts a single AudioProTrack or an array of them.
AudioPro.addMediaItems([
  {
    id: 'track-1',
    url: 'https://cdn.example.com/audio/track1.mp3',
    title: 'Track One',
    artwork: 'https://cdn.example.com/art/track1.jpg',
    artist: 'Artist Name',
    album: 'Album Title',
  },
  {
    id: 'track-2',
    url: 'https://cdn.example.com/audio/track2.mp3',
    title: 'Track Two',
    artwork: 'https://cdn.example.com/art/track2.jpg',
  },
]);

setMediaItems(items)

Replaces the entire queue with the provided array. Equivalent to clearing the queue and adding all items at once. The currently playing track will be stopped.
AudioPro.setMediaItems(playlist);

addMediaItemsAt(index, items)

Inserts one or more tracks at the specified zero-based index. Items at and after index are shifted right.
// Insert a track at position 2 (0-based)
AudioPro.addMediaItemsAt(2, {
  id: 'bonus-track',
  url: 'https://cdn.example.com/audio/bonus.mp3',
  title: 'Bonus Track',
  artwork: 'https://cdn.example.com/art/bonus.jpg',
});

removeMediaItem(index)

Removes the single track at the specified zero-based index.
// Remove the track at position 3
AudioPro.removeMediaItem(3);

removeMediaItems(fromIndex, toIndex)

Removes all tracks in the range [fromIndex, toIndex) — inclusive of fromIndex, exclusive of toIndex. This is the Media3-aligned half-open range convention.
// Remove tracks at positions 1, 2, and 3 (not 4)
AudioPro.removeMediaItems(1, 4);

moveMediaItem(currentIndex, newIndex)

Moves a track from one position to another in the queue. The indices are zero-based.
// Move the track at index 5 to index 1
AudioPro.moveMediaItem(5, 1);

clearMediaItems()

Removes all tracks from the queue. Playback stops immediately.
AudioPro.clearMediaItems();

getMediaItems()

Returns a Promise that resolves to the full array of AudioProTrack objects currently in the queue.
const tracks = await AudioPro.getMediaItems();
console.log(`Queue has ${tracks.length} tracks`);

seekToMediaItem(index, positionMs?)

Jumps to the track at the specified zero-based index. Optionally accepts a positionMs to start playback at a specific position within that track.
// Jump to track index 4
AudioPro.seekToMediaItem(4);

// Jump to track index 4, starting at 30 seconds in
AudioPro.seekToMediaItem(4, 30000);

seekToNextMediaItem()

Advances to the next track in the queue. If the current track is the last item and repeat is OFF, this is a no-op.
AudioPro.seekToNextMediaItem();

seekToPreviousMediaItem()

Moves to the previous track in the queue. If the current track is the first item, this is a no-op (or wraps if repeat mode is ALL).
AudioPro.seekToPreviousMediaItem();

setRepeatMode(mode)

Sets the repeat behavior for queue playback. Accepts 'OFF', 'ONE', or 'ALL'.
ModeBehavior
'OFF'Play through the queue once, then stop (default)
'ONE'Repeat the current track indefinitely
'ALL'Loop the entire queue after the last track ends
import { AudioPro } from 'react-native-audio-pro';

AudioPro.setRepeatMode('ALL');   // Loop the whole queue
AudioPro.setRepeatMode('ONE');   // Loop the current track
AudioPro.setRepeatMode('OFF');   // Play once and stop

setShuffleModeEnabled(enabled)

Enables or disables shuffle mode. When true, the queue plays in a randomised order. The original queue order is preserved and restored when shuffle is disabled.
AudioPro.setShuffleModeEnabled(true);  // Enable shuffle
AudioPro.setShuffleModeEnabled(false); // Disable shuffle, restore order

updateTrack(index, track)

Updates the track at the specified index with a new AudioProTrack object. Useful for refreshing a signed URL before it expires or updating metadata such as the artwork image.
const freshTrack: AudioProTrack = {
  id: 'track-3',
  url: 'https://cdn.example.com/audio/track3-refreshed.mp3?token=newtoken',
  title: 'Track Three',
  artwork: 'https://cdn.example.com/art/track3.jpg',
};

AudioPro.updateTrack(2, freshTrack);

Full Example: Load Queue, Play, and Sync UI

This example loads a playlist, starts playback, and listens for TRACK_CHANGED events to keep the UI in sync with the currently playing track.
import { useEffect, useState } from 'react';
import {
  AudioPro,
  AudioProEventType,
  useAudioPro,
} from 'react-native-audio-pro';
import type { AudioProTrack, AudioProEvent } from 'react-native-audio-pro';

const playlist: AudioProTrack[] = [
  {
    id: '1',
    url: 'https://cdn.example.com/audio/ep1.mp3',
    title: 'Episode 1',
    artwork: 'https://cdn.example.com/art/ep1.jpg',
    artist: 'Podcast Name',
    album: 'Season 1',
  },
  {
    id: '2',
    url: 'https://cdn.example.com/audio/ep2.mp3',
    title: 'Episode 2',
    artwork: 'https://cdn.example.com/art/ep2.jpg',
    artist: 'Podcast Name',
    album: 'Season 1',
  },
  {
    id: '3',
    url: 'https://cdn.example.com/audio/ep3.mp3',
    title: 'Episode 3',
    artwork: 'https://cdn.example.com/art/ep3.jpg',
    artist: 'Podcast Name',
    album: 'Season 1',
  },
];

function PodcastPlayer() {
  // Reactive state from the internal store
  const { state, playingTrack, activeTrackIndex, queueSize } = useAudioPro();

  function loadAndPlay() {
    // Replace the queue with the full playlist
    AudioPro.setMediaItems(playlist);
    // Start playback from the first track
    AudioPro.play();
  }

  // Listen for TRACK_CHANGED to update any custom UI beyond useAudioPro
  useEffect(() => {
    const subscription = AudioPro.addEventListener((event: AudioProEvent) => {
      if (event.type === AudioProEventType.TRACK_CHANGED) {
        const { index } = event.payload!;
        console.log(`Now playing: ${event.track?.title} (index ${index})`);
      }

      if (event.type === AudioProEventType.REMOTE_NEXT) {
        AudioPro.seekToNextMediaItem();
      }

      if (event.type === AudioProEventType.REMOTE_PREV) {
        AudioPro.seekToPreviousMediaItem();
      }
    });

    return () => {
      subscription.remove();
    };
  }, []);

  return (
    <View>
      <Text>{playingTrack?.title ?? 'No track loaded'}</Text>
      <Text>
        Track {activeTrackIndex + 1} of {queueSize}
      </Text>
      <Button title="Load Playlist" onPress={loadAndPlay} />
      <Button title="Previous" onPress={() => AudioPro.seekToPreviousMediaItem()} />
      <Button title="Next" onPress={() => AudioPro.seekToNextMediaItem()} />
    </View>
  );
}

Reading Queue State Reactively

The useAudioPro() hook exposes activeTrackIndex and queueSize — both updated automatically when QUEUE_CHANGED or TRACK_CHANGED events arrive from native:
const { activeTrackIndex, queueSize, playingTrack } = useAudioPro();

// Check if there's a next track
const hasNext = activeTrackIndex < queueSize - 1;

// Check if there's a previous track
const hasPrev = activeTrackIndex > 0;

Build docs developers (and LLMs) love