react-native-nitro-player 0.7.0 → 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/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 +1 -1
- 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
|
@@ -5,13 +5,19 @@ import com.margelo.nitro.core.AnyMap
|
|
|
5
5
|
import com.margelo.nitro.nitroplayer.QueueOperation
|
|
6
6
|
import com.margelo.nitro.nitroplayer.TrackItem
|
|
7
7
|
import com.margelo.nitro.nitroplayer.Variant_NullType_String
|
|
8
|
-
import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
|
|
9
8
|
import com.margelo.nitro.nitroplayer.media.NitroPlayerMediaBrowserService
|
|
10
9
|
import com.margelo.nitro.nitroplayer.storage.NitroPlayerStorage
|
|
11
10
|
import org.json.JSONArray
|
|
12
11
|
import org.json.JSONObject
|
|
13
12
|
import java.util.UUID
|
|
13
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
14
14
|
import java.util.concurrent.CopyOnWriteArrayList
|
|
15
|
+
import kotlinx.coroutines.CoroutineScope
|
|
16
|
+
import kotlinx.coroutines.Dispatchers
|
|
17
|
+
import kotlinx.coroutines.Job
|
|
18
|
+
import kotlinx.coroutines.SupervisorJob
|
|
19
|
+
import kotlinx.coroutines.delay
|
|
20
|
+
import kotlinx.coroutines.launch
|
|
15
21
|
|
|
16
22
|
/**
|
|
17
23
|
* Manages multiple playlists using ExoPlayer's native playlist functionality
|
|
@@ -20,17 +26,20 @@ import java.util.concurrent.CopyOnWriteArrayList
|
|
|
20
26
|
class PlaylistManager private constructor(
|
|
21
27
|
private val context: Context,
|
|
22
28
|
) {
|
|
23
|
-
private val playlists
|
|
29
|
+
private val playlists = ConcurrentHashMap<String, Playlist>()
|
|
24
30
|
private val listeners = CopyOnWriteArrayList<(List<Playlist>, QueueOperation?) -> Unit>()
|
|
25
31
|
private val playlistListeners = mutableMapOf<String, CopyOnWriteArrayList<(Playlist, QueueOperation?) -> Unit>>()
|
|
26
32
|
private var currentPlaylistId: String? = null
|
|
27
33
|
|
|
28
|
-
private val
|
|
29
|
-
private
|
|
34
|
+
private val saveScope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
|
35
|
+
private var saveJob: Job? = null
|
|
30
36
|
|
|
31
37
|
private fun scheduleSave() {
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
saveJob?.cancel()
|
|
39
|
+
saveJob = saveScope.launch {
|
|
40
|
+
delay(300)
|
|
41
|
+
saveToFile()
|
|
42
|
+
}
|
|
34
43
|
}
|
|
35
44
|
|
|
36
45
|
companion object {
|
|
@@ -63,9 +72,7 @@ class PlaylistManager private constructor(
|
|
|
63
72
|
val id = UUID.randomUUID().toString()
|
|
64
73
|
val playlist = Playlist(id, name, description, artwork)
|
|
65
74
|
|
|
66
|
-
|
|
67
|
-
playlists[id] = playlist
|
|
68
|
-
}
|
|
75
|
+
playlists[id] = playlist
|
|
69
76
|
|
|
70
77
|
// Only cache for Android Auto if connected
|
|
71
78
|
if (NitroPlayerMediaBrowserService.isAndroidAutoConnected) {
|
|
@@ -81,10 +88,7 @@ class PlaylistManager private constructor(
|
|
|
81
88
|
* Delete a playlist
|
|
82
89
|
*/
|
|
83
90
|
fun deletePlaylist(playlistId: String): Boolean {
|
|
84
|
-
val removed =
|
|
85
|
-
synchronized(playlists) {
|
|
86
|
-
playlists.remove(playlistId)
|
|
87
|
-
}
|
|
91
|
+
val removed = playlists.remove(playlistId)
|
|
88
92
|
|
|
89
93
|
if (removed != null) {
|
|
90
94
|
if (currentPlaylistId == playlistId) {
|
|
@@ -112,15 +116,13 @@ class PlaylistManager private constructor(
|
|
|
112
116
|
description: String? = null,
|
|
113
117
|
artwork: String? = null,
|
|
114
118
|
): Boolean {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
playlist.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
)
|
|
123
|
-
}
|
|
119
|
+
val playlist = playlists[playlistId] ?: return false
|
|
120
|
+
playlists[playlistId] =
|
|
121
|
+
playlist.copy(
|
|
122
|
+
name = name ?: playlist.name,
|
|
123
|
+
description = description ?: playlist.description,
|
|
124
|
+
artwork = artwork ?: playlist.artwork,
|
|
125
|
+
)
|
|
124
126
|
|
|
125
127
|
// Only cache for Android Auto if connected
|
|
126
128
|
if (NitroPlayerMediaBrowserService.isAndroidAutoConnected) {
|
|
@@ -136,18 +138,12 @@ class PlaylistManager private constructor(
|
|
|
136
138
|
/**
|
|
137
139
|
* Get a playlist by ID
|
|
138
140
|
*/
|
|
139
|
-
fun getPlaylist(playlistId: String): Playlist? =
|
|
140
|
-
synchronized(playlists) {
|
|
141
|
-
playlists[playlistId]
|
|
142
|
-
}
|
|
141
|
+
fun getPlaylist(playlistId: String): Playlist? = playlists[playlistId]
|
|
143
142
|
|
|
144
143
|
/**
|
|
145
144
|
* Get all playlists
|
|
146
145
|
*/
|
|
147
|
-
fun getAllPlaylists(): List<Playlist> =
|
|
148
|
-
synchronized(playlists) {
|
|
149
|
-
playlists.values.toList()
|
|
150
|
-
}
|
|
146
|
+
fun getAllPlaylists(): List<Playlist> = playlists.values.toList()
|
|
151
147
|
|
|
152
148
|
/**
|
|
153
149
|
* Add a track to a playlist
|
|
@@ -157,16 +153,14 @@ class PlaylistManager private constructor(
|
|
|
157
153
|
track: TrackItem,
|
|
158
154
|
index: Int? = null,
|
|
159
155
|
): Boolean {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
tracks.add(track)
|
|
167
|
-
}
|
|
168
|
-
playlists[playlistId] = playlist.copy(tracks = tracks)
|
|
156
|
+
val playlist = playlists[playlistId] ?: return false
|
|
157
|
+
val tracks = playlist.tracks.toMutableList()
|
|
158
|
+
if (index != null && index >= 0 && index <= tracks.size) {
|
|
159
|
+
tracks.add(index, track)
|
|
160
|
+
} else {
|
|
161
|
+
tracks.add(track)
|
|
169
162
|
}
|
|
163
|
+
playlists[playlistId] = playlist.copy(tracks = tracks)
|
|
170
164
|
|
|
171
165
|
// Only cache for Android Auto if connected
|
|
172
166
|
if (NitroPlayerMediaBrowserService.isAndroidAutoConnected) {
|
|
@@ -174,12 +168,6 @@ class PlaylistManager private constructor(
|
|
|
174
168
|
}
|
|
175
169
|
notifyPlaylistChanged(playlistId, QueueOperation.ADD)
|
|
176
170
|
NitroPlayerMediaBrowserService.getInstance()?.onPlaylistUpdated(playlistId)
|
|
177
|
-
|
|
178
|
-
// Update ExoPlayer if this is the current playlist
|
|
179
|
-
if (currentPlaylistId == playlistId) {
|
|
180
|
-
TrackPlayerCore.getInstance(context)?.updatePlaylist(playlistId)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
171
|
return true
|
|
184
172
|
}
|
|
185
173
|
|
|
@@ -191,16 +179,14 @@ class PlaylistManager private constructor(
|
|
|
191
179
|
tracks: List<TrackItem>,
|
|
192
180
|
index: Int? = null,
|
|
193
181
|
): Boolean {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
currentTracks.addAll(tracks)
|
|
201
|
-
}
|
|
202
|
-
playlists[playlistId] = playlist.copy(tracks = currentTracks)
|
|
182
|
+
val playlist = playlists[playlistId] ?: return false
|
|
183
|
+
val currentTracks = playlist.tracks.toMutableList()
|
|
184
|
+
if (index != null && index >= 0 && index <= currentTracks.size) {
|
|
185
|
+
currentTracks.addAll(index, tracks)
|
|
186
|
+
} else {
|
|
187
|
+
currentTracks.addAll(tracks)
|
|
203
188
|
}
|
|
189
|
+
playlists[playlistId] = playlist.copy(tracks = currentTracks)
|
|
204
190
|
|
|
205
191
|
// Only cache for Android Auto if connected
|
|
206
192
|
if (NitroPlayerMediaBrowserService.isAndroidAutoConnected) {
|
|
@@ -208,12 +194,6 @@ class PlaylistManager private constructor(
|
|
|
208
194
|
}
|
|
209
195
|
notifyPlaylistChanged(playlistId, QueueOperation.ADD)
|
|
210
196
|
NitroPlayerMediaBrowserService.getInstance()?.onPlaylistUpdated(playlistId)
|
|
211
|
-
|
|
212
|
-
// Update ExoPlayer if this is the current playlist
|
|
213
|
-
if (currentPlaylistId == playlistId) {
|
|
214
|
-
TrackPlayerCore.getInstance(context)?.updatePlaylist(playlistId)
|
|
215
|
-
}
|
|
216
|
-
|
|
217
197
|
return true
|
|
218
198
|
}
|
|
219
199
|
|
|
@@ -224,26 +204,17 @@ class PlaylistManager private constructor(
|
|
|
224
204
|
playlistId: String,
|
|
225
205
|
trackId: String,
|
|
226
206
|
): Boolean {
|
|
227
|
-
val
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
playlists[playlistId] = playlist.copy(tracks = tracks)
|
|
234
|
-
}
|
|
235
|
-
removed
|
|
236
|
-
}
|
|
207
|
+
val playlist = playlists[playlistId] ?: return false
|
|
208
|
+
val tracks = playlist.tracks.toMutableList()
|
|
209
|
+
val removed = tracks.removeAll { it.id == trackId }
|
|
210
|
+
if (removed) {
|
|
211
|
+
playlists[playlistId] = playlist.copy(tracks = tracks)
|
|
212
|
+
}
|
|
237
213
|
|
|
238
214
|
if (removed) {
|
|
239
215
|
scheduleSave()
|
|
240
216
|
notifyPlaylistChanged(playlistId, QueueOperation.REMOVE)
|
|
241
217
|
NitroPlayerMediaBrowserService.getInstance()?.onPlaylistUpdated(playlistId)
|
|
242
|
-
|
|
243
|
-
// Update ExoPlayer if this is the current playlist
|
|
244
|
-
if (currentPlaylistId == playlistId) {
|
|
245
|
-
TrackPlayerCore.getInstance(context)?.updatePlaylist(playlistId)
|
|
246
|
-
}
|
|
247
218
|
}
|
|
248
219
|
|
|
249
220
|
return removed
|
|
@@ -257,27 +228,19 @@ class PlaylistManager private constructor(
|
|
|
257
228
|
trackId: String,
|
|
258
229
|
newIndex: Int,
|
|
259
230
|
): Boolean {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return false
|
|
266
|
-
}
|
|
267
|
-
val track = tracks.removeAt(oldIndex)
|
|
268
|
-
tracks.add(newIndex, track)
|
|
269
|
-
playlists[playlistId] = playlist.copy(tracks = tracks)
|
|
231
|
+
val playlist = playlists[playlistId] ?: return false
|
|
232
|
+
val tracks = playlist.tracks.toMutableList()
|
|
233
|
+
val oldIndex = tracks.indexOfFirst { it.id == trackId }
|
|
234
|
+
if (oldIndex < 0 || newIndex < 0 || newIndex >= tracks.size) {
|
|
235
|
+
return false
|
|
270
236
|
}
|
|
237
|
+
val track = tracks.removeAt(oldIndex)
|
|
238
|
+
tracks.add(newIndex, track)
|
|
239
|
+
playlists[playlistId] = playlist.copy(tracks = tracks)
|
|
271
240
|
|
|
272
241
|
scheduleSave()
|
|
273
242
|
notifyPlaylistChanged(playlistId, QueueOperation.UPDATE)
|
|
274
243
|
NitroPlayerMediaBrowserService.getInstance()?.onPlaylistUpdated(playlistId)
|
|
275
|
-
|
|
276
|
-
// Update ExoPlayer if this is the current playlist
|
|
277
|
-
if (currentPlaylistId == playlistId) {
|
|
278
|
-
TrackPlayerCore.getInstance(context)?.updatePlaylist(playlistId)
|
|
279
|
-
}
|
|
280
|
-
|
|
281
244
|
return true
|
|
282
245
|
}
|
|
283
246
|
|
|
@@ -291,19 +254,17 @@ class PlaylistManager private constructor(
|
|
|
291
254
|
val tracksMap = tracks.associateBy { it.id }
|
|
292
255
|
val affectedPlaylists = mutableMapOf<String, Int>()
|
|
293
256
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
playlists[playlistId] = playlist.copy(tracks = newTracks)
|
|
306
|
-
}
|
|
257
|
+
playlists.forEach { (playlistId, playlist) ->
|
|
258
|
+
var updateCount = 0
|
|
259
|
+
val newTracks =
|
|
260
|
+
playlist.tracks
|
|
261
|
+
.map { track ->
|
|
262
|
+
tracksMap[track.id]?.also { updateCount++ } ?: track
|
|
263
|
+
}.toMutableList()
|
|
264
|
+
|
|
265
|
+
if (updateCount > 0) {
|
|
266
|
+
affectedPlaylists[playlistId] = updateCount
|
|
267
|
+
playlists[playlistId] = playlist.copy(tracks = newTracks)
|
|
307
268
|
}
|
|
308
269
|
}
|
|
309
270
|
|
|
@@ -327,12 +288,10 @@ class PlaylistManager private constructor(
|
|
|
327
288
|
val trackIdSet = trackIds.toSet()
|
|
328
289
|
val foundTracks = mutableMapOf<String, TrackItem>()
|
|
329
290
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
foundTracks[track.id] = track
|
|
335
|
-
}
|
|
291
|
+
playlists.values.forEach { playlist ->
|
|
292
|
+
playlist.tracks.forEach { track ->
|
|
293
|
+
if (trackIdSet.contains(track.id) && !foundTracks.containsKey(track.id)) {
|
|
294
|
+
foundTracks[track.id] = track
|
|
336
295
|
}
|
|
337
296
|
}
|
|
338
297
|
}
|
|
@@ -345,14 +304,8 @@ class PlaylistManager private constructor(
|
|
|
345
304
|
* Load a playlist for playback (sets it as current)
|
|
346
305
|
*/
|
|
347
306
|
fun loadPlaylist(playlistId: String): Boolean {
|
|
348
|
-
|
|
349
|
-
synchronized(playlists) {
|
|
350
|
-
playlists[playlistId]
|
|
351
|
-
} ?: return false
|
|
352
|
-
|
|
307
|
+
if (playlists[playlistId] == null) return false
|
|
353
308
|
currentPlaylistId = playlistId
|
|
354
|
-
TrackPlayerCore.getInstance(context)?.loadPlaylist(playlistId)
|
|
355
|
-
|
|
356
309
|
return true
|
|
357
310
|
}
|
|
358
311
|
|
|
@@ -364,7 +317,7 @@ class PlaylistManager private constructor(
|
|
|
364
317
|
/**
|
|
365
318
|
* Get the current playlist
|
|
366
319
|
*/
|
|
367
|
-
fun getCurrentPlaylist(): Playlist? = currentPlaylistId?.let {
|
|
320
|
+
fun getCurrentPlaylist(): Playlist? = currentPlaylistId?.let { playlists[it] }
|
|
368
321
|
|
|
369
322
|
/**
|
|
370
323
|
* Add a listener for playlist changes
|
|
@@ -387,22 +340,14 @@ class PlaylistManager private constructor(
|
|
|
387
340
|
}
|
|
388
341
|
|
|
389
342
|
private fun notifyPlaylistsChanged(operation: QueueOperation?) {
|
|
390
|
-
|
|
391
|
-
synchronized(playlists) {
|
|
392
|
-
playlists.values.toList()
|
|
393
|
-
}
|
|
394
|
-
listeners.forEach { it(allPlaylists, operation) }
|
|
343
|
+
listeners.forEach { it(playlists.values.toList(), operation) }
|
|
395
344
|
}
|
|
396
345
|
|
|
397
346
|
private fun notifyPlaylistChanged(
|
|
398
347
|
playlistId: String,
|
|
399
348
|
operation: QueueOperation?,
|
|
400
349
|
) {
|
|
401
|
-
val playlist =
|
|
402
|
-
synchronized(playlists) {
|
|
403
|
-
playlists[playlistId]
|
|
404
|
-
} ?: return
|
|
405
|
-
|
|
350
|
+
val playlist = playlists[playlistId] ?: return
|
|
406
351
|
playlistListeners[playlistId]?.forEach { it(playlist, operation) }
|
|
407
352
|
}
|
|
408
353
|
|
|
@@ -411,37 +356,34 @@ class PlaylistManager private constructor(
|
|
|
411
356
|
private fun saveToFile() {
|
|
412
357
|
try {
|
|
413
358
|
val jsonArray = JSONArray()
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
put("tracks", tracksArray)
|
|
442
|
-
}
|
|
443
|
-
jsonArray.put(jsonObject)
|
|
359
|
+
playlists.values.forEach { playlist ->
|
|
360
|
+
val jsonObject = JSONObject().apply {
|
|
361
|
+
put("id", playlist.id)
|
|
362
|
+
put("name", playlist.name)
|
|
363
|
+
put("description", playlist.description ?: "")
|
|
364
|
+
put("artwork", playlist.artwork ?: "")
|
|
365
|
+
val tracksArray = JSONArray()
|
|
366
|
+
playlist.tracks.forEach { track ->
|
|
367
|
+
tracksArray.put(
|
|
368
|
+
JSONObject().apply {
|
|
369
|
+
put("id", track.id)
|
|
370
|
+
put("title", track.title)
|
|
371
|
+
put("artist", track.artist)
|
|
372
|
+
put("album", track.album)
|
|
373
|
+
put("duration", track.duration)
|
|
374
|
+
put("url", track.url)
|
|
375
|
+
track.artwork?.let { put("artwork", it) }
|
|
376
|
+
track.extraPayload?.let { payload ->
|
|
377
|
+
val extraPayloadMap = payload.toHashMap()
|
|
378
|
+
val extraPayloadJson = JSONObject(extraPayloadMap)
|
|
379
|
+
put("extraPayload", extraPayloadJson)
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
)
|
|
383
|
+
}
|
|
384
|
+
put("tracks", tracksArray)
|
|
444
385
|
}
|
|
386
|
+
jsonArray.put(jsonObject)
|
|
445
387
|
}
|
|
446
388
|
|
|
447
389
|
val wrapper =
|
|
@@ -501,9 +443,8 @@ class PlaylistManager private constructor(
|
|
|
501
443
|
}
|
|
502
444
|
|
|
503
445
|
private fun parseAndLoadPlaylists(jsonArray: JSONArray) {
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
for (i in 0 until jsonArray.length()) {
|
|
446
|
+
playlists.clear()
|
|
447
|
+
for (i in 0 until jsonArray.length()) {
|
|
507
448
|
val jsonObject = jsonArray.getJSONObject(i)
|
|
508
449
|
val tracks = mutableListOf<TrackItem>()
|
|
509
450
|
val tracksArray = jsonObject.getJSONArray("tracks")
|
|
@@ -557,7 +498,6 @@ class PlaylistManager private constructor(
|
|
|
557
498
|
tracks = tracks,
|
|
558
499
|
)
|
|
559
500
|
playlists[playlist.id] = playlist
|
|
560
|
-
}
|
|
561
501
|
}
|
|
562
502
|
}
|
|
563
503
|
}
|
|
@@ -118,45 +118,51 @@ final class HybridDownloadManager: HybridDownloadManagerSpec {
|
|
|
118
118
|
|
|
119
119
|
// MARK: - Downloaded Content Queries
|
|
120
120
|
|
|
121
|
-
func isTrackDownloaded(trackId: String) throws -> Bool {
|
|
122
|
-
|
|
121
|
+
func isTrackDownloaded(trackId: String) throws -> Promise<Bool> {
|
|
122
|
+
Promise.async { self.core.isTrackDownloaded(trackId: trackId) }
|
|
123
123
|
}
|
|
124
124
|
|
|
125
|
-
func isPlaylistDownloaded(playlistId: String) throws -> Bool {
|
|
126
|
-
|
|
125
|
+
func isPlaylistDownloaded(playlistId: String) throws -> Promise<Bool> {
|
|
126
|
+
Promise.async { self.core.isPlaylistDownloaded(playlistId: playlistId) }
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
-
func isPlaylistPartiallyDownloaded(playlistId: String) throws -> Bool {
|
|
130
|
-
|
|
129
|
+
func isPlaylistPartiallyDownloaded(playlistId: String) throws -> Promise<Bool> {
|
|
130
|
+
Promise.async { self.core.isPlaylistPartiallyDownloaded(playlistId: playlistId) }
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
func getDownloadedTrack(trackId: String) throws -> Variant_NullType_DownloadedTrack {
|
|
134
|
-
|
|
135
|
-
|
|
133
|
+
func getDownloadedTrack(trackId: String) throws -> Promise<Variant_NullType_DownloadedTrack> {
|
|
134
|
+
Promise.async {
|
|
135
|
+
if let track = self.core.getDownloadedTrack(trackId: trackId) {
|
|
136
|
+
return Variant_NullType_DownloadedTrack.second(track)
|
|
137
|
+
}
|
|
138
|
+
return Variant_NullType_DownloadedTrack.first(NullType.null)
|
|
136
139
|
}
|
|
137
|
-
return Variant_NullType_DownloadedTrack.first(NullType.null)
|
|
138
140
|
}
|
|
139
141
|
|
|
140
|
-
func getAllDownloadedTracks() throws -> [DownloadedTrack] {
|
|
141
|
-
|
|
142
|
+
func getAllDownloadedTracks() throws -> Promise<[DownloadedTrack]> {
|
|
143
|
+
Promise.async { self.core.getAllDownloadedTracks() }
|
|
142
144
|
}
|
|
143
145
|
|
|
144
|
-
func getDownloadedPlaylist(playlistId: String) throws -> Variant_NullType_DownloadedPlaylist {
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
func getDownloadedPlaylist(playlistId: String) throws -> Promise<Variant_NullType_DownloadedPlaylist> {
|
|
147
|
+
Promise.async {
|
|
148
|
+
if let playlist = self.core.getDownloadedPlaylist(playlistId: playlistId) {
|
|
149
|
+
return Variant_NullType_DownloadedPlaylist.second(playlist)
|
|
150
|
+
}
|
|
151
|
+
return Variant_NullType_DownloadedPlaylist.first(NullType.null)
|
|
147
152
|
}
|
|
148
|
-
return Variant_NullType_DownloadedPlaylist.first(NullType.null)
|
|
149
153
|
}
|
|
150
154
|
|
|
151
|
-
func getAllDownloadedPlaylists() throws -> [DownloadedPlaylist] {
|
|
152
|
-
|
|
155
|
+
func getAllDownloadedPlaylists() throws -> Promise<[DownloadedPlaylist]> {
|
|
156
|
+
Promise.async { self.core.getAllDownloadedPlaylists() }
|
|
153
157
|
}
|
|
154
158
|
|
|
155
|
-
func getLocalPath(trackId: String) throws -> Variant_NullType_String {
|
|
156
|
-
|
|
157
|
-
|
|
159
|
+
func getLocalPath(trackId: String) throws -> Promise<Variant_NullType_String> {
|
|
160
|
+
Promise.async {
|
|
161
|
+
if let path = self.core.getLocalPath(trackId: trackId) {
|
|
162
|
+
return Variant_NullType_String.second(path)
|
|
163
|
+
}
|
|
164
|
+
return Variant_NullType_String.first(NullType.null)
|
|
158
165
|
}
|
|
159
|
-
return Variant_NullType_String.first(NullType.null)
|
|
160
166
|
}
|
|
161
167
|
|
|
162
168
|
// MARK: - Deletion
|
|
@@ -187,8 +193,8 @@ final class HybridDownloadManager: HybridDownloadManagerSpec {
|
|
|
187
193
|
}
|
|
188
194
|
}
|
|
189
195
|
|
|
190
|
-
func syncDownloads() throws -> Double {
|
|
191
|
-
|
|
196
|
+
func syncDownloads() throws -> Promise<Double> {
|
|
197
|
+
Promise.async { Double(self.core.syncDownloads()) }
|
|
192
198
|
}
|
|
193
199
|
|
|
194
200
|
// MARK: - Playback Source Preference
|
|
@@ -201,8 +207,8 @@ final class HybridDownloadManager: HybridDownloadManagerSpec {
|
|
|
201
207
|
return core.getPlaybackSourcePreference()
|
|
202
208
|
}
|
|
203
209
|
|
|
204
|
-
func getEffectiveUrl(track: TrackItem) throws -> String {
|
|
205
|
-
|
|
210
|
+
func getEffectiveUrl(track: TrackItem) throws -> Promise<String> {
|
|
211
|
+
Promise.async { self.core.getEffectiveUrl(track: track) }
|
|
206
212
|
}
|
|
207
213
|
|
|
208
214
|
// MARK: - Event Callbacks
|