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
package/README.md
CHANGED
|
@@ -42,41 +42,46 @@ npm install react-native-nitro-modules
|
|
|
42
42
|
|
|
43
43
|
### TrackPlayer Methods
|
|
44
44
|
|
|
45
|
+
Command-style methods return **`Promise<void>`** (or another **`Promise`**) and **reject** on failure; **`getRepeatMode()`** and **`isAndroidAutoConnected()`** are synchronous reads.
|
|
46
|
+
|
|
45
47
|
| Name | Platform | Description |
|
|
46
48
|
| --------------------------- | -------- | ------------------------------------------------------------------- |
|
|
47
|
-
| `play()` | Both | Resumes playback.
|
|
48
|
-
| `pause()` | Both | Pauses playback.
|
|
49
|
+
| `play()` | Both | **Async**. Resumes playback. |
|
|
50
|
+
| `pause()` | Both | **Async**. Pauses playback. |
|
|
49
51
|
| `playSong(id, playlistId?)` | Both | **Async**. Plays a specific song, optionally from a playlist. |
|
|
50
|
-
| `skipToNext()` | Both | Skips to the next track in the queue.
|
|
51
|
-
| `skipToPrevious()` | Both | Skips to the previous track.
|
|
52
|
-
| `seek(position)` | Both | Seeks to a specific time position in seconds.
|
|
52
|
+
| `skipToNext()` | Both | **Async**. Skips to the next track in the queue. |
|
|
53
|
+
| `skipToPrevious()` | Both | **Async**. Skips to the previous track. |
|
|
54
|
+
| `seek(position)` | Both | **Async**. Seeks to a specific time position in seconds. |
|
|
53
55
|
| `setPlaybackSpeed(speed)` | Both | **Async**. Sets playback speed (e.g. 0.5x, 1x, 1.5x, 2x). |
|
|
54
56
|
| `getPlaybackSpeed()` | Both | **Async**. Gets the current playback speed. |
|
|
55
|
-
| `setVolume(0-100)` | Both | Sets playback volume (0-100).
|
|
56
|
-
| `setRepeatMode(mode)` | Both | Sets repeat mode (`off`, `track`, `Playlist`).
|
|
57
|
+
| `setVolume(0-100)` | Both | **Async**. Sets playback volume (0-100). |
|
|
58
|
+
| `setRepeatMode(mode)` | Both | **Async**. Sets repeat mode (`off`, `track`, `Playlist`). |
|
|
59
|
+
| `getRepeatMode()` | Both | **Sync**. Current repeat mode. |
|
|
57
60
|
| `addToUpNext(id)` | Both | **Async**. Adds a track to the "up next" queue (FIFO). |
|
|
58
61
|
| `playNext(id)` | Both | **Async**. Adds a track to the "play next" stack (LIFO). |
|
|
59
|
-
| `getActualQueue()` | Both | **Async**.
|
|
60
|
-
| `getState()` | Both | **Async**.
|
|
61
|
-
| `skipToIndex(index)` | Both | **Async**. Skips to
|
|
62
|
-
| `configure(config)` | Both |
|
|
63
|
-
| `isAndroidAutoConnected()` | Both |
|
|
62
|
+
| `getActualQueue()` | Both | **Async**. Full playback queue including temporary tracks. |
|
|
63
|
+
| `getState()` | Both | **Async**. Snapshot of player state. |
|
|
64
|
+
| `skipToIndex(index)` | Both | **Async**. Skips to an index in the actual queue (`Promise<boolean>`). |
|
|
65
|
+
| `configure(config)` | Both | **Async**. Player settings (Android Auto, CarPlay, notification). |
|
|
66
|
+
| `isAndroidAutoConnected()` | Both | **Sync**. Android Auto connection. |
|
|
64
67
|
|
|
65
68
|
### PlayerQueue Methods
|
|
66
69
|
|
|
70
|
+
Mutations return **`Promise<void>`** (or **`Promise<string>`** for `createPlaylist`). **`getPlaylist`** / **`getAllPlaylists`** / **`getCurrentPlaylistId`** are synchronous reads.
|
|
71
|
+
|
|
67
72
|
| Name | Platform | Description |
|
|
68
73
|
| --------------------------------------- | -------- | ------------------------------------------------------- |
|
|
69
|
-
| `createPlaylist(name, ...)` | Both | Creates a
|
|
70
|
-
| `deletePlaylist(id)` | Both | Deletes a playlist by ID.
|
|
71
|
-
| `updatePlaylist(id, ...)` | Both | Updates
|
|
74
|
+
| `createPlaylist(name, ...)` | Both | **Async**. Creates a playlist; resolves to playlist ID. |
|
|
75
|
+
| `deletePlaylist(id)` | Both | **Async**. Deletes a playlist by ID. |
|
|
76
|
+
| `updatePlaylist(id, ...)` | Both | **Async**. Updates metadata (name, description, artwork). |
|
|
72
77
|
| `getPlaylist(id)` | Both | Gets a specific playlist object. |
|
|
73
78
|
| `getAllPlaylists()` | Both | Gets all available playlists. |
|
|
74
|
-
| `loadPlaylist(id)` | Both | Loads a playlist for playback.
|
|
79
|
+
| `loadPlaylist(id)` | Both | **Async**. Loads a playlist for playback. |
|
|
75
80
|
| `getCurrentPlaylistId()` | Both | Gets the ID of the currently playing playlist. |
|
|
76
|
-
| `addTrackToPlaylist(pid, track)` | Both | Adds a track to a playlist.
|
|
77
|
-
| `addTracksToPlaylist(pid, tracks)` | Both | Adds multiple tracks to a playlist.
|
|
78
|
-
| `removeTrackFromPlaylist(pid, tid)` | Both | Removes a track from a playlist.
|
|
79
|
-
| `reorderTrackInPlaylist(pid, tid, idx)` | Both | Moves a track to a new position
|
|
81
|
+
| `addTrackToPlaylist(pid, track)` | Both | **Async**. Adds a track to a playlist. |
|
|
82
|
+
| `addTracksToPlaylist(pid, tracks)` | Both | **Async**. Adds multiple tracks to a playlist. |
|
|
83
|
+
| `removeTrackFromPlaylist(pid, tid)` | Both | **Async**. Removes a track from a playlist. |
|
|
84
|
+
| `reorderTrackInPlaylist(pid, tid, idx)` | Both | **Async**. Moves a track to a new position. |
|
|
80
85
|
|
|
81
86
|
### Platform-Specific APIs
|
|
82
87
|
|
|
@@ -98,8 +103,10 @@ npm install react-native-nitro-modules
|
|
|
98
103
|
| `pauseDownload(downloadId)` | Both | **Async**. Pauses an active download. |
|
|
99
104
|
| `resumeDownload(downloadId)` | Both | **Async**. Resumes a paused download. |
|
|
100
105
|
| `cancelDownload(downloadId)` | Both | **Async**. Cancels a download. |
|
|
101
|
-
| `isTrackDownloaded(trackId)` | Both | Checks
|
|
102
|
-
| `getAllDownloadedTracks()` | Both |
|
|
106
|
+
| `isTrackDownloaded(trackId)` | Both | **Async**. Checks on-disk download state. |
|
|
107
|
+
| `getAllDownloadedTracks()` | Both | **Async**. Lists persisted downloaded tracks. |
|
|
108
|
+
| `getEffectiveUrl(track)` | Both | **Async**. Local or remote URL from preference + downloads. |
|
|
109
|
+
| `syncDownloads()` | Both | **Async**. Reconcile DB with files; returns cleanup count. |
|
|
103
110
|
| `deleteDownloadedTrack(trackId)` | Both | **Async**. Deletes a downloaded track. |
|
|
104
111
|
| `getStorageInfo()` | Both | **Async**. Gets download storage usage information. |
|
|
105
112
|
| `setPlaybackSourcePreference(pref)` | Both | Sets playback source: `'auto'`, `'download'`, or `'network'`. |
|
|
@@ -109,6 +116,8 @@ npm install react-native-nitro-modules
|
|
|
109
116
|
|
|
110
117
|
## Quick Start
|
|
111
118
|
|
|
119
|
+
`TrackPlayer` / `PlayerQueue` commands return **Promises**. The snippets use `await`—run them inside an `async` function, or use `.then()` / `void` / `.catch()` as appropriate.
|
|
120
|
+
|
|
112
121
|
### 1. Configure the Player
|
|
113
122
|
|
|
114
123
|
Configure the player before using it in your app:
|
|
@@ -116,7 +125,7 @@ Configure the player before using it in your app:
|
|
|
116
125
|
```typescript
|
|
117
126
|
import { TrackPlayer } from 'react-native-nitro-player'
|
|
118
127
|
|
|
119
|
-
TrackPlayer.configure({
|
|
128
|
+
await TrackPlayer.configure({
|
|
120
129
|
androidAutoEnabled: true,
|
|
121
130
|
carPlayEnabled: false,
|
|
122
131
|
showInNotification: true,
|
|
@@ -147,15 +156,13 @@ const tracks: TrackItem[] = [
|
|
|
147
156
|
},
|
|
148
157
|
]
|
|
149
158
|
|
|
150
|
-
|
|
151
|
-
const playlistId = PlayerQueue.createPlaylist(
|
|
159
|
+
const playlistId = await PlayerQueue.createPlaylist(
|
|
152
160
|
'My Playlist',
|
|
153
161
|
'Playlist description',
|
|
154
162
|
'https://example.com/playlist-artwork.jpg'
|
|
155
163
|
)
|
|
156
164
|
|
|
157
|
-
|
|
158
|
-
PlayerQueue.addTracksToPlaylist(playlistId, tracks)
|
|
165
|
+
await PlayerQueue.addTracksToPlaylist(playlistId, tracks)
|
|
159
166
|
```
|
|
160
167
|
|
|
161
168
|
### 3. Play Music
|
|
@@ -163,28 +170,23 @@ PlayerQueue.addTracksToPlaylist(playlistId, tracks)
|
|
|
163
170
|
```typescript
|
|
164
171
|
import { TrackPlayer, PlayerQueue } from 'react-native-nitro-player'
|
|
165
172
|
|
|
166
|
-
|
|
167
|
-
PlayerQueue.loadPlaylist(playlistId)
|
|
173
|
+
await PlayerQueue.loadPlaylist(playlistId)
|
|
168
174
|
|
|
169
|
-
// Or play a specific song
|
|
170
175
|
await TrackPlayer.playSong('song-id', playlistId)
|
|
171
176
|
|
|
172
|
-
|
|
173
|
-
TrackPlayer.
|
|
174
|
-
TrackPlayer.
|
|
175
|
-
TrackPlayer.
|
|
176
|
-
TrackPlayer.
|
|
177
|
-
TrackPlayer.seek(30) // Seek to 30 seconds
|
|
177
|
+
await TrackPlayer.play()
|
|
178
|
+
await TrackPlayer.pause()
|
|
179
|
+
await TrackPlayer.skipToNext()
|
|
180
|
+
await TrackPlayer.skipToPrevious()
|
|
181
|
+
await TrackPlayer.seek(30)
|
|
178
182
|
|
|
179
|
-
|
|
180
|
-
TrackPlayer.setRepeatMode('
|
|
181
|
-
TrackPlayer.setRepeatMode('
|
|
182
|
-
TrackPlayer.setRepeatMode('track') // Repeat current track
|
|
183
|
+
await TrackPlayer.setRepeatMode('off')
|
|
184
|
+
await TrackPlayer.setRepeatMode('Playlist')
|
|
185
|
+
await TrackPlayer.setRepeatMode('track')
|
|
183
186
|
|
|
184
|
-
|
|
185
|
-
TrackPlayer.setVolume(
|
|
186
|
-
TrackPlayer.setVolume(
|
|
187
|
-
TrackPlayer.setVolume(100) // Maximum volume
|
|
187
|
+
await TrackPlayer.setVolume(50)
|
|
188
|
+
await TrackPlayer.setVolume(0)
|
|
189
|
+
await TrackPlayer.setVolume(100)
|
|
188
190
|
|
|
189
191
|
// Add temporary tracks to queue
|
|
190
192
|
await TrackPlayer.addToUpNext('song-id') // Add to up-next queue (FIFO)
|
|
@@ -280,8 +282,7 @@ The actual playback order is:
|
|
|
280
282
|
Temporary tracks are automatically cleared when:
|
|
281
283
|
|
|
282
284
|
- `await TrackPlayer.playSong()` is called
|
|
283
|
-
- `PlayerQueue.loadPlaylist()` is called
|
|
284
|
-
- `TrackPlayer.playFromIndex()` is called
|
|
285
|
+
- `await PlayerQueue.loadPlaylist()` is called
|
|
285
286
|
|
|
286
287
|
### `skipToIndex(index: number): Promise<boolean>`
|
|
287
288
|
|
package/android/src/main/java/com/margelo/nitro/nitroplayer/HybridAndroidAutoMediaLibrary.kt
CHANGED
|
@@ -3,7 +3,10 @@ package com.margelo.nitro.nitroplayer
|
|
|
3
3
|
import androidx.annotation.Keep
|
|
4
4
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
5
5
|
import com.margelo.nitro.NitroModules
|
|
6
|
+
import com.margelo.nitro.core.Promise
|
|
6
7
|
import com.margelo.nitro.nitroplayer.core.TrackPlayerCore
|
|
8
|
+
import com.margelo.nitro.nitroplayer.core.clearAndroidAutoMediaLibrary
|
|
9
|
+
import com.margelo.nitro.nitroplayer.core.setAndroidAutoMediaLibrary
|
|
7
10
|
|
|
8
11
|
@DoNotStrip
|
|
9
12
|
@Keep
|
|
@@ -11,21 +14,14 @@ class HybridAndroidAutoMediaLibrary : HybridAndroidAutoMediaLibrarySpec() {
|
|
|
11
14
|
private val core: TrackPlayerCore
|
|
12
15
|
|
|
13
16
|
init {
|
|
14
|
-
val context =
|
|
15
|
-
|
|
16
|
-
?: throw IllegalStateException("React Context is not initialized")
|
|
17
|
+
val context = NitroModules.applicationContext
|
|
18
|
+
?: throw IllegalStateException("React Context is not initialized")
|
|
17
19
|
core = TrackPlayerCore.getInstance(context)
|
|
18
20
|
}
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
override fun setMediaLibrary(libraryJson: String) {
|
|
23
|
-
core.setAndroidAutoMediaLibrary(libraryJson)
|
|
24
|
-
}
|
|
22
|
+
override fun setMediaLibrary(libraryJson: String): Promise<Unit> =
|
|
23
|
+
Promise.async { core.setAndroidAutoMediaLibrary(libraryJson) }
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
override fun clearMediaLibrary() {
|
|
29
|
-
core.clearAndroidAutoMediaLibrary()
|
|
30
|
-
}
|
|
25
|
+
override fun clearMediaLibrary(): Promise<Unit> =
|
|
26
|
+
Promise.async { core.clearAndroidAutoMediaLibrary() }
|
|
31
27
|
}
|
|
@@ -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 android.content.Context
|
|
@@ -7,6 +9,7 @@ import android.os.Build
|
|
|
7
9
|
import androidx.annotation.Keep
|
|
8
10
|
import com.facebook.proguard.annotations.DoNotStrip
|
|
9
11
|
import com.margelo.nitro.NitroModules
|
|
12
|
+
import com.margelo.nitro.core.Promise
|
|
10
13
|
import com.margelo.nitro.nitroplayer.core.NitroPlayerLogger
|
|
11
14
|
|
|
12
15
|
@DoNotStrip
|
|
@@ -15,19 +18,13 @@ class HybridAudioDevices : HybridAudioDevicesSpec() {
|
|
|
15
18
|
val applicationContext = NitroModules.applicationContext
|
|
16
19
|
private val audioManager = applicationContext?.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
|
17
20
|
|
|
18
|
-
// Device types that can be set as communication devices
|
|
19
21
|
private val validCommunicationDeviceTypes: Set<Int> by lazy {
|
|
20
|
-
val types =
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
AudioDeviceInfo.TYPE_BLUETOOTH_SCO,
|
|
27
|
-
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
|
|
28
|
-
AudioDeviceInfo.TYPE_USB_HEADSET,
|
|
29
|
-
)
|
|
30
|
-
// BLE types are only available on Android S (API 31) and above
|
|
22
|
+
val types = mutableSetOf(
|
|
23
|
+
AudioDeviceInfo.TYPE_BUILTIN_EARPIECE, AudioDeviceInfo.TYPE_BUILTIN_SPEAKER,
|
|
24
|
+
AudioDeviceInfo.TYPE_WIRED_HEADSET, AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
|
|
25
|
+
AudioDeviceInfo.TYPE_BLUETOOTH_SCO, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
|
|
26
|
+
AudioDeviceInfo.TYPE_USB_HEADSET,
|
|
27
|
+
)
|
|
31
28
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
32
29
|
types.add(AudioDeviceInfo.TYPE_BLE_HEADSET)
|
|
33
30
|
types.add(AudioDeviceInfo.TYPE_BLE_SPEAKER)
|
|
@@ -35,100 +32,58 @@ class HybridAudioDevices : HybridAudioDevicesSpec() {
|
|
|
35
32
|
types
|
|
36
33
|
}
|
|
37
34
|
|
|
38
|
-
@DoNotStrip
|
|
39
|
-
@Keep
|
|
40
35
|
override fun getAudioDevices(): Array<TAudioDevice> {
|
|
41
|
-
val devices = audioManager.getDevices(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
validCommunicationDeviceTypes.contains(device.type)
|
|
52
|
-
}.map { device ->
|
|
53
|
-
TAudioDevice(
|
|
54
|
-
id = device.id.toDouble(),
|
|
55
|
-
name = device.productName?.toString() ?: getDeviceTypeName(device.type),
|
|
56
|
-
type = device.type.toDouble(),
|
|
57
|
-
isActive = device == activeDevice,
|
|
58
|
-
)
|
|
59
|
-
}.toTypedArray()
|
|
36
|
+
val devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
37
|
+
val activeDevice: AudioDeviceInfo? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) audioManager.communicationDevice else null
|
|
38
|
+
return devices.filter { validCommunicationDeviceTypes.contains(it.type) }.map { device ->
|
|
39
|
+
TAudioDevice(
|
|
40
|
+
id = device.id.toDouble(),
|
|
41
|
+
name = device.productName?.toString() ?: getDeviceTypeName(device.type),
|
|
42
|
+
type = device.type.toDouble(),
|
|
43
|
+
isActive = device == activeDevice,
|
|
44
|
+
)
|
|
45
|
+
}.toTypedArray()
|
|
60
46
|
}
|
|
61
47
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> "Wired Headphones"
|
|
68
|
-
AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> "Bluetooth SCO"
|
|
69
|
-
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> "Bluetooth"
|
|
70
|
-
AudioDeviceInfo.TYPE_USB_HEADSET -> "USB Headset"
|
|
71
|
-
26 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Headset" else "Type 26"
|
|
72
|
-
27 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Speaker" else "Type 27"
|
|
73
|
-
else -> "Type $type"
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
@DoNotStrip
|
|
77
|
-
@Keep
|
|
78
|
-
override fun setAudioDevice(deviceId: Double): Boolean {
|
|
79
|
-
val device =
|
|
80
|
-
audioManager
|
|
81
|
-
.getDevices(android.media.AudioManager.GET_DEVICES_OUTPUTS)
|
|
82
|
-
.firstOrNull { it.id == deviceId.toInt() }
|
|
83
|
-
?: return false
|
|
84
|
-
|
|
85
|
-
// Check if device type is valid for communication
|
|
48
|
+
/** v2: setAudioDevice now returns Promise<Unit> instead of Boolean */
|
|
49
|
+
override fun setAudioDevice(deviceId: Double): Promise<Unit> = Promise.async {
|
|
50
|
+
val device = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
|
51
|
+
.firstOrNull { it.id == deviceId.toInt() }
|
|
52
|
+
?: throw IllegalArgumentException("Audio device $deviceId not found")
|
|
86
53
|
if (!validCommunicationDeviceTypes.contains(device.type)) {
|
|
87
|
-
|
|
88
|
-
return false
|
|
54
|
+
throw IllegalArgumentException("Device type ${device.type} is not a valid communication device")
|
|
89
55
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
|
|
56
|
+
try {
|
|
57
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
|
93
58
|
audioManager.setCommunicationDevice(device)
|
|
94
59
|
} else {
|
|
95
|
-
// Pre-Android 12 fallback (best-effort)
|
|
96
60
|
when (device.type) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
-> {
|
|
100
|
-
audioManager.startBluetoothSco()
|
|
101
|
-
audioManager.isBluetoothScoOn = true
|
|
102
|
-
true
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> {
|
|
106
|
-
audioManager.isSpeakerphoneOn = true
|
|
107
|
-
true
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
android.media.AudioDeviceInfo.TYPE_WIRED_HEADSET,
|
|
111
|
-
android.media.AudioDeviceInfo.TYPE_WIRED_HEADPHONES,
|
|
112
|
-
-> {
|
|
113
|
-
audioManager.isSpeakerphoneOn = false
|
|
114
|
-
audioManager.isBluetoothScoOn = false
|
|
115
|
-
true
|
|
61
|
+
AudioDeviceInfo.TYPE_BLUETOOTH_SCO, AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> {
|
|
62
|
+
audioManager.startBluetoothSco(); audioManager.isBluetoothScoOn = true
|
|
116
63
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
false
|
|
64
|
+
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> audioManager.isSpeakerphoneOn = true
|
|
65
|
+
AudioDeviceInfo.TYPE_WIRED_HEADSET, AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> {
|
|
66
|
+
audioManager.isSpeakerphoneOn = false; audioManager.isBluetoothScoOn = false
|
|
121
67
|
}
|
|
68
|
+
else -> throw IllegalArgumentException("Unsupported device type for pre-Android 12: ${device.type}")
|
|
122
69
|
}
|
|
123
70
|
}
|
|
124
71
|
} catch (e: Exception) {
|
|
125
72
|
NitroPlayerLogger.log("HybridAudioDevices", "Error setting audio device: ${e.message}")
|
|
126
|
-
e
|
|
127
|
-
false
|
|
73
|
+
throw e
|
|
128
74
|
}
|
|
129
75
|
}
|
|
130
76
|
|
|
131
|
-
|
|
132
|
-
|
|
77
|
+
private fun getDeviceTypeName(type: Int): String = when (type) {
|
|
78
|
+
AudioDeviceInfo.TYPE_BUILTIN_EARPIECE -> "Built-in Earpiece"
|
|
79
|
+
AudioDeviceInfo.TYPE_BUILTIN_SPEAKER -> "Built-in Speaker"
|
|
80
|
+
AudioDeviceInfo.TYPE_WIRED_HEADSET -> "Wired Headset"
|
|
81
|
+
AudioDeviceInfo.TYPE_WIRED_HEADPHONES -> "Wired Headphones"
|
|
82
|
+
AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> "Bluetooth SCO"
|
|
83
|
+
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP -> "Bluetooth"
|
|
84
|
+
AudioDeviceInfo.TYPE_USB_HEADSET -> "USB Headset"
|
|
85
|
+
26 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Headset" else "Type 26"
|
|
86
|
+
27 -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) "BLE Speaker" else "Type 27"
|
|
87
|
+
else -> "Type $type"
|
|
133
88
|
}
|
|
134
89
|
}
|
|
@@ -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
|
|
@@ -7,219 +9,83 @@ import com.margelo.nitro.core.NullType
|
|
|
7
9
|
import com.margelo.nitro.core.Promise
|
|
8
10
|
import com.margelo.nitro.nitroplayer.download.DownloadManagerCore
|
|
9
11
|
|
|
10
|
-
/**
|
|
11
|
-
* Hybrid implementation of DownloadManagerSpec for Android
|
|
12
|
-
* Bridges Nitro modules with the native DownloadManagerCore implementation
|
|
13
|
-
*/
|
|
14
12
|
@DoNotStrip
|
|
15
13
|
@Keep
|
|
16
14
|
class HybridDownloadManager : HybridDownloadManagerSpec() {
|
|
17
15
|
private val core: DownloadManagerCore
|
|
18
16
|
|
|
19
17
|
init {
|
|
20
|
-
val context =
|
|
21
|
-
|
|
22
|
-
?: throw IllegalStateException("React Context is not initialized")
|
|
18
|
+
val context = NitroModules.applicationContext
|
|
19
|
+
?: throw IllegalStateException("React Context is not initialized")
|
|
23
20
|
core = DownloadManagerCore.getInstance(context)
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
// Configuration
|
|
27
|
-
|
|
28
|
-
@Keep
|
|
29
|
-
override fun configure(config: DownloadConfig) {
|
|
30
|
-
core.configure(config)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@DoNotStrip
|
|
34
|
-
@Keep
|
|
23
|
+
// ── Configuration ─────────────────────────────────────────────────────────
|
|
24
|
+
override fun configure(config: DownloadConfig) = core.configure(config)
|
|
35
25
|
override fun getConfig(): DownloadConfig = core.getConfig()
|
|
36
26
|
|
|
37
|
-
// Download
|
|
38
|
-
override fun downloadTrack(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
): Promise<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
override fun
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
): Promise<Array<String>> =
|
|
50
|
-
Promise.async {
|
|
51
|
-
core.downloadPlaylist(playlistId, tracks)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Download Control
|
|
55
|
-
override fun pauseDownload(downloadId: String): Promise<Unit> =
|
|
56
|
-
Promise.async {
|
|
57
|
-
core.pauseDownload(downloadId)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
override fun resumeDownload(downloadId: String): Promise<Unit> =
|
|
61
|
-
Promise.async {
|
|
62
|
-
core.resumeDownload(downloadId)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
override fun cancelDownload(downloadId: String): Promise<Unit> =
|
|
66
|
-
Promise.async {
|
|
67
|
-
core.cancelDownload(downloadId)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
override fun retryDownload(downloadId: String): Promise<Unit> =
|
|
71
|
-
Promise.async {
|
|
72
|
-
core.retryDownload(downloadId)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
override fun pauseAllDownloads(): Promise<Unit> =
|
|
76
|
-
Promise.async {
|
|
77
|
-
core.pauseAllDownloads()
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
override fun resumeAllDownloads(): Promise<Unit> =
|
|
81
|
-
Promise.async {
|
|
82
|
-
core.resumeAllDownloads()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
override fun cancelAllDownloads(): Promise<Unit> =
|
|
86
|
-
Promise.async {
|
|
87
|
-
core.cancelAllDownloads()
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Download Status
|
|
91
|
-
@DoNotStrip
|
|
92
|
-
@Keep
|
|
27
|
+
// ── Download operations ───────────────────────────────────────────────────
|
|
28
|
+
override fun downloadTrack(track: TrackItem, playlistId: String?): Promise<String> = Promise.async { core.downloadTrack(track, playlistId) }
|
|
29
|
+
override fun downloadPlaylist(playlistId: String, tracks: Array<TrackItem>): Promise<Array<String>> = Promise.async { core.downloadPlaylist(playlistId, tracks) }
|
|
30
|
+
override fun pauseDownload(downloadId: String): Promise<Unit> = Promise.async { core.pauseDownload(downloadId) }
|
|
31
|
+
override fun resumeDownload(downloadId: String): Promise<Unit> = Promise.async { core.resumeDownload(downloadId) }
|
|
32
|
+
override fun cancelDownload(downloadId: String): Promise<Unit> = Promise.async { core.cancelDownload(downloadId) }
|
|
33
|
+
override fun retryDownload(downloadId: String): Promise<Unit> = Promise.async { core.retryDownload(downloadId) }
|
|
34
|
+
override fun pauseAllDownloads(): Promise<Unit> = Promise.async { core.pauseAllDownloads() }
|
|
35
|
+
override fun resumeAllDownloads(): Promise<Unit> = Promise.async { core.resumeAllDownloads() }
|
|
36
|
+
override fun cancelAllDownloads(): Promise<Unit> = Promise.async { core.cancelAllDownloads() }
|
|
37
|
+
|
|
38
|
+
// ── Download status (sync) ────────────────────────────────────────────────
|
|
93
39
|
override fun getDownloadTask(downloadId: String): Variant_NullType_DownloadTask {
|
|
94
40
|
val task = core.getDownloadTask(downloadId)
|
|
95
|
-
return if (task != null)
|
|
96
|
-
|
|
97
|
-
} else {
|
|
98
|
-
Variant_NullType_DownloadTask.create(NullType.NULL)
|
|
99
|
-
}
|
|
41
|
+
return if (task != null) Variant_NullType_DownloadTask.create(task)
|
|
42
|
+
else Variant_NullType_DownloadTask.create(NullType.NULL)
|
|
100
43
|
}
|
|
101
|
-
|
|
102
|
-
@DoNotStrip
|
|
103
|
-
@Keep
|
|
104
44
|
override fun getActiveDownloads(): Array<DownloadTask> = core.getActiveDownloads()
|
|
105
|
-
|
|
106
|
-
@DoNotStrip
|
|
107
|
-
@Keep
|
|
108
45
|
override fun getQueueStatus(): DownloadQueueStatus = core.getQueueStatus()
|
|
109
|
-
|
|
110
|
-
@DoNotStrip
|
|
111
|
-
@Keep
|
|
112
46
|
override fun isDownloading(trackId: String): Boolean = core.isDownloading(trackId)
|
|
113
|
-
|
|
114
|
-
@DoNotStrip
|
|
115
|
-
@Keep
|
|
116
47
|
override fun getDownloadState(trackId: String): DownloadState = core.getDownloadState(trackId)
|
|
117
48
|
|
|
118
|
-
// Downloaded
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
override fun
|
|
49
|
+
// ── Downloaded content queries (now async per spec) ───────────────────────
|
|
50
|
+
override fun isTrackDownloaded(trackId: String): Promise<Boolean> = Promise.async { core.isTrackDownloaded(trackId) }
|
|
51
|
+
override fun isPlaylistDownloaded(playlistId: String): Promise<Boolean> = Promise.async { core.isPlaylistDownloaded(playlistId) }
|
|
52
|
+
override fun isPlaylistPartiallyDownloaded(playlistId: String): Promise<Boolean> = Promise.async { core.isPlaylistPartiallyDownloaded(playlistId) }
|
|
122
53
|
|
|
123
|
-
|
|
124
|
-
@Keep
|
|
125
|
-
override fun isPlaylistDownloaded(playlistId: String): Boolean = core.isPlaylistDownloaded(playlistId)
|
|
126
|
-
|
|
127
|
-
@DoNotStrip
|
|
128
|
-
@Keep
|
|
129
|
-
override fun isPlaylistPartiallyDownloaded(playlistId: String): Boolean = core.isPlaylistPartiallyDownloaded(playlistId)
|
|
130
|
-
|
|
131
|
-
@DoNotStrip
|
|
132
|
-
@Keep
|
|
133
|
-
override fun getDownloadedTrack(trackId: String): Variant_NullType_DownloadedTrack {
|
|
54
|
+
override fun getDownloadedTrack(trackId: String): Promise<Variant_NullType_DownloadedTrack> = Promise.async {
|
|
134
55
|
val track = core.getDownloadedTrack(trackId)
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
} else {
|
|
138
|
-
Variant_NullType_DownloadedTrack.create(NullType.NULL)
|
|
139
|
-
}
|
|
56
|
+
if (track != null) Variant_NullType_DownloadedTrack.create(track)
|
|
57
|
+
else Variant_NullType_DownloadedTrack.create(NullType.NULL)
|
|
140
58
|
}
|
|
59
|
+
override fun getAllDownloadedTracks(): Promise<Array<DownloadedTrack>> = Promise.async { core.getAllDownloadedTracks() }
|
|
141
60
|
|
|
142
|
-
|
|
143
|
-
@Keep
|
|
144
|
-
override fun getAllDownloadedTracks(): Array<DownloadedTrack> = core.getAllDownloadedTracks()
|
|
145
|
-
|
|
146
|
-
@DoNotStrip
|
|
147
|
-
@Keep
|
|
148
|
-
override fun getDownloadedPlaylist(playlistId: String): Variant_NullType_DownloadedPlaylist {
|
|
61
|
+
override fun getDownloadedPlaylist(playlistId: String): Promise<Variant_NullType_DownloadedPlaylist> = Promise.async {
|
|
149
62
|
val playlist = core.getDownloadedPlaylist(playlistId)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
} else {
|
|
153
|
-
Variant_NullType_DownloadedPlaylist.create(NullType.NULL)
|
|
154
|
-
}
|
|
63
|
+
if (playlist != null) Variant_NullType_DownloadedPlaylist.create(playlist)
|
|
64
|
+
else Variant_NullType_DownloadedPlaylist.create(NullType.NULL)
|
|
155
65
|
}
|
|
66
|
+
override fun getAllDownloadedPlaylists(): Promise<Array<DownloadedPlaylist>> = Promise.async { core.getAllDownloadedPlaylists() }
|
|
156
67
|
|
|
157
|
-
|
|
158
|
-
@Keep
|
|
159
|
-
override fun getAllDownloadedPlaylists(): Array<DownloadedPlaylist> = core.getAllDownloadedPlaylists()
|
|
160
|
-
|
|
161
|
-
@DoNotStrip
|
|
162
|
-
@Keep
|
|
163
|
-
override fun getLocalPath(trackId: String): Variant_NullType_String {
|
|
68
|
+
override fun getLocalPath(trackId: String): Promise<Variant_NullType_String> = Promise.async {
|
|
164
69
|
val path = core.getLocalPath(trackId)
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
} else {
|
|
168
|
-
Variant_NullType_String.create(NullType.NULL)
|
|
169
|
-
}
|
|
70
|
+
if (path != null) Variant_NullType_String.create(path)
|
|
71
|
+
else Variant_NullType_String.create(NullType.NULL)
|
|
170
72
|
}
|
|
171
73
|
|
|
172
|
-
|
|
173
|
-
override fun
|
|
174
|
-
Promise.async {
|
|
175
|
-
core.deleteDownloadedTrack(trackId)
|
|
176
|
-
}
|
|
74
|
+
override fun syncDownloads(): Promise<Double> = Promise.async { core.syncDownloads().toDouble() }
|
|
75
|
+
override fun getEffectiveUrl(track: TrackItem): Promise<String> = Promise.async { core.getEffectiveUrl(track) }
|
|
177
76
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
77
|
+
// ── Deletion ──────────────────────────────────────────────────────────────
|
|
78
|
+
override fun deleteDownloadedTrack(trackId: String): Promise<Unit> = Promise.async { core.deleteDownloadedTrack(trackId) }
|
|
79
|
+
override fun deleteDownloadedPlaylist(playlistId: String): Promise<Unit> = Promise.async { core.deleteDownloadedPlaylist(playlistId) }
|
|
80
|
+
override fun deleteAllDownloads(): Promise<Unit> = Promise.async { core.deleteAllDownloads() }
|
|
81
|
+
override fun getStorageInfo(): Promise<DownloadStorageInfo> = Promise.async { core.getStorageInfo() }
|
|
182
82
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
core.deleteAllDownloads()
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Storage Management
|
|
189
|
-
override fun getStorageInfo(): Promise<DownloadStorageInfo> =
|
|
190
|
-
Promise.async {
|
|
191
|
-
core.getStorageInfo()
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
@DoNotStrip
|
|
195
|
-
@Keep
|
|
196
|
-
override fun syncDownloads(): Double = core.syncDownloads().toDouble()
|
|
197
|
-
|
|
198
|
-
// Playback Source Preference
|
|
199
|
-
@DoNotStrip
|
|
200
|
-
@Keep
|
|
201
|
-
override fun setPlaybackSourcePreference(preference: PlaybackSource) {
|
|
202
|
-
core.setPlaybackSourcePreference(preference)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
@DoNotStrip
|
|
206
|
-
@Keep
|
|
83
|
+
// ── Playback source ───────────────────────────────────────────────────────
|
|
84
|
+
override fun setPlaybackSourcePreference(preference: PlaybackSource) = core.setPlaybackSourcePreference(preference)
|
|
207
85
|
override fun getPlaybackSourcePreference(): PlaybackSource = core.getPlaybackSourcePreference()
|
|
208
86
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
override fun
|
|
212
|
-
|
|
213
|
-
// Event Callbacks
|
|
214
|
-
override fun onDownloadProgress(callback: (progress: DownloadProgress) -> Unit) {
|
|
215
|
-
core.addProgressCallback(callback)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
override fun onDownloadStateChange(callback: (downloadId: String, trackId: String, state: DownloadState, error: DownloadError?) -> Unit) {
|
|
219
|
-
core.addStateChangeCallback(callback)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
override fun onDownloadComplete(callback: (downloadedTrack: DownloadedTrack) -> Unit) {
|
|
223
|
-
core.addCompleteCallback(callback)
|
|
224
|
-
}
|
|
87
|
+
// ── Events ────────────────────────────────────────────────────────────────
|
|
88
|
+
override fun onDownloadProgress(callback: (progress: DownloadProgress) -> Unit) = core.addProgressCallback(callback)
|
|
89
|
+
override fun onDownloadStateChange(callback: (downloadId: String, trackId: String, state: DownloadState, error: DownloadError?) -> Unit) = core.addStateChangeCallback(callback)
|
|
90
|
+
override fun onDownloadComplete(callback: (downloadedTrack: DownloadedTrack) -> Unit) = core.addCompleteCallback(callback)
|
|
225
91
|
}
|