capacitor-plugin-playlist 0.5.1 → 0.6.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.
Files changed (127) hide show
  1. package/README.md +29 -23
  2. package/android/build.gradle +1 -3
  3. package/android/src/main/java/org/dwbn/plugins/playlist/App.kt +0 -43
  4. package/android/src/main/java/org/dwbn/plugins/playlist/PlaylistPlugin.kt +217 -153
  5. package/android/src/main/java/org/dwbn/plugins/playlist/RmxAudioPlayer.java +4 -2
  6. package/android/src/main/java/org/dwbn/plugins/playlist/manager/PlaylistManager.kt +8 -6
  7. package/android/src/main/java/org/dwbn/plugins/playlist/playlist/AudioApi.kt +20 -11
  8. package/android/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler.java +1 -46
  9. package/android/src/main/java/org/dwbn/plugins/playlist/playlist/BaseMediaApi.kt +4 -8
  10. package/android/src/main/java/org/dwbn/plugins/playlist/service/MediaService.kt +17 -0
  11. package/package.json +1 -1
  12. package/android/.gradle/8.0.2/checksums/checksums.lock +0 -0
  13. package/android/.gradle/8.0.2/checksums/md5-checksums.bin +0 -0
  14. package/android/.gradle/8.0.2/checksums/sha1-checksums.bin +0 -0
  15. package/android/.gradle/8.0.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  16. package/android/.gradle/8.0.2/dependencies-accessors/gc.properties +0 -0
  17. package/android/.gradle/8.0.2/executionHistory/executionHistory.bin +0 -0
  18. package/android/.gradle/8.0.2/executionHistory/executionHistory.lock +0 -0
  19. package/android/.gradle/8.0.2/fileChanges/last-build.bin +0 -0
  20. package/android/.gradle/8.0.2/fileHashes/fileHashes.bin +0 -0
  21. package/android/.gradle/8.0.2/fileHashes/fileHashes.lock +0 -0
  22. package/android/.gradle/8.0.2/fileHashes/resourceHashesCache.bin +0 -0
  23. package/android/.gradle/8.0.2/gc.properties +0 -0
  24. package/android/.gradle/8.2.1/checksums/checksums.lock +0 -0
  25. package/android/.gradle/8.2.1/checksums/md5-checksums.bin +0 -0
  26. package/android/.gradle/8.2.1/checksums/sha1-checksums.bin +0 -0
  27. package/android/.gradle/8.2.1/dependencies-accessors/dependencies-accessors.lock +0 -0
  28. package/android/.gradle/8.2.1/dependencies-accessors/gc.properties +0 -0
  29. package/android/.gradle/8.2.1/executionHistory/executionHistory.bin +0 -0
  30. package/android/.gradle/8.2.1/executionHistory/executionHistory.lock +0 -0
  31. package/android/.gradle/8.2.1/fileChanges/last-build.bin +0 -0
  32. package/android/.gradle/8.2.1/fileHashes/fileHashes.bin +0 -0
  33. package/android/.gradle/8.2.1/fileHashes/fileHashes.lock +0 -0
  34. package/android/.gradle/8.2.1/gc.properties +0 -0
  35. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  36. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  37. package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  38. package/android/.gradle/config.properties +0 -2
  39. package/android/.gradle/file-system.probe +0 -0
  40. package/android/.gradle/vcs-1/gc.properties +0 -0
  41. package/android/.idea/compiler.xml +0 -6
  42. package/android/.idea/gradle.xml +0 -19
  43. package/android/.idea/kotlinc.xml +0 -6
  44. package/android/.idea/migrations.xml +0 -10
  45. package/android/.idea/misc.xml +0 -9
  46. package/android/.idea/vcs.xml +0 -6
  47. package/android/bin/.gradle/8.0.2/checksums/checksums.lock +0 -0
  48. package/android/bin/.gradle/8.0.2/checksums/md5-checksums.bin +0 -0
  49. package/android/bin/.gradle/8.0.2/checksums/sha1-checksums.bin +0 -0
  50. package/android/bin/.gradle/8.0.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  51. package/android/bin/.gradle/8.0.2/dependencies-accessors/gc.properties +0 -0
  52. package/android/bin/.gradle/8.0.2/executionHistory/executionHistory.bin +0 -0
  53. package/android/bin/.gradle/8.0.2/executionHistory/executionHistory.lock +0 -0
  54. package/android/bin/.gradle/8.0.2/fileChanges/last-build.bin +0 -0
  55. package/android/bin/.gradle/8.0.2/fileHashes/fileHashes.bin +0 -0
  56. package/android/bin/.gradle/8.0.2/fileHashes/fileHashes.lock +0 -0
  57. package/android/bin/.gradle/8.0.2/fileHashes/resourceHashesCache.bin +0 -0
  58. package/android/bin/.gradle/8.0.2/gc.properties +0 -0
  59. package/android/bin/.gradle/8.2.1/checksums/checksums.lock +0 -0
  60. package/android/bin/.gradle/8.2.1/checksums/md5-checksums.bin +0 -0
  61. package/android/bin/.gradle/8.2.1/checksums/sha1-checksums.bin +0 -0
  62. package/android/bin/.gradle/8.2.1/dependencies-accessors/dependencies-accessors.lock +0 -0
  63. package/android/bin/.gradle/8.2.1/dependencies-accessors/gc.properties +0 -0
  64. package/android/bin/.gradle/8.2.1/executionHistory/executionHistory.bin +0 -0
  65. package/android/bin/.gradle/8.2.1/executionHistory/executionHistory.lock +0 -0
  66. package/android/bin/.gradle/8.2.1/fileChanges/last-build.bin +0 -0
  67. package/android/bin/.gradle/8.2.1/fileHashes/fileHashes.bin +0 -0
  68. package/android/bin/.gradle/8.2.1/fileHashes/fileHashes.lock +0 -0
  69. package/android/bin/.gradle/8.2.1/gc.properties +0 -0
  70. package/android/bin/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  71. package/android/bin/.gradle/buildOutputCleanup/cache.properties +0 -2
  72. package/android/bin/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
  73. package/android/bin/.gradle/config.properties +0 -2
  74. package/android/bin/.gradle/file-system.probe +0 -0
  75. package/android/bin/.gradle/vcs-1/gc.properties +0 -0
  76. package/android/bin/.idea/compiler.xml +0 -6
  77. package/android/bin/.idea/gradle.xml +0 -19
  78. package/android/bin/.idea/kotlinc.xml +0 -6
  79. package/android/bin/.idea/migrations.xml +0 -10
  80. package/android/bin/.idea/misc.xml +0 -9
  81. package/android/bin/.idea/vcs.xml +0 -6
  82. package/android/bin/.project +0 -34
  83. package/android/bin/build.gradle +0 -79
  84. package/android/bin/gradle/wrapper/gradle-wrapper.jar +0 -0
  85. package/android/bin/gradle/wrapper/gradle-wrapper.properties +0 -7
  86. package/android/bin/gradle.properties +0 -22
  87. package/android/bin/gradlew +0 -248
  88. package/android/bin/gradlew.bat +0 -92
  89. package/android/bin/local.properties +0 -8
  90. package/android/bin/proguard-rules.pro +0 -21
  91. package/android/bin/settings.gradle +0 -2
  92. package/android/bin/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.class +0 -0
  93. package/android/bin/src/main/AndroidManifest.xml +0 -4
  94. package/android/bin/src/main/java/org/dwbn/plugins/playlist/App.kt +0 -62
  95. package/android/bin/src/main/java/org/dwbn/plugins/playlist/FakeR.kt +0 -39
  96. package/android/bin/src/main/java/org/dwbn/plugins/playlist/OnStatusCallback.kt +0 -34
  97. package/android/bin/src/main/java/org/dwbn/plugins/playlist/OnStatusReportListener.class +0 -0
  98. package/android/bin/src/main/java/org/dwbn/plugins/playlist/PlaylistItemOptions.class +0 -0
  99. package/android/bin/src/main/java/org/dwbn/plugins/playlist/PlaylistPlugin.kt +0 -356
  100. package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxAudioErrorType.class +0 -0
  101. package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxAudioPlayer.class +0 -0
  102. package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxAudioStatusMessage.class +0 -0
  103. package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxConstants.class +0 -0
  104. package/android/bin/src/main/java/org/dwbn/plugins/playlist/TrackRemovalItem.class +0 -0
  105. package/android/bin/src/main/java/org/dwbn/plugins/playlist/data/AudioTrack.kt +0 -94
  106. package/android/bin/src/main/java/org/dwbn/plugins/playlist/manager/MediaControlsListener.kt +0 -13
  107. package/android/bin/src/main/java/org/dwbn/plugins/playlist/manager/Options.kt +0 -77
  108. package/android/bin/src/main/java/org/dwbn/plugins/playlist/manager/PlaylistManager.kt +0 -286
  109. package/android/bin/src/main/java/org/dwbn/plugins/playlist/notification/PlaylistNotificationProvider.kt +0 -26
  110. package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/AudioApi.kt +0 -101
  111. package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler$Builder.class +0 -0
  112. package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler.class +0 -0
  113. package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/BaseMediaApi.kt +0 -40
  114. package/android/bin/src/main/java/org/dwbn/plugins/playlist/service/MediaImageProvider.kt +0 -79
  115. package/android/bin/src/main/java/org/dwbn/plugins/playlist/service/MediaService.kt +0 -53
  116. package/android/bin/src/main/res/.gitkeep +0 -0
  117. package/android/bin/src/main/res/drawable/ic_closed_caption_white_24dp.xml +0 -9
  118. package/android/bin/src/main/res/drawable/ic_demo_icon_adaptive.xml +0 -15
  119. package/android/bin/src/main/res/drawable/ic_launcher_background.xml +0 -48
  120. package/android/bin/src/main/res/drawable/ic_launcher_foreground.xml +0 -22
  121. package/android/bin/src/main/res/drawable/ic_notification_icon.png +0 -0
  122. package/android/bin/src/main/res/layout/bridge_layout_main.xml +0 -15
  123. package/android/bin/src/main/res/values/colors.xml +0 -3
  124. package/android/bin/src/main/res/values/strings.xml +0 -3
  125. package/android/bin/src/main/res/values/styles.xml +0 -3
  126. package/android/bin/src/test/java/com/getcapacitor/ExampleUnitTest.class +0 -0
  127. package/android/local.properties +0 -8
