react-native-apple-shazamkit
v1.0.18
Published
π΅ Powerful music recognition for React Native using Apple's ShazamKit. Identify songs, get metadata, and integrate with Apple Music seamlessly.
Maintainers
Readme
π΅ React Native Apple ShazamKit
A powerful React Native Expo module that brings Apple's ShazamKit audio recognition capabilities to your mobile applications. Identify music, get song metadata, and integrate with Apple Music seamlessly.
π¬ Preview
https://user-images.githubusercontent.com/30924086/229935589-ef3e60ae-10f0-4e0d-aebf-a0ce06d8dba2.mov
β¨ Features
- π€ Real-time Audio Recognition - Identify songs playing around you
- π΅ Rich Metadata - Get song title, artist, artwork, and more
- π Apple Music Integration - Direct links to Apple Music
- π Shazam Library - Add discoveries to user's Shazam library
- π§ Cross-platform - Works on both iOS and Android
- β‘ TypeScript Support - Full type definitions included
- π― Expo Compatible - Works with Expo managed and bare workflows
π Requirements
- iOS: 15.0+ (ShazamKit requirement)
- Android: API 21+ (Android 5.0+)
- Expo SDK: 49+
- React Native: 0.70+
π¦ Installation
npx expo install react-native-apple-shazamkitFor bare React Native projects, ensure you have installed and configured the expo package before continuing.
βοΈ Setup & Configuration
iOS Configuration π
1. Update iOS Deployment Target
ShazamKit requires iOS 15.0+. Update your deployment target:
Using expo-build-properties (Recommended):
{
"plugins": [
[
"expo-build-properties",
{
"ios": {
"deploymentTarget": "15.0"
},
"android": {
"minSdkVersion": 21
}
}
]
]
}For bare React Native projects:
Update ios/Podfile:
platform :ios, '15.0'2. Enable ShazamKit Service
- Go to Apple Developer Console
- Navigate to Certificates, Identifiers & Profiles β Identifiers
- Select your app identifier (or create a new one)
- Under App Services, enable ShazamKit
- Save your changes
3. Add Microphone Permission
Using the plugin (Recommended):
{
"plugins": [
[
"react-native-apple-shazamkit",
{
"microphonePermission": "This app needs microphone access to identify music"
}
]
]
}Manual setup for bare React Native:
Add to ios/YourApp/Info.plist:
<key>NSMicrophoneUsageDescription</key>
<string>This app needs microphone access to identify music</string>4. Install iOS Dependencies
npx pod-installAndroid Configuration π€
1. Add Microphone Permission
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.RECORD_AUDIO" />2. Add ShazamKit Android Dependency
For bare React Native projects, you need to manually add the ShazamKit Android AAR to your app's dependencies.
Option 1: Automatic setup (Recommended)
npx react-native-apple-shazamkit setup-androidOption 2: Manual setup
- Copy the AAR file from the module to your app:
cp node_modules/react-native-apple-shazamkit/android/libs/shazamkit-android-release.aar android/app/libs/- Add the dependency to your
android/app/build.gradle:
dependencies {
implementation files('libs/shazamkit-android-release.aar')
// ... other dependencies
}Note: For Expo managed projects, this is handled automatically during the build process.
3. Request Runtime Permission
import { Platform } from "react-native";
import { request, PERMISSIONS, RESULTS } from "react-native-permissions";
const requestMicrophonePermission = async () => {
if (Platform.OS === "android") {
const result = await request(PERMISSIONS.ANDROID.RECORD_AUDIO);
return result === RESULTS.GRANTED;
}
return true; // iOS handles this automatically
};π Quick Start
import React, { useState } from "react";
import { View, Button, Text, Image, Alert } from "react-native";
import * as Linking from "expo-linking";
import * as ShazamKit from "react-native-apple-shazamkit";
export default function App() {
const [isListening, setIsListening] = useState(false);
const [result, setResult] = useState(null);
const handleIdentifyMusic = async () => {
try {
// Check if ShazamKit is available
if (!(await ShazamKit.isAvailable())) {
Alert.alert("Error", "ShazamKit is not available on this device");
return;
}
setIsListening(true);
setResult(null);
// Start listening for audio
const matches = await ShazamKit.startListening();
if (matches.length > 0) {
setResult(matches[0]);
} else {
Alert.alert("No Match", "Could not identify the song");
}
} catch (error) {
Alert.alert("Error", error.message);
} finally {
setIsListening(false);
}
};
const addToLibrary = async () => {
if (result) {
const response = await ShazamKit.addToShazamLibrary();
Alert.alert(
response.success ? "Success" : "Error",
response.success
? "Added to Shazam library!"
: "Failed to add to library",
);
}
};
return (
<View style={{ flex: 1, justifyContent: "center", padding: 20 }}>
{result && (
<View style={{ alignItems: "center", marginBottom: 30 }}>
<Image
source={{ uri: result.artworkURL }}
style={{ width: 200, height: 200, borderRadius: 10 }}
/>
<Text style={{ fontSize: 24, fontWeight: "bold", marginTop: 15 }}>
{result.title}
</Text>
<Text style={{ fontSize: 18, color: "gray", marginBottom: 20 }}>
{result.artist}
</Text>
<View style={{ flexDirection: "row", gap: 10 }}>
{result.appleMusicURL && (
<Button
title="Open in Apple Music"
onPress={() => Linking.openURL(result.appleMusicURL)}
/>
)}
<Button title="Add to Shazam" onPress={addToLibrary} />
</View>
</View>
)}
<Button
title={isListening ? "Listening..." : "π΅ Identify Music"}
onPress={handleIdentifyMusic}
disabled={isListening}
/>
</View>
);
}π API Reference
Methods
isAvailable(): Promise<boolean>
Checks if ShazamKit is available on the current device.
const available = await ShazamKit.isAvailable();
if (!available) {
console.log("ShazamKit not available");
}startListening(): Promise<MatchedItem[]>
Starts listening for audio and attempts to identify any music. Returns an array of matched songs.
try {
const matches = await ShazamKit.startListening();
if (matches.length > 0) {
console.log("Found song:", matches[0].title);
}
} catch (error) {
console.error("Recognition failed:", error);
}stopListening(): void
Stops the audio recognition process.
ShazamKit.stopListening();addToShazamLibrary(): Promise<{ success: boolean }>
Adds the most recently identified song to the user's Shazam library.
const result = await ShazamKit.addToShazamLibrary();
console.log("Added to library:", result.success);Types
MatchedItem
interface MatchedItem {
/** Song title */
title?: string;
/** Artist name */
artist?: string;
/** Unique Shazam identifier */
shazamID?: string;
/** Apple Music track ID */
appleMusicID?: string;
/** Apple Music URL */
appleMusicURL?: string;
/** Album artwork URL */
artworkURL?: string;
/** Array of genres */
genres?: string[];
/** Web URL (Shazam page) */
webURL?: string;
/** Song subtitle/album */
subtitle?: string;
/** Music video URL */
videoURL?: string;
/** Whether content is explicit */
explicitContent?: boolean;
/** Match offset in seconds */
matchOffset?: number;
/** International Standard Recording Code (ISRC) */
isrc?: string;
}ποΈ Advanced Usage
Error Handling
import { ShazamKitError } from "react-native-apple-shazamkit";
try {
const matches = await ShazamKit.startListening();
} catch (error) {
if (error instanceof ShazamKitError) {
switch (error.code) {
case "PERMISSION_DENIED":
// Handle microphone permission denied
break;
case "NOT_AVAILABLE":
// Handle ShazamKit not available
break;
default:
// Handle other errors
break;
}
}
}Custom Recognition Duration
// Listen for a specific duration (implementation may vary)
const listenWithTimeout = async (timeoutMs = 10000) => {
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error("Recognition timeout")), timeoutMs),
);
try {
const result = await Promise.race([
ShazamKit.startListening(),
timeoutPromise,
]);
return result;
} catch (error) {
ShazamKit.stopListening();
throw error;
}
};Integration with Music Streaming Services
const openInMusicApp = (song: MatchedItem) => {
const musicApps = [
{ name: "Apple Music", url: song.appleMusicURL },
{ name: "Spotify", url: `spotify:search:${song.title} ${song.artist}` },
{
name: "YouTube Music",
url: `https://music.youtube.com/search?q=${encodeURIComponent(
`${song.title} ${song.artist}`,
)}`,
},
];
// Show action sheet with music app options
ActionSheetIOS.showActionSheetWithOptions(
{
options: ["Cancel", ...musicApps.map(app => app.name)],
cancelButtonIndex: 0,
},
buttonIndex => {
if (buttonIndex > 0) {
const selectedApp = musicApps[buttonIndex - 1];
Linking.openURL(selectedApp.url);
}
},
);
};π§ Troubleshooting
Common Issues
"ShazamKit is not available"
- Ensure iOS deployment target is 15.0+
- Verify ShazamKit is enabled in Apple Developer Console
- Check device compatibility (ShazamKit requires iOS 15.0+)
"Module was compiled with an incompatible version of Kotlin"
See our detailed Compatibility Guide for Kotlin version issues.
Microphone permission issues
import { check, request, PERMISSIONS, RESULTS } from "react-native-permissions";
const checkMicrophonePermission = async () => {
const permission =
Platform.OS === "ios"
? PERMISSIONS.IOS.MICROPHONE
: PERMISSIONS.ANDROID.RECORD_AUDIO;
const result = await check(permission);
if (result === RESULTS.DENIED) {
const requestResult = await request(permission);
return requestResult === RESULTS.GRANTED;
}
return result === RESULTS.GRANTED;
};No matches found
- Ensure audio is clear and music is playing
- Check internet connectivity
- Verify the song is in Shazam's database
- Try listening for a longer duration
Android Release Build Error: "Direct local .aar file dependencies are not supported"
This error occurs when building a release AAR for Android. The issue is that the module includes a local AAR dependency which isn't allowed in release builds.
For bare React Native projects:
- Copy the AAR file to your app:
mkdir -p android/app/libs
cp node_modules/react-native-apple-shazamkit/android/libs/shazamkit-android-release.aar android/app/libs/- Add the dependency to your
android/app/build.gradle:
dependencies {
implementation files('libs/shazamkit-android-release.aar')
// ... other dependencies
}For Expo managed projects: The AAR is automatically handled during the Expo build process. No additional configuration needed.
Alternative solution for advanced users: If you need more control, you can publish the AAR to a Maven repository and include it as a regular dependency.
Debug Mode
Enable debug logging to troubleshoot issues:
// This is a conceptual example - actual implementation may vary
ShazamKit.setDebugMode(true);π± Platform Differences
| Feature | iOS | Android | | ----------------------- | --------------------- | ------------------------ | | Audio Recognition | β Native ShazamKit | β Custom Implementation | | Apple Music Integration | β Full Support | β Web Links | | Shazam Library | β Native Integration | β Web Integration | | Offline Recognition | β Limited | β Requires Internet | | Background Recognition | β Supported | β οΈ Limited |
π€ Contributing
We welcome contributions! Please see our Contributing Guide for details.
Development Setup
- Clone the repository
- Install dependencies:
yarn install - Build the module:
yarn build - Run the example:
cd example && yarn ios
Testing
yarn test
yarn lintπ License
This project is licensed under the MIT License - see the LICENSE file for details.
π Acknowledgments
- Apple's ShazamKit framework
- The Expo team for the excellent module infrastructure
- All contributors and users of this library
π Support
- π Bug Reports: GitHub Issues
- π‘ Feature Requests: GitHub Discussions
- π Documentation: Wiki
- π¬ Community: Discord
Made with β€οΈ by the React Native community
