react-native-mp3-player
v1.1.1
Published
React Native audio player with reliable iOS background playback. Media controls, queue, hooks. Built for stability and long-running playback.
Maintainers
Readme
react-native-mp3-player
React Native audio player with reliable iOS background playback, media controls, queue management, and React hooks. Built for music and podcast apps. Independent package; no dependency on upstream track-player repos.
For maintainers / new Cursor chats: See HANDOFF.md for project history, what was done, and how to work in this repo.
Features
- Background playback (iOS & Android) – Audio continues when the app is in the background or the screen is locked. No patches required; compatible with current Xcode and Android 14/15.
- iOS – Uses
AVAudioSessionwith.longFormAudioand interruption handling; lock screen and Control Center work natively. - Android – Uses Media3
MediaLibraryServicewithforegroundServiceType="mediaPlayback"; system media notification, lock screen, and Android Auto are supported. - Multi-platform – Android, iOS, Windows.
- Media controls – Lock screen, notification, Bluetooth, Android Auto.
- Queue & playback – Add, remove, reorder tracks; play, pause, seek, repeat, crossfade (where supported).
- React hooks –
useProgress,usePlaybackState,useActiveTrack,useIsPlaying, and more. - Streaming – Local files and remote URLs.
- Input validation – Clear errors when tracks or options are invalid.
Installation
npm install react-native-mp3-playerLink native projects (see React Native docs).
iOS background playback
For audio to continue when the app is backgrounded or the screen is locked (and to avoid the ~50 second cutoff), you must:
- Enable Background Modes → Audio (or “Audio, AirPlay, and Picture in Picture”) in your app’s Xcode project: select your target → Signing & Capabilities → + Capability → Background Modes → check Audio.
- The package configures AVAudioSession (category
.playbackwith options for Bluetooth, AirPlay, ducking) and handles interruptions and background transitions so that playback can continue when the app is backgrounded. - Lock screen and Control Center controls (play, pause, seek, 15-second skip) are handled natively, so they work even when the JavaScript thread is suspended (e.g. screen locked). When the app returns to the foreground, events are emitted so your UI stays in sync.
- Now Playing widget: The package sets and updates MPNowPlayingInfoCenter as soon as a track is loaded (title, artist, duration, elapsed, rate, artwork) and keeps it updated every second during playback. When you pause, the widget shows the track as paused (rate 0), not "Not Playing". Now playing info is only cleared when there is no current track (e.g. after
reset()).
Android background playback
The package is built for Android 14+ compatibility and works when the app is in the background or the screen is off:
- Foreground service: The library declares
FOREGROUND_SERVICE_MEDIA_PLAYBACKand usesandroid:foregroundServiceType="mediaPlayback"on the playback service, as required since Android 14. No extra setup in your app is needed. - Media3 / ExoPlayer: Playback runs in a MediaLibraryService (Media3), which correctly starts as a foreground service with type
mediaPlayback, so background playback and the media notification are allowed by the system. - Media controls: The service is advertised via MediaSessionService and MediaLibraryService so the system media notification, lock screen, Bluetooth, and Android Auto can discover and control playback.
- Target SDK: The library compiles with
compileSdkVersion35 and defaults totargetSdkVersion34. Your app can override these viareact-native-mp3-player’s build extras if needed. Android 15: Do not start the media service from aBOOT_COMPLETEDreceiver; the platform no longer allows that for media playback.
Quick start
import TrackPlayer from 'react-native-mp3-player';
const start = async () => {
await TrackPlayer.setupPlayer({});
await TrackPlayer.add({
id: 'track-1',
url: 'https://example.com/audio.mp3',
title: 'Track Title',
artist: 'Artist Name',
artwork: 'https://example.com/artwork.png',
});
await TrackPlayer.play();
};
start();Register a playback service so remote events (play, pause, next, etc.) are handled:
import TrackPlayer, { Event } from 'react-native-mp3-player';
import PlaybackService from './PlaybackService';
TrackPlayer.registerPlaybackService(() => PlaybackService);API overview
- Lifecycle:
setupPlayer(options?, background?),registerPlaybackService(factory),reset() - Queue:
add(),load(),remove(),skip(),skipToNext(),skipToPrevious(),setQueue(),getQueue(),getActiveTrack()(current track),getActiveTrackIndex() - Playback:
play(),pause(),stop(),seekTo(),seekBy(),setVolume(),setRate(),setRepeatMode() - State & progress:
getPlaybackState()(returns{ state }; use this, notgetState),getProgress()(returns{ position, duration, buffered }in seconds),getPosition()andgetDuration()(convenience wrappers aroundgetProgress()),getVolume(),getRate() - Events:
addEventListener(event, listener)– seeEventenum. Listen forEvent.PlaybackStateso the UI stays in sync when the user taps play/pause. - Hooks:
useProgress(updateInterval?, background?)(interval in milliseconds; e.g.useProgress(250)= every 250 ms),usePlaybackState(),useActiveTrack(),useIsPlaying(),useSetupPlayer(),useMiniPlayer(),useTrackPlayerEvents(), etc.
Setup options (e.g. in setupPlayer / updateOptions): iosCategory (e.g. 'playback'), iosCategoryOptions (e.g. ['allowAirPlay','allowBluetooth','duckOthers']), autoHandleInterruptions, autoUpdateMetadata, waitForBuffer, minBuffer / buffer-related options, forwardJumpInterval / backwardJumpInterval (seconds, e.g. 15), progressUpdateEventInterval (seconds). Types and options are in the package TypeScript definitions.
Global mini player (iOS & Android)
The same APIs and hooks work on both iOS and Android, so you can build a single global mini player (e.g. a persistent bar above the tab bar) that works cross-platform.
- Setup once at app root with
useSetupPlayer(). It runssetupPlayer()and, on Android, retries if the app was in the background, so you get a singleisPlayerReadyfor both platforms. - In your mini player component, use
useMiniPlayer()to get:hasTrack,isPlaying,isLoadingAudiotrack,trackTitle,trackArtist,trackArtworktogglePlayPause(),pause(),stop()refreshActiveTrack(),refreshPlaybackState()(e.g. after returning from another screen)
- Full-screen and close are app-level: e.g. navigate to a full-screen player route for
openFullScreen, and callpause()orstop()plus your own state/navigation for close.
Example:
import TrackPlayer, { useSetupPlayer, useMiniPlayer } from 'react-native-mp3-player';
// At root (e.g. in a provider):
const isPlayerReady = useSetupPlayer({ options: {}, serviceFactory: () => PlaybackService });
// In your global mini player component (when isPlayerReady):
const {
hasTrack, isPlaying, isLoadingAudio,
trackTitle, trackArtist, trackArtwork,
togglePlayPause, pause, stop,
refreshActiveTrack, refreshPlaybackState,
} = useMiniPlayer();Use getActiveTrack() and getPlaybackState() when you need to sync state after navigation or from a widget; the hooks stay in sync via events.
Example app
From the repo root:
npm install
npm run build
npm run exampleSee example/README.md for running the example app.
Documentation
- PERFORMANCE.md – Optimizing speed and reducing bridge calls (progress, events, buffers).
- NOTICE – Attribution and license.
- LICENSE – Apache-2.0.
