react-native-nitro-player 0.7.0 → 0.7.1-alpha.1
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 +47 -46
- 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 +179 -0
- package/android/src/main/java/com/margelo/nitro/nitroplayer/core/TrackPlayerQueueBuild.kt +170 -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 +150 -135
- 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 +221 -0
- package/ios/core/TrackPlayerQueueBuild.swift +493 -0
- package/ios/core/TrackPlayerTempQueue.swift +167 -0
- package/ios/core/TrackPlayerUrlLoader.swift +169 -0
- package/ios/equalizer/EqualizerCore.swift +63 -123
- 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 +22 -17
- 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 +10 -10
- package/lib/specs/TrackPlayer.nitro.d.ts +38 -16
- package/lib/types/EqualizerTypes.d.ts +3 -3
- package/nitrogen/generated/android/NitroPlayerOnLoad.cpp +2 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__vector_TrackItem__std__vector_TrackItem_.hpp +122 -0
- package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.cpp +31 -6
- package/nitrogen/generated/android/c++/JHybridAndroidAutoMediaLibrarySpec.hpp +2 -2
- package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.cpp +16 -3
- package/nitrogen/generated/android/c++/JHybridAudioDevicesSpec.hpp +1 -1
- package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.cpp +154 -44
- package/nitrogen/generated/android/c++/JHybridDownloadManagerSpec.hpp +10 -10
- package/nitrogen/generated/android/c++/JHybridEqualizerSpec.cpp +130 -34
- package/nitrogen/generated/android/c++/JHybridEqualizerSpec.hpp +9 -9
- package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.cpp +115 -24
- package/nitrogen/generated/android/c++/JHybridPlayerQueueSpec.hpp +8 -8
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.cpp +243 -24
- package/nitrogen/generated/android/c++/JHybridTrackPlayerSpec.hpp +16 -8
- 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 +3 -2
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridAudioDevicesSpec.kt +2 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridDownloadManagerSpec.kt +10 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridEqualizerSpec.kt +10 -9
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridPlayerQueueSpec.kt +9 -8
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitroplayer/HybridTrackPlayerSpec.kt +45 -8
- 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 +5 -5
- package/src/hooks/useDownloadedTracks.ts +17 -13
- package/src/hooks/useEqualizer.ts +26 -21
- 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 +10 -10
- package/src/specs/TrackPlayer.nitro.ts +52 -16
- package/src/types/EqualizerTypes.ts +17 -13
|
@@ -4,6 +4,7 @@ import androidx.annotation.Keep
|
|
|
4
4
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
5
5
|
import com.margelo.nitro.NitroModules
|
|
6
6
|
import com.margelo.nitro.core.NullType
|
|
7
|
+
import com.margelo.nitro.core.Promise
|
|
7
8
|
import com.margelo.nitro.nitroplayer.equalizer.EqualizerCore
|
|
8
9
|
|
|
9
10
|
@DoNotStrip
|
|
@@ -12,94 +13,37 @@ class HybridEqualizer : HybridEqualizerSpec() {
|
|
|
12
13
|
private val core: EqualizerCore
|
|
13
14
|
|
|
14
15
|
init {
|
|
15
|
-
val context =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
// Get the equalizer core - it will initialize lazily with audio session 0
|
|
19
|
-
// and be re-initialized with the proper session when onAudioSessionIdChanged fires
|
|
16
|
+
val context = NitroModules.applicationContext
|
|
17
|
+
?: throw IllegalStateException("React Context is not initialized")
|
|
20
18
|
core = EqualizerCore.getInstance(context)
|
|
21
19
|
core.ensureInitialized()
|
|
22
20
|
}
|
|
23
21
|
|
|
24
|
-
|
|
25
|
-
@Keep
|
|
26
|
-
override fun setEnabled(enabled: Boolean): Boolean = core.setEnabled(enabled)
|
|
27
|
-
|
|
28
|
-
@DoNotStrip
|
|
29
|
-
@Keep
|
|
22
|
+
// ── Sync reads ────────────────────────────────────────────────────────────
|
|
30
23
|
override fun isEnabled(): Boolean = core.isEnabled()
|
|
31
|
-
|
|
32
|
-
@DoNotStrip
|
|
33
|
-
@Keep
|
|
34
|
-
override fun getBands(): Array<EqualizerBand> = core.getBands()
|
|
35
|
-
|
|
36
|
-
@DoNotStrip
|
|
37
|
-
@Keep
|
|
38
|
-
override fun setBandGain(
|
|
39
|
-
bandIndex: Double,
|
|
40
|
-
gainDb: Double,
|
|
41
|
-
): Boolean = core.setBandGain(bandIndex.toInt(), gainDb)
|
|
42
|
-
|
|
43
|
-
@DoNotStrip
|
|
44
|
-
@Keep
|
|
45
|
-
override fun setAllBandGains(gains: DoubleArray): Boolean = core.setAllBandGains(gains)
|
|
46
|
-
|
|
47
|
-
@DoNotStrip
|
|
48
|
-
@Keep
|
|
49
24
|
override fun getBandRange(): GainRange = core.getBandRange()
|
|
50
|
-
|
|
51
|
-
@DoNotStrip
|
|
52
|
-
@Keep
|
|
53
25
|
override fun getPresets(): Array<EqualizerPreset> = core.getPresets()
|
|
54
|
-
|
|
55
|
-
@DoNotStrip
|
|
56
|
-
@Keep
|
|
57
26
|
override fun getBuiltInPresets(): Array<EqualizerPreset> = core.getBuiltInPresets()
|
|
58
|
-
|
|
59
|
-
@DoNotStrip
|
|
60
|
-
@Keep
|
|
61
27
|
override fun getCustomPresets(): Array<EqualizerPreset> = core.getCustomPresets()
|
|
62
|
-
|
|
63
|
-
@DoNotStrip
|
|
64
|
-
@Keep
|
|
65
|
-
override fun applyPreset(presetName: String): Boolean = core.applyPreset(presetName)
|
|
66
|
-
|
|
67
|
-
@DoNotStrip
|
|
68
|
-
@Keep
|
|
69
28
|
override fun getCurrentPresetName(): Variant_NullType_String {
|
|
70
29
|
val name = core.getCurrentPresetName()
|
|
71
|
-
return if (name != null)
|
|
72
|
-
|
|
73
|
-
} else {
|
|
74
|
-
Variant_NullType_String.create(NullType.NULL)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
@DoNotStrip
|
|
79
|
-
@Keep
|
|
80
|
-
override fun saveCustomPreset(name: String): Boolean = core.saveCustomPreset(name)
|
|
81
|
-
|
|
82
|
-
@DoNotStrip
|
|
83
|
-
@Keep
|
|
84
|
-
override fun deleteCustomPreset(name: String): Boolean = core.deleteCustomPreset(name)
|
|
85
|
-
|
|
86
|
-
@DoNotStrip
|
|
87
|
-
@Keep
|
|
88
|
-
override fun getState(): EqualizerState = core.getState()
|
|
89
|
-
|
|
90
|
-
@DoNotStrip
|
|
91
|
-
@Keep
|
|
92
|
-
override fun reset() = core.reset()
|
|
93
|
-
|
|
94
|
-
override fun onEnabledChange(callback: (enabled: Boolean) -> Unit) {
|
|
95
|
-
core.addOnEnabledChangeListener(callback)
|
|
30
|
+
return if (name != null) Variant_NullType_String.create(name)
|
|
31
|
+
else Variant_NullType_String.create(NullType.NULL)
|
|
96
32
|
}
|
|
97
33
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
override fun
|
|
103
|
-
|
|
104
|
-
}
|
|
34
|
+
// ── Async mutations (per v2 spec) ─────────────────────────────────────────
|
|
35
|
+
override fun setEnabled(enabled: Boolean): Promise<Unit> = Promise.async { core.setEnabled(enabled) }
|
|
36
|
+
override fun getBands(): Promise<Array<EqualizerBand>> = Promise.async { core.getBands() }
|
|
37
|
+
override fun setBandGain(bandIndex: Double, gainDb: Double): Promise<Unit> = Promise.async { core.setBandGain(bandIndex.toInt(), gainDb) }
|
|
38
|
+
override fun setAllBandGains(gains: DoubleArray): Promise<Unit> = Promise.async { core.setAllBandGains(gains) }
|
|
39
|
+
override fun applyPreset(presetName: String): Promise<Unit> = Promise.async { core.applyPreset(presetName) }
|
|
40
|
+
override fun saveCustomPreset(name: String): Promise<Unit> = Promise.async { core.saveCustomPreset(name) }
|
|
41
|
+
override fun deleteCustomPreset(name: String): Promise<Unit> = Promise.async { core.deleteCustomPreset(name) }
|
|
42
|
+
override fun getState(): Promise<EqualizerState> = Promise.async { core.getState() }
|
|
43
|
+
override fun reset(): Promise<Unit> = Promise.async { core.reset() }
|
|
44
|
+
|
|
45
|
+
// ── Events ────────────────────────────────────────────────────────────────
|
|
46
|
+
override fun onEnabledChange(callback: (enabled: Boolean) -> Unit) = core.addOnEnabledChangeListener(callback)
|
|
47
|
+
override fun onBandChange(callback: (bands: Array<EqualizerBand>) -> Unit) = core.addOnBandChangeListener(callback)
|
|
48
|
+
override fun onPresetChange(callback: (presetName: Variant_NullType_String?) -> Unit) = core.addOnPresetChangeListener(callback)
|
|
105
49
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
+
@file:Suppress("ktlint:standard:max-line-length")
|
|
2
|
+
|
|
1
3
|
package com.margelo.nitro.nitroplayer
|
|
2
4
|
|
|
3
5
|
import androidx.annotation.Keep
|
|
4
|
-
import com.facebook.jni.HybridData
|
|
5
6
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
6
7
|
import com.margelo.nitro.NitroModules
|
|
7
8
|
import com.margelo.nitro.core.NullType
|
|
9
|
+
import com.margelo.nitro.core.Promise
|
|
8
10
|
import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
|
|
11
|
+
import com.margelo.nitro.nitroplayer.core.loadPlaylist
|
|
12
|
+
import com.margelo.nitro.nitroplayer.core.updatePlaylist
|
|
9
13
|
import com.margelo.nitro.nitroplayer.playlist.PlaylistManager
|
|
10
14
|
import java.util.UUID
|
|
11
15
|
import com.margelo.nitro.nitroplayer.playlist.Playlist as InternalPlaylist
|
|
@@ -17,7 +21,8 @@ class HybridPlayerQueue : HybridPlayerQueueSpec() {
|
|
|
17
21
|
private val playlistManager: PlaylistManager
|
|
18
22
|
|
|
19
23
|
init {
|
|
20
|
-
val context = NitroModules.applicationContext
|
|
24
|
+
val context = NitroModules.applicationContext
|
|
25
|
+
?: throw IllegalStateException("React Context is not initialized")
|
|
21
26
|
core = TrackPlayerCore.getInstance(context)
|
|
22
27
|
playlistManager = core.getPlaylistManager()
|
|
23
28
|
}
|
|
@@ -25,143 +30,89 @@ class HybridPlayerQueue : HybridPlayerQueueSpec() {
|
|
|
25
30
|
private val playlistsChangeListeners = java.util.concurrent.CopyOnWriteArrayList<() -> Unit>()
|
|
26
31
|
private val playlistChangeListeners = java.util.concurrent.ConcurrentHashMap<String, () -> Unit>()
|
|
27
32
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
override fun createPlaylist(
|
|
31
|
-
name
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
): String = playlistManager.createPlaylist(name, description, artwork)
|
|
35
|
-
|
|
36
|
-
@DoNotStrip
|
|
37
|
-
@Keep
|
|
38
|
-
override fun deletePlaylist(playlistId: String) {
|
|
33
|
+
// ── Playlist CRUD ─────────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
override fun createPlaylist(name: String, description: String?, artwork: String?): Promise<String> =
|
|
36
|
+
Promise.async { playlistManager.createPlaylist(name, description, artwork) }
|
|
37
|
+
|
|
38
|
+
override fun deletePlaylist(playlistId: String): Promise<Unit> = Promise.async {
|
|
39
39
|
playlistManager.deletePlaylist(playlistId)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
@Keep
|
|
44
|
-
override fun updatePlaylist(
|
|
45
|
-
playlistId: String,
|
|
46
|
-
name: String?,
|
|
47
|
-
description: String?,
|
|
48
|
-
artwork: String?,
|
|
49
|
-
) {
|
|
42
|
+
override fun updatePlaylist(playlistId: String, name: String?, description: String?, artwork: String?): Promise<Unit> = Promise.async {
|
|
50
43
|
playlistManager.updatePlaylist(playlistId, name, description, artwork)
|
|
44
|
+
core.updatePlaylist(playlistId)
|
|
51
45
|
}
|
|
52
46
|
|
|
53
|
-
@DoNotStrip
|
|
54
|
-
@Keep
|
|
55
47
|
override fun getPlaylist(playlistId: String): Variant_NullType_Playlist {
|
|
56
48
|
val playlist = playlistManager.getPlaylist(playlistId)
|
|
57
|
-
return if (playlist != null)
|
|
58
|
-
|
|
59
|
-
} else {
|
|
60
|
-
Variant_NullType_Playlist.create(NullType.NULL)
|
|
61
|
-
}
|
|
49
|
+
return if (playlist != null) Variant_NullType_Playlist.create(playlist.toPlaylist())
|
|
50
|
+
else Variant_NullType_Playlist.create(NullType.NULL)
|
|
62
51
|
}
|
|
63
52
|
|
|
64
|
-
@DoNotStrip
|
|
65
|
-
@Keep
|
|
66
53
|
override fun getAllPlaylists(): Array<Playlist> =
|
|
67
|
-
playlistManager
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
@Keep
|
|
75
|
-
override fun addTrackToPlaylist(
|
|
76
|
-
playlistId: String,
|
|
77
|
-
track: TrackItem,
|
|
78
|
-
index: Double?,
|
|
79
|
-
) {
|
|
80
|
-
val insertIndex = index?.toInt()
|
|
81
|
-
playlistManager.addTrackToPlaylist(playlistId, track, insertIndex)
|
|
54
|
+
playlistManager.getAllPlaylists().map { it.toPlaylist() }.toTypedArray()
|
|
55
|
+
|
|
56
|
+
// ── Track mutations ───────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
override fun addTrackToPlaylist(playlistId: String, track: TrackItem, index: Double?): Promise<Unit> = Promise.async {
|
|
59
|
+
playlistManager.addTrackToPlaylist(playlistId, track, index?.toInt())
|
|
60
|
+
core.updatePlaylist(playlistId)
|
|
82
61
|
}
|
|
83
62
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
playlistId: String,
|
|
88
|
-
tracks: Array<TrackItem>,
|
|
89
|
-
index: Double?,
|
|
90
|
-
) {
|
|
91
|
-
val insertIndex = index?.toInt()
|
|
92
|
-
playlistManager.addTracksToPlaylist(playlistId, tracks.toList(), insertIndex)
|
|
63
|
+
override fun addTracksToPlaylist(playlistId: String, tracks: Array<TrackItem>, index: Double?): Promise<Unit> = Promise.async {
|
|
64
|
+
playlistManager.addTracksToPlaylist(playlistId, tracks.toList(), index?.toInt())
|
|
65
|
+
core.updatePlaylist(playlistId)
|
|
93
66
|
}
|
|
94
67
|
|
|
95
|
-
|
|
96
|
-
@Keep
|
|
97
|
-
override fun removeTrackFromPlaylist(
|
|
98
|
-
playlistId: String,
|
|
99
|
-
trackId: String,
|
|
100
|
-
) {
|
|
68
|
+
override fun removeTrackFromPlaylist(playlistId: String, trackId: String): Promise<Unit> = Promise.async {
|
|
101
69
|
playlistManager.removeTrackFromPlaylist(playlistId, trackId)
|
|
70
|
+
core.updatePlaylist(playlistId)
|
|
102
71
|
}
|
|
103
72
|
|
|
104
|
-
|
|
105
|
-
@Keep
|
|
106
|
-
override fun reorderTrackInPlaylist(
|
|
107
|
-
playlistId: String,
|
|
108
|
-
trackId: String,
|
|
109
|
-
newIndex: Double,
|
|
110
|
-
) {
|
|
73
|
+
override fun reorderTrackInPlaylist(playlistId: String, trackId: String, newIndex: Double): Promise<Unit> = Promise.async {
|
|
111
74
|
playlistManager.reorderTrackInPlaylist(playlistId, trackId, newIndex.toInt())
|
|
75
|
+
core.updatePlaylist(playlistId)
|
|
112
76
|
}
|
|
113
77
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
override fun loadPlaylist(playlistId: String) {
|
|
117
|
-
|
|
78
|
+
// ── Playback control ──────────────────────────────────────────────────────
|
|
79
|
+
|
|
80
|
+
override fun loadPlaylist(playlistId: String): Promise<Unit> = Promise.async {
|
|
81
|
+
core.loadPlaylist(playlistId)
|
|
118
82
|
}
|
|
119
83
|
|
|
120
|
-
@DoNotStrip
|
|
121
|
-
@Keep
|
|
122
84
|
override fun getCurrentPlaylistId(): Variant_NullType_String {
|
|
123
|
-
val
|
|
124
|
-
return if (
|
|
125
|
-
|
|
126
|
-
} else {
|
|
127
|
-
Variant_NullType_String.create(NullType.NULL)
|
|
128
|
-
}
|
|
85
|
+
val id = core.getCurrentPlaylistId()
|
|
86
|
+
return if (id != null) Variant_NullType_String.create(id)
|
|
87
|
+
else Variant_NullType_String.create(NullType.NULL)
|
|
129
88
|
}
|
|
130
89
|
|
|
131
|
-
|
|
132
|
-
|
|
90
|
+
// ── Events ────────────────────────────────────────────────────────────────
|
|
91
|
+
|
|
133
92
|
override fun onPlaylistsChanged(callback: (playlists: Array<Playlist>, operation: QueueOperation?) -> Unit) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
callback(playlists.map { it.toPlaylist() }.toTypedArray(), operation)
|
|
138
|
-
}
|
|
93
|
+
val removeListener = playlistManager.addPlaylistsChangeListener { playlists, operation ->
|
|
94
|
+
callback(playlists.map { it.toPlaylist() }.toTypedArray(), operation)
|
|
95
|
+
}
|
|
139
96
|
playlistsChangeListeners.add(removeListener)
|
|
140
97
|
}
|
|
141
98
|
|
|
142
|
-
@DoNotStrip
|
|
143
|
-
@Keep
|
|
144
99
|
override fun onPlaylistChanged(callback: (playlistId: String, playlist: Playlist, operation: QueueOperation?) -> Unit) {
|
|
145
|
-
// Listen to all playlists and filter by playlistId
|
|
146
100
|
val listenerId = UUID.randomUUID().toString()
|
|
147
|
-
|
|
148
|
-
// For each playlist, add a listener
|
|
149
101
|
playlistManager.getAllPlaylists().forEach { internalPlaylist ->
|
|
150
|
-
val removeListener =
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
102
|
+
val removeListener = playlistManager.addPlaylistChangeListener(internalPlaylist.id) { playlist, operation ->
|
|
103
|
+
callback(playlist.id, playlist.toPlaylist(), operation)
|
|
104
|
+
}
|
|
154
105
|
playlistChangeListeners[listenerId] = removeListener
|
|
155
106
|
}
|
|
156
107
|
}
|
|
157
108
|
|
|
158
|
-
// Helper
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
109
|
+
// ── Helper ────────────────────────────────────────────────────────────────
|
|
110
|
+
|
|
111
|
+
private fun InternalPlaylist.toPlaylist(): Playlist = Playlist(
|
|
112
|
+
id = this.id,
|
|
113
|
+
name = this.name,
|
|
114
|
+
description = this.description?.let { Variant_NullType_String.create(it) },
|
|
115
|
+
artwork = this.artwork?.let { Variant_NullType_String.create(it) },
|
|
116
|
+
tracks = this.tracks.toTypedArray(),
|
|
117
|
+
)
|
|
167
118
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@file:Suppress("ktlint:standard:max-line-length")
|
|
2
|
+
|
|
1
3
|
package com.margelo.nitro.nitroplayer
|
|
2
4
|
|
|
3
5
|
import androidx.annotation.Keep
|
|
@@ -5,169 +7,157 @@ import com.facebook.proguard.annotations.DoNotStrip
|
|
|
5
7
|
import com.margelo.nitro.NitroModules
|
|
6
8
|
import com.margelo.nitro.core.Promise
|
|
7
9
|
import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
|
|
10
|
+
import com.margelo.nitro.nitroplayer.core.addToUpNext
|
|
11
|
+
import com.margelo.nitro.nitroplayer.core.clearPlayNext
|
|
12
|
+
import com.margelo.nitro.nitroplayer.core.clearUpNext
|
|
13
|
+
import com.margelo.nitro.nitroplayer.core.configure
|
|
14
|
+
import com.margelo.nitro.nitroplayer.core.getActualQueue
|
|
15
|
+
import com.margelo.nitro.nitroplayer.core.getCurrentTrackIndex
|
|
16
|
+
import com.margelo.nitro.nitroplayer.core.getNextTracks
|
|
17
|
+
import com.margelo.nitro.nitroplayer.core.getPlayBackSpeed
|
|
18
|
+
import com.margelo.nitro.nitroplayer.core.getPlayNextQueue
|
|
19
|
+
import com.margelo.nitro.nitroplayer.core.getRepeatMode
|
|
20
|
+
import com.margelo.nitro.nitroplayer.core.getState
|
|
21
|
+
import com.margelo.nitro.nitroplayer.core.getTracksById
|
|
22
|
+
import com.margelo.nitro.nitroplayer.core.getTracksNeedingUrls
|
|
23
|
+
import com.margelo.nitro.nitroplayer.core.getUpNextQueue
|
|
24
|
+
import com.margelo.nitro.nitroplayer.core.pause
|
|
25
|
+
import com.margelo.nitro.nitroplayer.core.play
|
|
26
|
+
import com.margelo.nitro.nitroplayer.core.playNext
|
|
27
|
+
import com.margelo.nitro.nitroplayer.core.playSong
|
|
28
|
+
import com.margelo.nitro.nitroplayer.core.removeFromPlayNext
|
|
29
|
+
import com.margelo.nitro.nitroplayer.core.removeFromUpNext
|
|
30
|
+
import com.margelo.nitro.nitroplayer.core.reorderTemporaryTrack
|
|
31
|
+
import com.margelo.nitro.nitroplayer.core.seek
|
|
32
|
+
import com.margelo.nitro.nitroplayer.core.setPlayBackSpeed
|
|
33
|
+
import com.margelo.nitro.nitroplayer.core.setRepeatMode
|
|
34
|
+
import com.margelo.nitro.nitroplayer.core.setVolume
|
|
35
|
+
import com.margelo.nitro.nitroplayer.core.skipToIndex
|
|
36
|
+
import com.margelo.nitro.nitroplayer.core.skipToNext
|
|
37
|
+
import com.margelo.nitro.nitroplayer.core.skipToPrevious
|
|
38
|
+
import com.margelo.nitro.nitroplayer.core.updateTracks
|
|
8
39
|
|
|
9
40
|
@DoNotStrip
|
|
10
41
|
@Keep
|
|
11
42
|
class HybridTrackPlayer : HybridTrackPlayerSpec() {
|
|
12
43
|
private val core: TrackPlayerCore
|
|
13
44
|
|
|
45
|
+
// Track listener IDs for cleanup in dispose()
|
|
46
|
+
private val listenerIds = mutableListOf<Pair<String, Long>>()
|
|
47
|
+
|
|
14
48
|
init {
|
|
15
|
-
val context =
|
|
16
|
-
|
|
49
|
+
val context = NitroModules.applicationContext
|
|
50
|
+
?: throw IllegalStateException("React Context is not initialized")
|
|
17
51
|
core = TrackPlayerCore.getInstance(context)
|
|
18
52
|
}
|
|
19
53
|
|
|
20
|
-
|
|
21
|
-
@Keep
|
|
22
|
-
override fun play() {
|
|
23
|
-
core.play()
|
|
24
|
-
}
|
|
54
|
+
// ── Playback ─────────────────────────────────────────────────────────────
|
|
25
55
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
override fun
|
|
29
|
-
|
|
30
|
-
}
|
|
56
|
+
override fun play(): Promise<Unit> = Promise.async { core.play() }
|
|
57
|
+
override fun pause(): Promise<Unit> = Promise.async { core.pause() }
|
|
58
|
+
override fun seek(position: Double): Promise<Unit> = Promise.async { core.seek(position) }
|
|
59
|
+
override fun skipToNext(): Promise<Unit> = Promise.async { core.skipToNext() }
|
|
60
|
+
override fun skipToPrevious(): Promise<Unit> = Promise.async { core.skipToPrevious() }
|
|
61
|
+
override fun playSong(songId: String, fromPlaylist: String?): Promise<Unit> = Promise.async { core.playSong(songId, fromPlaylist) }
|
|
62
|
+
override fun skipToIndex(index: Double): Promise<Boolean> = Promise.async { core.skipToIndex(index.toInt()) }
|
|
31
63
|
|
|
32
|
-
override fun
|
|
33
|
-
|
|
34
|
-
fromPlaylist: String?,
|
|
35
|
-
): Promise<Unit> =
|
|
36
|
-
Promise.async {
|
|
37
|
-
core.playSong(songId, fromPlaylist)
|
|
38
|
-
}
|
|
64
|
+
override fun setRepeatMode(mode: RepeatMode): Promise<Unit> = Promise.async { core.setRepeatMode(mode) }
|
|
65
|
+
override fun getRepeatMode(): RepeatMode = core.getRepeatMode()
|
|
39
66
|
|
|
40
|
-
|
|
41
|
-
@Keep
|
|
42
|
-
override fun skipToNext() {
|
|
43
|
-
core.skipToNext()
|
|
44
|
-
}
|
|
67
|
+
override fun setVolume(volume: Double): Promise<Unit> = Promise.async { core.setVolume(volume) }
|
|
45
68
|
|
|
46
|
-
|
|
47
|
-
@Keep
|
|
48
|
-
override fun skipToPrevious() {
|
|
49
|
-
core.skipToPrevious()
|
|
50
|
-
}
|
|
69
|
+
override fun configure(config: PlayerConfig): Promise<Unit> = Promise.async { core.configure(config) }
|
|
51
70
|
|
|
52
|
-
|
|
53
|
-
@Keep
|
|
54
|
-
override fun seek(position: Double) {
|
|
55
|
-
core.seek(position)
|
|
56
|
-
}
|
|
71
|
+
// ── Queue / state reads ───────────────────────────────────────────────────
|
|
57
72
|
|
|
58
|
-
override fun
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
override fun getActualQueue(): Promise<Array<TrackItem>> = Promise.async { core.getActualQueue().toTypedArray() }
|
|
74
|
+
override fun getState(): Promise<PlayerState> = Promise.async { core.getState() }
|
|
75
|
+
override fun getTracksById(trackIds: Array<String>): Promise<Array<TrackItem>> = Promise.async { core.getTracksById(trackIds.toList()).toTypedArray() }
|
|
76
|
+
override fun getTracksNeedingUrls(): Promise<Array<TrackItem>> = Promise.async { core.getTracksNeedingUrls().toTypedArray() }
|
|
77
|
+
override fun getNextTracks(count: Double): Promise<Array<TrackItem>> = Promise.async { core.getNextTracks(count.toInt()).toTypedArray() }
|
|
78
|
+
override fun getCurrentTrackIndex(): Promise<Double> = Promise.async { core.getCurrentTrackIndex().toDouble() }
|
|
62
79
|
|
|
63
|
-
|
|
64
|
-
Promise.async {
|
|
65
|
-
core.playNext(trackId)
|
|
66
|
-
}
|
|
80
|
+
// ── URL updates ───────────────────────────────────────────────────────────
|
|
67
81
|
|
|
68
|
-
override fun
|
|
69
|
-
Promise.async {
|
|
70
|
-
core.getActualQueue().toTypedArray()
|
|
71
|
-
}
|
|
82
|
+
override fun updateTracks(tracks: Array<TrackItem>): Promise<Unit> = Promise.async { core.updateTracks(tracks.toList()) }
|
|
72
83
|
|
|
73
|
-
|
|
74
|
-
Promise.async {
|
|
75
|
-
core.getState()
|
|
76
|
-
}
|
|
84
|
+
// ── Temporary queue ───────────────────────────────────────────────────────
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
override fun
|
|
86
|
+
override fun addToUpNext(trackId: String): Promise<Unit> = Promise.async { core.addToUpNext(trackId) }
|
|
87
|
+
override fun playNext(trackId: String): Promise<Unit> = Promise.async { core.playNext(trackId) }
|
|
88
|
+
override fun removeFromPlayNext(trackId: String): Promise<Boolean> = Promise.async { core.removeFromPlayNext(trackId) }
|
|
89
|
+
override fun removeFromUpNext(trackId: String): Promise<Boolean> = Promise.async { core.removeFromUpNext(trackId) }
|
|
90
|
+
override fun clearPlayNext(): Promise<Unit> = Promise.async { core.clearPlayNext() }
|
|
91
|
+
override fun clearUpNext(): Promise<Unit> = Promise.async { core.clearUpNext() }
|
|
92
|
+
override fun reorderTemporaryTrack(trackId: String, newIndex: Double): Promise<Boolean> = Promise.async { core.reorderTemporaryTrack(trackId, newIndex.toInt()) }
|
|
93
|
+
override fun getPlayNextQueue(): Promise<Array<TrackItem>> = Promise.async { core.getPlayNextQueue().toTypedArray() }
|
|
94
|
+
override fun getUpNextQueue(): Promise<Array<TrackItem>> = Promise.async { core.getUpNextQueue().toTypedArray() }
|
|
81
95
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
override fun
|
|
96
|
+
// ── Playback speed ────────────────────────────────────────────────────────
|
|
97
|
+
|
|
98
|
+
override fun setPlaybackSpeed(speed: Double): Promise<Unit> = Promise.async { core.setPlayBackSpeed(speed) }
|
|
99
|
+
override fun getPlaybackSpeed(): Promise<Double> = Promise.async { core.getPlayBackSpeed() }
|
|
100
|
+
|
|
101
|
+
// ── Android Auto ──────────────────────────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
override fun isAndroidAutoConnected(): Boolean = core.isAndroidAutoConnected()
|
|
104
|
+
|
|
105
|
+
// ── Event listeners ───────────────────────────────────────────────────────
|
|
85
106
|
|
|
86
107
|
override fun onChangeTrack(callback: (track: TrackItem, reason: Reason?) -> Unit) {
|
|
87
|
-
core.addOnChangeTrackListener(callback)
|
|
108
|
+
val id = core.addOnChangeTrackListener(callback)
|
|
109
|
+
listenerIds += "onChangeTrack" to id
|
|
88
110
|
}
|
|
89
111
|
|
|
90
112
|
override fun onPlaybackStateChange(callback: (state: TrackPlayerState, reason: Reason?) -> Unit) {
|
|
91
|
-
core.addOnPlaybackStateChangeListener(callback)
|
|
113
|
+
val id = core.addOnPlaybackStateChangeListener(callback)
|
|
114
|
+
listenerIds += "onPlaybackStateChange" to id
|
|
92
115
|
}
|
|
93
116
|
|
|
94
117
|
override fun onSeek(callback: (position: Double, totalDuration: Double) -> Unit) {
|
|
95
|
-
core.addOnSeekListener(callback)
|
|
118
|
+
val id = core.addOnSeekListener(callback)
|
|
119
|
+
listenerIds += "onSeek" to id
|
|
96
120
|
}
|
|
97
121
|
|
|
98
122
|
override fun onPlaybackProgressChange(callback: (position: Double, totalDuration: Double, isManuallySeeked: Boolean?) -> Unit) {
|
|
99
|
-
core.addOnPlaybackProgressChangeListener(callback)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
@DoNotStrip
|
|
103
|
-
@Keep
|
|
104
|
-
override fun configure(config: PlayerConfig) {
|
|
105
|
-
core.configure(
|
|
106
|
-
androidAutoEnabled = config.androidAutoEnabled,
|
|
107
|
-
carPlayEnabled = config.carPlayEnabled,
|
|
108
|
-
showInNotification = config.showInNotification,
|
|
109
|
-
lookaheadCount = config.lookaheadCount?.toInt(),
|
|
110
|
-
)
|
|
123
|
+
val id = core.addOnPlaybackProgressChangeListener(callback)
|
|
124
|
+
listenerIds += "onPlaybackProgressChange" to id
|
|
111
125
|
}
|
|
112
126
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
127
|
+
override fun onAndroidAutoConnectionChange(callback: (connected: Boolean) -> Unit) {
|
|
128
|
+
val id = core.addOnAndroidAutoConnectionListener(callback)
|
|
129
|
+
listenerIds += "onAndroidAutoConnectionChange" to id
|
|
116
130
|
}
|
|
117
131
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
@DoNotStrip
|
|
122
|
-
@Keep
|
|
123
|
-
override fun setVolume(volume: Double): Boolean = core.setVolume(volume)
|
|
124
|
-
|
|
125
|
-
@DoNotStrip
|
|
126
|
-
@Keep
|
|
127
|
-
override fun skipToIndex(index: Double): Promise<Boolean> =
|
|
128
|
-
Promise.async {
|
|
129
|
-
core.skipToIndex(index.toInt())
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
override fun updateTracks(tracks: Array<TrackItem>): Promise<Unit> =
|
|
133
|
-
Promise.async {
|
|
134
|
-
core.updateTracks(tracks.toList())
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
override fun getTracksById(trackIds: Array<String>): Promise<Array<TrackItem>> =
|
|
138
|
-
Promise.async {
|
|
139
|
-
core.getTracksById(trackIds.toList()).toTypedArray()
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
override fun getTracksNeedingUrls(): Promise<Array<TrackItem>> =
|
|
143
|
-
Promise.async {
|
|
144
|
-
core.getTracksNeedingUrls().toTypedArray()
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
override fun getNextTracks(count: Double): Promise<Array<TrackItem>> =
|
|
148
|
-
Promise.async {
|
|
149
|
-
core.getNextTracks(count.toInt()).toTypedArray()
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
override fun getCurrentTrackIndex(): Promise<Double> =
|
|
153
|
-
Promise.async {
|
|
154
|
-
core.getCurrentTrackIndex().toDouble()
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
override fun setPlaybackSpeed(speed: Double): Promise<Unit> =
|
|
158
|
-
Promise.async {
|
|
159
|
-
core.setPlayBackSpeed(speed)
|
|
160
|
-
Unit
|
|
132
|
+
override fun onTracksNeedUpdate(callback: (tracks: Array<TrackItem>, lookahead: Double) -> Unit) {
|
|
133
|
+
val id = core.addOnTracksNeedUpdateListener { tracks, lookahead ->
|
|
134
|
+
callback(tracks.toTypedArray(), lookahead.toDouble())
|
|
161
135
|
}
|
|
136
|
+
listenerIds += "onTracksNeedUpdate" to id
|
|
137
|
+
}
|
|
162
138
|
|
|
163
|
-
override fun
|
|
164
|
-
|
|
165
|
-
|
|
139
|
+
override fun onTemporaryQueueChange(callback: (playNextQueue: Array<TrackItem>, upNextQueue: Array<TrackItem>) -> Unit) {
|
|
140
|
+
val id = core.addOnTemporaryQueueChangeListener { pn, un ->
|
|
141
|
+
callback(pn.toTypedArray(), un.toTypedArray())
|
|
166
142
|
}
|
|
143
|
+
listenerIds += "onTemporaryQueueChange" to id
|
|
144
|
+
}
|
|
167
145
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
146
|
+
// ── Cleanup ───────────────────────────────────────────────────────────────
|
|
147
|
+
|
|
148
|
+
override fun dispose() {
|
|
149
|
+
super.dispose()
|
|
150
|
+
listenerIds.forEach { (type, id) ->
|
|
151
|
+
when (type) {
|
|
152
|
+
"onChangeTrack" -> core.removeOnChangeTrackListener(id)
|
|
153
|
+
"onPlaybackStateChange" -> core.removeOnPlaybackStateChangeListener(id)
|
|
154
|
+
"onSeek" -> core.removeOnSeekListener(id)
|
|
155
|
+
"onPlaybackProgressChange" -> core.removeOnPlaybackProgressChangeListener(id)
|
|
156
|
+
"onAndroidAutoConnectionChange" -> core.removeOnAndroidAutoConnectionListener(id)
|
|
157
|
+
"onTracksNeedUpdate" -> core.removeOnTracksNeedUpdateListener(id)
|
|
158
|
+
"onTemporaryQueueChange" -> core.removeOnTemporaryQueueChangeListener(id)
|
|
159
|
+
}
|
|
171
160
|
}
|
|
161
|
+
listenerIds.clear()
|
|
172
162
|
}
|
|
173
163
|
}
|