From e4c6093a82cea9e371e8160f47360677f3c4aa09 Mon Sep 17 00:00:00 2001 From: advplyr Date: Sat, 2 Jul 2022 14:18:21 -0500 Subject: [PATCH] Update:Notification player closed when closing in-app player and stop button on notification player #255, Add:Setting for disabling auto rewind --- .../audiobookshelf/app/data/DeviceClasses.kt | 5 ++ .../app/player/AbMediaDescriptionAdapter.kt | 3 - .../app/player/PlayerListener.kt | 5 +- .../app/player/PlayerNotificationListener.kt | 7 ++ .../app/player/PlayerNotificationService.kt | 66 +++++++++++-------- .../drawable-anydpi/exo_icon_fastforward.xml | 6 -- .../res/drawable-anydpi/exo_icon_rewind.xml | 6 -- .../res/drawable/exo_icon_fastforward.xml | 2 - .../src/main/res/drawable/exo_icon_rewind.xml | 2 - components/connection/ServerConnectForm.vue | 8 ++- 10 files changed, 59 insertions(+), 51 deletions(-) diff --git a/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt b/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt index 59e843f0..9007f748 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/data/DeviceClasses.kt @@ -27,6 +27,11 @@ data class DeviceSettings( return DeviceSettings(false, 10, 10) } } + + @get:JsonIgnore + val jumpBackwardsTimeMs get() = jumpBackwardsTime * 1000L + @get:JsonIgnore + val jumpForwardTimeMs get() = jumpForwardTime * 1000L } data class DeviceData( diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/AbMediaDescriptionAdapter.kt b/android/app/src/main/java/com/audiobookshelf/app/player/AbMediaDescriptionAdapter.kt index 9894361a..2b31e6ba 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/AbMediaDescriptionAdapter.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/AbMediaDescriptionAdapter.kt @@ -21,9 +21,6 @@ class AbMediaDescriptionAdapter constructor(private val controller: MediaControl var currentIconUri: Uri? = null var currentBitmap: Bitmap? = null - private val glideOptions = RequestOptions() - .fallback(R.drawable.icon) - .diskCacheStrategy(DiskCacheStrategy.DATA) private val serviceJob = SupervisorJob() private val serviceScope = CoroutineScope(Dispatchers.Main + serviceJob) diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt index 9c521ab2..cc9f1e3c 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerListener.kt @@ -2,6 +2,7 @@ package com.audiobookshelf.app.player import android.util.Log import com.audiobookshelf.app.data.PlayerState +import com.audiobookshelf.app.device.DeviceManager import com.google.android.exoplayer2.PlaybackException import com.google.android.exoplayer2.Player @@ -23,7 +24,7 @@ class PlayerListener(var playerNotificationService:PlayerNotificationService) : } override fun onEvents(player: Player, events: Player.Events) { - Log.d(tag, "onEvents ${player.deviceInfo} | ${playerNotificationService.getMediaPlayer()} | ${events.size()}") + Log.d(tag, "onEvents ${playerNotificationService.getMediaPlayer()} | ${events.size()}") if (events.contains(Player.EVENT_POSITION_DISCONTINUITY)) { Log.d(tag, "EVENT_POSITION_DISCONTINUITY") @@ -69,7 +70,7 @@ class PlayerListener(var playerNotificationService:PlayerNotificationService) : if (player.isPlaying) { Log.d(tag, "SeekBackTime: Player is playing") - if (lastPauseTime > 0) { + if (lastPauseTime > 0 && DeviceManager.deviceData.deviceSettings?.disableAutoRewind != true) { if (onSeekBack) onSeekBack = false else { Log.d(tag, "SeekBackTime: playing started now set seek back time $lastPauseTime") diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationListener.kt b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationListener.kt index d1db2bdc..ef58fbed 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationListener.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationListener.kt @@ -14,6 +14,7 @@ class PlayerNotificationListener(var playerNotificationService:PlayerNotificatio // Start foreground service Log.d(tag, "Notification Posted $notificationId - Start Foreground | $notification") + PlayerNotificationService.isClosed = false playerNotificationService.startForeground(notificationId, notification) } @@ -26,6 +27,12 @@ class PlayerNotificationListener(var playerNotificationService:PlayerNotificatio playerNotificationService.stopSelf() } else { Log.d(tag, "onNotificationCancelled not dismissed by user") + + // When stop button is pressed on the notification I guess it isn't considered "dismissedByUser" so we need to close playback ourselves + if (!PlayerNotificationService.isClosed) { + Log.d(tag, "PNS is not closed - closing it now") + playerNotificationService.closePlayback() + } } } } diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt index 27478cc7..ee8447fc 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/PlayerNotificationService.kt @@ -41,6 +41,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { companion object { var isStarted = false + var isClosed = false } interface ClientEventEmitter { @@ -112,11 +113,6 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { fun getService(): PlayerNotificationService = this@PlayerNotificationService } - fun stopService(context: Context) { - val stopIntent = Intent(context, PlayerNotificationService::class.java) - context.stopService(stopIntent) - } - override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { isStarted = true Log.d(tag, "onStartCommand $startId") @@ -159,31 +155,11 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { stopSelf() } - override fun onCreate() { + Log.d(tag, "onCreate") super.onCreate() ctx = this - // Initialize player - val customLoadControl:LoadControl = DefaultLoadControl.Builder().setBufferDurationsMs( - 1000 * 20, // 20s min buffer - 1000 * 45, // 45s max buffer - 1000 * 5, // 5s playback start - 1000 * 20 // 20s playback rebuffer - ).build() - - mPlayer = ExoPlayer.Builder(this) - .setLoadControl(customLoadControl) - .setSeekBackIncrementMs(10000) - .setSeekForwardIncrementMs(10000) - .build() - mPlayer.setHandleAudioBecomingNoisy(true) - mPlayer.addListener(PlayerListener(this)) - val audioAttributes:AudioAttributes = AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).setContentType(C.CONTENT_TYPE_SPEECH).build() - mPlayer.setAudioAttributes(audioAttributes, true) - - currentPlayer = mPlayer - // Initialize API apiHandler = ApiHandler(ctx) @@ -234,6 +210,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { playerNotificationManager.setUseNextAction(false) playerNotificationManager.setUsePreviousAction(false) playerNotificationManager.setUseChronometer(false) + playerNotificationManager.setUseStopAction(true) playerNotificationManager.setVisibility(NotificationCompat.VISIBILITY_PUBLIC) playerNotificationManager.setPriority(NotificationCompat.PRIORITY_MAX) playerNotificationManager.setUseFastForwardActionInCompactView(true) @@ -276,17 +253,47 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { ) mediaSessionConnector.setQueueNavigator(queueNavigator) mediaSessionConnector.setPlaybackPreparer(MediaSessionPlaybackPreparer(this)) - mediaSessionConnector.setPlayer(mPlayer) + + mediaSession.setCallback(MediaSessionCallback(this)) + + initializeMPlayer() + currentPlayer = mPlayer + } + + private fun initializeMPlayer() { + val customLoadControl:LoadControl = DefaultLoadControl.Builder().setBufferDurationsMs( + 1000 * 20, // 20s min buffer + 1000 * 45, // 45s max buffer + 1000 * 5, // 5s playback start + 1000 * 20 // 20s playback rebuffer + ).build() + + val seekBackTime = DeviceManager.deviceData.deviceSettings?.jumpBackwardsTimeMs ?: 10000 + val seekForwardTime = DeviceManager.deviceData.deviceSettings?.jumpForwardTimeMs ?: 10000 + Log.d(tag, "Seek Back Time $seekBackTime") + Log.d(tag, "Seek Forward Time $seekForwardTime") + + mPlayer = ExoPlayer.Builder(this) + .setLoadControl(customLoadControl) + .setSeekBackIncrementMs(seekBackTime) + .setSeekForwardIncrementMs(seekForwardTime) + .build() + mPlayer.setHandleAudioBecomingNoisy(true) + mPlayer.addListener(PlayerListener(this)) + val audioAttributes:AudioAttributes = AudioAttributes.Builder().setUsage(C.USAGE_MEDIA).setContentType(C.CONTENT_TYPE_SPEECH).build() + mPlayer.setAudioAttributes(audioAttributes, true) //attach player to playerNotificationManager playerNotificationManager.setPlayer(mPlayer) - mediaSession.setCallback(MediaSessionCallback(this)) + + mediaSessionConnector.setPlayer(mPlayer) } /* User callable methods */ fun preparePlayer(playbackSession: PlaybackSession, playWhenReady:Boolean, playbackRate:Float?) { + isClosed = false val playbackRateToUse = playbackRate ?: initialPlaybackRate ?: 1f initialPlaybackRate = playbackRate @@ -633,11 +640,14 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { } fun closePlayback() { + Log.d(tag, "closePlayback") currentPlayer.clearMediaItems() currentPlayer.stop() currentPlaybackSession = null clientEventEmitter?.onPlaybackClosed() PlayerListener.lastPauseTime = 0 + isClosed = true + stopForeground(true) } fun sendClientMetadata(playerState: PlayerState) { diff --git a/android/app/src/main/res/drawable-anydpi/exo_icon_fastforward.xml b/android/app/src/main/res/drawable-anydpi/exo_icon_fastforward.xml index 5076abdb..c9238b38 100644 --- a/android/app/src/main/res/drawable-anydpi/exo_icon_fastforward.xml +++ b/android/app/src/main/res/drawable-anydpi/exo_icon_fastforward.xml @@ -11,11 +11,5 @@ - - diff --git a/android/app/src/main/res/drawable-anydpi/exo_icon_rewind.xml b/android/app/src/main/res/drawable-anydpi/exo_icon_rewind.xml index 2b854c66..9e701276 100644 --- a/android/app/src/main/res/drawable-anydpi/exo_icon_rewind.xml +++ b/android/app/src/main/res/drawable-anydpi/exo_icon_rewind.xml @@ -11,11 +11,5 @@ - - diff --git a/android/app/src/main/res/drawable/exo_icon_fastforward.xml b/android/app/src/main/res/drawable/exo_icon_fastforward.xml index f6a6c064..a9301c5a 100644 --- a/android/app/src/main/res/drawable/exo_icon_fastforward.xml +++ b/android/app/src/main/res/drawable/exo_icon_fastforward.xml @@ -2,6 +2,4 @@ android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> - - diff --git a/android/app/src/main/res/drawable/exo_icon_rewind.xml b/android/app/src/main/res/drawable/exo_icon_rewind.xml index 06db412b..13480ca6 100644 --- a/android/app/src/main/res/drawable/exo_icon_rewind.xml +++ b/android/app/src/main/res/drawable/exo_icon_rewind.xml @@ -2,6 +2,4 @@ android:viewportHeight="24" android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> - - diff --git a/components/connection/ServerConnectForm.vue b/components/connection/ServerConnectForm.vue index 05a63ecd..4c01bbb9 100644 --- a/components/connection/ServerConnectForm.vue +++ b/components/connection/ServerConnectForm.vue @@ -76,10 +76,14 @@ import { Dialog } from '@capacitor/dialog' export default { - props: {}, + props: { + deviceData: { + type: Object, + default: () => {} + } + }, data() { return { - deviceData: null, loggedIn: false, showAuth: false, processing: false,