react-native-nitro-player 1.7.0-alpha.5 → 1.7.0-alpha.6

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.
@@ -100,7 +100,8 @@ final class HybridTrackPlayer: HybridTrackPlayerSpec {
100
100
  showInNotification: config.showInNotification,
101
101
  lookaheadCount: config.lookaheadCount.map { Int($0) },
102
102
  remoteSkipForwardInterval: config.remoteSkipForwardInterval,
103
- remoteSkipBackwardInterval: config.remoteSkipBackwardInterval
103
+ remoteSkipBackwardInterval: config.remoteSkipBackwardInterval,
104
+ preferRemoteSkipIntervals: config.preferRemoteSkipIntervals
104
105
  )
105
106
  }
106
107
  }
@@ -104,7 +104,8 @@ extension TrackPlayerCore {
104
104
  func configureOnQueue(
105
105
  androidAutoEnabled: Bool?, carPlayEnabled: Bool?,
106
106
  showInNotification: Bool?, lookaheadCount: Int?,
107
- remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?
107
+ remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?,
108
+ preferRemoteSkipIntervals: Bool?
108
109
  ) {
109
110
  if let la = lookaheadCount {
110
111
  self.lookaheadCount = la
@@ -118,6 +119,7 @@ extension TrackPlayerCore {
118
119
  showInNotification: showInNotification,
119
120
  remoteSkipForwardInterval: remoteSkipForwardInterval,
120
121
  remoteSkipBackwardInterval: remoteSkipBackwardInterval,
122
+ preferRemoteSkipIntervals: preferRemoteSkipIntervals,
121
123
  playbackSpeed: playbackSpeed
122
124
  )
123
125
  }
@@ -125,14 +127,16 @@ extension TrackPlayerCore {
125
127
  func configure(
126
128
  androidAutoEnabled: Bool?, carPlayEnabled: Bool?,
127
129
  showInNotification: Bool?, lookaheadCount: Int?,
128
- remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?
130
+ remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?,
131
+ preferRemoteSkipIntervals: Bool?
129
132
  ) async {
130
133
  await withPlayerQueueNoThrow {
131
134
  self.configureOnQueue(
132
135
  androidAutoEnabled: androidAutoEnabled, carPlayEnabled: carPlayEnabled,
133
136
  showInNotification: showInNotification, lookaheadCount: lookaheadCount,
134
137
  remoteSkipForwardInterval: remoteSkipForwardInterval,
135
- remoteSkipBackwardInterval: remoteSkipBackwardInterval)
138
+ remoteSkipBackwardInterval: remoteSkipBackwardInterval,
139
+ preferRemoteSkipIntervals: preferRemoteSkipIntervals)
136
140
  }
137
141
  }
138
142
 
@@ -28,6 +28,7 @@ class MediaSessionManager {
28
28
  private var showInNotification: Bool = true
29
29
  private var remoteSkipForwardInterval: Double = Constants.defaultRemoteSkipInterval
30
30
  private var remoteSkipBackwardInterval: Double = Constants.defaultRemoteSkipInterval
31
+ private var preferRemoteSkipIntervals = false
31
32
 
32
33
  // Tracks the artwork URL currently shown so we can discard stale async loads
33
34
  private var lastArtworkUrl: String?
@@ -56,11 +57,15 @@ class MediaSessionManager {
56
57
  showInNotification: Bool?,
57
58
  remoteSkipForwardInterval: Double?,
58
59
  remoteSkipBackwardInterval: Double?,
60
+ preferRemoteSkipIntervals: Bool?,
59
61
  playbackSpeed: Double?
60
62
  ) {
61
63
  if let showInNotification = showInNotification {
62
64
  self.showInNotification = showInNotification
63
65
  }
66
+ if let preferRemoteSkipIntervals = preferRemoteSkipIntervals {
67
+ self.preferRemoteSkipIntervals = preferRemoteSkipIntervals
68
+ }
64
69
  if let playbackSpeed = sanitizedPositive(playbackSpeed) {
65
70
  cachedPlaybackSpeed = playbackSpeed
66
71
  }
@@ -321,8 +326,9 @@ class MediaSessionManager {
321
326
 
322
327
  commandCenter.nextTrackCommand.isEnabled = hasCurrentTrack && isNotLast
323
328
  commandCenter.previousTrackCommand.isEnabled = hasCurrentTrack
324
- commandCenter.skipForwardCommand.isEnabled = hasCurrentTrack
325
- commandCenter.skipBackwardCommand.isEnabled = hasCurrentTrack
329
+ // iOS shows enabled skip-interval commands in place of next/previous, so they stay off unless the app prefers them
330
+ commandCenter.skipForwardCommand.isEnabled = hasCurrentTrack && preferRemoteSkipIntervals
331
+ commandCenter.skipBackwardCommand.isEnabled = hasCurrentTrack && preferRemoteSkipIntervals
326
332
  commandCenter.changePlaybackRateCommand.isEnabled = hasCurrentTrack
327
333
  commandCenter.changePlaybackPositionCommand.isEnabled = hasCurrentTrack && hasDuration
328
334
  }
@@ -68,6 +68,10 @@ export interface PlayerConfig {
68
68
  * Fixed interval, in seconds, for remote skip-backward controls (default: 15)
69
69
  */
70
70
  remoteSkipBackwardInterval?: number;
71
+ /**
72
+ * iOS only, ignored on Android: the lock screen, Control Center and CarPlay side buttons skip by the remote skip intervals instead of changing track (default: false)
73
+ */
74
+ preferRemoteSkipIntervals?: boolean;
71
75
  /**
72
76
  * Number of upcoming tracks to preload URLs for (default: 5)
73
77
  * Higher values = more proactive loading, but more network requests
@@ -44,6 +44,8 @@ namespace margelo::nitro::nitroplayer {
44
44
  jni::local_ref<jni::JDouble> remoteSkipForwardInterval = this->getFieldValue(fieldRemoteSkipForwardInterval);
45
45
  static const auto fieldRemoteSkipBackwardInterval = clazz->getField<jni::JDouble>("remoteSkipBackwardInterval");
46
46
  jni::local_ref<jni::JDouble> remoteSkipBackwardInterval = this->getFieldValue(fieldRemoteSkipBackwardInterval);
47
+ static const auto fieldPreferRemoteSkipIntervals = clazz->getField<jni::JBoolean>("preferRemoteSkipIntervals");
48
+ jni::local_ref<jni::JBoolean> preferRemoteSkipIntervals = this->getFieldValue(fieldPreferRemoteSkipIntervals);
47
49
  static const auto fieldLookaheadCount = clazz->getField<jni::JDouble>("lookaheadCount");
48
50
  jni::local_ref<jni::JDouble> lookaheadCount = this->getFieldValue(fieldLookaheadCount);
49
51
  static const auto fieldAndroidNotificationIcon = clazz->getField<jni::JString>("androidNotificationIcon");
@@ -56,6 +58,7 @@ namespace margelo::nitro::nitroplayer {
56
58
  showInNotification != nullptr ? std::make_optional(static_cast<bool>(showInNotification->value())) : std::nullopt,
57
59
  remoteSkipForwardInterval != nullptr ? std::make_optional(remoteSkipForwardInterval->value()) : std::nullopt,
58
60
  remoteSkipBackwardInterval != nullptr ? std::make_optional(remoteSkipBackwardInterval->value()) : std::nullopt,
61
+ preferRemoteSkipIntervals != nullptr ? std::make_optional(static_cast<bool>(preferRemoteSkipIntervals->value())) : std::nullopt,
59
62
  lookaheadCount != nullptr ? std::make_optional(lookaheadCount->value()) : std::nullopt,
60
63
  androidNotificationIcon != nullptr ? std::make_optional(androidNotificationIcon->toStdString()) : std::nullopt,
61
64
  androidAudioFocus != nullptr ? std::make_optional(androidAudioFocus->toCpp()) : std::nullopt
@@ -68,7 +71,7 @@ namespace margelo::nitro::nitroplayer {
68
71
  */
69
72
  [[maybe_unused]]
70
73
  static jni::local_ref<JPlayerConfig::javaobject> fromCpp(const PlayerConfig& value) {
71
- using JSignature = JPlayerConfig(jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JString>, jni::alias_ref<JAndroidAudioFocusMode>);
74
+ using JSignature = JPlayerConfig(jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JString>, jni::alias_ref<JAndroidAudioFocusMode>);
72
75
  static const auto clazz = javaClassStatic();
73
76
  static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
74
77
  return create(
@@ -78,6 +81,7 @@ namespace margelo::nitro::nitroplayer {
78
81
  value.showInNotification.has_value() ? jni::JBoolean::valueOf(value.showInNotification.value()) : nullptr,
79
82
  value.remoteSkipForwardInterval.has_value() ? jni::JDouble::valueOf(value.remoteSkipForwardInterval.value()) : nullptr,
80
83
  value.remoteSkipBackwardInterval.has_value() ? jni::JDouble::valueOf(value.remoteSkipBackwardInterval.value()) : nullptr,
84
+ value.preferRemoteSkipIntervals.has_value() ? jni::JBoolean::valueOf(value.preferRemoteSkipIntervals.value()) : nullptr,
81
85
  value.lookaheadCount.has_value() ? jni::JDouble::valueOf(value.lookaheadCount.value()) : nullptr,
82
86
  value.androidNotificationIcon.has_value() ? jni::make_jstring(value.androidNotificationIcon.value()) : nullptr,
83
87
  value.androidAudioFocus.has_value() ? JAndroidAudioFocusMode::fromCpp(value.androidAudioFocus.value()) : nullptr
@@ -34,6 +34,9 @@ data class PlayerConfig(
34
34
  val remoteSkipBackwardInterval: Double?,
35
35
  @DoNotStrip
36
36
  @Keep
37
+ val preferRemoteSkipIntervals: Boolean?,
38
+ @DoNotStrip
39
+ @Keep
37
40
  val lookaheadCount: Double?,
38
41
  @DoNotStrip
39
42
  @Keep
@@ -52,8 +55,8 @@ data class PlayerConfig(
52
55
  @Keep
53
56
  @Suppress("unused")
54
57
  @JvmStatic
55
- private fun fromCpp(androidAutoEnabled: Boolean?, carPlayEnabled: Boolean?, showInNotification: Boolean?, remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?, lookaheadCount: Double?, androidNotificationIcon: String?, androidAudioFocus: AndroidAudioFocusMode?): PlayerConfig {
56
- return PlayerConfig(androidAutoEnabled, carPlayEnabled, showInNotification, remoteSkipForwardInterval, remoteSkipBackwardInterval, lookaheadCount, androidNotificationIcon, androidAudioFocus)
58
+ private fun fromCpp(androidAutoEnabled: Boolean?, carPlayEnabled: Boolean?, showInNotification: Boolean?, remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?, preferRemoteSkipIntervals: Boolean?, lookaheadCount: Double?, androidNotificationIcon: String?, androidAudioFocus: AndroidAudioFocusMode?): PlayerConfig {
59
+ return PlayerConfig(androidAutoEnabled, carPlayEnabled, showInNotification, remoteSkipForwardInterval, remoteSkipBackwardInterval, preferRemoteSkipIntervals, lookaheadCount, androidNotificationIcon, androidAudioFocus)
57
60
  }
58
61
  }
59
62
  }
@@ -18,7 +18,7 @@ public extension PlayerConfig {
18
18
  /**
19
19
  * Create a new instance of `PlayerConfig`.
20
20
  */
21
- init(androidAutoEnabled: Bool?, carPlayEnabled: Bool?, showInNotification: Bool?, remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?, lookaheadCount: Double?, androidNotificationIcon: String?, androidAudioFocus: AndroidAudioFocusMode?) {
21
+ init(androidAutoEnabled: Bool?, carPlayEnabled: Bool?, showInNotification: Bool?, remoteSkipForwardInterval: Double?, remoteSkipBackwardInterval: Double?, preferRemoteSkipIntervals: Bool?, lookaheadCount: Double?, androidNotificationIcon: String?, androidAudioFocus: AndroidAudioFocusMode?) {
22
22
  self.init({ () -> bridge.std__optional_bool_ in
23
23
  if let __unwrappedValue = androidAutoEnabled {
24
24
  return bridge.create_std__optional_bool_(__unwrappedValue)
@@ -49,6 +49,12 @@ public extension PlayerConfig {
49
49
  } else {
50
50
  return .init()
51
51
  }
52
+ }(), { () -> bridge.std__optional_bool_ in
53
+ if let __unwrappedValue = preferRemoteSkipIntervals {
54
+ return bridge.create_std__optional_bool_(__unwrappedValue)
55
+ } else {
56
+ return .init()
57
+ }
52
58
  }(), { () -> bridge.std__optional_double_ in
53
59
  if let __unwrappedValue = lookaheadCount {
54
60
  return bridge.create_std__optional_double_(__unwrappedValue)
@@ -130,6 +136,18 @@ public extension PlayerConfig {
130
136
  }()
131
137
  }
132
138
 
139
+ @inline(__always)
140
+ var preferRemoteSkipIntervals: Bool? {
141
+ return { () -> Bool? in
142
+ if bridge.has_value_std__optional_bool_(self.__preferRemoteSkipIntervals) {
143
+ let __unwrapped = bridge.get_std__optional_bool_(self.__preferRemoteSkipIntervals)
144
+ return __unwrapped
145
+ } else {
146
+ return nil
147
+ }
148
+ }()
149
+ }
150
+
133
151
  @inline(__always)
134
152
  var lookaheadCount: Double? {
135
153
  return { () -> Double? in
@@ -47,13 +47,14 @@ namespace margelo::nitro::nitroplayer {
47
47
  std::optional<bool> showInNotification SWIFT_PRIVATE;
48
48
  std::optional<double> remoteSkipForwardInterval SWIFT_PRIVATE;
49
49
  std::optional<double> remoteSkipBackwardInterval SWIFT_PRIVATE;
50
+ std::optional<bool> preferRemoteSkipIntervals SWIFT_PRIVATE;
50
51
  std::optional<double> lookaheadCount SWIFT_PRIVATE;
51
52
  std::optional<std::string> androidNotificationIcon SWIFT_PRIVATE;
52
53
  std::optional<AndroidAudioFocusMode> androidAudioFocus SWIFT_PRIVATE;
53
54
 
54
55
  public:
55
56
  PlayerConfig() = default;
56
- explicit PlayerConfig(std::optional<bool> androidAutoEnabled, std::optional<bool> carPlayEnabled, std::optional<bool> showInNotification, std::optional<double> remoteSkipForwardInterval, std::optional<double> remoteSkipBackwardInterval, std::optional<double> lookaheadCount, std::optional<std::string> androidNotificationIcon, std::optional<AndroidAudioFocusMode> androidAudioFocus): androidAutoEnabled(androidAutoEnabled), carPlayEnabled(carPlayEnabled), showInNotification(showInNotification), remoteSkipForwardInterval(remoteSkipForwardInterval), remoteSkipBackwardInterval(remoteSkipBackwardInterval), lookaheadCount(lookaheadCount), androidNotificationIcon(androidNotificationIcon), androidAudioFocus(androidAudioFocus) {}
57
+ explicit PlayerConfig(std::optional<bool> androidAutoEnabled, std::optional<bool> carPlayEnabled, std::optional<bool> showInNotification, std::optional<double> remoteSkipForwardInterval, std::optional<double> remoteSkipBackwardInterval, std::optional<bool> preferRemoteSkipIntervals, std::optional<double> lookaheadCount, std::optional<std::string> androidNotificationIcon, std::optional<AndroidAudioFocusMode> androidAudioFocus): androidAutoEnabled(androidAutoEnabled), carPlayEnabled(carPlayEnabled), showInNotification(showInNotification), remoteSkipForwardInterval(remoteSkipForwardInterval), remoteSkipBackwardInterval(remoteSkipBackwardInterval), preferRemoteSkipIntervals(preferRemoteSkipIntervals), lookaheadCount(lookaheadCount), androidNotificationIcon(androidNotificationIcon), androidAudioFocus(androidAudioFocus) {}
57
58
 
58
59
  public:
59
60
  friend bool operator==(const PlayerConfig& lhs, const PlayerConfig& rhs) = default;
@@ -74,6 +75,7 @@ namespace margelo::nitro {
74
75
  JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "showInNotification"))),
75
76
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "remoteSkipForwardInterval"))),
76
77
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "remoteSkipBackwardInterval"))),
78
+ JSIConverter<std::optional<bool>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "preferRemoteSkipIntervals"))),
77
79
  JSIConverter<std::optional<double>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "lookaheadCount"))),
78
80
  JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "androidNotificationIcon"))),
79
81
  JSIConverter<std::optional<margelo::nitro::nitroplayer::AndroidAudioFocusMode>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "androidAudioFocus")))
