1
0
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:
tzugen 2022-04-21 10:45:37 +02:00
parent d550eabf88
commit 2e1e627b7a
No known key found for this signature in database
GPG Key ID: 61E9C34BC10EC930
5 changed files with 38 additions and 18 deletions

View File

@ -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)

View File

@ -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)
} }

View File

@ -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
} }

View File

@ -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()
} }
} }

View File

@ -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> =