mirror of
https://gitlab.com/ultrasonic/ultrasonic.git
synced 2025-05-01 08:01:34 +03:00
Finish
This commit is contained in:
parent
f9aac1ca43
commit
594e94eea7
@ -1,21 +1,21 @@
|
|||||||
package org.moire.ultrasonic.service
|
package org.moire.ultrasonic.service
|
||||||
|
|
||||||
import org.koin.core.component.KoinComponent
|
|
||||||
import org.koin.core.component.inject
|
|
||||||
import org.moire.ultrasonic.domain.MusicDirectory
|
|
||||||
import org.moire.ultrasonic.util.Util.isExternalStoragePresent
|
|
||||||
import org.moire.ultrasonic.util.Util.isNetworkConnected
|
|
||||||
import org.moire.ultrasonic.util.Util.getPreloadCount
|
|
||||||
import org.moire.ultrasonic.util.Util.getMaxSongs
|
|
||||||
import org.moire.ultrasonic.util.ShufflePlayBuffer
|
|
||||||
import timber.log.Timber
|
|
||||||
import org.moire.ultrasonic.domain.PlayerState
|
|
||||||
import org.moire.ultrasonic.util.LRUCache
|
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.PriorityQueue
|
import java.util.PriorityQueue
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.inject
|
||||||
|
import org.moire.ultrasonic.domain.MusicDirectory
|
||||||
|
import org.moire.ultrasonic.domain.PlayerState
|
||||||
|
import org.moire.ultrasonic.util.LRUCache
|
||||||
|
import org.moire.ultrasonic.util.ShufflePlayBuffer
|
||||||
|
import org.moire.ultrasonic.util.Util.getMaxSongs
|
||||||
|
import org.moire.ultrasonic.util.Util.getPreloadCount
|
||||||
|
import org.moire.ultrasonic.util.Util.isExternalStoragePresent
|
||||||
|
import org.moire.ultrasonic.util.Util.isNetworkConnected
|
||||||
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is responsible for maintaining the playlist and downloading
|
* This class is responsible for maintaining the playlist and downloading
|
||||||
@ -26,7 +26,7 @@ class Downloader(
|
|||||||
private val externalStorageMonitor: ExternalStorageMonitor,
|
private val externalStorageMonitor: ExternalStorageMonitor,
|
||||||
private val localMediaPlayer: LocalMediaPlayer
|
private val localMediaPlayer: LocalMediaPlayer
|
||||||
) : KoinComponent {
|
) : KoinComponent {
|
||||||
val playList: MutableList<DownloadFile> = ArrayList()
|
val playlist: MutableList<DownloadFile> = ArrayList()
|
||||||
private val downloadQueue: PriorityQueue<DownloadFile> = PriorityQueue<DownloadFile>()
|
private val downloadQueue: PriorityQueue<DownloadFile> = PriorityQueue<DownloadFile>()
|
||||||
private val activelyDownloading: MutableList<DownloadFile> = ArrayList()
|
private val activelyDownloading: MutableList<DownloadFile> = ArrayList()
|
||||||
|
|
||||||
@ -35,7 +35,8 @@ class Downloader(
|
|||||||
private val downloadFileCache = LRUCache<MusicDirectory.Entry, DownloadFile>(100)
|
private val downloadFileCache = LRUCache<MusicDirectory.Entry, DownloadFile>(100)
|
||||||
|
|
||||||
private var executorService: ScheduledExecutorService? = null
|
private var executorService: ScheduledExecutorService? = null
|
||||||
var downloadListUpdateRevision: Long = 0
|
|
||||||
|
var playlistUpdateRevision: Long = 0
|
||||||
private set
|
private set
|
||||||
|
|
||||||
val downloadChecker = Runnable {
|
val downloadChecker = Runnable {
|
||||||
@ -49,7 +50,9 @@ class Downloader(
|
|||||||
|
|
||||||
fun onCreate() {
|
fun onCreate() {
|
||||||
executorService = Executors.newSingleThreadScheduledExecutor()
|
executorService = Executors.newSingleThreadScheduledExecutor()
|
||||||
executorService!!.scheduleWithFixedDelay(downloadChecker, 5, 5, TimeUnit.SECONDS)
|
executorService!!.scheduleWithFixedDelay(
|
||||||
|
downloadChecker, CHECK_INTERVAL, CHECK_INTERVAL, TimeUnit.SECONDS
|
||||||
|
)
|
||||||
Timber.i("Downloader created")
|
Timber.i("Downloader created")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +84,47 @@ class Downloader(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the active downloads for failures or completions
|
// Check the active downloads for failures or completions and remove them
|
||||||
|
cleanupActiveDownloads()
|
||||||
|
|
||||||
|
// Check if need to preload more from playlist
|
||||||
|
val preloadCount = getPreloadCount()
|
||||||
|
|
||||||
|
// Start preloading at the current playing song
|
||||||
|
var start = currentPlayingIndex
|
||||||
|
if (start == -1) start = 0
|
||||||
|
|
||||||
|
val end = (start + preloadCount).coerceAtMost(playlist.size)
|
||||||
|
|
||||||
|
for (i in start until end) {
|
||||||
|
val download = playlist[i]
|
||||||
|
|
||||||
|
// Set correct priority (the lower the number, the higher the priority)
|
||||||
|
download.priority = i
|
||||||
|
|
||||||
|
// Add file to queue if not in one of the queues already.
|
||||||
|
if (!download.isWorkDone &&
|
||||||
|
!activelyDownloading.contains(download) &&
|
||||||
|
!downloadQueue.contains(download)
|
||||||
|
) {
|
||||||
|
downloadQueue.add(download)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill up active List with waiting tasks
|
||||||
|
while (activelyDownloading.size < PARALLEL_DOWNLOADS && downloadQueue.size > 0) {
|
||||||
|
val task = downloadQueue.remove()
|
||||||
|
activelyDownloading.add(task)
|
||||||
|
task.download()
|
||||||
|
|
||||||
|
// The next file on the playlist is currently downloading
|
||||||
|
if (playlist.indexOf(task) == 1) {
|
||||||
|
localMediaPlayer.setNextPlayerState(PlayerState.DOWNLOADING)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cleanupActiveDownloads() {
|
||||||
activelyDownloading.retainAll {
|
activelyDownloading.retainAll {
|
||||||
when {
|
when {
|
||||||
it.isDownloading -> true
|
it.isDownloading -> true
|
||||||
@ -96,138 +139,17 @@ class Downloader(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check if need to preload more from playlist
|
|
||||||
val preloadCount = getPreloadCount()
|
|
||||||
|
|
||||||
// Start preloading at the current playing song
|
|
||||||
var start = if (localMediaPlayer.currentPlaying == null) 0 else currentPlayingIndex
|
|
||||||
if (start == -1) start = 0
|
|
||||||
|
|
||||||
var end = (start + preloadCount).coerceAtMost(playList.size)
|
|
||||||
|
|
||||||
// Playlist also contains played songs!!!!
|
|
||||||
for (i in start until end) {
|
|
||||||
val download = playList[i]
|
|
||||||
|
|
||||||
// Set correct priority (the lower the number, the higher the priority)
|
|
||||||
download.priority = i
|
|
||||||
|
|
||||||
// Add file to queue if not in one of the queues already.
|
|
||||||
if (!download.isWorkDone && !activelyDownloading.contains(download) && !downloadQueue.contains(download)) {
|
|
||||||
downloadQueue.add(download)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Fill up active List with waiting tasks
|
|
||||||
while (activelyDownloading.size < PARALLEL_DOWNLOADS && downloadQueue.size > 0 ) {
|
|
||||||
val task = downloadQueue.remove()
|
|
||||||
activelyDownloading.add(task)
|
|
||||||
task.download()
|
|
||||||
|
|
||||||
// The next file on the playlist is currently downloading
|
|
||||||
// TODO: really necessary?
|
|
||||||
if (playList.indexOf(task) == 1) {
|
|
||||||
localMediaPlayer.setNextPlayerState(PlayerState.DOWNLOADING)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// fun oldStuff() {
|
|
||||||
// // Need to download current playing?
|
|
||||||
// if (localMediaPlayer.currentPlaying != null && localMediaPlayer.currentPlaying != currentDownloading && !localMediaPlayer.currentPlaying!!.isWorkDone) {
|
|
||||||
// // Cancel current download, if necessary.
|
|
||||||
// if (currentDownloading != null) {
|
|
||||||
// currentDownloading!!.cancelDownload()
|
|
||||||
// }
|
|
||||||
// currentDownloading = localMediaPlayer.currentPlaying
|
|
||||||
// currentDownloading!!.download()
|
|
||||||
// cleanupCandidates.add(currentDownloading)
|
|
||||||
//
|
|
||||||
// // Delete obsolete .partial and .complete files.
|
|
||||||
// cleanup()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Find a suitable target for download.
|
|
||||||
// if (currentDownloading != null &&
|
|
||||||
// !currentDownloading!!.isWorkDone &&
|
|
||||||
// (!currentDownloading!!.isFailed || playList.isEmpty() && backgroundDownloadList.isEmpty())
|
|
||||||
// ) {
|
|
||||||
// cleanup()
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // There is a target to download
|
|
||||||
// currentDownloading = null
|
|
||||||
// val n = playList.size
|
|
||||||
// var preloaded = 0
|
|
||||||
// if (n != 0) {
|
|
||||||
// var start = if (localMediaPlayer.currentPlaying == null) 0 else currentPlayingIndex
|
|
||||||
// if (start == -1) start = 0
|
|
||||||
// var i = start
|
|
||||||
// // Check all DownloadFiles on the playlist
|
|
||||||
// do {
|
|
||||||
// val downloadFile = playList[i]
|
|
||||||
// if (!downloadFile.isWorkDone) {
|
|
||||||
// if (downloadFile.shouldSave() || preloaded < getPreloadCount()) {
|
|
||||||
// currentDownloading = downloadFile
|
|
||||||
// currentDownloading!!.download()
|
|
||||||
// cleanupCandidates.add(currentDownloading)
|
|
||||||
// if (i == start + 1) {
|
|
||||||
// // The next file on the playlist is currently downloading
|
|
||||||
// localMediaPlayer.setNextPlayerState(PlayerState.DOWNLOADING)
|
|
||||||
// }
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// } else if (localMediaPlayer.currentPlaying != downloadFile) {
|
|
||||||
// preloaded++
|
|
||||||
// }
|
|
||||||
// i = (i + 1) % n
|
|
||||||
// } while (i != start)
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // If the downloadList contains no work, check the backgroundDownloadList
|
|
||||||
// if ((preloaded + 1 == n || preloaded >= getPreloadCount() || playList.isEmpty()) && backgroundDownloadList.isNotEmpty()) {
|
|
||||||
// var i = 0
|
|
||||||
// while (i < backgroundDownloadList.size) {
|
|
||||||
// val downloadFile = backgroundDownloadList[i]
|
|
||||||
// if (downloadFile.isWorkDone && (!downloadFile.shouldSave() || downloadFile.isSaved)) {
|
|
||||||
// scanMedia(downloadFile.completeFile)
|
|
||||||
//
|
|
||||||
// // Don't need to keep list like active song list
|
|
||||||
// backgroundDownloadList.removeAt(i)
|
|
||||||
// downloadListUpdateRevision++
|
|
||||||
// i--
|
|
||||||
// } else if (downloadFile.isFailed && !downloadFile.shouldRetry()) {
|
|
||||||
// // Don't continue to attempt to download forever
|
|
||||||
// backgroundDownloadList.removeAt(i)
|
|
||||||
// downloadListUpdateRevision++
|
|
||||||
// i--
|
|
||||||
// } else {
|
|
||||||
// currentDownloading = downloadFile
|
|
||||||
// currentDownloading!!.download()
|
|
||||||
// cleanupCandidates.add(currentDownloading)
|
|
||||||
// break
|
|
||||||
// }
|
|
||||||
// i++
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
|
|
||||||
@get:Synchronized
|
@get:Synchronized
|
||||||
val currentPlayingIndex: Int
|
val currentPlayingIndex: Int
|
||||||
get() = playList.indexOf(localMediaPlayer.currentPlaying)
|
get() = playlist.indexOf(localMediaPlayer.currentPlaying)
|
||||||
|
|
||||||
@get:Synchronized
|
@get:Synchronized
|
||||||
val downloadListDuration: Long
|
val downloadListDuration: Long
|
||||||
get() {
|
get() {
|
||||||
var totalDuration: Long = 0
|
var totalDuration: Long = 0
|
||||||
for (downloadFile in playList) {
|
for (downloadFile in playlist) {
|
||||||
val song = downloadFile.song
|
val song = downloadFile.song
|
||||||
if (!song.isDirectory) {
|
if (!song.isDirectory) {
|
||||||
if (song.artist != null) {
|
if (song.artist != null) {
|
||||||
@ -244,7 +166,7 @@ class Downloader(
|
|||||||
val downloads: List<DownloadFile?>
|
val downloads: List<DownloadFile?>
|
||||||
get() {
|
get() {
|
||||||
val temp: MutableList<DownloadFile?> = ArrayList()
|
val temp: MutableList<DownloadFile?> = ArrayList()
|
||||||
temp.addAll(playList)
|
temp.addAll(playlist)
|
||||||
temp.addAll(activelyDownloading)
|
temp.addAll(activelyDownloading)
|
||||||
temp.addAll(downloadQueue)
|
temp.addAll(downloadQueue)
|
||||||
return temp.distinct()
|
return temp.distinct()
|
||||||
@ -252,7 +174,7 @@ class Downloader(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun clearPlaylist() {
|
fun clearPlaylist() {
|
||||||
playList.clear()
|
playlist.clear()
|
||||||
|
|
||||||
// Cancel all active downloads with a high priority
|
// Cancel all active downloads with a high priority
|
||||||
for (download in activelyDownloading) {
|
for (download in activelyDownloading) {
|
||||||
@ -260,7 +182,7 @@ class Downloader(
|
|||||||
download.cancelDownload()
|
download.cancelDownload()
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadListUpdateRevision++
|
playlistUpdateRevision++
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@ -273,8 +195,6 @@ class Downloader(
|
|||||||
if (download.priority >= 100)
|
if (download.priority >= 100)
|
||||||
download.cancelDownload()
|
download.cancelDownload()
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadListUpdateRevision++
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@ -290,8 +210,8 @@ class Downloader(
|
|||||||
if (activelyDownloading.contains(downloadFile)) {
|
if (activelyDownloading.contains(downloadFile)) {
|
||||||
downloadFile.cancelDownload()
|
downloadFile.cancelDownload()
|
||||||
}
|
}
|
||||||
playList.remove(downloadFile)
|
playlist.remove(downloadFile)
|
||||||
downloadListUpdateRevision++
|
playlistUpdateRevision++
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@ -308,7 +228,7 @@ class Downloader(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (newPlaylist) {
|
if (newPlaylist) {
|
||||||
playList.clear()
|
playlist.clear()
|
||||||
}
|
}
|
||||||
if (playNext) {
|
if (playNext) {
|
||||||
if (autoPlay && currentPlayingIndex >= 0) {
|
if (autoPlay && currentPlayingIndex >= 0) {
|
||||||
@ -316,17 +236,17 @@ class Downloader(
|
|||||||
}
|
}
|
||||||
for (song in songs) {
|
for (song in songs) {
|
||||||
val downloadFile = DownloadFile(song!!, save)
|
val downloadFile = DownloadFile(song!!, save)
|
||||||
playList.add(currentPlayingIndex + offset, downloadFile)
|
playlist.add(currentPlayingIndex + offset, downloadFile)
|
||||||
offset++
|
offset++
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (song in songs) {
|
for (song in songs) {
|
||||||
val downloadFile = DownloadFile(song!!, save)
|
val downloadFile = DownloadFile(song!!, save)
|
||||||
playList.add(downloadFile)
|
playlist.add(downloadFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
downloadListUpdateRevision++
|
playlistUpdateRevision++
|
||||||
//checkDownloads()
|
checkDownloads()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@ -338,26 +258,26 @@ class Downloader(
|
|||||||
downloadQueue.add(DownloadFile(song, save))
|
downloadQueue.add(DownloadFile(song, save))
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadListUpdateRevision++
|
checkDownloads()
|
||||||
//checkDownloads()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun shuffle() {
|
fun shuffle() {
|
||||||
playList.shuffle()
|
playlist.shuffle()
|
||||||
|
|
||||||
// Move the current song to the top..
|
// Move the current song to the top..
|
||||||
if (localMediaPlayer.currentPlaying != null) {
|
if (localMediaPlayer.currentPlaying != null) {
|
||||||
playList.remove(localMediaPlayer.currentPlaying)
|
playlist.remove(localMediaPlayer.currentPlaying)
|
||||||
playList.add(0, localMediaPlayer.currentPlaying!!)
|
playlist.add(0, localMediaPlayer.currentPlaying!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadListUpdateRevision++
|
playlistUpdateRevision++
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@Suppress("ReturnCount")
|
||||||
fun getDownloadFileForSong(song: MusicDirectory.Entry): DownloadFile {
|
fun getDownloadFileForSong(song: MusicDirectory.Entry): DownloadFile {
|
||||||
for (downloadFile in playList) {
|
for (downloadFile in playlist) {
|
||||||
if (downloadFile.song == song) {
|
if (downloadFile.song == song) {
|
||||||
return downloadFile
|
return downloadFile
|
||||||
}
|
}
|
||||||
@ -380,49 +300,50 @@ class Downloader(
|
|||||||
return downloadFile
|
return downloadFile
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun checkShufflePlay() {
|
private fun checkShufflePlay() {
|
||||||
// Get users desired random playlist size
|
// Get users desired random playlist size
|
||||||
val listSize = getMaxSongs()
|
val listSize = getMaxSongs()
|
||||||
val wasEmpty = playList.isEmpty()
|
val wasEmpty = playlist.isEmpty()
|
||||||
val revisionBefore = downloadListUpdateRevision
|
val revisionBefore = playlistUpdateRevision
|
||||||
|
|
||||||
// First, ensure that list is at least 20 songs long.
|
// First, ensure that list is at least 20 songs long.
|
||||||
val size = playList.size
|
val size = playlist.size
|
||||||
if (size < listSize) {
|
if (size < listSize) {
|
||||||
for (song in shufflePlayBuffer[listSize - size]) {
|
for (song in shufflePlayBuffer[listSize - size]) {
|
||||||
val downloadFile = DownloadFile(song, false)
|
val downloadFile = DownloadFile(song, false)
|
||||||
playList.add(downloadFile)
|
playlist.add(downloadFile)
|
||||||
downloadListUpdateRevision++
|
playlistUpdateRevision++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val currIndex = if (localMediaPlayer.currentPlaying == null) 0 else currentPlayingIndex
|
val currIndex = if (localMediaPlayer.currentPlaying == null) 0 else currentPlayingIndex
|
||||||
|
|
||||||
// Only shift playlist if playing song #5 or later.
|
// Only shift playlist if playing song #5 or later.
|
||||||
if (currIndex > 4) {
|
if (currIndex > SHUFFLE_BUFFER_LIMIT) {
|
||||||
val songsToShift = currIndex - 2
|
val songsToShift = currIndex - 2
|
||||||
for (song in shufflePlayBuffer[songsToShift]) {
|
for (song in shufflePlayBuffer[songsToShift]) {
|
||||||
playList.add(DownloadFile(song, false))
|
playlist.add(DownloadFile(song, false))
|
||||||
playList[0].cancelDownload()
|
playlist[0].cancelDownload()
|
||||||
playList.removeAt(0)
|
playlist.removeAt(0)
|
||||||
downloadListUpdateRevision++
|
playlistUpdateRevision++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (revisionBefore != downloadListUpdateRevision) {
|
if (revisionBefore != playlistUpdateRevision) {
|
||||||
jukeboxMediaPlayer.updatePlaylist()
|
jukeboxMediaPlayer.updatePlaylist()
|
||||||
}
|
}
|
||||||
if (wasEmpty && playList.isNotEmpty()) {
|
if (wasEmpty && playlist.isNotEmpty()) {
|
||||||
if (jukeboxMediaPlayer.isEnabled) {
|
if (jukeboxMediaPlayer.isEnabled) {
|
||||||
jukeboxMediaPlayer.skip(0, 0)
|
jukeboxMediaPlayer.skip(0, 0)
|
||||||
localMediaPlayer.setPlayerState(PlayerState.STARTED)
|
localMediaPlayer.setPlayerState(PlayerState.STARTED)
|
||||||
} else {
|
} else {
|
||||||
localMediaPlayer.play(playList[0])
|
localMediaPlayer.play(playlist[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
companion object {
|
companion object {
|
||||||
const val PARALLEL_DOWNLOADS = 3
|
const val PARALLEL_DOWNLOADS = 3
|
||||||
|
const val CHECK_INTERVAL = 5L
|
||||||
|
const val SHUFFLE_BUFFER_LIMIT = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ class MediaPlayerController(
|
|||||||
downloader.addToPlaylist(filteredSongs, save, autoPlay, playNext, newPlaylist)
|
downloader.addToPlaylist(filteredSongs, save, autoPlay, playNext, newPlaylist)
|
||||||
jukeboxMediaPlayer.updatePlaylist()
|
jukeboxMediaPlayer.updatePlaylist()
|
||||||
if (shuffle) shuffle()
|
if (shuffle) shuffle()
|
||||||
val isLastTrack = (downloader.playList.size - 1 == downloader.currentPlayingIndex)
|
val isLastTrack = (downloader.playlist.size - 1 == downloader.currentPlayingIndex)
|
||||||
|
|
||||||
if (!playNext && !autoPlay && isLastTrack) {
|
if (!playNext && !autoPlay && isLastTrack) {
|
||||||
val mediaPlayerService = runningInstance
|
val mediaPlayerService = runningInstance
|
||||||
@ -190,15 +190,15 @@ class MediaPlayerController(
|
|||||||
if (autoPlay) {
|
if (autoPlay) {
|
||||||
play(0)
|
play(0)
|
||||||
} else {
|
} else {
|
||||||
if (localMediaPlayer.currentPlaying == null && downloader.playList.size > 0) {
|
if (localMediaPlayer.currentPlaying == null && downloader.playlist.size > 0) {
|
||||||
localMediaPlayer.currentPlaying = downloader.playList[0]
|
localMediaPlayer.currentPlaying = downloader.playlist[0]
|
||||||
downloader.playList[0].setPlaying(true)
|
downloader.playlist[0].setPlaying(true)
|
||||||
}
|
}
|
||||||
downloader.checkDownloads()
|
downloader.checkDownloads()
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
playerPosition
|
playerPosition
|
||||||
)
|
)
|
||||||
@ -210,7 +210,7 @@ class MediaPlayerController(
|
|||||||
val filteredSongs = songs.filterNotNull()
|
val filteredSongs = songs.filterNotNull()
|
||||||
downloader.downloadBackground(filteredSongs, save)
|
downloader.downloadBackground(filteredSongs, save)
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
playerPosition
|
playerPosition
|
||||||
)
|
)
|
||||||
@ -241,7 +241,7 @@ class MediaPlayerController(
|
|||||||
fun shuffle() {
|
fun shuffle() {
|
||||||
downloader.shuffle()
|
downloader.shuffle()
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
playerPosition
|
playerPosition
|
||||||
)
|
)
|
||||||
@ -274,7 +274,7 @@ class MediaPlayerController(
|
|||||||
downloader.clearPlaylist()
|
downloader.clearPlaylist()
|
||||||
if (serialize) {
|
if (serialize) {
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex, playerPosition
|
downloader.currentPlayingIndex, playerPosition
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -285,7 +285,7 @@ class MediaPlayerController(
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
fun clearIncomplete() {
|
fun clearIncomplete() {
|
||||||
reset()
|
reset()
|
||||||
val iterator = downloader.playList.iterator()
|
val iterator = downloader.playlist.iterator()
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val downloadFile = iterator.next()
|
val downloadFile = iterator.next()
|
||||||
if (!downloadFile.isCompleteFileAvailable) {
|
if (!downloadFile.isCompleteFileAvailable) {
|
||||||
@ -294,7 +294,7 @@ class MediaPlayerController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
playerPosition
|
playerPosition
|
||||||
)
|
)
|
||||||
@ -311,7 +311,7 @@ class MediaPlayerController(
|
|||||||
downloader.removeFromPlaylist(downloadFile)
|
downloader.removeFromPlaylist(downloadFile)
|
||||||
|
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
playerPosition
|
playerPosition
|
||||||
)
|
)
|
||||||
@ -363,12 +363,12 @@ class MediaPlayerController(
|
|||||||
when (repeatMode) {
|
when (repeatMode) {
|
||||||
RepeatMode.SINGLE, RepeatMode.OFF -> {
|
RepeatMode.SINGLE, RepeatMode.OFF -> {
|
||||||
// Play next if exists
|
// Play next if exists
|
||||||
if (index + 1 >= 0 && index + 1 < downloader.playList.size) {
|
if (index + 1 >= 0 && index + 1 < downloader.playlist.size) {
|
||||||
play(index + 1)
|
play(index + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RepeatMode.ALL -> {
|
RepeatMode.ALL -> {
|
||||||
play((index + 1) % downloader.playList.size)
|
play((index + 1) % downloader.playlist.size)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
}
|
}
|
||||||
@ -495,16 +495,16 @@ class MediaPlayerController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val playlistSize: Int
|
val playlistSize: Int
|
||||||
get() = downloader.playList.size
|
get() = downloader.playlist.size
|
||||||
|
|
||||||
val currentPlayingNumberOnPlaylist: Int
|
val currentPlayingNumberOnPlaylist: Int
|
||||||
get() = downloader.currentPlayingIndex
|
get() = downloader.currentPlayingIndex
|
||||||
|
|
||||||
val playList: List<DownloadFile>
|
val playList: List<DownloadFile>
|
||||||
get() = downloader.playList
|
get() = downloader.playlist
|
||||||
|
|
||||||
val playListUpdateRevision: Long
|
val playListUpdateRevision: Long
|
||||||
get() = downloader.downloadListUpdateRevision
|
get() = downloader.playlistUpdateRevision
|
||||||
|
|
||||||
val playListDuration: Long
|
val playListDuration: Long
|
||||||
get() = downloader.downloadListDuration
|
get() = downloader.downloadListDuration
|
||||||
|
@ -76,7 +76,7 @@ class MediaPlayerLifecycleSupport : KoinComponent {
|
|||||||
// Work-around: Serialize again, as the restore() method creates a
|
// Work-around: Serialize again, as the restore() method creates a
|
||||||
// serialization without current playing info.
|
// serialization without current playing info.
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
mediaPlayerController.playerPosition
|
mediaPlayerController.playerPosition
|
||||||
)
|
)
|
||||||
@ -94,7 +94,7 @@ class MediaPlayerLifecycleSupport : KoinComponent {
|
|||||||
if (!created) return
|
if (!created) return
|
||||||
|
|
||||||
downloadQueueSerializer.serializeDownloadQueueNow(
|
downloadQueueSerializer.serializeDownloadQueueNow(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
mediaPlayerController.playerPosition
|
mediaPlayerController.playerPosition
|
||||||
)
|
)
|
||||||
|
@ -88,7 +88,7 @@ class MediaPlayerService : Service() {
|
|||||||
|
|
||||||
localMediaPlayer.onPrepared = {
|
localMediaPlayer.onPrepared = {
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex,
|
downloader.currentPlayingIndex,
|
||||||
playerPosition
|
playerPosition
|
||||||
)
|
)
|
||||||
@ -189,7 +189,7 @@ class MediaPlayerService : Service() {
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
fun setCurrentPlaying(currentPlayingIndex: Int) {
|
fun setCurrentPlaying(currentPlayingIndex: Int) {
|
||||||
try {
|
try {
|
||||||
localMediaPlayer.setCurrentPlaying(downloader.playList[currentPlayingIndex])
|
localMediaPlayer.setCurrentPlaying(downloader.playlist[currentPlayingIndex])
|
||||||
} catch (ignored: IndexOutOfBoundsException) {
|
} catch (ignored: IndexOutOfBoundsException) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,7 +208,7 @@ class MediaPlayerService : Service() {
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
when (repeatMode) {
|
when (repeatMode) {
|
||||||
RepeatMode.OFF -> index += 1
|
RepeatMode.OFF -> index += 1
|
||||||
RepeatMode.ALL -> index = (index + 1) % downloader.playList.size
|
RepeatMode.ALL -> index = (index + 1) % downloader.playlist.size
|
||||||
RepeatMode.SINGLE -> {
|
RepeatMode.SINGLE -> {
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@ -217,8 +217,8 @@ class MediaPlayerService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
localMediaPlayer.clearNextPlaying(false)
|
localMediaPlayer.clearNextPlaying(false)
|
||||||
if (index < downloader.playList.size && index != -1) {
|
if (index < downloader.playlist.size && index != -1) {
|
||||||
localMediaPlayer.setNextPlaying(downloader.playList[index])
|
localMediaPlayer.setNextPlaying(downloader.playlist[index])
|
||||||
} else {
|
} else {
|
||||||
localMediaPlayer.clearNextPlaying(true)
|
localMediaPlayer.clearNextPlaying(true)
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ class MediaPlayerService : Service() {
|
|||||||
@Synchronized
|
@Synchronized
|
||||||
fun play(index: Int, start: Boolean) {
|
fun play(index: Int, start: Boolean) {
|
||||||
Timber.v("play requested for %d", index)
|
Timber.v("play requested for %d", index)
|
||||||
if (index < 0 || index >= downloader.playList.size) {
|
if (index < 0 || index >= downloader.playlist.size) {
|
||||||
resetPlayback()
|
resetPlayback()
|
||||||
} else {
|
} else {
|
||||||
setCurrentPlaying(index)
|
setCurrentPlaying(index)
|
||||||
@ -280,7 +280,7 @@ class MediaPlayerService : Service() {
|
|||||||
jukeboxMediaPlayer.skip(index, 0)
|
jukeboxMediaPlayer.skip(index, 0)
|
||||||
localMediaPlayer.setPlayerState(PlayerState.STARTED)
|
localMediaPlayer.setPlayerState(PlayerState.STARTED)
|
||||||
} else {
|
} else {
|
||||||
localMediaPlayer.play(downloader.playList[index])
|
localMediaPlayer.play(downloader.playlist[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
downloader.checkDownloads()
|
downloader.checkDownloads()
|
||||||
@ -293,7 +293,7 @@ class MediaPlayerService : Service() {
|
|||||||
localMediaPlayer.reset()
|
localMediaPlayer.reset()
|
||||||
localMediaPlayer.setCurrentPlaying(null)
|
localMediaPlayer.setCurrentPlaying(null)
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex, playerPosition
|
downloader.currentPlayingIndex, playerPosition
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -395,7 +395,7 @@ class MediaPlayerService : Service() {
|
|||||||
|
|
||||||
if (playerState === PlayerState.PAUSED) {
|
if (playerState === PlayerState.PAUSED) {
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList, downloader.currentPlayingIndex, playerPosition
|
downloader.playlist, downloader.currentPlayingIndex, playerPosition
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,8 +408,8 @@ class MediaPlayerService : Service() {
|
|||||||
Util.broadcastPlaybackStatusChange(context, playerState)
|
Util.broadcastPlaybackStatusChange(context, playerState)
|
||||||
Util.broadcastA2dpPlayStatusChange(
|
Util.broadcastA2dpPlayStatusChange(
|
||||||
context, playerState, song,
|
context, playerState, song,
|
||||||
downloader.playList.size,
|
downloader.playlist.size,
|
||||||
downloader.playList.indexOf(currentPlaying) + 1, playerPosition
|
downloader.playlist.indexOf(currentPlaying) + 1, playerPosition
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update widget
|
// Update widget
|
||||||
@ -455,7 +455,7 @@ class MediaPlayerService : Service() {
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
when (repeatMode) {
|
when (repeatMode) {
|
||||||
RepeatMode.OFF -> {
|
RepeatMode.OFF -> {
|
||||||
if (index + 1 < 0 || index + 1 >= downloader.playList.size) {
|
if (index + 1 < 0 || index + 1 >= downloader.playlist.size) {
|
||||||
if (Util.getShouldClearPlaylist()) {
|
if (Util.getShouldClearPlaylist()) {
|
||||||
clear(true)
|
clear(true)
|
||||||
jukeboxMediaPlayer.updatePlaylist()
|
jukeboxMediaPlayer.updatePlaylist()
|
||||||
@ -466,7 +466,7 @@ class MediaPlayerService : Service() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RepeatMode.ALL -> {
|
RepeatMode.ALL -> {
|
||||||
play((index + 1) % downloader.playList.size)
|
play((index + 1) % downloader.playlist.size)
|
||||||
}
|
}
|
||||||
RepeatMode.SINGLE -> play(index)
|
RepeatMode.SINGLE -> play(index)
|
||||||
else -> {
|
else -> {
|
||||||
@ -485,7 +485,7 @@ class MediaPlayerService : Service() {
|
|||||||
setNextPlaying()
|
setNextPlaying()
|
||||||
if (serialize) {
|
if (serialize) {
|
||||||
downloadQueueSerializer.serializeDownloadQueue(
|
downloadQueueSerializer.serializeDownloadQueue(
|
||||||
downloader.playList,
|
downloader.playlist,
|
||||||
downloader.currentPlayingIndex, playerPosition
|
downloader.currentPlayingIndex, playerPosition
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user