@@ -86,6 +88,7 @@ namespace margelo::nitro {
86
88
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "showInNotification"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.showInNotification));
87
89
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "remoteSkipForwardInterval"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.remoteSkipForwardInterval));
88
90
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "remoteSkipBackwardInterval"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.remoteSkipBackwardInterval));
91
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "preferRemoteSkipIntervals"), JSIConverter<std::optional<bool>>::toJSI(runtime, arg.preferRemoteSkipIntervals));
89
92
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "lookaheadCount"), JSIConverter<std::optional<double>>::toJSI(runtime, arg.lookaheadCount));
90
93
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "androidNotificationIcon"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.androidNotificationIcon));
91
94
  obj.setProperty(runtime, PropNameIDCache::get(runtime, "androidAudioFocus"), JSIConverter<std::optional<margelo::nitro::nitroplayer::AndroidAudioFocusMode>>::toJSI(runtime, arg.androidAudioFocus));
@@ -104,6 +107,7 @@ namespace margelo::nitro {
104
107
  if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "showInNotification")))) return false;
105
108
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "remoteSkipForwardInterval")))) return false;
106
109
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "remoteSkipBackwardInterval")))) return false;
110
+ if (!JSIConverter<std::optional<bool>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "preferRemoteSkipIntervals")))) return false;
107
111
  if (!JSIConverter<std::optional<double>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "lookaheadCount")))) return false;
108
112
  if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "androidNotificationIcon")))) return false;
109
113
  if (!JSIConverter<std::optional<margelo::nitro::nitroplayer::AndroidAudioFocusMode>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "androidAudioFocus")))) return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-player",
3
- "version": "1.7.0-alpha.5",
3
+ "version": "1.7.0-alpha.6",
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",
@@ -82,6 +82,10 @@ export interface PlayerConfig {
82
82
  * Fixed interval, in seconds, for remote skip-backward controls (default: 15)
83
83
  */
84
84
  remoteSkipBackwardInterval?: number
85
+ /**
86
+ * iOS only, ignored on Android: the lock screen, Control Center and CarPlay side buttons skip by the remote skip intervals instead of changing track (default: false)
87
+ */
88
+ preferRemoteSkipIntervals?: boolean
85
89
  /**
86
90
  * Number of upcoming tracks to preload URLs for (default: 5)
87
91
  * Higher values = more proactive loading, but more network requests