@javascriptcommon/react-native-track-player 1.2.9 → 1.2.24

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 (131) hide show
  1. package/android/build.gradle +61 -4
  2. package/android/src/main/AndroidManifest.xml +2 -4
  3. package/android/src/main/ic_home-playstore.png +0 -0
  4. package/android/src/main/ic_repeat-playstore.png +0 -0
  5. package/android/src/main/ic_repeat_50-playstore.png +0 -0
  6. package/android/src/main/ic_shuffle-playstore.png +0 -0
  7. package/android/src/main/ic_shuffle_50-playstore.png +0 -0
  8. package/android/src/main/ic_shuffle_sm-playstore.png +0 -0
  9. package/android/src/main/ic_stop-playstore.png +0 -0
  10. package/android/src/main/ic_test-playstore.png +0 -0
  11. package/android/src/main/java/com/guichaguri/trackplayer/{service/HeadlessJsMediaService.java → HeadlessJsMediaService.java} +83 -32
  12. package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.kt +25 -0
  13. package/android/src/main/java/com/guichaguri/trackplayer/extensions/AudioPlayerStateExt.kt +19 -0
  14. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/EventHolder.kt +30 -0
  15. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/NotificationEventHolder.kt +20 -0
  16. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/PlayerEventHolder.kt +111 -0
  17. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AAMediaSessionCallback.kt +10 -0
  18. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioContentType.kt +10 -0
  19. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItem.kt +66 -0
  20. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItemTransitionReason.kt +33 -0
  21. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioPlayerState.kt +30 -0
  22. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/BufferConfig.kt +8 -0
  23. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/CacheConfig.kt +17 -0
  24. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/Capability.kt +19 -0
  25. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/FocusChangeData.kt +3 -0
  26. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/MediaSessionCallback.kt +17 -0
  27. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationConfig.kt +43 -0
  28. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationMetadata.kt +8 -0
  29. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationState.kt +8 -0
  30. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayWhenReadyChangeData.kt +5 -0
  31. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackEndedReason.kt +5 -0
  32. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackError.kt +6 -0
  33. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackMetadata.kt +200 -0
  34. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerConfig.kt +33 -0
  35. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerOptions.kt +9 -0
  36. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PositionChangedReason.kt +39 -0
  37. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/QueuedPlayerOptions.kt +49 -0
  38. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/notification/NotificationManager.kt +678 -0
  39. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/AudioPlayer.kt +10 -0
  40. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/BaseAudioPlayer.kt +864 -0
  41. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/QueuedAudioPlayer.kt +269 -0
  42. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/MediaSourceExt.kt +35 -0
  43. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/PlayerCache.kt +26 -0
  44. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/utils/Utils.kt +12 -0
  45. package/android/src/main/java/com/guichaguri/trackplayer/model/MetadataAdapter.kt +224 -0
  46. package/android/src/main/java/com/guichaguri/trackplayer/model/State.kt +13 -0
  47. package/android/src/main/java/com/guichaguri/trackplayer/model/Track.kt +120 -0
  48. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackAudioItem.kt +19 -0
  49. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackType.kt +11 -0
  50. package/android/src/main/java/com/guichaguri/trackplayer/module/AutoConnectionDetector.kt +151 -0
  51. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.kt +66 -0
  52. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.kt +1192 -0
  53. package/android/src/main/java/com/guichaguri/trackplayer/service/BundleUtils.kt +117 -0
  54. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.kt +31 -0
  55. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.kt +347 -0
  56. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.kt +1268 -0
  57. package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.kt +228 -0
  58. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.kt +141 -0
  59. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.kt +396 -0
  60. package/android/src/main/res/drawable-hdpi/ic_home.png +0 -0
  61. package/android/src/main/res/drawable-mdpi/ic_home.png +0 -0
  62. package/android/src/main/res/drawable-xhdpi/ic_home.png +0 -0
  63. package/android/src/main/res/drawable-xxhdpi/ic_home.png +0 -0
  64. package/android/src/main/res/drawable-xxxhdpi/ic_home.png +0 -0
  65. package/android/src/main/res/mipmap-hdpi/ic_arrow_down_circle_foreground.png +0 -0
  66. package/android/src/main/res/mipmap-hdpi/ic_clock_now_foreground.png +0 -0
  67. package/android/src/main/res/mipmap-hdpi/ic_close_foreground.png +0 -0
  68. package/android/src/main/res/mipmap-hdpi/ic_heart_foreground.png +0 -0
  69. package/android/src/main/res/mipmap-hdpi/ic_heart_outlined_foreground.png +0 -0
  70. package/android/src/main/res/mipmap-hdpi/ic_repeat_off_foreground.png +0 -0
  71. package/android/src/main/res/mipmap-hdpi/ic_repeat_on_foreground.png +0 -0
  72. package/android/src/main/res/mipmap-hdpi/ic_shuffle_off_foreground.png +0 -0
  73. package/android/src/main/res/mipmap-hdpi/ic_shuffle_on_foreground.png +0 -0
  74. package/android/src/main/res/mipmap-mdpi/ic_arrow_down_circle_foreground.png +0 -0
  75. package/android/src/main/res/mipmap-mdpi/ic_clock_now_foreground.png +0 -0
  76. package/android/src/main/res/mipmap-mdpi/ic_close_foreground.png +0 -0
  77. package/android/src/main/res/mipmap-mdpi/ic_heart_foreground.png +0 -0
  78. package/android/src/main/res/mipmap-mdpi/ic_heart_outlined_foreground.png +0 -0
  79. package/android/src/main/res/mipmap-mdpi/ic_repeat_off_foreground.png +0 -0
  80. package/android/src/main/res/mipmap-mdpi/ic_repeat_on_foreground.png +0 -0
  81. package/android/src/main/res/mipmap-mdpi/ic_shuffle_off_foreground.png +0 -0
  82. package/android/src/main/res/mipmap-mdpi/ic_shuffle_on_foreground.png +0 -0
  83. package/android/src/main/res/mipmap-xhdpi/ic_arrow_down_circle_foreground.png +0 -0
  84. package/android/src/main/res/mipmap-xhdpi/ic_clock_now_foreground.png +0 -0
  85. package/android/src/main/res/mipmap-xhdpi/ic_close_foreground.png +0 -0
  86. package/android/src/main/res/mipmap-xhdpi/ic_heart_foreground.png +0 -0
  87. package/android/src/main/res/mipmap-xhdpi/ic_heart_outlined_foreground.png +0 -0
  88. package/android/src/main/res/mipmap-xhdpi/ic_repeat_off_foreground.png +0 -0
  89. package/android/src/main/res/mipmap-xhdpi/ic_repeat_on_foreground.png +0 -0
  90. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_off_foreground.png +0 -0
  91. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_on_foreground.png +0 -0
  92. package/android/src/main/res/mipmap-xxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  93. package/android/src/main/res/mipmap-xxhdpi/ic_clock_now_foreground.png +0 -0
  94. package/android/src/main/res/mipmap-xxhdpi/ic_close_foreground.png +0 -0
  95. package/android/src/main/res/mipmap-xxhdpi/ic_heart_foreground.png +0 -0
  96. package/android/src/main/res/mipmap-xxhdpi/ic_heart_outlined_foreground.png +0 -0
  97. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_off_foreground.png +0 -0
  98. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_on_foreground.png +0 -0
  99. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_off_foreground.png +0 -0
  100. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_on_foreground.png +0 -0
  101. package/android/src/main/res/mipmap-xxxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  102. package/android/src/main/res/mipmap-xxxhdpi/ic_clock_now_foreground.png +0 -0
  103. package/android/src/main/res/mipmap-xxxhdpi/ic_close_foreground.png +0 -0
  104. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_foreground.png +0 -0
  105. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_outlined_foreground.png +0 -0
  106. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_off_foreground.png +0 -0
  107. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_on_foreground.png +0 -0
  108. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_off_foreground.png +0 -0
  109. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_on_foreground.png +0 -0
  110. package/android/src/main/res/raw/silent_5_seconds.mp3 +0 -0
  111. package/android/src/main/res/strings.xml +6 -0
  112. package/android/src/main/res/values/strings.xml +6 -0
  113. package/index.d.ts +62 -1
  114. package/lib/index.js +10 -9
  115. package/package.json +1 -1
  116. package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.java +0 -28
  117. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.java +0 -55
  118. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.java +0 -298
  119. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.java +0 -47
  120. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.java +0 -383
  121. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.java +0 -271
  122. package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.java +0 -243
  123. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.java +0 -148
  124. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.java +0 -379
  125. package/android/src/main/java/com/guichaguri/trackplayer/service/models/Track.java +0 -141
  126. package/android/src/main/java/com/guichaguri/trackplayer/service/models/TrackType.java +0 -35
  127. package/android/src/main/res/drawable-hdpi/ic_logo.png +0 -0
  128. package/android/src/main/res/drawable-mdpi/ic_logo.png +0 -0
  129. package/android/src/main/res/drawable-xhdpi/ic_logo.png +0 -0
  130. package/android/src/main/res/drawable-xxhdpi/ic_logo.png +0 -0
  131. package/android/src/main/res/drawable-xxxhdpi/ic_logo.png +0 -0
