react-native-nitro-player 1.5.1-alpha.0 → 1.6.0-alpha.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.
Files changed (41) hide show
  1. package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridTrackPlayer.kt +6 -0
  2. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +7 -0
  3. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerListener.kt +20 -0
  4. package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerNotify.kt +5 -0
  5. package/ios/HybridTrackPlayer.swift +6 -0
  6. package/ios/core/TrackPlayerCore.swift +13 -0
  7. package/ios/core/TrackPlayerListener.swift +64 -0
  8. package/ios/core/TrackPlayerNotify.swift +4 -0
  9. package/lib/hooks/callbackManager.d.ts +10 -1
  10. package/lib/hooks/callbackManager.js +33 -0
  11. package/lib/hooks/index.d.ts +1 -0
  12. package/lib/hooks/index.js +1 -0
  13. package/lib/hooks/useTimedMetadata.d.ts +16 -0
  14. package/lib/hooks/useTimedMetadata.js +21 -0
  15. package/lib/specs/TrackPlayer.nitro.d.ts +6 -1
  16. package/lib/types/PlayerQueue.d.ts +7 -0
  17. package/nitrogen/generated/android/NitroPlayerOnLoad.cpp +2 -0
  18. package/nitrogen/generated/android/c++/JFunc_void_TimedMetadata.hpp +79 -0
  19. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +9 -0
  20. package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +1 -0
  21. package/nitrogen/generated/android/c++/JTimedMetadata.hpp +70 -0
  22. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_TimedMetadata.kt +80 -0
  23. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +9 -0
  24. package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/TimedMetadata.kt +47 -0
  25. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.cpp +8 -0
  26. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +25 -0
  27. package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Umbrella.hpp +3 -0
  28. package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +9 -0
  29. package/nitrogen/generated/ios/swift/Func_void_TimedMetadata.swift +46 -0
  30. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +1 -0
  31. package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +16 -0
  32. package/nitrogen/generated/ios/swift/TimedMetadata.swift +96 -0
  33. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +1 -0
  34. package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +4 -0
  35. package/nitrogen/generated/shared/c++/TimedMetadata.hpp +96 -0
  36. package/package.json +1 -1
  37. package/src/hooks/callbackManager.ts +47 -1
  38. package/src/hooks/index.ts +1 -0
  39. package/src/hooks/useTimedMetadata.ts +25 -0
  40. package/src/specs/TrackPlayer.nitro.ts +6 -0
  41. package/src/types/PlayerQueue.ts +8 -0
@@ -0,0 +1,80 @@
1
+ ///
2
+ /// Func_void_TimedMetadata.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.nitroplayer
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.jni.HybridData
12
+ import com.facebook.proguard.annotations.DoNotStrip
13
+ import dalvik.annotation.optimization.FastNative
14
+
15
+
16
+ /**
17
+ * Represents the JavaScript callback `(metadata: struct) => void`.
18
+ * This can be either implemented in C++ (in which case it might be a callback coming from JS),
19
+ * or in Kotlin/Java (in which case it is a native callback).
20
+ */
21
+ @DoNotStrip
22
+ @Keep
23
+ @Suppress("ClassName", "RedundantUnitReturnType")
24
+ fun interface Func_void_TimedMetadata: (TimedMetadata) -> Unit {
25
+ /**
26
+ * Call the given JS callback.
27
+ * @throws Throwable if the JS function itself throws an error, or if the JS function/runtime has already been deleted.
28
+ */
29
+ @DoNotStrip
30
+ @Keep
31
+ override fun invoke(metadata: TimedMetadata): Unit
32
+ }
33
+
34
+ /**
35
+ * Represents the JavaScript callback `(metadata: struct) => void`.
36
+ * This is implemented in C++, via a `std::function<...>`.
37
+ * The callback might be coming from JS.
38
+ */
39
+ @DoNotStrip
40
+ @Keep
41
+ @Suppress(
42
+ "KotlinJniMissingFunction", "unused",
43
+ "RedundantSuppression", "RedundantUnitReturnType", "FunctionName",
44
+ "ConvertSecondaryConstructorToPrimary", "ClassName", "LocalVariableName",
45
+ )
46
+ class Func_void_TimedMetadata_cxx: Func_void_TimedMetadata {
47
+ @DoNotStrip
48
+ @Keep
49
+ private val mHybridData: HybridData
50
+
51
+ @DoNotStrip
52
+ @Keep
53
+ private constructor(hybridData: HybridData) {
54
+ mHybridData = hybridData
55
+ }
56
+
57
+ @DoNotStrip
58
+ @Keep
59
+ override fun invoke(metadata: TimedMetadata): Unit
60
+ = invoke_cxx(metadata)
61
+
62
+ @FastNative
63
+ private external fun invoke_cxx(metadata: TimedMetadata): Unit
64
+ }
65
+
66
+ /**
67
+ * Represents the JavaScript callback `(metadata: struct) => void`.
68
+ * This is implemented in Java/Kotlin, via a `(TimedMetadata) -> Unit`.
69
+ * The callback is always coming from native.
70
+ */
71
+ @DoNotStrip
72
+ @Keep
73
+ @Suppress("ClassName", "RedundantUnitReturnType", "unused")
74
+ class Func_void_TimedMetadata_java(private val function: (TimedMetadata) -> Unit): Func_void_TimedMetadata {
75
+ @DoNotStrip
76
+ @Keep
77
+ override fun invoke(metadata: TimedMetadata): Unit {
78
+ return this.function(metadata)
79
+ }
80
+ }
@@ -121,6 +121,15 @@ abstract class HybridTrackPlayerSpec: HybridObject() {
121
121
  return __result
122
122
  }