@@ -1,5 +1,7 @@
1
1
  package org.dwbn.plugins.playlist
2
2
 
3
+ import android.os.Handler
4
+ import android.os.Looper
3
5
  import android.util.Log
4
6
  import com.devbrackets.android.playlistcore.data.MediaProgress
5
7
  import com.getcapacitor.*
@@ -22,20 +24,25 @@ class PlaylistPlugin : Plugin(), OnStatusReportListener {
22
24
 
23
25
  @PluginMethod
24
26
  fun initialize(call: PluginCall) {
25
- statusCallback = OnStatusCallback(this)
26
- onStatus(RmxAudioStatusMessage.RMXSTATUS_REGISTER, "INIT", null)
27
- Log.i(TAG, "Initialized...")
28
- audioPlayerImpl!!.resume()
29
- call.resolve()
27
+ Handler(Looper.getMainLooper()).post {
28
+ statusCallback = OnStatusCallback(this)
29
+ onStatus(RmxAudioStatusMessage.RMXSTATUS_REGISTER, "INIT", null)
30
+ Log.i(TAG, "Initialized...")
31
+
32
+ audioPlayerImpl!!.resume()
33
+ call.resolve()
34
+ }
30
35
  }
31
36
  @PluginMethod
32
37
  fun setOptions(call: PluginCall) {
33
- val options: JSObject = call.getObject("options") ?: JSObject()
34
- resetStreamOnPause = options.optBoolean("resetStreamOnPause", this.resetStreamOnPause)
35
- Log.i("AudioPlayerOptions", options.toString())
36
- audioPlayerImpl!!.resetStreamOnPause = resetStreamOnPause
37
- audioPlayerImpl!!.setOptions(options)
38
- call.resolve()
38
+ Handler(Looper.getMainLooper()).post {
39
+ val options: JSObject = call.getObject("options") ?: JSObject()
40
+ resetStreamOnPause = options.optBoolean("resetStreamOnPause", this.resetStreamOnPause)
41
+ Log.i("AudioPlayerOptions", options.toString())
42
+ audioPlayerImpl!!.resetStreamOnPause = resetStreamOnPause
43
+ audioPlayerImpl!!.setOptions(options)
44
+ call.resolve()
45
+ }
39
46
  }
40
47
 
41
48
  @PluginMethod
@@ -47,260 +54,317 @@ class PlaylistPlugin : Plugin(), OnStatusReportListener {
47
54
 
48
55
  @PluginMethod
49
56
  fun setLoop(call: PluginCall) {
50
- val loop: Boolean = call.getBoolean("loop", audioPlayerImpl!!.playlistManager.loop)!!
51
- audioPlayerImpl!!.playlistManager.loop = loop
52
- call.resolve()
53
- Log.i(TAG,"setLoop: " + (if (loop) "TRUE" else "FALSE"))
57
+ Handler(Looper.getMainLooper()).post {
58
+ val loop: Boolean = call.getBoolean("loop", audioPlayerImpl!!.playlistManager.loop)!!
59
+ audioPlayerImpl!!.playlistManager.loop = loop
60
+ call.resolve()
61
+ Log.i(TAG, "setLoop: " + (if (loop) "TRUE" else "FALSE"))
62
+ }
54
63
  }
55
64
 
56
65
  @PluginMethod
57
66
  fun setPlaylistItems(call: PluginCall) {
58
- val items: JSArray = call.getArray("items")
59
- val optionsArgs: JSONObject = call.getObject("options")
60
- val options = PlaylistItemOptions(optionsArgs)
61
-
62
- val trackItems: ArrayList<AudioTrack> = getTrackItems(items)
63
- audioPlayerImpl!!.playlistManager.setAllItems(trackItems, options)
64
- for (playerItem in trackItems) {
65
- if (playerItem.trackId != null) {
66
- onStatus(RmxAudioStatusMessage.RMXSTATUS_ITEM_ADDED, playerItem.trackId, playerItem.toDict())
67
+ Handler(Looper.getMainLooper()).post {
68
+ val items: JSArray = call.getArray("items")
69
+ val optionsArgs: JSONObject = call.getObject("options")
70
+ val options = PlaylistItemOptions(optionsArgs)
71
+
72
+ val trackItems: ArrayList<AudioTrack> = getTrackItems(items)
73
+ audioPlayerImpl!!.playlistManager.setAllItems(trackItems, options)
74
+ for (playerItem in trackItems) {
75
+ if (playerItem.trackId != null) {
76
+ onStatus(
77
+ RmxAudioStatusMessage.RMXSTATUS_ITEM_ADDED,
78
+ playerItem.trackId,
79
+ playerItem.toDict()
80
+ )
81
+ }
67
82
  }
68
- }
69
83
 
70
- call.resolve()
84
+ call.resolve()
71
85
 
72
- Log.i(TAG,"setPlaylistItems" + items.length().toString())
86
+ Log.i(TAG, "setPlaylistItems" + items.length().toString())
87
+ }
73
88
  }
74
89
 
75
90
  @PluginMethod
76
91
  fun addItem(call: PluginCall) {
77
- val item: JSONObject = call.getObject("item")
78
- val playerItem: AudioTrack? = getTrackItem(item)
79
- audioPlayerImpl!!.getPlaylistManager().addItem(playerItem)
80
-
81
-
82
- if (playerItem?.trackId != null) {
83
- onStatus(RmxAudioStatusMessage.RMXSTATUS_ITEM_ADDED, playerItem.trackId, playerItem.toDict())
92
+ Handler(Looper.getMainLooper()).post {
93
+ val item: JSONObject = call.getObject("item")
94
+ val playerItem: AudioTrack? = getTrackItem(item)
95
+ audioPlayerImpl!!.getPlaylistManager().addItem(playerItem)
96
+
97
+
98
+ if (playerItem?.trackId != null) {
99
+ onStatus(
100
+ RmxAudioStatusMessage.RMXSTATUS_ITEM_ADDED,
101
+ playerItem.trackId,
102
+ playerItem.toDict()
103
+ )
104
+ }
105
+ call.resolve()
106
+ Log.i(TAG, "addItem")
84
107
  }
85
- call.resolve()
86
- Log.i(TAG,"addItem")
87
108
  }
88
109
 
89
110
  @PluginMethod
90
111
  fun addAllItems(call: PluginCall) {
91
- val items: JSONArray = call.getArray("items")
92
- val trackItems = getTrackItems(items)
93
- audioPlayerImpl!!.playlistManager.addAllItems(trackItems)
94
-
95
- for (playerItem in trackItems) {
96
- if (playerItem.trackId != null) {
97
- onStatus(RmxAudioStatusMessage.RMXSTATUS_ITEM_ADDED, playerItem.trackId, playerItem.toDict())
112
+ Handler(Looper.getMainLooper()).post {
113
+ val items: JSONArray = call.getArray("items")
114
+ val trackItems = getTrackItems(items)
115
+ audioPlayerImpl!!.playlistManager.addAllItems(trackItems)
116
+
117
+ for (playerItem in trackItems) {
118
+ if (playerItem.trackId != null) {
119
+ onStatus(
120
+ RmxAudioStatusMessage.RMXSTATUS_ITEM_ADDED,
121
+ playerItem.trackId,
122
+ playerItem.toDict()
123
+ )
124
+ }
98
125
  }
126
+ call.resolve()
127
+ Log.i(TAG, "addAllItems")
99
128
  }
100
- call.resolve()
101
- Log.i(TAG,"addAllItems")
102
129
  }
103
130
 
104
131
  @PluginMethod
105
132
  fun removeItem(call: PluginCall) {
106
- val trackIndex: Int = call.getInt("index", -1)!!
107
- val trackId: String = call.getString("id", "")!!
108
- Log.i(TAG,"removeItem trackIn" )
109
- val item = audioPlayerImpl!!.playlistManager.removeItem(trackIndex, trackId)
110
-
111
- if (item != null) {
112
- onStatus(RmxAudioStatusMessage.RMXSTATUS_ITEM_REMOVED, item.trackId, item.toDict())
113
- call.resolve()
114
- }
115
- else {
116
- call.reject("Could not find item!")
133
+ Handler(Looper.getMainLooper()).post {
134
+ val trackIndex: Int = call.getInt("index", -1)!!
135
+ val trackId: String = call.getString("id", "")!!
136
+ Log.i(TAG, "removeItem trackIn")
137
+ val item = audioPlayerImpl!!.playlistManager.removeItem(trackIndex, trackId)
138
+
139
+ if (item != null) {
140
+ onStatus(RmxAudioStatusMessage.RMXSTATUS_ITEM_REMOVED, item.trackId, item.toDict())
141
+ call.resolve()
142
+ } else {
143
+ call.reject("Could not find item!")
144
+ }
117
145
  }
118
146
  }
119
147
 
120
148
  @PluginMethod
121
149
  fun removeItems(call: PluginCall) {
122
- val items: JSONArray = call.getArray("items")
123
- var removed = 0
124
-
125
- val removals = ArrayList<TrackRemovalItem>()
126
- for (index in 0 until items.length()) {
127
- val entry = items.optJSONObject(index) ?: continue
128
- val trackIndex = entry.optInt("trackIndex", -1)
129
- val trackId = entry.optString("trackId", "")
130
- removals.add(TrackRemovalItem(trackIndex, trackId))
131
- val removedTracks = audioPlayerImpl!!.playlistManager.removeAllItems(removals)
132
- if (removedTracks.size > 0) {
133
- for (removedItem in removedTracks) {
134
- onStatus(RmxAudioStatusMessage.RMXSTATUS_ITEM_REMOVED, removedItem.trackId, removedItem.toDict())
150
+ Handler(Looper.getMainLooper()).post {
151
+ val items: JSONArray = call.getArray("items")
152
+ var removed = 0
153
+
154
+ val removals = ArrayList<TrackRemovalItem>()
155
+ for (index in 0 until items.length()) {
156
+ val entry = items.optJSONObject(index) ?: continue
157
+ val trackIndex = entry.optInt("trackIndex", -1)
158
+ val trackId = entry.optString("trackId", "")
159
+ removals.add(TrackRemovalItem(trackIndex, trackId))
160
+ val removedTracks = audioPlayerImpl!!.playlistManager.removeAllItems(removals)
161
+ if (removedTracks.size > 0) {
162
+ for (removedItem in removedTracks) {
163
+ onStatus(
164
+ RmxAudioStatusMessage.RMXSTATUS_ITEM_REMOVED,
165
+ removedItem.trackId,
166
+ removedItem.toDict()
167
+ )
168
+ }
169
+ removed = removedTracks.size
135
170
  }
136
- removed = removedTracks.size
137
171
  }
138
- }
139
172
 
140
- val result = JSObject()
141
- result.put("removed", removed)
142
- call.resolve(result)
173
+ val result = JSObject()
174
+ result.put("removed", removed)
175
+ call.resolve(result)
143
176
 
144
- Log.i(TAG,"removeItems")
177
+ Log.i(TAG, "removeItems")
178
+ }
145
179
  }
146
180
 
147
181
  @PluginMethod
148
182
  fun clearAllItems(call: PluginCall) {
149
- audioPlayerImpl!!.playlistManager.clearItems()
183
+ Handler(Looper.getMainLooper()).post {
184
+ audioPlayerImpl!!.playlistManager.clearItems()
150
185
 
151
- onStatus(RmxAudioStatusMessage.RMXSTATUS_PLAYLIST_CLEARED, "INVALID", null)
152
- call.resolve()
186
+ onStatus(RmxAudioStatusMessage.RMXSTATUS_PLAYLIST_CLEARED, "INVALID", null)
187
+ call.resolve()
153
188
 
154
- Log.i(TAG,"clearAllItems")
189
+ Log.i(TAG, "clearAllItems")
190
+ }
155
191
  }
156
192
 
157
193
  @PluginMethod
158
194
  fun play(call: PluginCall) {
159
- if (audioPlayerImpl!!.playlistManager.playlistHandler != null) {
160
- val isPlaying = (audioPlayerImpl!!.playlistManager.playlistHandler?.currentMediaPlayer != null
161
- && audioPlayerImpl!!.playlistManager.playlistHandler?.currentMediaPlayer?.isPlaying!!)
162
- // There's a bug in the threaded repeater that it stacks up the repeat calls instead of ignoring
163
- // additional ones or starting a new one. E.g. every time this is called, you'd get a new repeat cycle,
164
- // meaning you get N updates per second. Ew.
165
- if (!isPlaying) {
166
- audioPlayerImpl!!.playlistManager.playlistHandler?.play()
167
- //audioPlayerImpl.getPlaylistManager().playlistHandler.seek(position)
195
+ Handler(Looper.getMainLooper()).post {
196
+ if (audioPlayerImpl!!.playlistManager.playlistHandler != null) {
197
+ val isPlaying =
198
+ (audioPlayerImpl!!.playlistManager.playlistHandler?.currentMediaPlayer != null
199
+ && audioPlayerImpl!!.playlistManager.playlistHandler?.currentMediaPlayer?.isPlaying!!)
200
+ // There's a bug in the threaded repeater that it stacks up the repeat calls instead of ignoring
201
+ // additional ones or starting a new one. E.g. every time this is called, you'd get a new repeat cycle,
202
+ // meaning you get N updates per second. Ew.
203
+ if (!isPlaying) {
204
+ audioPlayerImpl!!.playlistManager.playlistHandler?.play()
205
+ //audioPlayerImpl.getPlaylistManager().playlistHandler.seek(position)
206
+ }
168
207
  }
169
- }
170
208
 
171
- call.resolve()
209
+ call.resolve()
172
210
 
173
- Log.i(TAG,"play")
211
+ Log.i(TAG, "play")
212
+ }
174
213
  }
175
214
 
176
215
  @PluginMethod
177
216
  fun playTrackByIndex(call: PluginCall) {
178
- val index: Int = call.getInt("index", audioPlayerImpl!!.playlistManager.currentPosition)!!
179
- val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
217
+ Handler(Looper.getMainLooper()).post {
218
+ val index: Int =
219
+ call.getInt("index", audioPlayerImpl!!.playlistManager.currentPosition)!!
220
+ val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
180
221
 
181
- audioPlayerImpl!!.playlistManager.currentPosition = index
182
- audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, false)
222
+ audioPlayerImpl!!.playlistManager.currentPosition = index
223
+ audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, false)
183
224
 
184
- call.resolve()
225
+ call.resolve()
185
226
 
186
- Log.i(TAG,"playTrackByIndex")
227
+ Log.i(TAG, "playTrackByIndex")
228
+ }
187
229
  }
188
230
 
189
231
  @PluginMethod
190
232
  fun playTrackById(call: PluginCall) {
191
- val id: String = call.getString("id")!!
192
- if ("" != id) {
193
- // alternatively we could search for the item and set the current index to that item.
194
- val code = id.hashCode()
195
- val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
196
- audioPlayerImpl!!.playlistManager.setCurrentItem(code.toLong())
197
- audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, false)
198
- }
233
+ Handler(Looper.getMainLooper()).post {
234
+ val id: String = call.getString("id")!!
235
+ if ("" != id) {
236
+ // alternatively we could search for the item and set the current index to that item.
237
+ val code = id.hashCode()
238
+ val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
239
+ audioPlayerImpl!!.playlistManager.setCurrentItem(code.toLong())
240
+ audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, false)
241
+ }
199
242
 
200
- call.resolve()
243
+ call.resolve()
201
244
 
202
- Log.i(TAG,"playTrackById")
245
+ Log.i(TAG, "playTrackById")
246
+ }
203
247
  }
204
248
 
205
249
  @PluginMethod
206
250
  fun selectTrackByIndex(call: PluginCall) {
207
- val index: Int = call.getInt("index", audioPlayerImpl!!.playlistManager.currentPosition)!!
251
+ Handler(Looper.getMainLooper()).post {
252
+ val index: Int =
253
+ call.getInt("index", audioPlayerImpl!!.playlistManager.currentPosition)!!
208
254
 
209
- audioPlayerImpl!!.playlistManager.currentPosition = index
255
+ audioPlayerImpl!!.playlistManager.currentPosition = index
210
256
 
211
- val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
257
+ val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
212
258
 
213
- audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, true)
259
+ audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, true)
214
260
 
215
- call.resolve()
261
+ call.resolve()
216
262
 
217
- Log.i(TAG,"selectTrackByIndex")
263
+ Log.i(TAG, "selectTrackByIndex")
264
+ }
218
265
  }
219
266
 
220
267
 
221
268
  @PluginMethod
222
269
  fun selectTrackById(call: PluginCall) {
223
- val id: String = call.getString("id")!!
224
- if ("" != id) {
225
- // alternatively we could search for the item and set the current index to that item.
226
- val code = id.hashCode()
227
- audioPlayerImpl!!.playlistManager.setCurrentItem(code.toLong())
270
+ Handler(Looper.getMainLooper()).post {
271
+ val id: String = call.getString("id")!!
272
+ if ("" != id) {
273
+ // alternatively we could search for the item and set the current index to that item.
274
+ val code = id.hashCode()
275
+ audioPlayerImpl!!.playlistManager.setCurrentItem(code.toLong())
228
276
 
229
- val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
277
+ val seekPosition = (call.getInt("position", 0)!! * 1000.0).toLong()
230
278
 
231
- audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, true)
232
- }
233
- call.resolve()
279
+ audioPlayerImpl!!.playlistManager.beginPlayback(seekPosition, true)
280
+ }
281
+ call.resolve()
234
282
 
235
- Log.i(TAG,"selectTrackById")
283
+ Log.i(TAG, "selectTrackById")
284
+ }
236
285
  }
237
286
 
238
287
  @PluginMethod
239
288
  fun pause(call: PluginCall) {
240
- audioPlayerImpl!!.playlistManager.invokePausePlay()
289
+ Handler(Looper.getMainLooper()).post {
290
+ audioPlayerImpl!!.playlistManager.invokePausePlay()
241
291
 
242
- call.resolve()
292
+ call.resolve()
243
293
 
244
- Log.i(TAG,"pause")
294
+ Log.i(TAG, "pause")
295
+ }
245
296
  }
246
297
 
247
298
  @PluginMethod
248
299
  fun skipForward(call: PluginCall) {
249
- audioPlayerImpl!!.playlistManager.invokeNext()
300
+ Handler(Looper.getMainLooper()).post {
301
+ audioPlayerImpl!!.playlistManager.invokeNext()
250
302
 
251
- call.resolve()
303
+ call.resolve()
252
304
 
253
- Log.i(TAG,"skipForward")
305
+ Log.i(TAG, "skipForward")
306
+ }
254
307
  }
255
308
 
256
309
  @PluginMethod
257
310
  fun skipBack(call: PluginCall) {
258
- audioPlayerImpl!!.playlistManager.invokePrevious()
311
+ Handler(Looper.getMainLooper()).post {
312
+ audioPlayerImpl!!.playlistManager.invokePrevious()
259
313
 
260
- call.resolve()
314
+ call.resolve()
261
315
 
262
- Log.i(TAG,"skipBack")
316
+ Log.i(TAG, "skipBack")
317
+ }
263
318
  }
264
319
 
265
320
  @PluginMethod
266
321
  fun seekTo(call: PluginCall) {
267
- var position: Long = 0
268
- val progress: MediaProgress? = audioPlayerImpl!!.playlistManager.currentProgress
269
- if (progress != null) {
270
- position = progress.position
271
- }
322
+ Handler(Looper.getMainLooper()).post {
323
+ var position: Long = 0
324
+ val progress: MediaProgress? = audioPlayerImpl!!.playlistManager.currentProgress
325
+ if (progress != null) {
326
+ position = progress.position
327
+ }
272
328
 
273
- val seekPosition = (call.getInt("position", (position / 1000.0f).toInt())!! * 1000.0).toLong()
329
+ val seekPosition =
330
+ (call.getInt("position", (position / 1000.0f).toInt())!! * 1000.0).toLong()
274
331
 
275
- val isPlaying: Boolean? = audioPlayerImpl!!.playlistManager.playlistHandler?.currentMediaPlayer?.isPlaying
276
- audioPlayerImpl!!.playlistManager.playlistHandler?.seek(seekPosition)
277
- if (isPlaying === null || !isPlaying) {
278
- audioPlayerImpl!!.playlistManager.playlistHandler?.pause(false)
279
- }
332
+ val isPlaying: Boolean? =
333
+ audioPlayerImpl!!.playlistManager.playlistHandler?.currentMediaPlayer?.isPlaying
334
+ audioPlayerImpl!!.playlistManager.playlistHandler?.seek(seekPosition)
335
+ if (isPlaying === null || !isPlaying) {
336
+ audioPlayerImpl!!.playlistManager.playlistHandler?.pause(false)
337
+ }
280
338
 
281
- call.resolve()
339
+ call.resolve()
282
340
 
283
- Log.i(TAG,"seekTo")
341
+ Log.i(TAG, "seekTo")
342
+ }
284
343
  }
285
344
 
286
345
  @PluginMethod
287
346
  fun setPlaybackRate(call: PluginCall) {
288
- val speed = call.getFloat("rate", audioPlayerImpl!!.playlistManager.getPlaybackSpeed())!!
289
- audioPlayerImpl!!.playlistManager.setPlaybackSpeed(speed)
347
+ Handler(Looper.getMainLooper()).post {
348
+ val speed =
349
+ call.getFloat("rate", audioPlayerImpl!!.playlistManager.getPlaybackSpeed())!!
350
+ audioPlayerImpl!!.playlistManager.setPlaybackSpeed(speed)
290
351
 
291
- call.resolve()
352
+ call.resolve()
292
353
 
293
- Log.i(TAG,"setPlaybackRate")
354
+ Log.i(TAG, "setPlaybackRate")
355
+ }
294
356
  }
295
357
 
296
358
  @PluginMethod
297
359
  fun setVolume(call: PluginCall) {
298
- val volume = call.getFloat("volume", audioPlayerImpl!!.volume)!!
299
- audioPlayerImpl!!.volume = volume
360
+ Handler(Looper.getMainLooper()).post {
361
+ val volume = call.getFloat("volume", audioPlayerImpl!!.volume)!!
362
+ audioPlayerImpl!!.volume = volume
300
363
 
301
- call.resolve()
364
+ call.resolve()
302
365
 
303
- Log.i(TAG,"addItem")
366
+ Log.i(TAG, "addItem")
367
+ }
304
368
  }
305
369
 
306
370
  override fun handleOnDestroy() {
@@ -4,6 +4,9 @@ import android.util.Log;
4
4
 
5
5
  import androidx.annotation.NonNull;
6
6
  import androidx.annotation.Nullable;
7
+ import androidx.annotation.OptIn;
8
+ import androidx.media3.common.util.UnstableApi;
9
+ import androidx.media3.exoplayer.ExoPlaybackException;
7
10
 
8
11
  import com.devbrackets.android.exomedia.listener.OnErrorListener;
9
12
  import com.devbrackets.android.playlistcore.data.MediaProgress;
@@ -12,7 +15,6 @@ import com.devbrackets.android.playlistcore.data.PlaylistItemChange;
12
15
  import com.devbrackets.android.playlistcore.listener.PlaybackStatusListener;
13
16
  import com.devbrackets.android.playlistcore.listener.PlaylistListener;
14
17
  import com.devbrackets.android.playlistcore.listener.ProgressListener;
15
- import com.google.android.exoplayer2.ExoPlaybackException;
16
18
 
17
19
  import org.dwbn.plugins.playlist.data.AudioTrack;
18
20
  import org.dwbn.plugins.playlist.manager.MediaControlsListener;
@@ -142,7 +144,7 @@ public class RmxAudioPlayer implements PlaybackStatusListener<AudioTrack>,
142
144
  onStatus(RmxAudioStatusMessage.RMX_STATUS_SKIP_FORWARD, trackId, param);
143
145
  }
144
146
 
145
- @Override
147
+ @OptIn(markerClass = UnstableApi.class) @Override
146
148
  public boolean onError(Exception e) {
147
149
  String errorMsg = e.toString();
148
150
  RmxAudioErrorType errorType = RmxAudioErrorType.RMXERR_NONE_SUPPORTED;
@@ -48,9 +48,10 @@ class PlaylistManager(application: Application) :
48
48
  val isPlaying: Boolean
49
49
  get() = playlistHandler != null && playlistHandler!!.currentMediaPlayer != null && playlistHandler!!.currentMediaPlayer!!.isPlaying
50
50
 
51
- override fun onError(e: Exception): Boolean {
52
- Log.i(TAG, "onError: $e")
53
- if (errorListener.get() != null) {
51
+ override fun onError(e: Exception?): Boolean {
52
+
53
+ if (e != null && errorListener.get() != null) {
54
+ Log.i(TAG, "onError: $e")
54
55
  errorListener.get()!!.onError(e)
55
56
  }
56
57
  return true
@@ -77,10 +78,10 @@ class PlaylistManager(application: Application) :
77
78
  override operator fun next(): AudioTrack? {
78
79
  if (isNextAvailable) {
79
80
  val isAtEnd = currentPosition + 1 >= itemCount
80
- if (isAtEnd && loop) {
81
- currentPosition = 0
81
+ currentPosition = if (isAtEnd && loop) {
82
+ 0
82
83
  } else {
83
- currentPosition = (currentPosition + 1).coerceAtMost(itemCount)
84
+ (currentPosition + 1).coerceAtMost(itemCount)
84
85
  }
85
86
  } else {
86
87
  if (loop) {
@@ -283,4 +284,5 @@ class PlaylistManager(application: Application) :
283
284
  setParameters(audioTracks, 0)
284
285
  options = Options(application.baseContext)
285
286
  }
287
+
286
288
  }
@@ -6,10 +6,12 @@ import android.net.Uri
6
6
  import android.os.PowerManager
7
7
  import androidx.annotation.FloatRange
8
8
  import androidx.annotation.IntRange
9
+ import androidx.media3.common.AudioAttributes
10
+ import androidx.media3.common.C
11
+ import androidx.media3.exoplayer.util.EventLogger
9
12
  import com.devbrackets.android.exomedia.AudioPlayer
10
13
  import com.devbrackets.android.exomedia.listener.OnErrorListener
11
14
  import com.devbrackets.android.playlistcore.manager.BasePlaylistManager
12
- import com.google.android.exoplayer2.util.EventLogger
13
15
  import org.dwbn.plugins.playlist.data.AudioTrack
14
16
  import java.lang.ref.WeakReference
15
17
  import java.util.concurrent.locks.ReentrantLock
@@ -42,8 +44,8 @@ class AudioApi(context: Context) : BaseMediaApi() {
42
44
  audioPlayer.setOnSeekCompletionListener(this)
43
45
  audioPlayer.setOnBufferUpdateListener(this)
44
46
 
45
- audioPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
46
- audioPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
47
+ audioPlayer.setWakeLevel(PowerManager.PARTIAL_WAKE_LOCK)
48
+ audioPlayer.setAudioAttributes(getAudioAttributes(C.USAGE_MEDIA, C.AUDIO_CONTENT_TYPE_MUSIC))
47
49
  audioPlayer.setAnalyticsListener(EventLogger(null))
48
50
  }
49
51
 
@@ -56,7 +58,7 @@ class AudioApi(context: Context) : BaseMediaApi() {
56
58
  }
57
59
 
58
60
  override fun stop() {
59
- audioPlayer.stopPlayback()
61
+ audioPlayer.stop()
60
62
  }
61
63
 
62
64
  override fun reset() {
@@ -68,7 +70,7 @@ class AudioApi(context: Context) : BaseMediaApi() {
68
70
  }
69
71
 
70
72
  override fun setVolume(@FloatRange(from = 0.0, to = 1.0) left: Float, @FloatRange(from = 0.0, to = 1.0) right: Float) {
71
- audioPlayer.setVolume(left, right)
73
+ audioPlayer.volume = (left + right) / 2
72
74
  }
73
75
 
74
76
  override fun seekTo(@IntRange(from = 0L) milliseconds: Long) {
@@ -79,23 +81,30 @@ class AudioApi(context: Context) : BaseMediaApi() {
79
81
  return item.mediaType == BasePlaylistManager.AUDIO
80
82
  }
81
83
 
82
- fun setPlaybackSpeed(@FloatRange(from = 0.0, to = 1.0) speed: Float) {
83
- audioPlayer.playbackSpeed = speed
84
- }
85
84
  override fun playItem(item: AudioTrack) {
86
85
  try {
87
- prepared = false
88
86
  bufferPercent = 0
89
- audioPlayer.setDataSource(Uri.parse(if (item.downloaded) item.downloadedMediaUri else item.mediaUrl))
90
- audioPlayer.prepareAsync()
87
+ audioPlayer.setMedia(Uri.parse(if (item.downloaded) item.downloadedMediaUri else item.mediaUrl))
91
88
  } catch (e: Exception) {
92
89
  //Purposefully left blank
93
90
  }
94
91
  }
95
92
 
93
+ fun setPlaybackSpeed(@FloatRange(from = 0.0, to = 1.0) speed: Float) {
94
+ audioPlayer.setPlaybackSpeed(speed)
95
+ }
96
+
96
97
  fun addErrorListener(listener: OnErrorListener) {
97
98
  errorListenersLock.lock()
98
99
  errorListeners.add(WeakReference<OnErrorListener>(listener))
99
100
  errorListenersLock.unlock()
100
101
  }
102
+
103
+ @Suppress("SameParameterValue")
104
+ private fun getAudioAttributes(@C.AudioUsage usage: Int, @C.AudioContentType contentType: Int): AudioAttributes {
105
+ return AudioAttributes.Builder()
106
+ .setUsage(usage)
107
+ .setContentType(contentType)
108
+ .build()
109
+ }
101
110
  }