@mustafaj/capacitor-plugin-playlist 0.9.6 → 0.9.8
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 +4 -4
- package/android/build.gradle +15 -5
- package/android/gradlew +0 -0
- package/android/src/main/java/org/dwbn/plugins/playlist/PlaylistPlugin.kt +13 -12
- package/android/src/main/java/org/dwbn/plugins/playlist/data/AudioTrack.kt +14 -1
- package/android/src/main/java/org/dwbn/plugins/playlist/manager/PlaylistManager.kt +43 -12
- package/dist/docs.json +64 -901
- package/dist/esm/RmxAudioPlayer.js +2 -1
- package/dist/esm/RmxAudioPlayer.js.map +1 -1
- package/dist/esm/plugin.d.ts +1 -2
- package/dist/esm/plugin.js +30 -2
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/utils.js +3 -0
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/web.d.ts +16 -0
- package/dist/esm/web.js +90 -47
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.js +134 -59
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/Plugin.swift +11 -8
- package/ios/Plugin/RmxAudioPlayer.swift +37 -10
- package/package.json +17 -19
package/README.md
CHANGED
|
@@ -35,8 +35,8 @@ cordova, and here we wanna give back to the community our outcome, any help is a
|
|
|
35
35
|
As with most capacitor plugins...
|
|
36
36
|
|
|
37
37
|
```
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
pnpm add @mustafaj/capacitor-plugin-playlist
|
|
39
|
+
pnpm exec cap sync
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
### For web
|
|
@@ -46,7 +46,7 @@ include hlsjs in your build
|
|
|
46
46
|
#### E.G. for Angular 2+:
|
|
47
47
|
|
|
48
48
|
```
|
|
49
|
-
|
|
49
|
+
pnpm add hls.js
|
|
50
50
|
```
|
|
51
51
|
|
|
52
52
|
then add to angular.json:
|
|
@@ -168,7 +168,7 @@ Example:
|
|
|
168
168
|
import {Playlist, AudioTrack} from '@mustafaj/capacitor-plugin-playlist'
|
|
169
169
|
|
|
170
170
|
const item: AudioTrack = {
|
|
171
|
-
trackId: 1,
|
|
171
|
+
trackId: 'track-1',
|
|
172
172
|
assetUrl: 'http://your_audio',
|
|
173
173
|
albumArt: 'http://some_image'
|
|
174
174
|
}
|
package/android/build.gradle
CHANGED
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
|
2
|
-
|
|
3
1
|
ext {
|
|
2
|
+
kotlin_version = project.hasProperty('kotlin_version') ? project.property('kotlin_version') : '2.3.0'
|
|
4
3
|
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
5
4
|
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.3.0'
|
|
6
5
|
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.7.0'
|
|
7
6
|
}
|
|
8
7
|
|
|
8
|
+
buildscript {
|
|
9
|
+
repositories {
|
|
10
|
+
google()
|
|
11
|
+
mavenCentral()
|
|
12
|
+
}
|
|
13
|
+
dependencies {
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.13.0'
|
|
15
|
+
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.3.0'
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
9
19
|
apply plugin: 'com.android.library'
|
|
10
20
|
apply plugin: 'kotlin-android'
|
|
11
21
|
|
|
@@ -34,9 +44,9 @@ android {
|
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
|
|
37
|
-
kotlin {
|
|
38
|
-
|
|
39
|
-
jvmTarget =
|
|
47
|
+
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
|
|
48
|
+
kotlinOptions {
|
|
49
|
+
jvmTarget = '21'
|
|
40
50
|
}
|
|
41
51
|
}
|
|
42
52
|
|
package/android/gradlew
CHANGED
|
File without changes
|
|
@@ -3,6 +3,7 @@ package org.dwbn.plugins.playlist
|
|
|
3
3
|
import android.os.Handler
|
|
4
4
|
import android.os.Looper
|
|
5
5
|
import android.util.Log
|
|
6
|
+
import com.devbrackets.android.playlistcore.manager.BasePlaylistManager
|
|
6
7
|
import com.devbrackets.android.playlistcore.data.MediaProgress
|
|
7
8
|
import com.getcapacitor.*
|
|
8
9
|
import com.getcapacitor.annotation.CapacitorPlugin
|
|
@@ -254,12 +255,13 @@ public class PlaylistPlugin : Plugin(), OnStatusReportListener {
|
|
|
254
255
|
Handler(Looper.getMainLooper()).post {
|
|
255
256
|
val id: String = call.getString("id")!!
|
|
256
257
|
if ("" != id) {
|
|
257
|
-
// alternatively we could search for the item and set the current index to that item.
|
|
258
|
-
val code = id.hashCode()
|
|
259
258
|
val seekPosition = (call.getFloat("position", 0f)!! * 1000.0f).toLong()
|
|
260
|
-
audioPlayerImpl!!.playlistManager.
|
|
261
|
-
|
|
262
|
-
|
|
259
|
+
val itemPosition = audioPlayerImpl!!.playlistManager.findItemPosition(id)
|
|
260
|
+
if (itemPosition != BasePlaylistManager.INVALID_POSITION) {
|
|
261
|
+
audioPlayerImpl!!.playlistManager.currentPosition = itemPosition
|
|
262
|
+
audioPlayerImpl!!.clearTrackSelectionSuppression()
|
|
263
|
+
audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, false)
|
|
264
|
+
}
|
|
263
265
|
}
|
|
264
266
|
|
|
265
267
|
call.resolve()
|
|
@@ -293,14 +295,13 @@ public class PlaylistPlugin : Plugin(), OnStatusReportListener {
|
|
|
293
295
|
Handler(Looper.getMainLooper()).post {
|
|
294
296
|
val id: String = call.getString("id")!!
|
|
295
297
|
if ("" != id) {
|
|
296
|
-
// alternatively we could search for the item and set the current index to that item.
|
|
297
|
-
val code = id.hashCode()
|
|
298
|
-
audioPlayerImpl!!.playlistManager.setCurrentItem(code.toLong())
|
|
299
|
-
audioPlayerImpl!!.prepareForTrackSelection(id)
|
|
300
|
-
|
|
301
298
|
val seekPosition = (call.getFloat("position", 0f)!! * 1000.0f).toLong()
|
|
302
|
-
|
|
303
|
-
|
|
299
|
+
val itemPosition = audioPlayerImpl!!.playlistManager.findItemPosition(id)
|
|
300
|
+
if (itemPosition != BasePlaylistManager.INVALID_POSITION) {
|
|
301
|
+
audioPlayerImpl!!.playlistManager.currentPosition = itemPosition
|
|
302
|
+
audioPlayerImpl!!.prepareForTrackSelection(id)
|
|
303
|
+
audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, true)
|
|
304
|
+
}
|
|
304
305
|
}
|
|
305
306
|
call.resolve()
|
|
306
307
|
|
|
@@ -5,8 +5,21 @@ import com.devbrackets.android.playlistcore.api.PlaylistItem
|
|
|
5
5
|
import com.devbrackets.android.playlistcore.manager.BasePlaylistManager
|
|
6
6
|
import org.json.JSONException
|
|
7
7
|
import org.json.JSONObject
|
|
8
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
9
|
+
import java.util.concurrent.atomic.AtomicLong
|
|
8
10
|
|
|
9
11
|
class AudioTrack (private val config: JSONObject) : PlaylistItem {
|
|
12
|
+
companion object {
|
|
13
|
+
private val stable_ids = ConcurrentHashMap<String, Long>()
|
|
14
|
+
private val next_stable_id = AtomicLong(1)
|
|
15
|
+
|
|
16
|
+
fun stableIdFor(trackId: String): Long {
|
|
17
|
+
return stable_ids.computeIfAbsent(trackId) {
|
|
18
|
+
next_stable_id.getAndIncrement()
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
10
23
|
var bufferPercentFloat = 0f
|
|
11
24
|
set(buff) {
|
|
12
25
|
// There is a bug in MediaProgress where if bufferPercent == 100 it sets bufferPercentFloat
|
|
@@ -42,7 +55,7 @@ class AudioTrack (private val config: JSONObject) : PlaylistItem {
|
|
|
42
55
|
get() =
|
|
43
56
|
if (trackId == null) {
|
|
44
57
|
0
|
|
45
|
-
} else trackId
|
|
58
|
+
} else stableIdFor(trackId!!)
|
|
46
59
|
|
|
47
60
|
val isStream: Boolean
|
|
48
61
|
get() = config.optBoolean("isStream", false)
|
|
@@ -100,6 +100,12 @@ class PlaylistManager(application: Application) :
|
|
|
100
100
|
* List management
|
|
101
101
|
*/
|
|
102
102
|
fun setAllItems(items: List<AudioTrack>?, options: PlaylistItemOptions) {
|
|
103
|
+
val retainedPosition =
|
|
104
|
+
if (options.retainPosition) {
|
|
105
|
+
currentProgress?.position ?: 0
|
|
106
|
+
} else {
|
|
107
|
+
0
|
|
108
|
+
}
|
|
103
109
|
clearItems()
|
|
104
110
|
addAllItems(items)
|
|
105
111
|
currentPosition = 0
|
|
@@ -108,10 +114,7 @@ class PlaylistManager(application: Application) :
|
|
|
108
114
|
if (options.playFromPosition > 0) {
|
|
109
115
|
seekStart = options.playFromPosition
|
|
110
116
|
} else if (options.retainPosition) {
|
|
111
|
-
|
|
112
|
-
if (progress != null) {
|
|
113
|
-
seekStart = progress.position
|
|
114
|
-
}
|
|
117
|
+
seekStart = retainedPosition
|
|
115
118
|
}
|
|
116
119
|
|
|
117
120
|
// If the options said to start from a specific id, do so.
|
|
@@ -120,8 +123,10 @@ class PlaylistManager(application: Application) :
|
|
|
120
123
|
idStart = options.playFromId
|
|
121
124
|
}
|
|
122
125
|
if (idStart != null && "" != idStart) {
|
|
123
|
-
val
|
|
124
|
-
|
|
126
|
+
val itemPosition = findItemPosition(idStart)
|
|
127
|
+
if (itemPosition != INVALID_POSITION) {
|
|
128
|
+
currentPosition = itemPosition
|
|
129
|
+
}
|
|
125
130
|
}
|
|
126
131
|
|
|
127
132
|
// We assume that if the playlist is fully loaded in one go,
|
|
@@ -160,7 +165,8 @@ class PlaylistManager(application: Application) :
|
|
|
160
165
|
if (playlistHandler != null) {
|
|
161
166
|
playlistHandler!!.pause(true)
|
|
162
167
|
}
|
|
163
|
-
|
|
168
|
+
val previousPosition = currentPosition
|
|
169
|
+
val currentItem = currentItem
|
|
164
170
|
var foundItem: AudioTrack? = null
|
|
165
171
|
var removingCurrent = false
|
|
166
172
|
|
|
@@ -181,7 +187,14 @@ class PlaylistManager(application: Application) :
|
|
|
181
187
|
audioTracks.removeAt(resolvedIndex)
|
|
182
188
|
}
|
|
183
189
|
items = audioTracks
|
|
184
|
-
currentPosition =
|
|
190
|
+
currentPosition =
|
|
191
|
+
if (audioTracks.isEmpty()) {
|
|
192
|
+
INVALID_POSITION
|
|
193
|
+
} else if (removingCurrent) {
|
|
194
|
+
previousPosition.coerceAtMost(audioTracks.lastIndex)
|
|
195
|
+
} else {
|
|
196
|
+
audioTracks.indexOf(currentItem).takeIf { it >= 0 } ?: INVALID_POSITION
|
|
197
|
+
}
|
|
185
198
|
// If removing the current item, start from beginning (0), otherwise preserve playback position
|
|
186
199
|
val seekStart = if (removingCurrent) 0 else seekPosition
|
|
187
200
|
beginPlayback(seekStart, !wasPlaying)
|
|
@@ -197,8 +210,8 @@ class PlaylistManager(application: Application) :
|
|
|
197
210
|
if (playlistHandler != null) {
|
|
198
211
|
playlistHandler!!.pause(true)
|
|
199
212
|
}
|
|
200
|
-
|
|
201
|
-
val currentItem = currentItem
|
|
213
|
+
val previousPosition = currentPosition
|
|
214
|
+
val currentItem = currentItem
|
|
202
215
|
var removingCurrent = false
|
|
203
216
|
|
|
204
217
|
// Get the current playback position in milliseconds before removing items
|
|
@@ -232,7 +245,14 @@ class PlaylistManager(application: Application) :
|
|
|
232
245
|
}
|
|
233
246
|
}
|
|
234
247
|
items = audioTracks
|
|
235
|
-
currentPosition =
|
|
248
|
+
currentPosition =
|
|
249
|
+
if (audioTracks.isEmpty()) {
|
|
250
|
+
INVALID_POSITION
|
|
251
|
+
} else if (removingCurrent) {
|
|
252
|
+
previousPosition.coerceAtMost(audioTracks.lastIndex)
|
|
253
|
+
} else {
|
|
254
|
+
audioTracks.indexOf(currentItem).takeIf { it >= 0 } ?: INVALID_POSITION
|
|
255
|
+
}
|
|
236
256
|
// If removing the current item, start from beginning (0), otherwise preserve playback position
|
|
237
257
|
val seekStart = if (removingCurrent) 0 else seekPosition
|
|
238
258
|
beginPlayback(seekStart, !wasPlaying)
|
|
@@ -255,7 +275,7 @@ class PlaylistManager(application: Application) :
|
|
|
255
275
|
if (trackIndex >= 0 && trackIndex < audioTracks.size) {
|
|
256
276
|
resolvedPosition = trackIndex
|
|
257
277
|
} else if ("" != trackId) {
|
|
258
|
-
val itemPos = getPositionForItem(
|
|
278
|
+
val itemPos = getPositionForItem(AudioTrack.stableIdFor(trackId))
|
|
259
279
|
if (itemPos != INVALID_POSITION) {
|
|
260
280
|
resolvedPosition = itemPos
|
|
261
281
|
}
|
|
@@ -263,6 +283,17 @@ class PlaylistManager(application: Application) :
|
|
|
263
283
|
return resolvedPosition
|
|
264
284
|
}
|
|
265
285
|
|
|
286
|
+
fun findItemPosition(trackId: String?): Int {
|
|
287
|
+
if (trackId.isNullOrEmpty()) {
|
|
288
|
+
return INVALID_POSITION
|
|
289
|
+
}
|
|
290
|
+
val itemPos = getPositionForItem(AudioTrack.stableIdFor(trackId))
|
|
291
|
+
if (itemPos != INVALID_POSITION) {
|
|
292
|
+
return itemPos
|
|
293
|
+
}
|
|
294
|
+
return audioTracks.indexOfFirst { it.trackId == trackId }
|
|
295
|
+
}
|
|
296
|
+
|
|
266
297
|
fun getVolumeLeft(): Float {
|
|
267
298
|
return volumeLeft
|
|
268
299
|
}
|