mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-08-04 18:15:01 +02:00
Add support for fading out on sleep timer end
Playback will start to fadeout during last 60 seconds of the sleep timer. Once faded out, playback will be paused, volume reset, and playback seeked to start of fadeout.
This commit is contained in:
parent
769ce0ade9
commit
33c738873f
6 changed files with 75 additions and 5 deletions
|
@ -14,7 +14,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
// Override point for customization after application launch.
|
||||
|
||||
let configuration = Realm.Configuration(
|
||||
schemaVersion: 18,
|
||||
schemaVersion: 19,
|
||||
migrationBlock: { [weak self] migration, oldSchemaVersion in
|
||||
if (oldSchemaVersion < 1) {
|
||||
self?.logger.log("Realm schema version was \(oldSchemaVersion)")
|
||||
|
@ -61,6 +61,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||
newObject?["streamingUsingCellular"] = "ALWAYS"
|
||||
}
|
||||
}
|
||||
if (oldSchemaVersion < 18) {
|
||||
self?.logger.log("Realm schema version was \(oldSchemaVersion)... Adding disableSleepTimerFadeOut settings")
|
||||
migration.enumerateObjects(ofType: PlayerSettings.className()) { oldObject, newObject in
|
||||
newObject?["disableSleepTimerFadeOut"] = false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
)
|
||||
|
|
|
@ -246,6 +246,7 @@ public class AbsDatabase: CAPPlugin {
|
|||
let languageCode = call.getString("languageCode") ?? "en-us"
|
||||
let downloadUsingCellular = call.getString("downloadUsingCellular") ?? "ALWAYS"
|
||||
let streamingUsingCellular = call.getString("streamingUsingCellular") ?? "ALWAYS"
|
||||
let disableSleepTimerFadeOut = call.getBool("disableSleepTimerFadeOut") ?? false
|
||||
let settings = DeviceSettings()
|
||||
settings.disableAutoRewind = disableAutoRewind
|
||||
settings.enableAltView = enableAltView
|
||||
|
@ -257,6 +258,7 @@ public class AbsDatabase: CAPPlugin {
|
|||
settings.languageCode = languageCode
|
||||
settings.downloadUsingCellular = downloadUsingCellular
|
||||
settings.streamingUsingCellular = streamingUsingCellular
|
||||
settings.disableSleepTimerFadeOut = disableSleepTimerFadeOut
|
||||
|
||||
Database.shared.setDeviceSettings(deviceSettings: settings)
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ class DeviceSettings: Object {
|
|||
@Persisted var languageCode: String = "en-us"
|
||||
@Persisted var downloadUsingCellular: String = "ALWAYS"
|
||||
@Persisted var streamingUsingCellular: String = "ALWAYS"
|
||||
@Persisted var disableSleepTimerFadeOut: Bool = false
|
||||
}
|
||||
|
||||
func getDefaultDeviceSettings() -> DeviceSettings {
|
||||
|
@ -36,6 +37,7 @@ func deviceSettingsToJSON(settings: DeviceSettings) -> Dictionary<String, Any> {
|
|||
"hapticFeedback": settings.hapticFeedback,
|
||||
"languageCode": settings.languageCode,
|
||||
"downloadUsingCellular": settings.downloadUsingCellular,
|
||||
"streamingUsingCellular": settings.streamingUsingCellular
|
||||
"streamingUsingCellular": settings.streamingUsingCellular,
|
||||
"disableSleepTimerFadeOut": settings.disableSleepTimerFadeOut
|
||||
]
|
||||
}
|
||||
|
|
|
@ -365,7 +365,57 @@ class AudioPlayer: NSObject {
|
|||
self.status = .paused
|
||||
updateNowPlaying()
|
||||
}
|
||||
|
||||
|
||||
public func startFadeOut() {
|
||||
guard self.isInitialized() else { return }
|
||||
guard let currentTime = self.getCurrentTime() else { return }
|
||||
logger.log("fadeOut: Fading out playback")
|
||||
|
||||
// Define fade parameters.
|
||||
let fadeDuration: Float = 60.0 // total fade duration in seconds
|
||||
let interval: Float = 1.0 // timer interval in seconds
|
||||
|
||||
// Get the current volume.
|
||||
let initialVolume = self.audioPlayer.volume
|
||||
let targetVolume: Float = 0.0
|
||||
|
||||
// If the current volume is already at or below zero, just pause.
|
||||
if initialVolume <= targetVolume {
|
||||
self.pause()
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate the volume change per timer tick.
|
||||
// (targetVolume - initialVolume) is negative since target < initial.
|
||||
let step = (targetVolume - initialVolume) * interval / fadeDuration
|
||||
|
||||
// Schedule a timer on the main queue to adjust the volume.
|
||||
DispatchQueue.runOnMainQueue { [weak self] in
|
||||
var timer = Timer.scheduledTimer(withTimeInterval: TimeInterval(interval), repeats: true) { t in
|
||||
guard let self = self else {
|
||||
t.invalidate()
|
||||
return
|
||||
}
|
||||
|
||||
// Calculate the new volume.
|
||||
let newVolume = self.audioPlayer.volume + step
|
||||
|
||||
// Check if the next step would go below zero.
|
||||
if newVolume > targetVolume {
|
||||
self.audioPlayer.volume = newVolume
|
||||
} else {
|
||||
// Ensure volume is exactly zero and end fade.
|
||||
self.audioPlayer.volume = targetVolume
|
||||
t.invalidate()
|
||||
self.logger.log("Fadeout: Fade complete, pausing playback")
|
||||
self.pause()
|
||||
self.audioPlayer.volume = initialVolume
|
||||
self.seek(currentTime, from: "fadeOut")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func seek(_ to: Double, from: String) {
|
||||
logger.log("SEEK: Seek to \(to) from \(from)")
|
||||
|
||||
|
|
|
@ -125,7 +125,11 @@ extension AudioPlayer {
|
|||
if var sleepTimeRemaining = self.sleepTimeRemaining {
|
||||
sleepTimeRemaining -= 1
|
||||
self.sleepTimeRemaining = sleepTimeRemaining
|
||||
|
||||
|
||||
if sleepTimeRemaining == 60 && self.isSleepTimerFadeOutEnabled() {
|
||||
self.startFadeOut()
|
||||
}
|
||||
|
||||
// Handle the sleep if the timer has expired
|
||||
if sleepTimeRemaining <= 0 {
|
||||
self.handleSleepEnd()
|
||||
|
@ -154,5 +158,9 @@ extension AudioPlayer {
|
|||
private func isChapterSleepTimerSet() -> Bool {
|
||||
return self.sleepTimeChapterStopAt != nil
|
||||
}
|
||||
|
||||
|
||||
private func isSleepTimerFadeOutEnabled() -> Bool {
|
||||
let deviceSettings = Database.shared.getDeviceSettings()
|
||||
return !deviceSettings.disableSleepTimerFadeOut
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue