react-native-music-control
React Native module to control remote controls on lockscreen + display Now playing Info on lockscreen (MPNowPlayingInfoCenter)
Play well with React Native Sound
Mix between :
Project using it :
Install
Add it to your project
npm install react-native-music-control --save
iOS
Automatic
react-native link
:warning: You must enable Audio Background mode in XCode project settings :
Manual
In XCode, right click Libraries. Click Add Files to "[Your project]". Navigate to node_modules/react-native-music-control. Add the file MusicControl.xcodeproj.
In the Project Navigator, select your project. Click the build target. Click Build Phases. Expand Link Binary With Libraries. Click the plus button and add libMusicControl.a under Workspace.
CocoaPods
pod 'react-native-music-control', :path => '../node_modules/react-native-music-control'
Android
Automatic
react-native link
Manual
android/app/build.gradle
dependencies {
...
compile "com.facebook.react:react-native:+" // From node_modules
+ compile project(':react-native-music-control')
}
android/settings.gradle
...
include ':app'
+include ':react-native-music-control'
+project(':react-native-music-control').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-music-control/android')
MainActivity.java
+import com.tanguyantoine.react.MusicControl;
public class MainApplication extends Application implements ReactApplication {
//......
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
+ new MusicControl(),
new MainReactPackage()
);
}
//......
}
Use
import MusicControl from 'react-native-music-control';
Now Playing
This method enables the music controls. To disable them, use resetNowPlaying()
You should call this method after a sound is playing.
For Android's rating system, remove the rating
value for unrated tracks, use boolean for RATING_HEART or RATING_THUMBS_UP_DOWN and use a number for other types. Note: To use custom types, you have to define the type with updatePlayback
before calling this function.
MusicControl.setNowPlaying({
title: 'Billie Jean',
artwork: 'https://i.imgur.com/e1cpwdo.png',
artist: 'Michael Jackson',
album: 'Thriller',
genre: 'Post-disco, Rhythm and Blues, Funk, Dance-pop',
duration: 294,
description: '',
color: 0xFFFFFF,
date: '1983-01-02T00:00:00Z',
rating: 84,
notificationIcon: 'my_custom_icon'
})
Playback
You don't need to call this method filling all properties, but you should always fill elapsedTime
for iOS support and better performance on Android.
You also don't need to call this method repeatedly to update the elapsedTime
, only call it when you need to update any other property
MusicControl.updatePlayback({
state: MusicControl.STATE_PLAYING,
speed: 1,
elapsedTime: 103,
bufferedTime: 200,
volume: 10,
maxVolume: 10,
rating: MusicControl.RATING_PERCENTAGE
})
Examples
MusicControl.updatePlayback({
state: MusicControl.STATE_PAUSED,
elapsedTime: 135
})
MusicControl.updatePlayback({
volume: 9,
elapsedTime: 167
})
Reset now playing
Resets and hides the music controls
MusicControl.resetNowPlaying()
Stop controls
Resets, hides the music controls and disables everything
MusicControl.stopControl()
Enable/disable controls
iOS: Lockscreen
Android: Notification and external devices (smartwatches, cars)
MusicControl.enableControl('play', true)
MusicControl.enableControl('pause', true)
MusicControl.enableControl('stop', false)
MusicControl.enableControl('nextTrack', true)
MusicControl.enableControl('previousTrack', false)
MusicControl.enableControl('seekForward', false)
MusicControl.enableControl('seekBackward', false)
MusicControl.enableControl('seek', false)
MusicControl.enableControl('skipForward', false)
MusicControl.enableControl('skipBackward', false)
MusicControl.enableControl('setRating', false)
MusicControl.enableControl('volume', true)
MusicControl.enableControl('remoteVolume', false)
MusicControl.enableControl('enableLanguageOption', false)
MusicControl.enableControl('disableLanguageOption', false)
skipBackward
and skipForward
controls on accept additional configuration options with interval
key:
MusicControl.enableControl('skipBackward', true, {interval: 15}))
MusicControl.enableControl('skipForward', true, {interval: 30}))
Important Notes:
- Android only supports the intervals 5, 10, & 30, while iOS supports any number
- The interval value only changes what number displays in the UI, the actual logic to skip forward or backward by a given amount must be implemented in the appropriate callbacks
- When using react-native-sound for audio playback, make sure that on iOS
mixWithOthers
is set to false
in Sound.setCategory(value, mixWithOthers)
. MusicControl will not work on a real device when this is set to true
. - For lockscreen controls to appear enabled instead of greyed out, the accompanying listener for each control that you want to display on the lock screen must contain a valid function:
MusicControl.on('play', () => {
// A valid funcion must be present
player.play()
})
There is also a closeNotification
control on Android controls the swipe behavior of the audio playing notification, and accepts additional configuration options with the when
key:
MusicControl.enableControl('closeNotification', true, {when: 'always'})
MusicControl.enableControl('closeNotification', true, {when: 'paused'})
MusicControl.enableControl('closeNotification', true, {when: 'never'})
Register to events
componentDidMount() {
MusicControl.enableBackgroundMode(true);
MusicControl.handleAudioInterruptions(true);
MusicControl.on('play', ()=> {
this.props.dispatch(playRemoteControl());
})
MusicControl.on('pause', ()=> {
this.props.dispatch(pauseRemoteControl());
})
MusicControl.on('stop', ()=> {
this.props.dispatch(stopRemoteControl());
})
MusicControl.on('nextTrack', ()=> {
this.props.dispatch(nextRemoteControl());
})
MusicControl.on('previousTrack', ()=> {
this.props.dispatch(previousRemoteControl());
})
MusicControl.on('seekForward', ()=> {});
MusicControl.on('seekBackward', ()=> {});
MusicControl.on('seek', (pos)=> {});
MusicControl.on('volume', (volume)=> {});
MusicControl.on('setRating', (rating)=> {});
MusicControl.on('togglePlayPause', ()=> {});
MusicControl.on('enableLanguageOption', ()=> {});
MusicControl.on('disableLanguageOption', ()=> {});
MusicControl.on('skipForward', ()=> {});
MusicControl.on('skipBackward', ()=> {});
MusicControl.on('closeNotification', ()=> {
this.props.dispatch(onAudioEnd());
})
}
Customization
It is possible to customize the icon used in the notification on Android.
By default you can add a drawable resource to your package with the file name music_control_icon
and the notification will use your custom icon.
If you need to specify a custom icon name, or change your notification icon during runtime, the setNowPlaying
function accepts a string
for an Android drawable resource name in the notificationIcon
prop. Keep in mind that just like with music_control_icon
the resource specified has
to be in the drawable package of your Android app.
MusicControl.setCustomNotificationIcon('my_custom_icon');
TODOS
Contributing