diff --git a/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt b/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt index 339954ee..99ce3a8d 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/MainActivity.kt @@ -103,6 +103,9 @@ class MainActivity : BridgeActivity() { } } + fun isPlayerNotificationServiceInitialized():Boolean { + return ::foregroundService.isInitialized + } fun stopMyService() { if (mBounded) { 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 078b5b09..0473a1ea 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 @@ -107,6 +107,7 @@ data class PlayItemRequestPayload( data class DeviceSettings( var disableAutoRewind:Boolean, var enableAltView:Boolean, + var allowSeekingOnMediaControls:Boolean, var jumpBackwardsTime:Int, var jumpForwardTime:Int, var enableMp3IndexSeeking:Boolean, @@ -130,6 +131,7 @@ data class DeviceSettings( return DeviceSettings( disableAutoRewind = false, enableAltView = true, + allowSeekingOnMediaControls = false, jumpBackwardsTime = 10, jumpForwardTime = 10, enableMp3IndexSeeking = false, 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 16e0f19b..17416663 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 @@ -329,15 +329,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { } } - mediaSessionConnector.setEnabledPlaybackActions( - PlaybackStateCompat.ACTION_PLAY_PAUSE - or PlaybackStateCompat.ACTION_PLAY - or PlaybackStateCompat.ACTION_PAUSE - or PlaybackStateCompat.ACTION_SEEK_TO - or PlaybackStateCompat.ACTION_FAST_FORWARD - or PlaybackStateCompat.ACTION_REWIND - or PlaybackStateCompat.ACTION_STOP - ) + setMediaSessionConnectorPlaybackActions() mediaSessionConnector.setQueueNavigator(queueNavigator) mediaSessionConnector.setPlaybackPreparer(MediaSessionPlaybackPreparer(this)) @@ -512,6 +504,20 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { mediaSessionConnector.setCustomActionProviders(*customActionProviders.toTypedArray()) } + fun setMediaSessionConnectorPlaybackActions() { + var playbackActions = PlaybackStateCompat.ACTION_PLAY_PAUSE or + PlaybackStateCompat.ACTION_PLAY or + PlaybackStateCompat.ACTION_PAUSE or + PlaybackStateCompat.ACTION_FAST_FORWARD or + PlaybackStateCompat.ACTION_REWIND or + PlaybackStateCompat.ACTION_STOP + + if (deviceSettings.allowSeekingOnMediaControls) { + playbackActions = playbackActions or PlaybackStateCompat.ACTION_SEEK_TO + } + mediaSessionConnector.setEnabledPlaybackActions(playbackActions) + } + fun handlePlayerPlaybackError(errorMessage:String) { // On error and was attempting to direct play - fallback to transcode currentPlaybackSession?.let { playbackSession -> diff --git a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDatabase.kt b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDatabase.kt index f398589a..304cbdd6 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDatabase.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/plugins/AbsDatabase.kt @@ -1,5 +1,7 @@ package com.audiobookshelf.app.plugins +import android.os.Handler +import android.os.Looper import android.util.Log import com.audiobookshelf.app.MainActivity import com.audiobookshelf.app.data.* @@ -493,9 +495,16 @@ class AbsDatabase : Plugin() { fun updateDeviceSettings(call:PluginCall) { // Returns device data Log.d(tag, "updateDeviceSettings ${call.data}") val newDeviceSettings = jacksonMapper.readValue(call.data.toString()) - GlobalScope.launch(Dispatchers.IO) { + + Handler(Looper.getMainLooper()).post { DeviceManager.deviceData.deviceSettings = newDeviceSettings DeviceManager.dbManager.saveDeviceData(DeviceManager.deviceData) + + // Updates playback actions for media notification (handles media control seek locking setting) + if (mainActivity.isPlayerNotificationServiceInitialized()) { + mainActivity.foregroundService.setMediaSessionConnectorPlaybackActions() + } + call.resolve(JSObject(jacksonMapper.writeValueAsString(DeviceManager.deviceData))) } } diff --git a/ios/App/App/AppDelegate.swift b/ios/App/App/AppDelegate.swift index 26a74dcc..73a88b05 100644 --- a/ios/App/App/AppDelegate.swift +++ b/ios/App/App/AppDelegate.swift @@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Override point for customization after application launch. let configuration = Realm.Configuration( - schemaVersion: 16, + schemaVersion: 17, migrationBlock: { [weak self] migration, oldSchemaVersion in if (oldSchemaVersion < 1) { self?.logger.log("Realm schema version was \(oldSchemaVersion)") diff --git a/ios/App/App/plugins/AbsDatabase.swift b/ios/App/App/plugins/AbsDatabase.swift index 44f542db..76153629 100644 --- a/ios/App/App/plugins/AbsDatabase.swift +++ b/ios/App/App/plugins/AbsDatabase.swift @@ -238,6 +238,7 @@ public class AbsDatabase: CAPPlugin { @objc func updateDeviceSettings(_ call: CAPPluginCall) { let disableAutoRewind = call.getBool("disableAutoRewind") ?? false let enableAltView = call.getBool("enableAltView") ?? false + let allowSeekingOnMediaControls = call.getBool("allowSeekingOnMediaControls") ?? false let jumpBackwardsTime = call.getInt("jumpBackwardsTime") ?? 10 let jumpForwardTime = call.getInt("jumpForwardTime") ?? 10 let lockOrientation = call.getString("lockOrientation") ?? "NONE" @@ -246,6 +247,7 @@ public class AbsDatabase: CAPPlugin { let settings = DeviceSettings() settings.disableAutoRewind = disableAutoRewind settings.enableAltView = enableAltView + settings.allowSeekingOnMediaControls = allowSeekingOnMediaControls settings.jumpBackwardsTime = jumpBackwardsTime settings.jumpForwardTime = jumpForwardTime settings.lockOrientation = lockOrientation @@ -254,7 +256,9 @@ public class AbsDatabase: CAPPlugin { Database.shared.setDeviceSettings(deviceSettings: settings) -// call.resolve([ "value": [] ]) + // Updates the media notification controls (for allowSeekingOnMediaControls setting) + PlayerHandler.updateRemoteTransportControls() + getDeviceData(call) } diff --git a/ios/App/Shared/models/DeviceSettings.swift b/ios/App/Shared/models/DeviceSettings.swift index 4156fa29..c42a35bb 100644 --- a/ios/App/Shared/models/DeviceSettings.swift +++ b/ios/App/Shared/models/DeviceSettings.swift @@ -11,6 +11,7 @@ import RealmSwift class DeviceSettings: Object { @Persisted var disableAutoRewind: Bool = false @Persisted var enableAltView: Bool = true + @Persisted var allowSeekingOnMediaControls: Bool = false @Persisted var jumpBackwardsTime: Int = 10 @Persisted var jumpForwardTime: Int = 10 @Persisted var lockOrientation: String = "NONE" @@ -26,6 +27,7 @@ func deviceSettingsToJSON(settings: DeviceSettings) -> Dictionary { return [ "disableAutoRewind": settings.disableAutoRewind, "enableAltView": settings.enableAltView, + "allowSeekingOnMediaControls": settings.allowSeekingOnMediaControls, "jumpBackwardsTime": settings.jumpBackwardsTime, "jumpForwardTime": settings.jumpForwardTime, "lockOrientation": settings.lockOrientation, diff --git a/ios/App/Shared/player/AudioPlayer.swift b/ios/App/Shared/player/AudioPlayer.swift index 5bc075cf..2cc60f64 100644 --- a/ios/App/Shared/player/AudioPlayer.swift +++ b/ios/App/Shared/player/AudioPlayer.swift @@ -588,7 +588,7 @@ class AudioPlayer: NSObject { } // MARK: - Now playing - private func setupRemoteTransportControls() { + func setupRemoteTransportControls() { DispatchQueue.runOnMainQueue { UIApplication.shared.beginReceivingRemoteControlEvents() } @@ -672,7 +672,7 @@ class AudioPlayer: NSObject { return .success } - commandCenter.changePlaybackPositionCommand.isEnabled = true + commandCenter.changePlaybackPositionCommand.isEnabled = deviceSettings.allowSeekingOnMediaControls commandCenter.changePlaybackPositionCommand.addTarget { [weak self] event in guard let event = event as? MPChangePlaybackPositionCommandEvent else { return .noSuchContent diff --git a/ios/App/Shared/player/PlayerHandler.swift b/ios/App/Shared/player/PlayerHandler.swift index 718cdf95..c895a2c3 100644 --- a/ios/App/Shared/player/PlayerHandler.swift +++ b/ios/App/Shared/player/PlayerHandler.swift @@ -135,6 +135,10 @@ class PlayerHandler { ) } + public static func updateRemoteTransportControls() { + self.player?.setupRemoteTransportControls() + } + // MARK: - Helper logic private static func cleanupOldSessions(currentSessionId: String?) { diff --git a/pages/settings.vue b/pages/settings.vue index a217410f..fd0e82d0 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -61,6 +61,12 @@

{{ $strings.LabelEnableMp3IndexSeeking }}

info +
+
+ +
+

{{ $strings.LabelAllowSeekingOnMediaControls }}

+