Skip to content

Commit 56ada15

Browse files
committed
Improve seek/next previous performance with large playlists
1 parent 81e6f47 commit 56ada15

File tree

1 file changed

+47
-4
lines changed

1 file changed

+47
-4
lines changed

app/src/main/kotlin/com/simplemobiletools/musicplayer/playback/player/SimpleMusicPlayer.kt

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,19 @@ import androidx.media3.exoplayer.ExoPlayer
88
import androidx.media3.exoplayer.source.ShuffleOrder.DefaultShuffleOrder
99
import com.simplemobiletools.musicplayer.extensions.*
1010
import com.simplemobiletools.musicplayer.inlines.indexOfFirstOrNull
11+
import kotlinx.coroutines.*
1112

1213
private const val DEFAULT_SHUFFLE_ORDER_SEED = 42L
1314

1415
@UnstableApi
1516
class SimpleMusicPlayer(private val exoPlayer: ExoPlayer) : ForwardingPlayer(exoPlayer) {
1617

18+
private var seekToNextCount = 0
19+
private var seekToPreviousCount = 0
20+
21+
private val scope = CoroutineScope(Dispatchers.Default)
22+
private var seekJob: Job? = null
23+
1724
/**
1825
* The default implementation only advertises the seek to next and previous item in the case
1926
* that it's not the first or last track. We manually advertise that these
@@ -53,28 +60,32 @@ class SimpleMusicPlayer(private val exoPlayer: ExoPlayer) : ForwardingPlayer(exo
5360
override fun seekToNext() {
5461
play()
5562
if (!maybeForceNext()) {
56-
super.seekToNext()
63+
seekToNextCount += 1
64+
seekWithDelay()
5765
}
5866
}
5967

6068
override fun seekToPrevious() {
6169
play()
6270
if (!maybeForcePrevious()) {
63-
super.seekToPrevious()
71+
seekToPreviousCount += 1
72+
seekWithDelay()
6473
}
6574
}
6675

6776
override fun seekToNextMediaItem() {
6877
play()
6978
if (!maybeForceNext()) {
70-
super.seekToNextMediaItem()
79+
seekToNextCount += 1
80+
seekWithDelay()
7181
}
7282
}
7383

7484
override fun seekToPreviousMediaItem() {
7585
play()
7686
if (!maybeForcePrevious()) {
77-
super.seekToPreviousMediaItem()
87+
seekToPreviousCount += 1
88+
seekWithDelay()
7889
}
7990
}
8091

@@ -122,4 +133,36 @@ class SimpleMusicPlayer(private val exoPlayer: ExoPlayer) : ForwardingPlayer(exo
122133
exoPlayer.setShuffleOrder(DefaultShuffleOrder(shuffledIndices.toIntArray(), DEFAULT_SHUFFLE_ORDER_SEED))
123134
}
124135
}
136+
137+
/**
138+
* This is here so the player can quickly seek next/previous without doing too much work.
139+
* It probably won't be needed once https://github.com/androidx/media/issues/81 is resolved.
140+
*/
141+
private fun seekWithDelay() {
142+
seekJob?.cancel()
143+
seekJob = scope.launch {
144+
delay(timeMillis = 400)
145+
if (seekToNextCount > 0 || seekToPreviousCount > 0) {
146+
runOnPlayerThread {
147+
if (currentMediaItem != null) {
148+
if (seekToNextCount > 0) {
149+
seekTo(rotateIndex(currentMediaItemIndex + seekToNextCount), 0)
150+
}
151+
152+
if (seekToPreviousCount > 0) {
153+
seekTo(rotateIndex(currentMediaItemIndex - seekToPreviousCount), 0)
154+
}
155+
156+
seekToNextCount = 0
157+
seekToPreviousCount = 0
158+
}
159+
}
160+
}
161+
}
162+
}
163+
164+
private fun rotateIndex(index: Int): Int {
165+
val count = mediaItemCount
166+
return (index % count + count) % count
167+
}
125168
}

0 commit comments

Comments
 (0)