react-native-nitro-player 1.0.3 → 1.1.0

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.
@@ -167,7 +167,7 @@ internal fun TrackPlayerCore.emitStateChange(reason: Reason? = null) {
167
167
  val state =
168
168
  when (exo.playbackState) {
169
169
  Player.STATE_IDLE -> TrackPlayerState.STOPPED
170
- Player.STATE_BUFFERING -> if (exo.playWhenReady) TrackPlayerState.PLAYING else TrackPlayerState.PAUSED
170
+ Player.STATE_BUFFERING -> if (exo.playWhenReady) TrackPlayerState.BUFFERING else TrackPlayerState.PAUSED
171
171
  Player.STATE_READY -> if (exo.isPlaying) TrackPlayerState.PLAYING else TrackPlayerState.PAUSED
172
172
  Player.STATE_ENDED -> TrackPlayerState.STOPPED
173
173
  else -> TrackPlayerState.STOPPED
@@ -38,7 +38,7 @@ internal fun TrackPlayerCore.getStateInternal(): PlayerState {
38
38
  val state =
39
39
  when (exo.playbackState) {
40
40
  Player.STATE_IDLE -> TrackPlayerState.STOPPED
41
- Player.STATE_BUFFERING -> if (exo.playWhenReady) TrackPlayerState.PLAYING else TrackPlayerState.PAUSED
41
+ Player.STATE_BUFFERING -> if (exo.playWhenReady) TrackPlayerState.BUFFERING else TrackPlayerState.PAUSED
42
42
  Player.STATE_READY -> if (exo.isPlaying) TrackPlayerState.PLAYING else TrackPlayerState.PAUSED
43
43
  Player.STATE_ENDED -> TrackPlayerState.STOPPED
44
44
  else -> TrackPlayerState.STOPPED
@@ -372,16 +372,18 @@ extension TrackPlayerCore {
372
372
  }
373
373
  currentItemObservers.append(statusObserver)
374
374
 
375
- let bufferEmptyObserver = item.observe(\.isPlaybackBufferEmpty, options: [.new]) { item, _ in
375
+ let bufferEmptyObserver = item.observe(\.isPlaybackBufferEmpty, options: [.new]) { [weak self] item, _ in
376
376
  if item.isPlaybackBufferEmpty {
377
377
  NitroPlayerLogger.log("TrackPlayerCore", "⏸️ Buffer empty (buffering)")
378
+ self?.emitStateChange()
378
379
  }
379
380
  }
380
381
  currentItemObservers.append(bufferEmptyObserver)
381
382
 
382
- let bufferKeepUpObserver = item.observe(\.isPlaybackLikelyToKeepUp, options: [.new]) { item, _ in
383
+ let bufferKeepUpObserver = item.observe(\.isPlaybackLikelyToKeepUp, options: [.new]) { [weak self] item, _ in
383
384
  if item.isPlaybackLikelyToKeepUp {
384
385
  NitroPlayerLogger.log("TrackPlayerCore", "▶️ Buffer likely to keep up")
386
+ self?.emitStateChange()
385
387
  }
386
388
  }
387
389
  currentItemObservers.append(bufferKeepUpObserver)
@@ -390,10 +392,15 @@ extension TrackPlayerCore {
390
392
  func emitStateChange(reason: Reason? = nil) {
391
393
  guard let player else { return }
392
394
  let state: TrackPlayerState
393
- if player.rate == 0 { state = .paused }
394
- else if player.timeControlStatus == .playing { state = .playing }
395
- else if player.timeControlStatus == .waitingToPlayAtSpecifiedRate { state = .paused }
396
- else { state = .stopped }
395
+ if player.timeControlStatus == .playing {
396
+ state = .playing
397
+ } else if player.timeControlStatus == .waitingToPlayAtSpecifiedRate {
398
+ state = .buffering
399
+ } else if player.rate == 0 {
400
+ state = .paused
401
+ } else {
402
+ state = .stopped
403
+ }
397
404
  NitroPlayerLogger.log("TrackPlayerCore", "🔔 Emitting state change: \(state)")
398
405
  notifyPlaybackStateChange(state, reason)
399
406
  }
@@ -47,8 +47,9 @@ extension TrackPlayerCore {
47
47
  let totalDuration = (rawDuration > 0 && !rawDuration.isNaN && !rawDuration.isInfinite) ? rawDuration : 0.0
48
48
 
49
49
  let state: TrackPlayerState
50
- if player.rate == 0 { state = .paused }
51
- else if player.timeControlStatus == .playing { state = .playing }
50
+ if player.timeControlStatus == .playing { state = .playing }
51
+ else if player.timeControlStatus == .waitingToPlayAtSpecifiedRate { state = .buffering }
52
+ else if player.rate == 0 { state = .paused }
52
53
  else { state = .stopped }
53
54
 
54
55
  let currentIndex: Double = currentTrackIndex >= 0 ? Double(currentTrackIndex) : -1.0
@@ -18,7 +18,7 @@ export interface Playlist {
18
18
  tracks: TrackItem[];
19
19
  }
20
20
  export type QueueOperation = 'add' | 'remove' | 'clear' | 'update';
21
- export type TrackPlayerState = 'playing' | 'paused' | 'stopped';
21
+ export type TrackPlayerState = 'playing' | 'paused' | 'stopped' | 'buffering';
22
22
  export type Reason = 'user_action' | 'skip' | 'end' | 'error' | 'repeat';
23
23
  export interface PlayerState {
24
24
  currentTrack: TrackItem | null;
@@ -51,6 +51,9 @@ namespace margelo::nitro::nitroplayer {
51
51
  case TrackPlayerState::STOPPED:
52
52
  static const auto fieldSTOPPED = clazz->getStaticField<JTrackPlayerState>("STOPPED");
53
53
  return clazz->getStaticFieldValue(fieldSTOPPED);
54
+ case TrackPlayerState::BUFFERING:
55
+ static const auto fieldBUFFERING = clazz->getStaticField<JTrackPlayerState>("BUFFERING");
56
+ return clazz->getStaticFieldValue(fieldBUFFERING);
54
57
  default:
55
58
  std::string stringValue = std::to_string(static_cast<int>(value));
56
59
  throw std::invalid_argument("Invalid enum value (" + stringValue + "!");
@@ -18,7 +18,8 @@ import com.facebook.proguard.annotations.DoNotStrip
18
18
  enum class TrackPlayerState(@DoNotStrip @Keep val value: Int) {
19
19
  PAUSED(0),
20
20
  PLAYING(1),
21
- STOPPED(2);
21
+ STOPPED(2),
22
+ BUFFERING(3);
22
23
 
23
24
  companion object
24
25
  }
@@ -23,6 +23,8 @@ public extension TrackPlayerState {
23
23
  self = .playing
24
24
  case "stopped":
25
25
  self = .stopped
26
+ case "buffering":
27
+ self = .buffering
26
28
  default:
27
29
  return nil
28
30
  }
@@ -39,6 +41,8 @@ public extension TrackPlayerState {
39
41
  return "playing"
40
42
  case .stopped:
41
43
  return "stopped"
44
+ case .buffering:
45
+ return "buffering"
42
46
  }
43
47
  }
44
48
  }
@@ -32,6 +32,7 @@ namespace margelo::nitro::nitroplayer {
32
32
  PAUSED SWIFT_NAME(paused) = 0,
33
33
  PLAYING SWIFT_NAME(playing) = 1,
34
34
  STOPPED SWIFT_NAME(stopped) = 2,
35
+ BUFFERING SWIFT_NAME(buffering) = 3,
35
36
  } CLOSED_ENUM;
36
37
 
37
38
  } // namespace margelo::nitro::nitroplayer
@@ -47,6 +48,7 @@ namespace margelo::nitro {
47
48
  case hashString("paused"): return margelo::nitro::nitroplayer::TrackPlayerState::PAUSED;
48
49
  case hashString("playing"): return margelo::nitro::nitroplayer::TrackPlayerState::PLAYING;
49
50
  case hashString("stopped"): return margelo::nitro::nitroplayer::TrackPlayerState::STOPPED;
51
+ case hashString("buffering"): return margelo::nitro::nitroplayer::TrackPlayerState::BUFFERING;
50
52
  default: [[unlikely]]
51
53
  throw std::invalid_argument("Cannot convert \"" + unionValue + "\" to enum TrackPlayerState - invalid value!");
52
54
  }
@@ -56,6 +58,7 @@ namespace margelo::nitro {
56
58
  case margelo::nitro::nitroplayer::TrackPlayerState::PAUSED: return JSIConverter<std::string>::toJSI(runtime, "paused");
57
59
  case margelo::nitro::nitroplayer::TrackPlayerState::PLAYING: return JSIConverter<std::string>::toJSI(runtime, "playing");
58
60
  case margelo::nitro::nitroplayer::TrackPlayerState::STOPPED: return JSIConverter<std::string>::toJSI(runtime, "stopped");
61
+ case margelo::nitro::nitroplayer::TrackPlayerState::BUFFERING: return JSIConverter<std::string>::toJSI(runtime, "buffering");
59
62
  default: [[unlikely]]
60
63
  throw std::invalid_argument("Cannot convert TrackPlayerState to JS - invalid value: "
61
64
  + std::to_string(static_cast<int>(arg)) + "!");
@@ -70,6 +73,7 @@ namespace margelo::nitro {
70
73
  case hashString("paused"):
71
74
  case hashString("playing"):
72
75
  case hashString("stopped"):
76
+ case hashString("buffering"):
73
77
  return true;
74
78
  default:
75
79
  return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-player",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "description": "A powerful audio player library for React Native with playlist management, playback controls, and support for Android Auto and CarPlay",
5
5
  "main": "lib/index",
6
6
  "module": "lib/index",
@@ -26,7 +26,7 @@ export interface Playlist {
26
26
 
27
27
  export type QueueOperation = 'add' | 'remove' | 'clear' | 'update'
28
28
 
29
- export type TrackPlayerState = 'playing' | 'paused' | 'stopped'
29
+ export type TrackPlayerState = 'playing' | 'paused' | 'stopped' | 'buffering'
30
30
 
31
31
  export type Reason = 'user_action' | 'skip' | 'end' | 'error' | 'repeat'
32
32