123
123
 
124
+ abstract fun onTimedMetadata(callback: (metadata: TimedMetadata) -> Unit): Unit
125
+
126
+ @DoNotStrip
127
+ @Keep
128
+ private fun onTimedMetadata_cxx(callback: Func_void_TimedMetadata): Unit {
129
+ val __result = onTimedMetadata(callback)
130
+ return __result
131
+ }
132
+
124
133
  abstract fun onAndroidAutoConnectionChange(callback: (connected: Boolean) -> Unit): Unit
125
134
 
126
135
  @DoNotStrip
@@ -0,0 +1,47 @@
1
+ ///
2
+ /// TimedMetadata.kt
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ package com.margelo.nitro.nitroplayer
9
+
10
+ import androidx.annotation.Keep
11
+ import com.facebook.proguard.annotations.DoNotStrip
12
+
13
+
14
+ /**
15
+ * Represents the JavaScript object/struct "TimedMetadata".
16
+ */
17
+ @DoNotStrip
18
+ @Keep
19
+ data class TimedMetadata(
20
+ @DoNotStrip
21
+ @Keep
22
+ val title: String?,
23
+ @DoNotStrip
24
+ @Keep
25
+ val artist: String?,
26
+ @DoNotStrip
27
+ @Keep
28
+ val album: String?,
29
+ @DoNotStrip
30
+ @Keep
31
+ val artworkUrl: String?
32
+ ) {
33
+ /* primary constructor */
34
+
35
+ companion object {
36
+ /**
37
+ * Constructor called from C++
38
+ */
39
+ @DoNotStrip
40
+ @Keep
41
+ @Suppress("unused")
42
+ @JvmStatic
43
+ private fun fromCpp(title: String?, artist: String?, album: String?, artworkUrl: String?): TimedMetadata {
44
+ return TimedMetadata(title, artist, album, artworkUrl)
45
+ }
46
+ }
47
+ }
@@ -315,6 +315,14 @@ namespace margelo::nitro::nitroplayer::bridge::swift {
315
315
  };
316
316
  }
317
317
 
318
+ // pragma MARK: std::function<void(const TimedMetadata& /* metadata */)>
319
+ Func_void_TimedMetadata create_Func_void_TimedMetadata(void* NON_NULL swiftClosureWrapper) noexcept {
320
+ auto swiftClosure = NitroPlayer::Func_void_TimedMetadata::fromUnsafe(swiftClosureWrapper);
321
+ return [swiftClosure = std::move(swiftClosure)](const TimedMetadata& metadata) mutable -> void {
322
+ swiftClosure.call(metadata);
323
+ };
324
+ }
325
+
318
326
  // pragma MARK: std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)>