@@ -0,0 +1,269 @@
1
+ package com.guichaguri.trackplayer.kotlinaudio.players
2
+
3
+ import android.content.Context
4
+ import android.util.Log
5
+ import com.doublesymmetry.kotlinaudio.players.BaseAudioPlayer
6
+ import com.google.android.exoplayer2.C
7
+ import com.google.android.exoplayer2.IllegalSeekPositionException
8
+ import com.google.android.exoplayer2.source.MediaSource
9
+ import com.guichaguri.trackplayer.kotlinaudio.models.*
10
+ import java.util.*
11
+ import kotlin.math.max
12
+ import kotlin.math.min
13
+
14
+ class QueuedAudioPlayer(
15
+ context: Context,
16
+ playerConfig: PlayerConfig = PlayerConfig(),
17
+ bufferConfig: BufferConfig? = null,
18
+ cacheConfig: CacheConfig? = null,
19
+ mediaSessionCallback: AAMediaSessionCallBack
20
+ ) : BaseAudioPlayer(context, playerConfig, bufferConfig, cacheConfig, mediaSessionCallback) {
21
+ private val queue = LinkedList<MediaSource>()
22
+ override val playerOptions = DefaultQueuedPlayerOptions(exoPlayer)
23
+
24
+ // val currentIndex
25
+ // get() = exoPlayer.currentMediaItemIndex
26
+
27
+ val currentIndex = 0
28
+
29
+ override val currentItem: AudioItem?
30
+ get() = (queue.getOrNull(currentIndex)?.mediaItem?.localConfiguration?.tag as AudioItemHolder?)?.audioItem
31
+
32
+ val nextIndex: Int?
33
+ get() {
34
+ return if (exoPlayer.nextMediaItemIndex == C.INDEX_UNSET) null
35
+ else exoPlayer.nextMediaItemIndex
36
+ }
37
+
38
+ val previousIndex: Int?
39
+ get() {
40
+ return if (exoPlayer.previousMediaItemIndex == C.INDEX_UNSET) null
41
+ else exoPlayer.previousMediaItemIndex
42
+ }
43
+
44
+ val items: List<AudioItem>
45
+ get() = queue.map { (it.mediaItem.localConfiguration?.tag as AudioItemHolder).audioItem }
46
+
47
+ fun getQueueHead(): MediaSource? {
48
+ return if (queue.isNotEmpty()) {
49
+ queue.peek()
50
+ } else {
51
+ null
52
+ }
53
+ }
54
+
55
+ fun getQueueSize(): Int {
56
+ return queue.size
57
+ }
58
+
59
+ val previousItems: List<AudioItem>
60
+ get() {
61
+ return if (queue.isEmpty()) emptyList()
62
+ else queue
63
+ .subList(0, exoPlayer.currentMediaItemIndex)
64
+ .map { (it.mediaItem.localConfiguration?.tag as AudioItemHolder).audioItem }
65
+ }
66
+
67
+ val nextItems: List<AudioItem>
68
+ get() {
69
+ return if (queue.isEmpty()) emptyList()
70
+ else queue
71
+ .subList(exoPlayer.currentMediaItemIndex, queue.lastIndex)
72
+ .map { (it.mediaItem.localConfiguration?.tag as AudioItemHolder).audioItem }
73
+ }
74
+
75
+ val nextItem: AudioItem?
76
+ get() = items.getOrNull(currentIndex + 1)
77
+
78
+ val previousItem: AudioItem?
79
+ get() = items.getOrNull(currentIndex - 1)
80
+
81
+ override fun load(item: AudioItem, playWhenReady: Boolean) {
82
+ exoPlayer.playWhenReady = playWhenReady
83
+ load(item)
84
+ }
85
+
86
+ override fun load(item: AudioItem) {
87
+ if (queue.isEmpty()) {
88
+ add(item)
89
+ } else {
90
+ val mediaSource = getMediaSourceFromAudioItem(item)
91
+ queue[currentIndex] = mediaSource
92
+ exoPlayer.addMediaSource(currentIndex + 1, mediaSource)
93
+ exoPlayer.removeMediaItem(currentIndex)
94
+ exoPlayer.prepare()
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Add a single item to the queue. If the AudioPlayer has no item loaded, it will load the `item`.
100
+ * @param item The [AudioItem] to add.
101
+ */
102
+ fun add(item: AudioItem, playWhenReady: Boolean) {
103
+ exoPlayer.playWhenReady = playWhenReady
104
+ add(item)
105
+ }
106
+
107
+ /**
108
+ * Add a single item to the queue. If the AudioPlayer has no item loaded, it will load the `item`.
109
+ * @param item The [AudioItem] to add.
110
+ * @param playWhenReady Whether playback starts automatically.
111
+ */
112
+ fun add(item: AudioItem) {
113
+ val mediaSource = getMediaSourceFromAudioItem(item)
114
+ queue.add(mediaSource)
115
+ exoPlayer.addMediaSource(mediaSource)
116
+ exoPlayer.prepare()
117
+ }
118
+
119
+ /**
120
+ * Add multiple items to the queue. If the AudioPlayer has no item loaded, it will load the first item in the list.
121
+ * @param items The [AudioItem]s to add.
122
+ * @param playWhenReady Whether playback starts automatically.
123
+ */
124
+ fun add(items: List<AudioItem>, playWhenReady: Boolean) {
125
+ exoPlayer.playWhenReady = playWhenReady
126
+ add(items)
127
+ }
128
+
129
+ /**
130
+ * Add multiple items to the queue. If the AudioPlayer has no item loaded, it will load the first item in the list.
131
+ * @param items The [AudioItem]s to add.
132
+ */
133
+ fun add(items: List<AudioItem>) {
134
+ val mediaSources = items.map { getMediaSourceFromAudioItem(it) }
135
+ queue.addAll(mediaSources)
136
+ exoPlayer.addMediaSources(mediaSources)
137
+ exoPlayer.prepare()
138
+ }
139
+
140
+ /**
141
+ * Add multiple items to the queue.
142
+ * @param items The [AudioItem]s to add.
143
+ * @param atIndex Index to insert items at, if no items loaded this will not automatically start playback.
144
+ */
145
+ fun add(items: List<AudioItem>, atIndex: Int) {
146
+ val mediaSources = items.map { getMediaSourceFromAudioItem(it) }
147
+ queue.addAll(atIndex, mediaSources)
148
+ exoPlayer.addMediaSources(atIndex, mediaSources)
149
+ exoPlayer.prepare()
150
+ }
151
+
152
+ /**
153
+ * Remove an item from the queue.
154
+ * @param index The index of the item to remove.
155
+ */
156
+ fun remove(index: Int) {
157
+ queue.removeAt(index)
158
+ exoPlayer.removeMediaItem(index)
159
+ }
160
+
161
+ /**
162
+ * Remove items from the queue.
163
+ * @param indexes The indexes of the items to remove.
164
+ */
165
+ fun remove(indexes: List<Int>) {
166
+ var sorted = indexes.toList()
167
+ // Sort the indexes in descending order so we can safely remove them one by one
168
+ // without having the next index possibly newly pointing to another item than intended:
169
+ Collections.sort(sorted, Collections.reverseOrder());
170
+ sorted.forEach {
171
+ remove(it)
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Skip to the next item in the queue, which may depend on the current repeat mode.
177
+ * Does nothing if there is no next item to skip to.
178
+ */
179
+ fun next() {
180
+ exoPlayer.seekToNextMediaItem()
181
+ exoPlayer.prepare()
182
+ }
183
+
184
+ /**
185
+ * Skip to the previous item in the queue, which may depend on the current repeat mode.
186
+ * Does nothing if there is no previous item to skip to.
187
+ */
188
+ fun previous() {
189
+ exoPlayer.seekToPreviousMediaItem()
190
+ exoPlayer.prepare()
191
+ }
192
+
193
+ /**
194
+ * Move an item in the queue from one position to another.
195
+ * @param fromIndex The index of the item ot move.
196
+ * @param toIndex The index to move the item to. If the index is larger than the size of the queue, the item is moved to the end of the queue instead.
197
+ */
198
+ fun move(fromIndex: Int, toIndex: Int) {
199
+ exoPlayer.moveMediaItem(fromIndex, toIndex)
200
+ var item = queue[fromIndex]
201
+ queue.removeAt(fromIndex)
202
+ queue.add(max(0, min(items.size, if (toIndex > fromIndex) toIndex else toIndex - 1)), item)
203
+ }
204
+
205
+ /**
206
+ * Jump to an item in the queue.
207
+ * @param index the index to jump to
208
+ * @param playWhenReady Whether playback starts automatically.
209
+ */
210
+ fun jumpToItem(index: Int, playWhenReady: Boolean) {
211
+ exoPlayer.playWhenReady = playWhenReady
212
+ jumpToItem(index)
213
+ }
214
+
215
+ /**
216
+ * Jump to an item in the queue.
217
+ * @param index the index to jump to
218
+ */
219
+ fun jumpToItem(index: Int) {
220
+ try {
221
+ exoPlayer.seekTo(index, C.TIME_UNSET)
222
+ exoPlayer.prepare()
223
+ } catch (e: IllegalSeekPositionException) {
224
+ throw Error("This item index $index does not exist. The size of the queue is ${queue.size} items.")
225
+ }
226
+ }
227
+
228
+ /**
229
+ * Replaces item at index in queue.
230
+ * If updating current index, we update the notification metadata if [automaticallyUpdateNotificationMetadata] is true.
231
+ */
232
+ fun replaceItem(index: Int, item: AudioItem) {
233
+ val mediaSource = getMediaSourceFromAudioItem(item)
234
+ queue[index] = mediaSource
235
+ if (index == currentIndex) {
236
+ updateNotificationMetadataIfAutomatic(item)
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Removes all the upcoming items, if any (the ones returned by [next]).
242
+ */
243
+ fun removeUpcomingItems() {
244
+ if (queue.lastIndex == -1 || currentIndex == -1) return
245
+ val lastIndex = queue.lastIndex + 1
246
+ val fromIndex = currentIndex + 1
247
+
248
+ exoPlayer.removeMediaItems(fromIndex, lastIndex)
249
+ queue.subList(fromIndex, lastIndex).clear()
250
+ }
251
+
252
+ /**
253
+ * Removes all the previous items, if any (the ones returned by [previous]).
254
+ */
255
+ fun removePreviousItems() {
256
+ exoPlayer.removeMediaItems(0, currentIndex)
257
+ queue.subList(0, currentIndex).clear()
258
+ }
259
+
260
+ override fun destroy() {
261
+ queue.clear()
262
+ super.destroy()
263
+ }
264
+
265
+ override fun clear() {
266
+ queue.clear()
267
+ super.clear()
268
+ }
269
+ }
@@ -0,0 +1,35 @@
1
+ package com.guichaguri.trackplayer.kotlinaudio.players.components
2
+
3
+ import android.support.v4.media.MediaMetadataCompat
4
+ import android.support.v4.media.RatingCompat
5
+ import android.util.Log
6
+ import com.guichaguri.trackplayer.kotlinaudio.models.AudioItemHolder
7
+ import com.google.android.exoplayer2.source.MediaSource
8
+
9
+ fun MediaSource.getMediaMetadataCompat(): MediaMetadataCompat {
10
+ val audioItem = (mediaItem.localConfiguration?.tag as AudioItemHolder?)?.audioItem
11
+ val metadata = mediaItem.mediaMetadata
12
+ val title = metadata.title ?: audioItem?.title
13
+ val artist = metadata.artist ?: audioItem?.artist
14
+ val albumTitle = metadata.albumTitle ?: audioItem?.albumTitle
15
+ val genre = metadata.genre
16
+ val duration = audioItem?.duration ?: -1
17
+ val artwork = metadata.artworkUri ?: audioItem?.artwork
18
+ val rating = RatingCompat.fromRating(metadata.userRating)
19
+
20
+ return MediaMetadataCompat.Builder().apply {
21
+ putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist.toString())
22
+ putString(MediaMetadataCompat.METADATA_KEY_TITLE, title.toString())
23
+ putString(MediaMetadataCompat.METADATA_KEY_ALBUM, albumTitle.toString())
24
+ putString(MediaMetadataCompat.METADATA_KEY_GENRE, genre.toString())
25
+ putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration)
26
+
27
+ if (artwork != null) {
28
+ putString(MediaMetadataCompat.METADATA_KEY_ART_URI, artwork.toString())
29
+ }
30
+
31
+ if (rating != null) {
32
+ putRating(MediaMetadataCompat.METADATA_KEY_RATING, rating)
33
+ }
34
+ }.build()
35
+ }
@@ -0,0 +1,26 @@
1
+ package com.guichaguri.trackplayer.kotlinaudio.players.components
2
+
3
+ import android.content.Context
4
+ import com.guichaguri.trackplayer.kotlinaudio.models.CacheConfig
5
+ import com.google.android.exoplayer2.database.DatabaseProvider
6
+ import com.google.android.exoplayer2.database.StandaloneDatabaseProvider
7
+ import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor
8
+ import com.google.android.exoplayer2.upstream.cache.SimpleCache
9
+ import java.io.File
10
+
11
+ object PlayerCache {
12
+ @Volatile
13
+ private var instance: SimpleCache? = null
14
+
15
+ fun getInstance(context: Context, cacheConfig: CacheConfig): SimpleCache? {
16
+ val cacheDir = File(context.cacheDir, cacheConfig.identifier)
17
+ val db: DatabaseProvider = StandaloneDatabaseProvider(context)
18
+
19
+ instance ?: synchronized(this) {
20
+ instance ?: SimpleCache(cacheDir, LeastRecentlyUsedCacheEvictor(cacheConfig.maxCacheSize ?: 0), db)
21
+ .also { instance = it }
22
+ }
23
+
24
+ return instance
25
+ }
26
+ }
@@ -0,0 +1,12 @@
1
+ package com.guichaguri.trackplayer.kotlinaudio.utils
2
+
3
+ import android.content.ContentResolver
4
+ import android.net.Uri
5
+ import com.google.android.exoplayer2.upstream.RawResourceDataSource
6
+
7
+ fun isUriLocal(uri: Uri?): Boolean {
8
+ if (uri == null) return false
9
+ val scheme = uri.scheme
10
+ val host = uri.host
11
+ return scheme == null || scheme == ContentResolver.SCHEME_FILE || scheme == ContentResolver.SCHEME_ANDROID_RESOURCE || scheme == ContentResolver.SCHEME_CONTENT || scheme == RawResourceDataSource.RAW_RESOURCE_SCHEME || scheme == "res" || host == null || host == "localhost" || host == "127.0.0.1" || host == "[::1]"
12
+ }
@@ -0,0 +1,224 @@
1
+ package com.guichaguri.trackplayer.model
2
+
3
+ import android.os.Bundle
4
+ import com.google.android.exoplayer2.MediaMetadata
5
+ import com.google.android.exoplayer2.metadata.Metadata
6
+ import com.google.android.exoplayer2.metadata.flac.VorbisComment
7
+ import com.google.android.exoplayer2.metadata.icy.IcyHeaders
8
+ import com.google.android.exoplayer2.metadata.icy.IcyInfo
9
+ import com.google.android.exoplayer2.metadata.id3.ChapterFrame
10
+ import com.google.android.exoplayer2.metadata.id3.TextInformationFrame
11
+ import com.google.android.exoplayer2.metadata.id3.UrlLinkFrame
12
+ import com.google.android.exoplayer2.metadata.mp4.MdtaMetadataEntry
13
+ import timber.log.Timber
14
+
15
+ sealed class MetadataAdapter {
16
+ companion object {
17
+ fun fromMetadata(metadata: Metadata): List<Bundle> {
18
+ val group = mutableListOf<Bundle>()
19
+
20
+ (0 until metadata.length()).forEach { i ->
21
+ group.add(Bundle().apply {
22
+ val rawEntries = mutableListOf<Bundle>()
23
+
24
+ when (val entry = metadata[i]) {
25
+ is ChapterFrame -> {
26
+ Timber.d("ChapterFrame: ${entry.id}")
27
+ }
28
+ is TextInformationFrame -> {
29
+ val rawEntry = Bundle()
30
+
31
+ when (entry.id.uppercase()) {
32
+ "TIT2", "TT2" -> {
33
+ putString("title", entry.value)
34
+ rawEntry.putString("commonKey", "title")
35
+ }
36
+ "TALB", "TOAL", "TAL" -> {
37
+ putString("albumName", entry.value)
38
+ rawEntry.putString("commonKey", "albumName")
39
+ }
40
+ "TOPE", "TPE1", "TP1" -> {
41
+ putString("artist", entry.value)
42
+ rawEntry.putString("commonKey", "artist")
43
+ }
44
+ "TDRC", "TOR" -> {
45
+ putString("creationDate", entry.value)
46
+ rawEntry.putString("commonKey", "creationDate")
47
+ }
48
+ "TCON", "TCO" -> {
49
+ putString("genre", entry.value)
50
+ rawEntry.putString("commonKey", "genre")
51
+ }
52
+ }
53
+
54
+ rawEntry.putString("key", entry.id.uppercase())
55
+ rawEntry.putString("keySpace", "org.id3")
56
+ rawEntry.putString("value", entry.value)
57
+ rawEntry.putString("time", "-1")
58
+ rawEntries.add(rawEntry)
59
+ }
60
+
61
+ is UrlLinkFrame -> {
62
+ rawEntries.add(Bundle().apply {
63
+ putString("value", entry.url)
64
+ putString("key", entry.id.uppercase())
65
+ putString("keySpace", "org.id3")
66
+ putString("time", "-1")
67
+ })
68
+ }
69
+
70
+ is IcyHeaders -> {
71
+ putString("title", entry.name)
72
+ putString("genre", entry.genre)
73
+
74
+ rawEntries.add(Bundle().apply {
75
+ putString("value", entry.name)
76
+ putString("commonKey", "title")
77
+ putString("key", "StreamTitle")
78
+ putString("keySpace", "icy")
79
+ putString("time", "-1")
80
+ })
81
+
82
+ rawEntries.add(Bundle().apply {
83
+ putString("value", entry.url)
84
+ putString("key", "StreamURL")
85
+ putString("keySpace", "icy")
86
+ putString("time", "-1")
87
+ })
88
+
89
+ rawEntries.add(Bundle().apply {
90
+ putString("value", entry.genre)
91
+ putString("commonKey", "genre")
92
+ putString("key", "StreamGenre")
93
+ putString("keySpace", "icy")
94
+ putString("time", "-1")
95
+ })
96
+ }
97
+
98
+ is IcyInfo -> {
99
+ putString("title", entry.title)
100
+
101
+ rawEntries.add(Bundle().apply {
102
+ putString("value", entry.url)
103
+ putString("key", "StreamURL")
104
+ putString("keySpace", "icy")
105
+ putString("time", "-1")
106
+ })
107
+
108
+ rawEntries.add(Bundle().apply {
109
+ putString("value", entry.title)
110
+ putString("commonKey", "title")
111
+ putString("key", "StreamTitle")
112
+ putString("keySpace", "icy")
113
+ putString("time", "-1")
114
+ })
115
+ }
116
+
117
+ is VorbisComment -> {
118
+ val rawEntry = Bundle()
119
+
120
+ when (entry.key) {
121
+ "TITLE" -> {
122
+ putString("title", entry.value)
123
+ rawEntry.putString("commonKey", "title")
124
+ }
125
+ "ARTIST" -> {
126
+ putString("artist", entry.value)
127
+ rawEntry.putString("commonKey", "artist")
128
+ }
129
+ "ALBUM" -> {
130
+ putString("albumName", entry.value)
131
+ rawEntry.putString("commonKey", "albumName")
132
+ }
133
+ "DATE" -> {
134
+ putString("creationDate", entry.value)
135
+ rawEntry.putString("commonKey", "creationDate")
136
+ }
137
+ "GENRE" -> {
138
+ putString("genre", entry.value)
139
+ rawEntry.putString("commonKey", "genre")
140
+ }
141
+ "URL" -> {
142
+ putString("url", entry.value)
143
+ }
144
+ }
145
+
146
+ rawEntry.putString("key", entry.key)
147
+ rawEntry.putString("keySpace", "org.vorbis")
148
+ rawEntry.putString("value", entry.value)
149
+ rawEntry.putString("time", "-1")
150
+ rawEntries.add(rawEntry)
151
+ }
152
+
153
+ is MdtaMetadataEntry -> {
154
+ val rawEntry = Bundle()
155
+ when (entry.key) {
156
+ "com.apple.quicktime.title" -> {
157
+ putString("title", entry.value.toString())
158
+ rawEntry.putString("commonKey", "title")
159
+ }
160
+ "com.apple.quicktime.artist" -> {
161
+ putString("artist", entry.value.toString())
162
+ rawEntry.putString("commonKey", "artist")
163
+ }
164
+ "com.apple.quicktime.album" -> {
165
+ putString("albumName", entry.value.toString())
166
+ rawEntry.putString("commonKey", "albumName")
167
+ }
168
+ "com.apple.quicktime.creationdate" -> {
169
+ putString("creationDate", entry.value.toString())
170
+ rawEntry.putString("commonKey", "creationDate")
171
+ }
172
+ "com.apple.quicktime.genre" -> {
173
+ putString("genre", entry.value.toString())
174
+ rawEntry.putString("commonKey", "genre")
175
+ }
176
+ }
177
+
178
+ rawEntry.putString("key", entry.key.substringAfterLast("."))
179
+ rawEntry.putString("keySpace", "com.apple.quicktime")
180
+ rawEntry.putString("value", entry.value.toString())
181
+ rawEntry.putString("time", "-1")
182
+ rawEntries.add(rawEntry)
183
+ }
184
+ }
185
+
186
+ putParcelableArray("raw", rawEntries.toTypedArray())
187
+ })
188
+ }
189
+
190
+ return group
191
+ }
192
+
193
+ fun fromMediaMetadata(metadata: MediaMetadata): Bundle {
194
+ return Bundle().apply {
195
+ metadata.title?.let { putString("title", it.toString()) }
196
+ metadata.artist?.let { putString("artist", it.toString()) }
197
+ metadata.albumTitle?.let { putString("albumName", it.toString()) }
198
+ metadata.subtitle?.let { putString("subtitle", it.toString()) }
199
+ metadata.description?.let { putString("description", it.toString()) }
200
+ metadata.artworkUri?.let { putString("artworkUri", it.toString()) }
201
+ metadata.trackNumber?.let { putInt("trackNumber", it) }
202
+ metadata.composer?.let { putString("composer", it.toString()) }
203
+ metadata.conductor?.let { putString("conductor", it.toString()) }
204
+ metadata.genre?.let { putString("genre", it.toString()) }
205
+ metadata.compilation?.let { putString("compilation", it.toString()) }
206
+ metadata.station?.let { putString("station", it.toString()) }
207
+ // metadata.mediaType?.let { putInt("mediaType", it) }
208
+
209
+ // This is how SwiftAudioEx outputs it in the metadata dictionary
210
+ (metadata.recordingDay to metadata.recordingMonth).let { (day, month) ->
211
+ // if both are not null, combine them into a single string
212
+ if (day != null && month != null) {
213
+ putString("creationDate", "${String.format("%02d", day)}${String.format("%02d", month)}")
214
+ } else if (day != null) {
215
+ putString("creationDate", String.format("%02d", day))
216
+ } else if (month != null) {
217
+ putString("creationDate", String.format("%02d", month))
218
+ }
219
+ }
220
+ metadata.recordingYear?.let { putString("creationYear", it.toString()) }
221
+ }
222
+ }
223
+ }
224
+ }
@@ -0,0 +1,13 @@
1
+ package com.guichaguri.trackplayer.model
2
+
3
+ enum class State(val state: String) {
4
+ Buffering("buffering"),
5
+ None("none"),
6
+ Ready("ready"),
7
+ Paused("paused"),
8
+ Stopped("stopped"),
9
+ Playing("playing"),
10
+ Loading("loading"),
11
+ Error("error"),
12
+ Ended("ended"),
13
+ }