npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-media-session

v0.2.1

Published

Implementation of MediaSession and MPNowPlayingInfoCenter on react native

Readme

react-native-media-session

Expose native media controls (iOS Lock Screen / Control Center, Android MediaStyle notification) to React Native. Built with Nitro Modules for synchronous, type-safe native bridging.

Designed to coexist with any audio library — just wire up the remote commands to your player of choice.

Requirements

  • React Native >= 0.76 (New Architecture)
  • iOS >= 13.0
  • Android minSdk >= 24

Installation

npm install react-native-media-session react-native-nitro-modules

react-native-nitro-modules is a required peer dependency.

iOS setup

  1. Install pods:

    cd ios && pod install
  2. Enable Background Modes in Xcode:

    • Open your .xcworkspace in Xcode
    • Select your app target > Signing & Capabilities
    • Click + Capability > Background Modes
    • Check Audio, AirPlay, and Picture in Picture

    Without this, the audio session will be interrupted when the app goes to background and lock screen controls won't appear.

Android setup

The library declares FOREGROUND_SERVICE and FOREGROUND_SERVICE_MEDIA_PLAYBACK permissions in its own manifest — they are merged automatically.

If targeting Android 13+ (API 33), your app must request the POST_NOTIFICATIONS runtime permission to display the media notification:

import { PermissionsAndroid, Platform } from 'react-native';

if (Platform.OS === 'android' && Platform.Version >= 33) {
  await PermissionsAndroid.request(
    PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
  );
}

No other configuration is needed. The module uses autolinking.

Usage

import { MediaSession } from 'react-native-media-session';

// 1. Set now-playing metadata
MediaSession.updateNowPlaying({
  title: 'Song Title',
  artist: 'Artist',
  album: 'Album',
  artwork: 'https://example.com/cover.jpg', // URL or local file path
  duration: 240,
  elapsedTime: 0,
  speed: 1.0,
});

// 2. Update playback state as the track progresses
MediaSession.updatePlaybackState('playing', 42, 1.0);

// 3. Listen to remote commands (lock screen / notification controls)
MediaSession.onRemotePlay(() => player.play());
MediaSession.onRemotePause(() => player.pause());
MediaSession.onRemoteStop(() => player.stop());
MediaSession.onRemoteNextTrack(() => player.next());
MediaSession.onRemotePreviousTrack(() => player.previous());
MediaSession.onRemoteSeek((position) => player.seekTo(position));

// 4. Clear metadata and disable controls when done
MediaSession.reset();

Integration with react-native-nitro-sound

import { MediaSession } from 'react-native-media-session';
import Sound from 'react-native-nitro-sound';

// Start playback and set metadata
await Sound.startPlayer('https://example.com/track.mp3');
MediaSession.updateNowPlaying({
  title: 'Track',
  artist: 'Artist',
  album: 'Album',
  artwork: 'https://example.com/cover.jpg',
  duration: 0, // updated below once known
  elapsedTime: 0,
  speed: 1.0,
});

// Sync progress
Sound.addPlayBackListener((e) => {
  MediaSession.updatePlaybackState(
    'playing',
    e.currentPosition / 1000,
    1.0
  );
});

// Wire remote commands to the player
MediaSession.onRemotePlay(() => Sound.resumePlayer());
MediaSession.onRemotePause(() => Sound.pausePlayer());
MediaSession.onRemoteStop(() => Sound.stopPlayer());
MediaSession.onRemoteSeek((pos) => Sound.seekToPlayer(pos * 1000));

API

updateNowPlaying(info: NowPlayingInfo)

Set the metadata displayed on the lock screen / notification.

| Field | Type | Description | | --- | --- | --- | | title | string | Track title | | artist | string | Artist name | | album | string | Album name | | artwork | string | Image URL or local file path (empty string = no artwork) | | duration | number | Total duration in seconds | | elapsedTime | number | Current position in seconds | | speed | number | Playback rate (1.0 = normal) |

updatePlaybackState(state, elapsedTime, speed)

Update the playback state and position. Call this regularly (e.g. from a playback progress listener) to keep the lock screen / notification in sync.

  • state: 'playing' | 'paused' | 'stopped' | 'buffering'
  • elapsedTime: current position in seconds
  • speed: playback rate

reset()

Clear all metadata, disable remote commands, and remove the notification (Android).

Remote command listeners

Register callbacks for lock screen / notification controls. Multiple callbacks can be registered per event.

| Method | Callback signature | Triggered by | | --- | --- | --- | | onRemotePlay(cb) | () => void | Play button | | onRemotePause(cb) | () => void | Pause button | | onRemoteStop(cb) | () => void | Stop button | | onRemoteNextTrack(cb) | () => void | Next track button | | onRemotePreviousTrack(cb) | () => void | Previous track button | | onRemoteSeek(cb) | (position: number) => void | Seek bar (position in seconds) |

Platform details

iOS

  • Uses MPNowPlayingInfoCenter and MPRemoteCommandCenter
  • Configures AVAudioSession with .playback category for background audio
  • Artwork loaded asynchronously via URLSession (remote URL) or UIImage(contentsOfFile:) (local path)

Android

  • Uses MediaSessionCompat with NotificationCompat.MediaStyle
  • Creates a notification channel "Media Playback" (Android 8+)
  • Notification includes previous / play-pause / next action buttons
  • Artwork loaded asynchronously via HttpURLConnection (remote URL) or BitmapFactory.decodeFile (local path)
  • Context is initialized automatically via a ContentProvider — no manual setup needed

Contributing

License

MIT


Made with create-react-native-library