319
327
  Func_void_std__vector_TrackItem__double create_Func_void_std__vector_TrackItem__double(void* NON_NULL swiftClosureWrapper) noexcept {
320
328
  auto swiftClosure = NitroPlayer::Func_void_std__vector_TrackItem__double::fromUnsafe(swiftClosureWrapper);
@@ -68,6 +68,8 @@ namespace margelo::nitro::nitroplayer { enum class Reason; }
68
68
  namespace margelo::nitro::nitroplayer { enum class RepeatMode; }
69
69
  // Forward declaration of `StorageLocation` to properly resolve imports.
70
70
  namespace margelo::nitro::nitroplayer { enum class StorageLocation; }
71
+ // Forward declaration of `TimedMetadata` to properly resolve imports.
72
+ namespace margelo::nitro::nitroplayer { struct TimedMetadata; }
71
73
  // Forward declaration of `TrackItem` to properly resolve imports.
72
74
  namespace margelo::nitro::nitroplayer { struct TrackItem; }
73
75
  // Forward declaration of `TrackPlayerState` to properly resolve imports.
@@ -118,6 +120,7 @@ namespace NitroPlayer { class HybridTrackPlayerSpec_cxx; }
118
120
  #include "Reason.hpp"
119
121
  #include "RepeatMode.hpp"
120
122
  #include "StorageLocation.hpp"
123
+ #include "TimedMetadata.hpp"
121
124
  #include "TrackItem.hpp"
122
125
  #include "TrackPlayerState.hpp"
123
126
  #include <NitroModules/AnyMap.hpp>
@@ -1727,6 +1730,28 @@ namespace margelo::nitro::nitroplayer::bridge::swift {
1727
1730
  return Func_void_double_double_std__optional_bool__Wrapper(std::move(value));
1728
1731
  }
1729
1732
 
1733
+ // pragma MARK: std::function<void(const TimedMetadata& /* metadata */)>
1734
+ /**
1735
+ * Specialized version of `std::function<void(const TimedMetadata&)>`.
1736
+ */
1737
+ using Func_void_TimedMetadata = std::function<void(const TimedMetadata& /* metadata */)>;
1738
+ /**
1739
+ * Wrapper class for a `std::function<void(const TimedMetadata& / * metadata * /)>`, this can be used from Swift.
1740
+ */
1741
+ class Func_void_TimedMetadata_Wrapper final {
1742
+ public:
1743
+ explicit Func_void_TimedMetadata_Wrapper(std::function<void(const TimedMetadata& /* metadata */)>&& func): _function(std::make_unique<std::function<void(const TimedMetadata& /* metadata */)>>(std::move(func))) {}
1744
+ inline void call(TimedMetadata metadata) const noexcept {
1745
+ _function->operator()(metadata);
1746
+ }
1747
+ private:
1748
+ std::unique_ptr<std::function<void(const TimedMetadata& /* metadata */)>> _function;
1749
+ } SWIFT_NONCOPYABLE;
1750
+ Func_void_TimedMetadata create_Func_void_TimedMetadata(void* NON_NULL swiftClosureWrapper) noexcept;
1751
+ inline Func_void_TimedMetadata_Wrapper wrap_Func_void_TimedMetadata(Func_void_TimedMetadata value) noexcept {
1752
+ return Func_void_TimedMetadata_Wrapper(std::move(value));
1753
+ }
1754
+
1730
1755
  // pragma MARK: std::function<void(const std::vector<TrackItem>& /* tracks */, double /* lookahead */)>
1731
1756
  /**
1732
1757
  * Specialized version of `std::function<void(const std::vector<TrackItem>&, double)>`.
@@ -70,6 +70,8 @@ namespace margelo::nitro::nitroplayer { enum class Reason; }
70
70
  namespace margelo::nitro::nitroplayer { enum class RepeatMode; }
71
71
  // Forward declaration of `StorageLocation` to properly resolve imports.
72
72
  namespace margelo::nitro::nitroplayer { enum class StorageLocation; }
73
+ // Forward declaration of `TimedMetadata` to properly resolve imports.
74
+ namespace margelo::nitro::nitroplayer { struct TimedMetadata; }
73
75
  // Forward declaration of `TrackItem` to properly resolve imports.
74
76
  namespace margelo::nitro::nitroplayer { struct TrackItem; }
75
77
  // Forward declaration of `TrackPlayerState` to properly resolve imports.
@@ -107,6 +109,7 @@ namespace margelo::nitro::nitroplayer { enum class TrackPlayerState; }
107
109
  #include "Reason.hpp"
108
110
  #include "RepeatMode.hpp"
109
111
  #include "StorageLocation.hpp"
112
+ #include "TimedMetadata.hpp"
110
113
  #include "TrackItem.hpp"
111
114
  #include "TrackPlayerState.hpp"
112
115
  #include <NitroModules/AnyMap.hpp>
@@ -26,6 +26,8 @@ namespace margelo::nitro::nitroplayer { enum class RepeatMode; }
26
26
  namespace margelo::nitro::nitroplayer { struct PlayerConfig; }
27
27
  // Forward declaration of `Reason` to properly resolve imports.
28
28
  namespace margelo::nitro::nitroplayer { enum class Reason; }
29
+ // Forward declaration of `TimedMetadata` to properly resolve imports.
30
+ namespace margelo::nitro::nitroplayer { struct TimedMetadata; }
29
31
 
30
32
  #include <NitroModules/Promise.hpp>
31
33
  #include <string>
@@ -42,6 +44,7 @@ namespace margelo::nitro::nitroplayer { enum class Reason; }
42
44
  #include "PlayerConfig.hpp"
43
45
  #include "Reason.hpp"
44
46
  #include <functional>
47
+ #include "TimedMetadata.hpp"
45
48
 
46
49
  #include "NitroPlayer-Swift-Cxx-Umbrella.hpp"
47
50
 
@@ -229,6 +232,12 @@ namespace margelo::nitro::nitroplayer {
229
232
  std::rethrow_exception(__result.error());
230
233
  }
231
234
  }
235
+ inline void onTimedMetadata(const std::function<void(const TimedMetadata& /* metadata */)>& callback) override {
236
+ auto __result = _swiftPart.onTimedMetadata(callback);
237
+ if (__result.hasError()) [[unlikely]] {
238
+ std::rethrow_exception(__result.error());
239
+ }
240
+ }
232
241
  inline void onAndroidAutoConnectionChange(const std::function<void(bool /* connected */)>& callback) override {
233
242
  auto __result = _swiftPart.onAndroidAutoConnectionChange(callback);
234
243
  if (__result.hasError()) [[unlikely]] {
@@ -0,0 +1,46 @@
1
+ ///
2
+ /// Func_void_TimedMetadata.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import NitroModules
9
+
10
+ /**
11
+ * Wraps a Swift `(_ metadata: TimedMetadata) -> Void` as a class.
12
+ * This class can be used from C++, e.g. to wrap the Swift closure as a `std::function`.
13
+ */
14
+ public final class Func_void_TimedMetadata {
15
+ public typealias bridge = margelo.nitro.nitroplayer.bridge.swift
16
+
17
+ private let closure: (_ metadata: TimedMetadata) -> Void
18
+
19
+ public init(_ closure: @escaping (_ metadata: TimedMetadata) -> Void) {
20
+ self.closure = closure
21
+ }
22
+
23
+ @inline(__always)
24
+ public func call(metadata: TimedMetadata) -> Void {
25
+ self.closure(metadata)
26
+ }
27
+
28
+ /**
29
+ * Casts this instance to a retained unsafe raw pointer.
30
+ * This acquires one additional strong reference on the object!
31
+ */
32
+ @inline(__always)
33
+ public func toUnsafe() -> UnsafeMutableRawPointer {
34
+ return Unmanaged.passRetained(self).toOpaque()
35
+ }
36
+
37
+ /**
38
+ * Casts an unsafe pointer to a `Func_void_TimedMetadata`.
39
+ * The pointer has to be a retained opaque `Unmanaged<Func_void_TimedMetadata>`.
40
+ * This removes one strong reference from the object!
41
+ */
42
+ @inline(__always)
43
+ public static func fromUnsafe(_ pointer: UnsafeMutableRawPointer) -> Func_void_TimedMetadata {
44
+ return Unmanaged<Func_void_TimedMetadata>.fromOpaque(pointer).takeRetainedValue()
45
+ }
46
+ }
@@ -31,6 +31,7 @@ public protocol HybridTrackPlayerSpec_protocol: HybridObject {
31
31
  func onPlaybackStateChange(callback: @escaping (_ state: TrackPlayerState, _ reason: Reason?) -> Void) throws -> Void
32
32
  func onSeek(callback: @escaping (_ position: Double, _ totalDuration: Double) -> Void) throws -> Void
33
33
  func onPlaybackProgressChange(callback: @escaping (_ position: Double, _ totalDuration: Double, _ isManuallySeeked: Bool?) -> Void) throws -> Void
34
+ func onTimedMetadata(callback: @escaping (_ metadata: TimedMetadata) -> Void) throws -> Void
34
35
  func onAndroidAutoConnectionChange(callback: @escaping (_ connected: Bool) -> Void) throws -> Void
35
36
  func isAndroidAutoConnected() throws -> Bool
36
37
  func setVolume(volume: Double) throws -> Promise<Void>
@@ -478,6 +478,22 @@ open class HybridTrackPlayerSpec_cxx {
478
478
  }
479
479
  }
480
480
 
481
+ @inline(__always)
482
+ public final func onTimedMetadata(callback: bridge.Func_void_TimedMetadata) -> bridge.Result_void_ {
483
+ do {
484
+ try self.__implementation.onTimedMetadata(callback: { () -> (TimedMetadata) -> Void in
485
+ let __wrappedFunction = bridge.wrap_Func_void_TimedMetadata(callback)
486
+ return { (__metadata: TimedMetadata) -> Void in
487
+ __wrappedFunction.call(__metadata)
488
+ }
489
+ }())
490
+ return bridge.create_Result_void_()
491
+ } catch (let __error) {
492
+ let __exceptionPtr = __error.toCpp()
493
+ return bridge.create_Result_void_(__exceptionPtr)
494
+ }
495
+ }
496
+
481
497
  @inline(__always)
482
498
  public final func onAndroidAutoConnectionChange(callback: bridge.Func_void_bool) -> bridge.Result_void_ {
483
499
  do {
@@ -0,0 +1,96 @@
1
+ ///
2
+ /// TimedMetadata.swift
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ import NitroModules
9
+
10
+ /**
11
+ * Represents an instance of `TimedMetadata`, backed by a C++ struct.
12
+ */
13
+ public typealias TimedMetadata = margelo.nitro.nitroplayer.TimedMetadata
14
+
15
+ public extension TimedMetadata {
16
+ private typealias bridge = margelo.nitro.nitroplayer.bridge.swift
17
+
18
+ /**
19
+ * Create a new instance of `TimedMetadata`.
20
+ */
21
+ init(title: String?, artist: String?, album: String?, artworkUrl: String?) {
22
+ self.init({ () -> bridge.std__optional_std__string_ in
23
+ if let __unwrappedValue = title {
24
+ return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
25
+ } else {
26
+ return .init()
27
+ }
28
+ }(), { () -> bridge.std__optional_std__string_ in
29
+ if let __unwrappedValue = artist {
30
+ return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
31
+ } else {
32
+ return .init()
33
+ }
34
+ }(), { () -> bridge.std__optional_std__string_ in
35
+ if let __unwrappedValue = album {
36
+ return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
37
+ } else {
38
+ return .init()
39
+ }
40
+ }(), { () -> bridge.std__optional_std__string_ in
41
+ if let __unwrappedValue = artworkUrl {
42
+ return bridge.create_std__optional_std__string_(std.string(__unwrappedValue))
43
+ } else {
44
+ return .init()
45
+ }
46
+ }())
47
+ }
48
+
49
+ @inline(__always)
50
+ var title: String? {
51
+ return { () -> String? in
52
+ if bridge.has_value_std__optional_std__string_(self.__title) {
53
+ let __unwrapped = bridge.get_std__optional_std__string_(self.__title)
54
+ return String(__unwrapped)
55
+ } else {
56
+ return nil
57
+ }
58
+ }()
59
+ }
60
+
61
+ @inline(__always)
62
+ var artist: String? {
63
+ return { () -> String? in
64
+ if bridge.has_value_std__optional_std__string_(self.__artist) {
65
+ let __unwrapped = bridge.get_std__optional_std__string_(self.__artist)
66
+ return String(__unwrapped)
67
+ } else {
68
+ return nil
69
+ }
70
+ }()
71
+ }
72
+
73
+ @inline(__always)
74
+ var album: String? {
75
+ return { () -> String? in
76
+ if bridge.has_value_std__optional_std__string_(self.__album) {
77
+ let __unwrapped = bridge.get_std__optional_std__string_(self.__album)
78
+ return String(__unwrapped)
79
+ } else {
80
+ return nil
81
+ }
82
+ }()
83
+ }
84
+
85
+ @inline(__always)
86
+ var artworkUrl: String? {
87
+ return { () -> String? in
88
+ if bridge.has_value_std__optional_std__string_(self.__artworkUrl) {
89
+ let __unwrapped = bridge.get_std__optional_std__string_(self.__artworkUrl)
90
+ return String(__unwrapped)
91
+ } else {
92
+ return nil
93
+ }
94
+ }()
95
+ }
96
+ }
@@ -32,6 +32,7 @@ namespace margelo::nitro::nitroplayer {
32
32
  prototype.registerHybridMethod("onPlaybackStateChange", &HybridTrackPlayerSpec::onPlaybackStateChange);
33
33
  prototype.registerHybridMethod("onSeek", &HybridTrackPlayerSpec::onSeek);
34
34
  prototype.registerHybridMethod("onPlaybackProgressChange", &HybridTrackPlayerSpec::onPlaybackProgressChange);
35
+ prototype.registerHybridMethod("onTimedMetadata", &HybridTrackPlayerSpec::onTimedMetadata);
35
36
  prototype.registerHybridMethod("onAndroidAutoConnectionChange", &HybridTrackPlayerSpec::onAndroidAutoConnectionChange);
36
37
  prototype.registerHybridMethod("isAndroidAutoConnected", &HybridTrackPlayerSpec::isAndroidAutoConnected);
37
38
  prototype.registerHybridMethod("setVolume", &HybridTrackPlayerSpec::setVolume);
@@ -25,6 +25,8 @@ namespace margelo::nitro::nitroplayer { struct PlayerConfig; }
25
25
  namespace margelo::nitro::nitroplayer { enum class Reason; }
26
26
  // Forward declaration of `TrackPlayerState` to properly resolve imports.
27
27
  namespace margelo::nitro::nitroplayer { enum class TrackPlayerState; }
28
+ // Forward declaration of `TimedMetadata` to properly resolve imports.
29
+ namespace margelo::nitro::nitroplayer { struct TimedMetadata; }
28
30
 
29
31
  #include <NitroModules/Promise.hpp>
30
32
  #include <string>
@@ -37,6 +39,7 @@ namespace margelo::nitro::nitroplayer { enum class TrackPlayerState; }
37
39
  #include "Reason.hpp"
38
40
  #include <functional>
39
41
  #include "TrackPlayerState.hpp"
42
+ #include "TimedMetadata.hpp"
40
43
 
41
44
  namespace margelo::nitro::nitroplayer {
42
45
 
@@ -87,6 +90,7 @@ namespace margelo::nitro::nitroplayer {
87
90
  virtual void onPlaybackStateChange(const std::function<void(TrackPlayerState /* state */, std::optional<Reason> /* reason */)>& callback) = 0;
88
91
  virtual void onSeek(const std::function<void(double /* position */, double /* totalDuration */)>& callback) = 0;
89
92
  virtual void onPlaybackProgressChange(const std::function<void(double /* position */, double /* totalDuration */, std::optional<bool> /* isManuallySeeked */)>& callback) = 0;
93
+ virtual void onTimedMetadata(const std::function<void(const TimedMetadata& /* metadata */)>& callback) = 0;
90
94
  virtual void onAndroidAutoConnectionChange(const std::function<void(bool /* connected */)>& callback) = 0;
91
95
  virtual bool isAndroidAutoConnected() = 0;
92
96
  virtual std::shared_ptr<Promise<void>> setVolume(double volume) = 0;
@@ -0,0 +1,96 @@
1
+ ///
2
+ /// TimedMetadata.hpp
3
+ /// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
4
+ /// https://github.com/mrousavy/nitro
5
+ /// Copyright © Marc Rousavy @ Margelo
6
+ ///
7
+
8
+ #pragma once
9
+
10
+ #if __has_include(<NitroModules/JSIConverter.hpp>)
11
+ #include <NitroModules/JSIConverter.hpp>
12
+ #else
13
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
14
+ #endif
15
+ #if __has_include(<NitroModules/NitroDefines.hpp>)
16
+ #include <NitroModules/NitroDefines.hpp>
17
+ #else
18
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
19
+ #endif
20
+ #if __has_include(<NitroModules/JSIHelpers.hpp>)
21
+ #include <NitroModules/JSIHelpers.hpp>
22
+ #else
23
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
24
+ #endif
25
+ #if __has_include(<NitroModules/PropNameIDCache.hpp>)
26
+ #include <NitroModules/PropNameIDCache.hpp>
27
+ #else
28
+ #error NitroModules cannot be found! Are you sure you installed NitroModules properly?
29
+ #endif
30
+
31
+
32
+
33
+ #include <string>
34
+ #include <optional>
35
+
36
+ namespace margelo::nitro::nitroplayer {
37
+
38
+ /**
39
+ * A struct which can be represented as a JavaScript object (TimedMetadata).
40
+ */
41
+ struct TimedMetadata final {
42
+ public:
43
+ std::optional<std::string> title SWIFT_PRIVATE;
44
+ std::optional<std::string> artist SWIFT_PRIVATE;
45
+ std::optional<std::string> album SWIFT_PRIVATE;
46
+ std::optional<std::string> artworkUrl SWIFT_PRIVATE;
47
+
48
+ public:
49
+ TimedMetadata() = default;
50
+ explicit TimedMetadata(std::optional<std::string> title, std::optional<std::string> artist, std::optional<std::string> album, std::optional<std::string> artworkUrl): title(title), artist(artist), album(album), artworkUrl(artworkUrl) {}
51
+
52
+ public:
53
+ friend bool operator==(const TimedMetadata& lhs, const TimedMetadata& rhs) = default;
54
+ };
55
+
56
+ } // namespace margelo::nitro::nitroplayer
57
+
58
+ namespace margelo::nitro {
59
+
60
+ // C++ TimedMetadata <> JS TimedMetadata (object)
61
+ template <>
62
+ struct JSIConverter<margelo::nitro::nitroplayer::TimedMetadata> final {
63
+ static inline margelo::nitro::nitroplayer::TimedMetadata fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
64
+ jsi::Object obj = arg.asObject(runtime);
65
+ return margelo::nitro::nitroplayer::TimedMetadata(
66
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "title"))),
67
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "artist"))),
68
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "album"))),
69
+ JSIConverter<std::optional<std::string>>::fromJSI(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "artworkUrl")))
70
+ );
71
+ }
72
+ static inline jsi::Value toJSI(jsi::Runtime& runtime, const margelo::nitro::nitroplayer::TimedMetadata& arg) {
73
+ jsi::Object obj(runtime);
74
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "title"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.title));
75
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "artist"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.artist));
76
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "album"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.album));
77
+ obj.setProperty(runtime, PropNameIDCache::get(runtime, "artworkUrl"), JSIConverter<std::optional<std::string>>::toJSI(runtime, arg.artworkUrl));
78
+ return obj;
79
+ }
80
+ static inline bool canConvert(jsi::Runtime& runtime, const jsi::Value& value) {
81
+ if (!value.isObject()) {
82
+ return false;
83
+ }
84
+ jsi::Object obj = value.getObject(runtime);
85
+ if (!nitro::isPlainObject(runtime, obj)) {
86
+ return false;
87
+ }
88
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "title")))) return false;
89
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "artist")))) return false;
90
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "album")))) return false;
91
+ if (!JSIConverter<std::optional<std::string>>::canConvert(runtime, obj.getProperty(runtime, PropNameIDCache::get(runtime, "artworkUrl")))) return false;
92
+ return true;
93
+ }
94
+ };
95
+
96
+ } // namespace margelo::nitro
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-nitro-player",
3
- "version": "1.5.1-alpha.0",
3
+ "version": "1.6.0-alpha.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",
@@ -1,5 +1,10 @@
1
1
  import { PlayerQueue, TrackPlayer } from '../index'
