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

@beatsphere/expo-music-detector

v0.1.0

Published

Expo native module for detecting currently playing music on Android via MediaSession and NotificationListener

Readme

@beatsphere/expo-music-detector

Expo native module that detects currently playing music on Android. Uses MediaSession and NotificationListenerService to detect tracks from 10+ music apps in real-time. Battle-tested in BeatSphere.

Supported Apps

| App | Package Name | |-----|-------------| | Spotify | com.spotify.music | | YouTube | com.google.android.youtube | | YouTube Music | com.google.android.apps.youtube.music | | Apple Music | com.apple.android.music | | SoundCloud | com.soundcloud.android | | Last.fm | fm.last.android | | Amazon Music | com.amazon.mp3 | | Pandora | com.pandora.android | | Tidal | com.aspiro.tidal | | Deezer | deezer.android.app |

Any other app using Android's MediaSession API will be detected as unknown provider.

Install

npm install @beatsphere/expo-music-detector

Add the plugin to your app.config.js:

export default {
  plugins: [
    '@beatsphere/expo-music-detector',
  ],
};

Run prebuild:

npx expo prebuild --clean

Quick Start

import {
  isSupported,
  isNotificationAccessGranted,
  openNotificationSettings,
  getCurrentTrack,
  addTrackChangedListener,
} from '@beatsphere/expo-music-detector';

// Check platform support (Android only)
if (!isSupported) {
  console.log('Music detection is only supported on Android');
}

// Check and request permission
const hasAccess = isNotificationAccessGranted();
if (!hasAccess) {
  // Opens system settings — user must manually enable
  openNotificationSettings();
}

// Get current track
const track = getCurrentTrack();
if (track) {
  console.log(`${track.title} by ${track.artist} (${track.provider})`);
}

// Listen for track changes
const subscription = addTrackChangedListener((event) => {
  if (event.track) {
    console.log(`Now playing: ${event.track.title} by ${event.track.artist}`);
    console.log(`Provider: ${event.track.provider}`);
    console.log(`Playing: ${event.track.isPlaying}`);
  } else {
    console.log('Playback stopped');
  }
});

// Clean up
subscription.remove();

How It Works

On Android, the module uses two detection mechanisms:

  1. MediaSessionManager (primary) — Listens for active media sessions and registers callbacks for metadata and playback state changes. This provides the most reliable detection.

  2. NotificationListenerService (fallback) — Parses music notifications for apps that don't use MediaSession properly. Extracts title, artist, and album from notification extras.

The module requires Notification Listener Access, which the user must grant manually in system settings. This is an Android system-level permission that cannot be requested via a dialog.

API Reference

| Function | Description | |----------|-------------| | isSupported | boolean — Whether the current platform supports music detection (Android only) | | isNotificationAccessGranted() | Check if notification listener permission is granted | | openNotificationSettings() | Open system settings for notification access | | startMonitoring() | Start monitoring (service starts automatically with permission) | | stopMonitoring() | Stop monitoring | | getCurrentTrack() | Get the currently playing track, or null | | addTrackChangedListener(cb) | Subscribe to track changes. Returns { remove() } |

Track Type

interface Track {
  title: string;
  artist: string;
  album?: string;
  albumArt?: string;
  provider: MusicProvider;
  isPlaying: boolean;
}

type MusicProvider =
  | 'spotify'
  | 'youtube'
  | 'apple_music'
  | 'soundcloud'
  | 'lastfm'
  | 'amazon_music'
  | 'pandora'
  | 'tidal'
  | 'deezer'
  | 'unknown';

Platform Notes

Android

  • API 21+ (Lollipop) required
  • Uses MediaSessionManager for reliable detection on API 22+
  • Falls back to notification parsing on older versions
  • Requires BIND_NOTIFICATION_LISTENER_SERVICE permission
  • The NotificationListenerService runs as long as the user grants access
  • Automatically detects track changes across all supported music apps

iOS

  • Music detection is not supported on iOS
  • All functions return safe defaults (null, false, no-ops)
  • The iOS module stub is included so your app builds cross-platform without conditional imports

License

MIT