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`, this item bypasses the cache and is played directly from the origin, and it is never preloaded. Live segments are consumed once at the live edge and never replayed, so caching them would only churn the cache (evicting reusable on-demand content) and waste bandwidth. Set this for genuine live streams (radio, live events). You do **not** need it just to play HLS — on-demand `.m3u8` streams are cached and play fine without it. On iOS, live HLS is additionally detected automatically (a playlist with no `#EXT-X-ENDLIST` is treated as live and its segments are never cached), so forgetting the flag degrades gracefully; on Android, detection relies on this flag, so set it to avoid live-segment cache churn. |
| 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 field accepts:
- A remote URL —
'https://example.com/song.mp3' - A
file://URL —'file:///path/to/song.mp3' - A bare absolute path —
'/path/to/song.mp3'(automatically treated asfile://) - A bare asset name —
'song.mp3'(resolved from the app bundle on iOS,res/rawon Android) - A
require()asset —require('./song.mp3') - An object with a URI and optional HTTP headers —
{ uri, headers }. Per-item headers override any defaults injected by the underlying player. - On iOS,
{ uri: 'song.mp3', bundle: 'Sounds' }loads fromSounds.bundle/song.mp3.
Setting the queue
Replace the entire queue and reset position:
Clears the queue, adds the media items, and resets position.
TrackPlayer.setMediaItems(items);
TrackPlayer.setMediaItems(items, 2); // start from index 2 Set a single item (replaces the queue with one track):
Clears the queue, adds the media item, and resets position. To begin playback, call play after this.
TrackPlayer.setMediaItem(item); To begin playback after either call, follow with TrackPlayer.play().
Adding tracks
Append a media item to the end of the queue.
Append media items to the end of the queue.
Insert a media item at the given index.
Insert media items starting at the given index.
TrackPlayer.addMediaItem(item);
TrackPlayer.addMediaItems(items);
TrackPlayer.insertMediaItem(index, item);
TrackPlayer.insertMediaItems(index, items); Removing tracks
Remove the media item at the given index.
Remove media items in the range [fromIndex, toIndex).
Clear all media items from the queue.
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
Move a media item from one position to another.
TrackPlayer.moveMediaItem(fromIndex, toIndex); Replacing a track
Replace the media item at the given index. May continue playback seamlessly if the URL hasn't changed.
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.
Update display metadata for a media item without interrupting playback. Only provided fields are updated; omitted fields keep their current values. Useful for livestreams/radio where metadata changes while the stream URL stays the same.
TrackPlayer.updateMetadata(index, {
title: 'Now Playing: Song Title',
artist: 'Artist Name',
}); Reading queue state
Gets all media items in the queue.
Gets the currently active media item, or null if none.
Gets the index of the currently active media item, or null if none.
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.