react-native-mp3-player 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,6 +34,7 @@ For audio to continue when the app is backgrounded or the screen is locked (and
34
34
  1. **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**.
35
35
  2. The package configures **AVAudioSession** (category `.playback` with options for Bluetooth, AirPlay, ducking) and handles **interruptions** and **background transitions** so that playback can continue when the app is backgrounded.
36
36
  3. **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.
37
+ 4. **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()`).
37
38
 
38
39
  ### Android background playback
39
40
 
@@ -202,6 +202,10 @@ public class RNTrackPlayer: NSObject, AudioSessionControllerDelegate {
202
202
  player.remoteCommandController.handlePauseCommand = { [weak self] _ in
203
203
  guard let self = self else { return MPRemoteCommandHandlerStatus.commandFailed }
204
204
  self.player.pause()
205
+ if self.player.currentItem != nil && self.player.automaticallyUpdateNowPlayingInfo {
206
+ self.player.updateNowPlayingPlaybackValues()
207
+ }
208
+ self.emit(event: EventType.PlaybackState, body: self.getPlaybackStateBodyKeyValues(state: .paused))
205
209
  self.emit(event: EventType.RemotePause)
206
210
  return MPRemoteCommandHandlerStatus.success
207
211
  }
@@ -209,6 +213,10 @@ public class RNTrackPlayer: NSObject, AudioSessionControllerDelegate {
209
213
  player.remoteCommandController.handlePlayCommand = { [weak self] _ in
210
214
  guard let self = self else { return MPRemoteCommandHandlerStatus.commandFailed }
211
215
  self.player.play()
216
+ if self.player.currentItem != nil && self.player.automaticallyUpdateNowPlayingInfo {
217
+ self.player.updateNowPlayingPlaybackValues()
218
+ }
219
+ self.emit(event: EventType.PlaybackState, body: self.getPlaybackStateBodyKeyValues(state: .playing))
212
220
  self.emit(event: EventType.RemotePlay)
213
221
  return MPRemoteCommandHandlerStatus.success
214
222
  }
@@ -247,6 +255,10 @@ public class RNTrackPlayer: NSObject, AudioSessionControllerDelegate {
247
255
  player.remoteCommandController.handleStopCommand = { [weak self] _ in
248
256
  guard let self = self else { return MPRemoteCommandHandlerStatus.commandFailed }
249
257
  self.player.stop()
258
+ if self.player.currentItem != nil && self.player.automaticallyUpdateNowPlayingInfo {
259
+ self.player.updateNowPlayingPlaybackValues()
260
+ }
261
+ self.emit(event: EventType.PlaybackState, body: self.getPlaybackStateBodyKeyValues(state: .stopped))
250
262
  self.emit(event: EventType.RemoteStop)
251
263
  return MPRemoteCommandHandlerStatus.success
252
264
  }
@@ -255,9 +267,17 @@ public class RNTrackPlayer: NSObject, AudioSessionControllerDelegate {
255
267
  guard let self = self else { return MPRemoteCommandHandlerStatus.commandFailed }
256
268
  if self.player.playerState == .paused {
257
269
  self.player.play()
270
+ if self.player.currentItem != nil && self.player.automaticallyUpdateNowPlayingInfo {
271
+ self.player.updateNowPlayingPlaybackValues()
272
+ }
273
+ self.emit(event: EventType.PlaybackState, body: self.getPlaybackStateBodyKeyValues(state: .playing))
258
274
  self.emit(event: EventType.RemotePlay)
259
275
  } else {
260
276
  self.player.pause()
277
+ if self.player.currentItem != nil && self.player.automaticallyUpdateNowPlayingInfo {
278
+ self.player.updateNowPlayingPlaybackValues()
279
+ }
280
+ self.emit(event: EventType.PlaybackState, body: self.getPlaybackStateBodyKeyValues(state: .paused))
261
281
  self.emit(event: EventType.RemotePause)
262
282
  }
263
283
  return MPRemoteCommandHandlerStatus.success
@@ -544,8 +564,11 @@ public class RNTrackPlayer: NSObject, AudioSessionControllerDelegate {
544
564
  public func play(resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
545
565
  if (rejectWhenNotInitialized(reject: reject)) { return }
546
566
  player.play()
567
+ // Update Now Playing widget immediately (rate 1, current elapsed) so it never shows "Not Playing".
568
+ if player.currentItem != nil && player.automaticallyUpdateNowPlayingInfo {
569
+ player.updateNowPlayingPlaybackValues()
570
+ }
547
571
  resolve(NSNull())
548
- // Emit PlaybackState immediately so in-app UI (play/pause button) updates without waiting for native state transition.
549
572
  emit(event: EventType.PlaybackState, body: getPlaybackStateBodyKeyValues(state: .playing))
550
573
  }
551
574
 
@@ -554,8 +577,11 @@ public class RNTrackPlayer: NSObject, AudioSessionControllerDelegate {
554
577
  if (rejectWhenNotInitialized(reject: reject)) { return }
555
578
 
556
579
  player.pause()
580
+ // Update Now Playing widget immediately (rate 0, current elapsed) so it shows "Paused" not "Not Playing".
581
+ if player.currentItem != nil && player.automaticallyUpdateNowPlayingInfo {
582
+ player.updateNowPlayingPlaybackValues()
583
+ }
557
584
  resolve(NSNull())
558
- // Emit PlaybackState immediately so in-app UI (play/pause button) updates without waiting for native state transition.
559
585
  emit(event: EventType.PlaybackState, body: getPlaybackStateBodyKeyValues(state: .paused))
560
586
  }
561
587
 
@@ -211,12 +211,12 @@ public class AudioPlayer: AVPlayerWrapperDelegate {
211
211
  currentItem = item
212
212
 
213
213
  if (automaticallyUpdateNowPlayingInfo) {
214
- // Reset playback values without updating, because that will happen in
215
- // the loadNowPlayingMetaValues call straight after:
216
- nowPlayingInfoController.setWithoutUpdate(keyValues: [
217
- MediaItemProperty.duration(nil),
218
- NowPlayingInfoProperty.playbackRate(nil),
219
- NowPlayingInfoProperty.elapsedPlaybackTime(nil)
214
+ // Set initial playback values so the Now Playing widget never shows "Not Playing"
215
+ // (duration/elapsed/rate must be set; use 0 until the player reports real values).
216
+ nowPlayingInfoController.set(keyValues: [
217
+ MediaItemProperty.duration(0),
218
+ NowPlayingInfoProperty.playbackRate(playWhenReady ? 1.0 : 0.0),
219
+ NowPlayingInfoProperty.elapsedPlaybackTime(0)
220
220
  ])
221
221
  loadNowPlayingMetaValues()
222
222
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-mp3-player",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "React Native audio player with reliable iOS background playback. Media controls, queue, hooks. Built for stability and long-running playback.",
5
5
  "main": "lib/src/index.js",
6
6
  "types": "lib/src/index.d.ts",