2
- import type { TrackItem, TrackPlayerState, Reason } from '../types/PlayerQueue'
2
+ import type {
3
+ TrackItem,
4
+ TrackPlayerState,
5
+ Reason,
6
+ TimedMetadata,
7
+ } from '../types/PlayerQueue'
3
8
 
4
9
  type PlaybackStateCallback = (state: TrackPlayerState, reason?: Reason) => void
5
10
  type TrackChangeCallback = (track: TrackItem, reason?: Reason) => void
@@ -9,6 +14,7 @@ type PlaybackProgressCallback = (
9
14
  isManuallySeeked?: boolean
10
15
  ) => void
11
16
  type SeekCallback = (position: number, totalDuration: number) => void
17
+ type TimedMetadataCallback = (metadata: TimedMetadata) => void
12
18
  type TemporaryQueueCallback = (
13
19
  playNextQueue: TrackItem[],
14
20
  upNextQueue: TrackItem[]
@@ -24,6 +30,7 @@ class CallbackSubscriptionManager {
24
30
  private trackChangeSubscribers = new Set<TrackChangeCallback>()
25
31
  private playbackProgressSubscribers = new Set<PlaybackProgressCallback>()
26
32
  private seekSubscribers = new Set<SeekCallback>()
33
+ private timedMetadataSubscribers = new Set<TimedMetadataCallback>()
27
34
  private temporaryQueueSubscribers = new Set<TemporaryQueueCallback>()
28
35
  private playlistsChangedSubscribers = new Set<() => void>()
29
36
  private isPlaylistsChangedRegistered = false
@@ -31,6 +38,7 @@ class CallbackSubscriptionManager {
31
38
  private isTrackChangeRegistered = false
32
39
  private isPlaybackProgressRegistered = false
33
40
  private isSeekRegistered = false
41
+ private isTimedMetadataRegistered = false
34
42
  private isTemporaryQueueRegistered = false
35
43
 
36
44
  /**
@@ -263,6 +271,44 @@ class CallbackSubscriptionManager {
263
271
  )
264
272
  }
265
273
  }
274
+
275
+ /**
276
+ * Subscribe to in-stream (timed) metadata events
277
+ * @returns Unsubscribe function
278
+ */
279
+ subscribeToTimedMetadata(callback: TimedMetadataCallback): () => void {
280
+ this.timedMetadataSubscribers.add(callback)
281
+ this.ensureTimedMetadataRegistered()
282
+
283
+ return () => {
284
+ this.timedMetadataSubscribers.delete(callback)
285
+ }
286
+ }
287
+
288
+ private ensureTimedMetadataRegistered(): void {
289
+ if (this.isTimedMetadataRegistered) return
290
+
291
+ try {
292
+ TrackPlayer.onTimedMetadata((metadata) => {
293
+ this.timedMetadataSubscribers.forEach((subscriber) => {
294
+ try {
295
+ subscriber(metadata)
296
+ } catch (error) {
297
+ console.error(
298
+ '[CallbackManager] Error in timed metadata subscriber:',
299
+ error
300
+ )
301
+ }
302
+ })
303
+ })
304
+ this.isTimedMetadataRegistered = true
305
+ } catch (error) {
306
+ console.error(
307
+ '[CallbackManager] Failed to register timed metadata callback:',
308
+ error
309
+ )
310
+ }
311
+ }
266
312
  }
267
313
 
268
314
  // Export singleton instance
@@ -4,6 +4,7 @@ export { useOnPlaybackStateChange } from './useOnPlaybackStateChange'
4
4
  export type { PlaybackStateResult } from './useOnPlaybackStateChange'
5
5
  export { useOnSeek } from './useOnSeek'
6
6
  export { useOnPlaybackProgressChange } from './useOnPlaybackProgressChange'
7
+ export { useTimedMetadata } from './useTimedMetadata'
7
8
  export { useAndroidAutoConnection } from './useAndroidAutoConnection'
8
9
  export { useAudioDevices } from './useAudioDevices'
9
10
  export { useNowPlaying } from './useNowPlaying'