Queue
MediaItem
Every item in the queue is a MediaItem:
| Field | Type | Default | Description |
|---|---|---|---|
| mediaId | string | — | Stable identifier for this media item. Should be unique within your app. If not provided, the URL will be used as the mediaId. This maps to Media3's MediaItem.mediaId on Android. |
| url * | MediaUrl | — | URL or URI to the media file. Can be a string or an object with options. |
| title | string | — | — |
| artist | string | — | — |
| albumTitle | string | — | — |
| artworkUrl | MediaUrl | — | — |
| duration | number | — | Duration in seconds (optional hint for UI). |
| isLive | boolean | — | Whether this is a live stream. When `true`, caching and preloading are disabled and the stream is played directly. |
| mimeType | string | — | MIME type of the media (e.g. 'audio/mpeg', 'audio/aac', 'application/x-mpegURL'). On Android, this is passed to ExoPlayer and to the Chromecast receiver. Set it when the URL has no file extension (e.g. bare Icecast streams) so the Cast receiver can identify the format — without it the track will be skipped. |
| extras v5.1.0+ | Record<string, unknown> | — | App-defined payload attached to this media item. Opaque to the player — stored verbatim and returned unchanged by getActiveMediaItem, getQueue, and the Event.MediaItemTransition event. Use this for app-specific metadata that should travel with the item (e.g. recommendation source, ISRC, internal IDs) without polluting the typed fields. Must be JSON-serializable. Keep payloads small — large blobs are better kept in your own JS state, keyed by mediaId. |
The url accepts a string, a React Native asset (require('./file.mp3')), or an object with custom HTTP headers ({ uri, headers }). Per-item headers override any defaults injected by the underlying player.
Setting the queue
Replace the entire queue and reset position:
TrackPlayer.setMediaItems(items);
TrackPlayer.setMediaItems(items, 2); // start from index 2 Set a single item (replaces the queue with one track):
TrackPlayer.setMediaItem(item); To begin playback after either call, follow with TrackPlayer.play().
Adding tracks
TrackPlayer.addMediaItem(item);
TrackPlayer.addMediaItems(items);
TrackPlayer.insertMediaItem(index, item);
TrackPlayer.insertMediaItems(index, items); Removing tracks
TrackPlayer.removeMediaItem(index);
// Range is half-open: [fromIndex, toIndex) — toIndex is exclusive.
TrackPlayer.removeMediaItems(fromIndex, toIndex);
TrackPlayer.clear(); removeMediaItems uses a half-open range — toIndex is exclusive. removeMediaItems(0, 3) removes items at indices 0, 1, 2.Reordering
TrackPlayer.moveMediaItem(fromIndex, toIndex); Replacing a track
TrackPlayer.replaceMediaItem(index, newItem); May continue playback seamlessly if the URL hasn’t changed.
Updating metadata
Useful for live streams where metadata arrives mid-playback (e.g. ICY stream tags). Only the provided fields are updated; omitted fields keep their current values.
TrackPlayer.updateMetadata(index, {
title: 'Now Playing: Song Title',
artist: 'Artist Name',
}); Reading queue state
const queue = TrackPlayer.getQueue();
const current = TrackPlayer.getActiveMediaItem();
const index = TrackPlayer.getActiveMediaItemIndex(); All three are synchronous — no await needed.
App-defined payload
Use extras to attach app-specific data (ISRC, recommendation source, internal IDs, etc.) to a media item. The payload is opaque to the player — stored verbatim and delivered back unchanged via getActiveMediaItem, getQueue, and MediaItemTransition.
TrackPlayer.setMediaItem({
mediaId: 'track-1',
url: 'https://example.com/track.mp3',
title: 'My Track',
extras: {
source: 'recommendations',
isrc: 'USRC17607839',
},
}); mediaId.