mirror of
https://github.com/ultrasonic/ultrasonic
synced 2025-01-28 16:09:33 +01:00
- Set Wake mode flag according to Offline status
- Use Rx to trigger CheckDownloads() - Fix #680 by listening to PositionDiscontinuity - Throttle RxEvents
This commit is contained in:
parent
d550eabf88
commit
2e1e627b7a
@ -35,6 +35,7 @@ import org.koin.core.component.inject
|
|||||||
import org.moire.ultrasonic.activity.NavigationActivity
|
import org.moire.ultrasonic.activity.NavigationActivity
|
||||||
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
import org.moire.ultrasonic.api.subsonic.SubsonicAPIClient
|
||||||
import org.moire.ultrasonic.app.UApp
|
import org.moire.ultrasonic.app.UApp
|
||||||
|
import org.moire.ultrasonic.data.ActiveServerProvider
|
||||||
import org.moire.ultrasonic.service.RxBus
|
import org.moire.ultrasonic.service.RxBus
|
||||||
import org.moire.ultrasonic.service.plusAssign
|
import org.moire.ultrasonic.service.plusAssign
|
||||||
import org.moire.ultrasonic.util.Constants
|
import org.moire.ultrasonic.util.Constants
|
||||||
@ -74,9 +75,16 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
|
|||||||
// Update the API endpoint when the active server has changed
|
// Update the API endpoint when the active server has changed
|
||||||
val newClient: SubsonicAPIClient by inject()
|
val newClient: SubsonicAPIClient by inject()
|
||||||
apiDataSource.setAPIClient(newClient)
|
apiDataSource.setAPIClient(newClient)
|
||||||
|
|
||||||
|
// Set the player wake mode
|
||||||
|
player.setWakeMode(getWakeModeFlag())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getWakeModeFlag(): Int {
|
||||||
|
return if (ActiveServerProvider.isOffline()) C.WAKE_MODE_LOCAL else C.WAKE_MODE_NETWORK
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
player.release()
|
player.release()
|
||||||
mediaLibrarySession.release()
|
mediaLibrarySession.release()
|
||||||
@ -90,10 +98,6 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
|
|||||||
|
|
||||||
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
|
@androidx.annotation.OptIn(androidx.media3.common.util.UnstableApi::class)
|
||||||
private fun initializeSessionAndPlayer() {
|
private fun initializeSessionAndPlayer() {
|
||||||
/*
|
|
||||||
* TODO:
|
|
||||||
* * Could be refined to use WAKE_MODE_LOCAL when offline....
|
|
||||||
*/
|
|
||||||
|
|
||||||
setMediaNotificationProvider(MediaNotificationProvider(UApp.applicationContext()))
|
setMediaNotificationProvider(MediaNotificationProvider(UApp.applicationContext()))
|
||||||
|
|
||||||
@ -112,7 +116,7 @@ class PlaybackService : MediaLibraryService(), KoinComponent {
|
|||||||
// Create the player
|
// Create the player
|
||||||
player = ExoPlayer.Builder(this)
|
player = ExoPlayer.Builder(this)
|
||||||
.setAudioAttributes(getAudioAttributes(), true)
|
.setAudioAttributes(getAudioAttributes(), true)
|
||||||
.setWakeMode(C.WAKE_MODE_NETWORK)
|
.setWakeMode(getWakeModeFlag())
|
||||||
.setHandleAudioBecomingNoisy(true)
|
.setHandleAudioBecomingNoisy(true)
|
||||||
.setMediaSourceFactory(DefaultMediaSourceFactory(cacheDataSourceFactory))
|
.setMediaSourceFactory(DefaultMediaSourceFactory(cacheDataSourceFactory))
|
||||||
.setRenderersFactory(renderer)
|
.setRenderersFactory(renderer)
|
||||||
|
@ -56,7 +56,7 @@ class DownloadService : Service() {
|
|||||||
updateNotification()
|
updateNotification()
|
||||||
|
|
||||||
instance = this
|
instance = this
|
||||||
Timber.i("DownloadService created")
|
Timber.i("DownloadService initiated")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||||
@ -74,10 +74,11 @@ class DownloadService : Service() {
|
|||||||
mediaSession = null
|
mediaSession = null
|
||||||
} catch (ignored: Throwable) {
|
} catch (ignored: Throwable) {
|
||||||
}
|
}
|
||||||
Timber.i("DownloadService stopped")
|
Timber.i("DownloadService destroyed")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notifyDownloaderStopped() {
|
fun notifyDownloaderStopped() {
|
||||||
|
Timber.i("DownloadService stopped")
|
||||||
isInForeground = false
|
isInForeground = false
|
||||||
stopForeground(true)
|
stopForeground(true)
|
||||||
stopSelf()
|
stopSelf()
|
||||||
@ -193,6 +194,7 @@ class DownloadService : Service() {
|
|||||||
} else {
|
} else {
|
||||||
context.startService(Intent(context, DownloadService::class.java))
|
context.startService(Intent(context, DownloadService::class.java))
|
||||||
}
|
}
|
||||||
|
Timber.i("DownloadService started")
|
||||||
}
|
}
|
||||||
Util.sleepQuietly(100L)
|
Util.sleepQuietly(100L)
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,13 @@ class Downloader(
|
|||||||
|
|
||||||
private val rxBusSubscription: CompositeDisposable = CompositeDisposable()
|
private val rxBusSubscription: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
|
init {
|
||||||
|
// Check downloads if the playlist changed
|
||||||
|
rxBusSubscription += RxBus.playlistObservable.subscribe {
|
||||||
|
checkDownloads()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private var downloadChecker = object : Runnable {
|
private var downloadChecker = object : Runnable {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
try {
|
try {
|
||||||
@ -100,11 +107,6 @@ class Downloader(
|
|||||||
wifiLock = Util.createWifiLock(toString())
|
wifiLock = Util.createWifiLock(toString())
|
||||||
wifiLock?.acquire()
|
wifiLock?.acquire()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check downloads if the playlist changed
|
|
||||||
rxBusSubscription += RxBus.playlistObservable.subscribe {
|
|
||||||
checkDownloads()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stop() {
|
fun stop() {
|
||||||
@ -133,7 +135,7 @@ class Downloader(
|
|||||||
|
|
||||||
@Suppress("ComplexMethod", "ComplexCondition")
|
@Suppress("ComplexMethod", "ComplexCondition")
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun checkDownloadsInternal() {
|
private fun checkDownloadsInternal() {
|
||||||
if (!Util.isExternalStoragePresent() || !storageMonitor.isExternalStorageAvailable) {
|
if (!Util.isExternalStoragePresent() || !storageMonitor.isExternalStorageAvailable) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -115,6 +115,20 @@ class MediaPlayerController(
|
|||||||
legacyPlaylistManager.updateCurrentPlaying(mediaItem)
|
legacyPlaylistManager.updateCurrentPlaying(mediaItem)
|
||||||
publishPlaybackState()
|
publishPlaybackState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the same item is contained in a playlist multiple times directly after each
|
||||||
|
* other, Media3 on emits a PositionDiscontinuity event.
|
||||||
|
* Can be removed if https://github.com/androidx/media/issues/68 is fixed.
|
||||||
|
*/
|
||||||
|
override fun onPositionDiscontinuity(
|
||||||
|
oldPosition: Player.PositionInfo,
|
||||||
|
newPosition: Player.PositionInfo,
|
||||||
|
reason: Int
|
||||||
|
) {
|
||||||
|
playerStateChangedHandler()
|
||||||
|
publishPlaybackState()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onCreated()
|
onCreated()
|
||||||
@ -149,9 +163,7 @@ class MediaPlayerController(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save playback state
|
// Save playback state
|
||||||
playbackStateSerializer.serialize(
|
serializeCurrentSession()
|
||||||
playList, currentMediaItemIndex, playerPosition
|
|
||||||
)
|
|
||||||
|
|
||||||
// Update widget
|
// Update widget
|
||||||
if (currentPlaying != null) {
|
if (currentPlaying != null) {
|
||||||
@ -347,8 +359,6 @@ class MediaPlayerController(
|
|||||||
|
|
||||||
if (autoPlay) {
|
if (autoPlay) {
|
||||||
play(0)
|
play(0)
|
||||||
} else {
|
|
||||||
downloader.checkDownloads()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import io.reactivex.rxjava3.core.Observable
|
|||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import io.reactivex.rxjava3.disposables.Disposable
|
import io.reactivex.rxjava3.disposables.Disposable
|
||||||
import io.reactivex.rxjava3.subjects.PublishSubject
|
import io.reactivex.rxjava3.subjects.PublishSubject
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class RxBus {
|
class RxBus {
|
||||||
companion object {
|
companion object {
|
||||||
@ -37,6 +38,7 @@ class RxBus {
|
|||||||
playlistPublisher.observeOn(AndroidSchedulers.mainThread())
|
playlistPublisher.observeOn(AndroidSchedulers.mainThread())
|
||||||
.replay(1)
|
.replay(1)
|
||||||
.autoConnect(0)
|
.autoConnect(0)
|
||||||
|
.throttleLatest(1, TimeUnit.SECONDS)
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
val dismissNowPlayingCommandPublisher: PublishSubject<Unit> =
|
val dismissNowPlayingCommandPublisher: PublishSubject<Unit> =
|
||||||
|
Loading…
x
Reference in New Issue
Block a user