react-native-nitro-player 0.6.1 → 0.7.1-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.
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrary.kt +9 -13
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAudioDevices.kt +45 -90
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridDownloadManager.kt +48 -182
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridEqualizer.kt +21 -77
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridPlayerQueue.kt +55 -104
- package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridTrackPlayer.kt +113 -123
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/ExoPlayerCore.kt +82 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/ListenerRegistry.kt +48 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerAndroidAuto.kt +62 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerCore.kt +153 -1887
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerListener.kt +122 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerNotify.kt +44 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerPlayback.kt +162 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerQueue.kt +165 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerQueueBuild.kt +161 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerSetup.kt +28 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerTempQueue.kt +121 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerUrlLoader.kt +98 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/download/DownloadDatabase.kt +27 -18
- package/android/src/main/java/com/margelo/nitro/nitroplayer/equalizer/EqualizerCore.kt +11 -58
- package/android/src/main/java/com/margelo/nitro/nitroplayer/media/MediaSessionManager.kt +13 -30
- package/android/src/main/java/com/margelo/nitro/nitroplayer/playlist/PlaylistManager.kt +102 -162
- package/ios/HybridDownloadManager.swift +32 -26
- package/ios/HybridEqualizer.swift +48 -35
- package/ios/HybridTrackPlayer.swift +127 -102
- package/ios/core/ListenerRegistry.swift +60 -0
- package/ios/core/TrackPlayerCore.swift +130 -2356
- package/ios/core/TrackPlayerListener.swift +395 -0
- package/ios/core/TrackPlayerNotify.swift +52 -0
- package/ios/core/TrackPlayerPlayback.swift +274 -0
- package/ios/core/TrackPlayerQueue.swift +212 -0
- package/ios/core/TrackPlayerQueueBuild.swift +482 -0
- package/ios/core/TrackPlayerTempQueue.swift +167 -0
- package/ios/core/TrackPlayerUrlLoader.swift +169 -0
- package/ios/equalizer/EqualizerCore.swift +24 -89
- package/ios/media/MediaSessionManager.swift +32 -49
- package/ios/playlist/PlaylistManager.swift +2 -9
- package/ios/queue/HybridPlayerQueue.swift +69 -66
- package/lib/hooks/useDownloadedTracks.js +16 -13
- package/lib/hooks/useEqualizer.d.ts +4 -4
- package/lib/hooks/useEqualizer.js +12 -12
- package/lib/hooks/useEqualizerPresets.d.ts +3 -3
- package/lib/hooks/useEqualizerPresets.js +12 -18
- package/lib/specs/AndroidAutoMediaLibrary.nitro.d.ts +2 -2
- package/lib/specs/AudioDevices.nitro.d.ts +2 -2
- package/lib/specs/DownloadManager.nitro.d.ts +10 -10
- package/lib/specs/Equalizer.nitro.d.ts +9 -9
- package/lib/specs/TrackPlayer.nitro.d.ts +38 -16
- package/nitro.json +44 -11
- package/nitrogen/generated/android/NitroPlayerOnLoad.cpp +63 -24
- package/nitrogen/generated/android/c++/JCurrentPlayingType.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadConfig.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadError.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadErrorReason.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadProgress.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadQueueStatus.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadState.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadStorageInfo.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadTask.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadedPlaylist.hpp +1 -1
- package/nitrogen/generated/android/c++/JDownloadedTrack.hpp +1 -1
- package/nitrogen/generated/android/c++/JEqualizerBand.hpp +1 -1
- package/nitrogen/generated/android/c++/JEqualizerPreset.hpp +1 -1
- package/nitrogen/generated/android/c++/JEqualizerState.hpp +1 -1
- package/nitrogen/generated/android/c++/JFunc_void_DownloadProgress.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_DownloadedTrack.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_TrackItem_std__optional_Reason_.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_TrackPlayerState_std__optional_Reason_.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_bool.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_double_double.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_double_double_std__optional_bool_.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_std__variant_nitro__NullType__std__string__.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__string_Playlist_std__optional_QueueOperation_.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__string_std__string_DownloadState_std__optional_DownloadError_.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_EqualizerBand_.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_Playlist__std__optional_QueueOperation_.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__double.hpp +2 -2
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__std__vector_TrackItem_.hpp +122 -0
- package/nitrogen/generated/android/c++/JGainRange.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.cpp +49 -30
- package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.hpp +21 -24
- package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.cpp +35 -28
- package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.hpp +20 -23
- package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.cpp +197 -93
- package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.hpp +29 -32
- package/nitrogen/generated/android/c++/JHybridEqualizerSpec.cpp +157 -67
- package/nitrogen/generated/android/c++/JHybridEqualizerSpec.hpp +28 -31
- package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.cpp +138 -53
- package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.hpp +27 -30
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +282 -69
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +35 -30
- package/nitrogen/generated/android/c++/JPlaybackSource.hpp +1 -1
- package/nitrogen/generated/android/c++/JPlayerConfig.hpp +1 -1
- package/nitrogen/generated/android/c++/JPlayerState.hpp +1 -1
- package/nitrogen/generated/android/c++/JPlaylist.hpp +1 -1
- package/nitrogen/generated/android/c++/JPresetType.hpp +1 -1
- package/nitrogen/generated/android/c++/JQueueOperation.hpp +1 -1
- package/nitrogen/generated/android/c++/JReason.hpp +1 -1
- package/nitrogen/generated/android/c++/JRepeatMode.hpp +1 -1
- package/nitrogen/generated/android/c++/JStorageLocation.hpp +1 -1
- package/nitrogen/generated/android/c++/JTAudioDevice.hpp +1 -1
- package/nitrogen/generated/android/c++/JTrackItem.hpp +1 -1
- package/nitrogen/generated/android/c++/JTrackPlayerState.hpp +1 -1
- package/nitrogen/generated/android/c++/JVariant_NullType_Double.hpp +3 -3
- package/nitrogen/generated/android/c++/JVariant_NullType_DownloadError.hpp +3 -3
- package/nitrogen/generated/android/c++/JVariant_NullType_DownloadTask.hpp +3 -3
- package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedPlaylist.hpp +3 -3
- package/nitrogen/generated/android/c++/JVariant_NullType_DownloadedTrack.hpp +3 -3
- package/nitrogen/generated/android/c++/JVariant_NullType_Playlist.hpp +3 -3
- package/nitrogen/generated/android/c++/JVariant_NullType_String.hpp +3 -3
- package/nitrogen/generated/android/c++/JVariant_NullType_TrackItem.hpp +3 -3
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Func_void_std__vector_TrackItem__std__vector_TrackItem_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrarySpec.kt +18 -20
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridAudioDevicesSpec.kt +17 -19
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridDownloadManagerSpec.kt +25 -28
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridEqualizerSpec.kt +25 -27
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridPlayerQueueSpec.kt +24 -26
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +60 -26
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_Double.kt +0 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadError.kt +0 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadTask.kt +0 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadedPlaylist.kt +0 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_DownloadedTrack.kt +0 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_Playlist.kt +0 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_String.kt +0 -6
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/Variant_NullType_TrackItem.kt +0 -6
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.cpp +74 -18
- package/nitrogen/generated/ios/NitroPlayer-Swift-Cxx-Bridge.hpp +380 -151
- package/nitrogen/generated/ios/c++/HybridDownloadManagerSpecSwift.hpp +10 -10
- package/nitrogen/generated/ios/c++/HybridEqualizerSpecSwift.hpp +12 -9
- package/nitrogen/generated/ios/c++/HybridPlayerQueueSpecSwift.hpp +23 -8
- package/nitrogen/generated/ios/c++/HybridTrackPlayerSpecSwift.hpp +82 -8
- package/nitrogen/generated/ios/swift/Func_void_EqualizerState.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__DownloadedPlaylist_.swift +58 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__DownloadedTrack_.swift +58 -0
- package/nitrogen/generated/ios/swift/Func_void_std__variant_nitro__NullType__std__string_.swift +58 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_DownloadedPlaylist_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_DownloadedTrack_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__vector_EqualizerBand_.swift +5 -5
- package/nitrogen/generated/ios/swift/Func_void_std__vector_TrackItem__std__vector_TrackItem_.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridDownloadManagerSpec.swift +10 -10
- package/nitrogen/generated/ios/swift/HybridDownloadManagerSpec_cxx.swift +141 -71
- package/nitrogen/generated/ios/swift/HybridEqualizerSpec.swift +9 -9
- package/nitrogen/generated/ios/swift/HybridEqualizerSpec_cxx.swift +105 -41
- package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec.swift +8 -8
- package/nitrogen/generated/ios/swift/HybridPlayerQueueSpec_cxx.swift +95 -32
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec.swift +16 -8
- package/nitrogen/generated/ios/swift/HybridTrackPlayerSpec_cxx.swift +267 -32
- package/nitrogen/generated/shared/c++/HybridAndroidAutoMediaLibrarySpec.hpp +3 -2
- package/nitrogen/generated/shared/c++/HybridAudioDevicesSpec.hpp +2 -1
- package/nitrogen/generated/shared/c++/HybridDownloadManagerSpec.hpp +10 -10
- package/nitrogen/generated/shared/c++/HybridEqualizerSpec.hpp +10 -9
- package/nitrogen/generated/shared/c++/HybridPlayerQueueSpec.hpp +9 -8
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.cpp +8 -0
- package/nitrogen/generated/shared/c++/HybridTrackPlayerSpec.hpp +16 -8
- package/package.json +3 -3
- package/src/hooks/useDownloadedTracks.ts +17 -13
- package/src/hooks/useEqualizer.ts +16 -16
- package/src/hooks/useEqualizerPresets.ts +15 -21
- package/src/specs/AndroidAutoMediaLibrary.nitro.ts +2 -2
- package/src/specs/AudioDevices.nitro.ts +2 -2
- package/src/specs/DownloadManager.nitro.ts +10 -10
- package/src/specs/Equalizer.nitro.ts +9 -9
- package/src/specs/TrackPlayer.nitro.ts +52 -16
|
@@ -12,6 +12,7 @@ final class HybridEqualizer: HybridEqualizerSpec {
|
|
|
12
12
|
// MARK: - Properties
|
|
13
13
|
|
|
14
14
|
private let core: EqualizerCore
|
|
15
|
+
private var listenerIds: [(String, Int64)] = []
|
|
15
16
|
|
|
16
17
|
// MARK: - Initialization
|
|
17
18
|
|
|
@@ -22,90 +23,102 @@ final class HybridEqualizer: HybridEqualizerSpec {
|
|
|
22
23
|
|
|
23
24
|
// MARK: - Enable/Disable
|
|
24
25
|
|
|
25
|
-
func setEnabled(enabled: Bool) throws ->
|
|
26
|
-
|
|
26
|
+
func setEnabled(enabled: Bool) throws -> Promise<Void> {
|
|
27
|
+
Promise.async { _ = self.core.setEnabled(enabled) }
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
func isEnabled() throws -> Bool {
|
|
30
|
-
|
|
31
|
+
core.isEnabled()
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
// MARK: - Band Control
|
|
34
35
|
|
|
35
|
-
func getBands() throws -> [EqualizerBand] {
|
|
36
|
-
|
|
36
|
+
func getBands() throws -> Promise<[EqualizerBand]> {
|
|
37
|
+
Promise.async { self.core.getBands() }
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
func setBandGain(bandIndex: Double, gainDb: Double) throws ->
|
|
40
|
-
|
|
40
|
+
func setBandGain(bandIndex: Double, gainDb: Double) throws -> Promise<Void> {
|
|
41
|
+
Promise.async { _ = self.core.setBandGain(bandIndex: Int(bandIndex), gainDb: gainDb) }
|
|
41
42
|
}
|
|
42
43
|
|
|
43
|
-
func setAllBandGains(gains: [Double]) throws ->
|
|
44
|
-
|
|
44
|
+
func setAllBandGains(gains: [Double]) throws -> Promise<Void> {
|
|
45
|
+
Promise.async { _ = self.core.setAllBandGains(gains) }
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
func getBandRange() throws -> GainRange {
|
|
48
|
-
|
|
49
|
+
core.getBandRange()
|
|
49
50
|
}
|
|
50
51
|
|
|
51
52
|
// MARK: - Presets
|
|
52
53
|
|
|
53
54
|
func getPresets() throws -> [EqualizerPreset] {
|
|
54
|
-
|
|
55
|
+
core.getPresets()
|
|
55
56
|
}
|
|
56
57
|
|
|
57
58
|
func getBuiltInPresets() throws -> [EqualizerPreset] {
|
|
58
|
-
|
|
59
|
+
core.getBuiltInPresets()
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
func getCustomPresets() throws -> [EqualizerPreset] {
|
|
62
|
-
|
|
63
|
+
core.getCustomPresets()
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
func applyPreset(presetName: String) throws ->
|
|
66
|
-
|
|
66
|
+
func applyPreset(presetName: String) throws -> Promise<Void> {
|
|
67
|
+
Promise.async { _ = self.core.applyPreset(presetName) }
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
func getCurrentPresetName() throws -> Variant_NullType_String {
|
|
70
71
|
if let name = core.getCurrentPresetName() {
|
|
71
72
|
return .second(name)
|
|
72
|
-
} else {
|
|
73
|
-
return .first(NullType.null)
|
|
74
73
|
}
|
|
74
|
+
return .first(NullType.null)
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
func saveCustomPreset(name: String) throws ->
|
|
78
|
-
|
|
77
|
+
func saveCustomPreset(name: String) throws -> Promise<Void> {
|
|
78
|
+
Promise.async { _ = self.core.saveCustomPreset(name) }
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
func deleteCustomPreset(name: String) throws ->
|
|
82
|
-
|
|
81
|
+
func deleteCustomPreset(name: String) throws -> Promise<Void> {
|
|
82
|
+
Promise.async { _ = self.core.deleteCustomPreset(name) }
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// MARK: - State
|
|
86
86
|
|
|
87
|
-
func getState() throws -> EqualizerState {
|
|
88
|
-
|
|
87
|
+
func getState() throws -> Promise<EqualizerState> {
|
|
88
|
+
Promise.async { self.core.getState() }
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
func reset() throws {
|
|
92
|
-
core.reset()
|
|
91
|
+
func reset() throws -> Promise<Void> {
|
|
92
|
+
Promise.async { self.core.reset() }
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
// MARK: - Event
|
|
95
|
+
// MARK: - Event listeners (v2 — store IDs for cleanup)
|
|
96
96
|
|
|
97
|
-
func onEnabledChange(callback: @escaping (Bool) -> Void) throws {
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
func onEnabledChange(callback: @escaping (_ enabled: Bool) -> Void) throws {
|
|
98
|
+
let id = core.addOnEnabledChangeListener(callback)
|
|
99
|
+
listenerIds.append(("onEnabledChange", id))
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
func onBandChange(callback: @escaping ([EqualizerBand]) -> Void) throws {
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
func onBandChange(callback: @escaping (_ bands: [EqualizerBand]) -> Void) throws {
|
|
103
|
+
let id = core.addOnBandChangeListener(callback)
|
|
104
|
+
listenerIds.append(("onBandChange", id))
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
func onPresetChange(callback: @escaping (Variant_NullType_String?) -> Void) throws {
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
func onPresetChange(callback: @escaping (_ presetName: Variant_NullType_String?) -> Void) throws {
|
|
108
|
+
let id = core.addOnPresetChangeListener(callback)
|
|
109
|
+
listenerIds.append(("onPresetChange", id))
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// MARK: - Cleanup
|
|
113
|
+
|
|
114
|
+
deinit {
|
|
115
|
+
for (type, id) in listenerIds {
|
|
116
|
+
switch type {
|
|
117
|
+
case "onEnabledChange": _ = core.removeOnEnabledChangeListener(id: id)
|
|
118
|
+
case "onBandChange": _ = core.removeOnBandChangeListener(id: id)
|
|
119
|
+
case "onPresetChange": _ = core.removeOnPresetChangeListener(id: id)
|
|
120
|
+
default: break
|
|
121
|
+
}
|
|
122
|
+
}
|
|
110
123
|
}
|
|
111
124
|
}
|
|
@@ -15,6 +15,9 @@ final class HybridTrackPlayer: HybridTrackPlayerSpec {
|
|
|
15
15
|
|
|
16
16
|
private let core: TrackPlayerCore
|
|
17
17
|
|
|
18
|
+
/// Stable listener IDs for cleanup on deinit
|
|
19
|
+
private var listenerIds: [(String, Int64)] = []
|
|
20
|
+
|
|
18
21
|
// MARK: - Initialization
|
|
19
22
|
|
|
20
23
|
override init() {
|
|
@@ -22,174 +25,196 @@ final class HybridTrackPlayer: HybridTrackPlayerSpec {
|
|
|
22
25
|
super.init()
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
// MARK: - Playback Control
|
|
28
|
+
// MARK: - Playback Control (async Promise<Void>)
|
|
29
|
+
|
|
30
|
+
func play() throws -> Promise<Void> {
|
|
31
|
+
Promise.async { await self.core.play() }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
func pause() throws -> Promise<Void> {
|
|
35
|
+
Promise.async { await self.core.pause() }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
func seek(position: Double) throws -> Promise<Void> {
|
|
39
|
+
Promise.async { await self.core.seek(position: position) }
|
|
40
|
+
}
|
|
26
41
|
|
|
27
|
-
func
|
|
28
|
-
core.
|
|
42
|
+
func skipToNext() throws -> Promise<Void> {
|
|
43
|
+
Promise.async { await self.core.skipToNext() }
|
|
29
44
|
}
|
|
30
45
|
|
|
31
|
-
func
|
|
32
|
-
core.
|
|
46
|
+
func skipToPrevious() throws -> Promise<Void> {
|
|
47
|
+
Promise.async { await self.core.skipToPrevious() }
|
|
33
48
|
}
|
|
34
49
|
|
|
35
50
|
func playSong(songId: String, fromPlaylist: String?) throws -> Promise<Void> {
|
|
36
|
-
|
|
37
|
-
self.core.playSong(songId: songId, fromPlaylist: fromPlaylist)
|
|
38
|
-
}
|
|
51
|
+
Promise.async { await self.core.playSong(songId: songId, fromPlaylist: fromPlaylist) }
|
|
39
52
|
}
|
|
40
53
|
|
|
41
|
-
func
|
|
42
|
-
core.
|
|
54
|
+
func skipToIndex(index: Double) throws -> Promise<Bool> {
|
|
55
|
+
Promise.async { await self.core.skipToIndex(index: Int(index)) }
|
|
43
56
|
}
|
|
44
57
|
|
|
45
|
-
|
|
46
|
-
|
|
58
|
+
// MARK: - Repeat / Volume / Config
|
|
59
|
+
|
|
60
|
+
func setRepeatMode(mode: RepeatMode) throws -> Promise<Void> {
|
|
61
|
+
Promise.async { await self.core.setRepeatMode(mode: mode) }
|
|
47
62
|
}
|
|
48
63
|
|
|
49
|
-
func
|
|
50
|
-
core.
|
|
64
|
+
func getRepeatMode() throws -> RepeatMode {
|
|
65
|
+
core.getRepeatMode()
|
|
51
66
|
}
|
|
52
67
|
|
|
53
|
-
func
|
|
54
|
-
|
|
55
|
-
self.core.addToUpNext(trackId: trackId)
|
|
56
|
-
}
|
|
68
|
+
func setVolume(volume: Double) throws -> Promise<Void> {
|
|
69
|
+
Promise.async { await self.core.setVolume(volume: volume) }
|
|
57
70
|
}
|
|
58
71
|
|
|
59
|
-
func
|
|
60
|
-
|
|
61
|
-
self.core.
|
|
72
|
+
func configure(config: PlayerConfig) throws -> Promise<Void> {
|
|
73
|
+
Promise.async {
|
|
74
|
+
await self.core.configure(
|
|
75
|
+
androidAutoEnabled: config.androidAutoEnabled,
|
|
76
|
+
carPlayEnabled: config.carPlayEnabled,
|
|
77
|
+
showInNotification: config.showInNotification,
|
|
78
|
+
lookaheadCount: config.lookaheadCount.map { Int($0) }
|
|
79
|
+
)
|
|
62
80
|
}
|
|
63
81
|
}
|
|
64
82
|
|
|
83
|
+
// MARK: - Queue / State reads
|
|
84
|
+
|
|
65
85
|
func getActualQueue() throws -> Promise<[TrackItem]> {
|
|
66
|
-
|
|
67
|
-
return self.core.getActualQueue()
|
|
68
|
-
}
|
|
86
|
+
Promise.async { await self.core.getActualQueue() }
|
|
69
87
|
}
|
|
70
88
|
|
|
71
89
|
func getState() throws -> Promise<PlayerState> {
|
|
72
|
-
|
|
73
|
-
return self.core.getState()
|
|
74
|
-
}
|
|
90
|
+
Promise.async { await self.core.getState() }
|
|
75
91
|
}
|
|
76
92
|
|
|
77
|
-
func
|
|
78
|
-
|
|
93
|
+
func getCurrentTrackIndex() throws -> Promise<Double> {
|
|
94
|
+
Promise.async { Double(await self.core.getCurrentTrackIndex()) }
|
|
79
95
|
}
|
|
80
96
|
|
|
81
|
-
|
|
82
|
-
|
|
97
|
+
// MARK: - URL updates / lazy loading
|
|
98
|
+
|
|
99
|
+
func updateTracks(tracks: [TrackItem]) throws -> Promise<Void> {
|
|
100
|
+
Promise.async { await self.core.updateTracks(tracks: tracks) }
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
func getTracksById(trackIds: [String]) throws -> Promise<[TrackItem]> {
|
|
104
|
+
Promise.async { await self.core.getTracksById(trackIds: trackIds) }
|
|
83
105
|
}
|
|
84
106
|
|
|
85
|
-
|
|
107
|
+
func getTracksNeedingUrls() throws -> Promise<[TrackItem]> {
|
|
108
|
+
Promise.async { await self.core.getTracksNeedingUrls() }
|
|
109
|
+
}
|
|
86
110
|
|
|
87
|
-
func
|
|
88
|
-
core.
|
|
89
|
-
androidAutoEnabled: config.androidAutoEnabled,
|
|
90
|
-
carPlayEnabled: config.carPlayEnabled,
|
|
91
|
-
showInNotification: config.showInNotification,
|
|
92
|
-
lookaheadCount: config.lookaheadCount.map { Int($0) }
|
|
93
|
-
)
|
|
111
|
+
func getNextTracks(count: Double) throws -> Promise<[TrackItem]> {
|
|
112
|
+
Promise.async { await self.core.getNextTracks(count: Int(count)) }
|
|
94
113
|
}
|
|
95
114
|
|
|
96
|
-
// MARK: -
|
|
115
|
+
// MARK: - Playback speed
|
|
116
|
+
|
|
117
|
+
func setPlaybackSpeed(speed: Double) throws -> Promise<Void> {
|
|
118
|
+
Promise.async { await self.core.setPlaybackSpeed(speed) }
|
|
119
|
+
}
|
|
97
120
|
|
|
98
|
-
func
|
|
99
|
-
|
|
100
|
-
core.addOnChangeTrackListener(owner: self, callback)
|
|
121
|
+
func getPlaybackSpeed() throws -> Promise<Double> {
|
|
122
|
+
Promise.async { await self.core.getPlaybackSpeed() }
|
|
101
123
|
}
|
|
102
124
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
125
|
+
// MARK: - Temporary queue v2
|
|
126
|
+
|
|
127
|
+
func addToUpNext(trackId: String) throws -> Promise<Void> {
|
|
128
|
+
Promise.async { try await self.core.addToUpNext(trackId: trackId) }
|
|
106
129
|
}
|
|
107
130
|
|
|
108
|
-
func
|
|
109
|
-
|
|
110
|
-
core.addOnSeekListener(owner: self, callback)
|
|
131
|
+
func playNext(trackId: String) throws -> Promise<Void> {
|
|
132
|
+
Promise.async { try await self.core.playNext(trackId: trackId) }
|
|
111
133
|
}
|
|
112
134
|
|
|
113
|
-
func
|
|
114
|
-
|
|
115
|
-
core.addOnPlaybackProgressChangeListener(owner: self, callback)
|
|
135
|
+
func removeFromPlayNext(trackId: String) throws -> Promise<Bool> {
|
|
136
|
+
Promise.async { await self.core.removeFromPlayNext(trackId: trackId) }
|
|
116
137
|
}
|
|
117
138
|
|
|
118
|
-
|
|
139
|
+
func removeFromUpNext(trackId: String) throws -> Promise<Bool> {
|
|
140
|
+
Promise.async { await self.core.removeFromUpNext(trackId: trackId) }
|
|
141
|
+
}
|
|
119
142
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
func onAndroidAutoConnectionChange(callback: @escaping (Bool) -> Void) throws {
|
|
123
|
-
// iOS doesn't have Android Auto, so this is a no-op
|
|
143
|
+
func clearPlayNext() throws -> Promise<Void> {
|
|
144
|
+
Promise.async { await self.core.clearPlayNext() }
|
|
124
145
|
}
|
|
125
146
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
func isAndroidAutoConnected() throws -> Bool {
|
|
129
|
-
return false
|
|
147
|
+
func clearUpNext() throws -> Promise<Void> {
|
|
148
|
+
Promise.async { await self.core.clearUpNext() }
|
|
130
149
|
}
|
|
131
150
|
|
|
132
|
-
func
|
|
133
|
-
|
|
134
|
-
return self.core.skipToIndex(index: Int(index))
|
|
135
|
-
}
|
|
151
|
+
func reorderTemporaryTrack(trackId: String, newIndex: Double) throws -> Promise<Bool> {
|
|
152
|
+
Promise.async { await self.core.reorderTemporaryTrack(trackId: trackId, newIndex: Int(newIndex)) }
|
|
136
153
|
}
|
|
137
154
|
|
|
138
|
-
|
|
155
|
+
func getPlayNextQueue() throws -> Promise<[TrackItem]> {
|
|
156
|
+
Promise.async { await self.core.getPlayNextQueue() }
|
|
157
|
+
}
|
|
139
158
|
|
|
140
|
-
func
|
|
141
|
-
|
|
159
|
+
func getUpNextQueue() throws -> Promise<[TrackItem]> {
|
|
160
|
+
Promise.async { await self.core.getUpNextQueue() }
|
|
142
161
|
}
|
|
143
162
|
|
|
144
|
-
// MARK: -
|
|
163
|
+
// MARK: - Android Auto (iOS no-op)
|
|
145
164
|
|
|
146
|
-
func
|
|
147
|
-
|
|
148
|
-
self.core.updateTracks(tracks: tracks)
|
|
149
|
-
}
|
|
165
|
+
func onAndroidAutoConnectionChange(callback: @escaping (Bool) -> Void) throws {
|
|
166
|
+
// No-op on iOS
|
|
150
167
|
}
|
|
151
168
|
|
|
152
|
-
func
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
169
|
+
func isAndroidAutoConnected() throws -> Bool { false }
|
|
170
|
+
|
|
171
|
+
// MARK: - Event listeners (v2 — store IDs for cleanup)
|
|
172
|
+
|
|
173
|
+
func onChangeTrack(callback: @escaping (_ track: TrackItem, _ reason: Reason?) -> Void) throws {
|
|
174
|
+
let id = core.addOnChangeTrackListener(callback)
|
|
175
|
+
listenerIds.append(("onChangeTrack", id))
|
|
156
176
|
}
|
|
157
177
|
|
|
158
|
-
func
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
178
|
+
func onPlaybackStateChange(callback: @escaping (_ state: TrackPlayerState, _ reason: Reason?) -> Void) throws {
|
|
179
|
+
let id = core.addOnPlaybackStateChangeListener(callback)
|
|
180
|
+
listenerIds.append(("onPlaybackStateChange", id))
|
|
162
181
|
}
|
|
163
182
|
|
|
164
|
-
func
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
}
|
|
183
|
+
func onSeek(callback: @escaping (_ position: Double, _ totalDuration: Double) -> Void) throws {
|
|
184
|
+
let id = core.addOnSeekListener(callback)
|
|
185
|
+
listenerIds.append(("onSeek", id))
|
|
168
186
|
}
|
|
169
187
|
|
|
170
|
-
func
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
}
|
|
188
|
+
func onPlaybackProgressChange(callback: @escaping (_ position: Double, _ totalDuration: Double, _ isManuallySeeked: Bool?) -> Void) throws {
|
|
189
|
+
let id = core.addOnProgressListener(callback)
|
|
190
|
+
listenerIds.append(("onPlaybackProgressChange", id))
|
|
174
191
|
}
|
|
175
192
|
|
|
176
|
-
func onTracksNeedUpdate(callback: @escaping ([TrackItem], Double) -> Void) throws {
|
|
177
|
-
core.addOnTracksNeedUpdateListener { tracks, lookahead in
|
|
193
|
+
func onTracksNeedUpdate(callback: @escaping (_ tracks: [TrackItem], _ lookahead: Double) -> Void) throws {
|
|
194
|
+
let id = core.addOnTracksNeedUpdateListener { tracks, lookahead in
|
|
178
195
|
callback(tracks, Double(lookahead))
|
|
179
196
|
}
|
|
197
|
+
listenerIds.append(("onTracksNeedUpdate", id))
|
|
180
198
|
}
|
|
181
|
-
|
|
182
|
-
func
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
|
|
199
|
+
|
|
200
|
+
func onTemporaryQueueChange(callback: @escaping (_ playNextQueue: [TrackItem], _ upNextQueue: [TrackItem]) -> Void) throws {
|
|
201
|
+
let id = core.addOnTemporaryQueueChangeListener(callback)
|
|
202
|
+
listenerIds.append(("onTemporaryQueueChange", id))
|
|
187
203
|
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
204
|
+
|
|
205
|
+
// MARK: - Cleanup
|
|
206
|
+
|
|
207
|
+
deinit {
|
|
208
|
+
for (type, id) in listenerIds {
|
|
209
|
+
switch type {
|
|
210
|
+
case "onChangeTrack": _ = core.removeOnChangeTrackListener(id: id)
|
|
211
|
+
case "onPlaybackStateChange": _ = core.removeOnPlaybackStateChangeListener(id: id)
|
|
212
|
+
case "onSeek": _ = core.removeOnSeekListener(id: id)
|
|
213
|
+
case "onPlaybackProgressChange":_ = core.removeOnProgressListener(id: id)
|
|
214
|
+
case "onTracksNeedUpdate": _ = core.removeOnTracksNeedUpdateListener(id: id)
|
|
215
|
+
case "onTemporaryQueueChange": _ = core.removeOnTemporaryQueueChangeListener(id: id)
|
|
216
|
+
default: break
|
|
217
|
+
}
|
|
192
218
|
}
|
|
193
|
-
|
|
194
219
|
}
|
|
195
220
|
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
//
|
|
2
|
+
// ListenerRegistry.swift
|
|
3
|
+
// NitroPlayer
|
|
4
|
+
//
|
|
5
|
+
// Created by Ritesh Shukla on 25/03/26.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
|
|
10
|
+
final class ListenerRegistry<T> {
|
|
11
|
+
private struct Entry {
|
|
12
|
+
let id: Int64
|
|
13
|
+
let callback: T
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private let queue = DispatchQueue(label: "com.nitroplayer.registry")
|
|
17
|
+
private var entries: [Entry] = []
|
|
18
|
+
private var nextId: Int64 = 0
|
|
19
|
+
|
|
20
|
+
/// Register a callback and return its stable ID for later removal.
|
|
21
|
+
@discardableResult
|
|
22
|
+
func add(_ callback: T) -> Int64 {
|
|
23
|
+
var id: Int64 = 0
|
|
24
|
+
queue.sync {
|
|
25
|
+
nextId += 1
|
|
26
|
+
id = nextId
|
|
27
|
+
entries.append(Entry(id: id, callback: callback))
|
|
28
|
+
}
|
|
29
|
+
return id
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/// Remove the callback with the given ID. Returns true if found.
|
|
33
|
+
@discardableResult
|
|
34
|
+
func remove(id: Int64) -> Bool {
|
|
35
|
+
var found = false
|
|
36
|
+
queue.sync {
|
|
37
|
+
if let idx = entries.firstIndex(where: { $0.id == id }) {
|
|
38
|
+
entries.remove(at: idx)
|
|
39
|
+
found = true
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return found
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/// Remove all registered callbacks.
|
|
46
|
+
func clear() {
|
|
47
|
+
queue.sync { entries.removeAll() }
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/// Invoke action for every registered callback (snapshot iteration — safe under mutation).
|
|
51
|
+
func forEach(_ action: (T) -> Void) {
|
|
52
|
+
let snap = queue.sync { entries.map(\.callback) }
|
|
53
|
+
snap.forEach(action)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/// True when no callbacks are registered.
|
|
57
|
+
var isEmpty: Bool {
|
|
58
|
+
queue.sync { entries.isEmpty }
|
|
59
|
+
}
|
|
60
|
+
}
|