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 40763a67..6358ea2c 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 @@ -135,6 +135,7 @@ data class DeviceSettings( var sleepTimerLength: Long, // Time in milliseconds var disableSleepTimerFadeOut: Boolean, var disableSleepTimerResetFeedback: Boolean, + var enableSleepTimerAlmostDoneChime: Boolean, var languageCode: String, var downloadUsingCellular: DownloadUsingCellularSetting, var streamingUsingCellular: StreamingUsingCellularSetting, @@ -163,6 +164,7 @@ data class DeviceSettings( autoSleepTimerAutoRewindTime = 300000L, // 5 minutes disableSleepTimerFadeOut = false, disableSleepTimerResetFeedback = false, + enableSleepTimerAlmostDoneChime = false, languageCode = "en-us", downloadUsingCellular = DownloadUsingCellularSetting.ALWAYS, streamingUsingCellular = StreamingUsingCellularSetting.ALWAYS, @@ -188,9 +190,9 @@ data class DeviceSettings( @JsonIgnore fun getShakeThresholdGravity() : Float { // Used in ShakeDetector - return if (shakeSensitivity == ShakeSensitivitySetting.VERY_HIGH) 1.2f - else if (shakeSensitivity == ShakeSensitivitySetting.HIGH) 1.4f - else if (shakeSensitivity == ShakeSensitivitySetting.MEDIUM) 1.6f + return if (shakeSensitivity == ShakeSensitivitySetting.VERY_HIGH) 1.1f + else if (shakeSensitivity == ShakeSensitivitySetting.HIGH) 1.3f + else if (shakeSensitivity == ShakeSensitivitySetting.MEDIUM) 1.5f else if (shakeSensitivity == ShakeSensitivitySetting.LOW) 2f else if (shakeSensitivity == ShakeSensitivitySetting.VERY_LOW) 2.7f else { diff --git a/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt b/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt index 2ba28d05..d31891ff 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/device/DeviceManager.kt @@ -64,6 +64,10 @@ object DeviceManager { if (deviceData.deviceSettings?.autoSleepTimerAutoRewindTime == null) { deviceData.deviceSettings?.autoSleepTimerAutoRewindTime = 300000L // 5 minutes } + // Initialize sleep timer almost done chime added in v0.9.81 + if (deviceData.deviceSettings?.enableSleepTimerAlmostDoneChime == null) { + deviceData.deviceSettings?.enableSleepTimerAlmostDoneChime = false + } // Language added in v0.9.69 if (deviceData.deviceSettings?.languageCode == null) { diff --git a/android/app/src/main/java/com/audiobookshelf/app/managers/SleepTimerManager.kt b/android/app/src/main/java/com/audiobookshelf/app/managers/SleepTimerManager.kt index c7b7aaa4..263a243e 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/managers/SleepTimerManager.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/managers/SleepTimerManager.kt @@ -1,15 +1,20 @@ package com.audiobookshelf.app.managers import android.content.Context +import android.media.MediaPlayer import android.os.* import android.util.Log +import com.audiobookshelf.app.R import com.audiobookshelf.app.device.DeviceManager import com.audiobookshelf.app.player.PlayerNotificationService import com.audiobookshelf.app.player.SLEEP_TIMER_WAKE_UP_EXPIRATION +import com.audiobookshelf.app.plugins.AbsLogger import java.util.* import kotlin.concurrent.schedule import kotlin.math.roundToInt +const val SLEEP_TIMER_CHIME_SOUND_VOLUME = 0.7f + class SleepTimerManager constructor(private val playerNotificationService: PlayerNotificationService) { private val tag = "SleepTimerManager" @@ -156,6 +161,10 @@ constructor(private val playerNotificationService: PlayerNotificationService) { ) } + if (sleepTimeSecondsRemaining == 30 && sleepTimerElapsed > 1 && DeviceManager.deviceData.deviceSettings?.enableSleepTimerAlmostDoneChime == true) { + playChimeSound() + } + if (sleepTimeSecondsRemaining <= 0) { Log.d(tag, "Sleep Timer Pausing Player on Chapter") pause() @@ -263,6 +272,19 @@ constructor(private val playerNotificationService: PlayerNotificationService) { } } + /** Plays chime sound */ + private fun playChimeSound() { + AbsLogger.info(tag, "playChimeSound: Playing sleep timer chime sound") + val ctx = playerNotificationService.getContext() + val mediaPlayer = MediaPlayer.create(ctx, R.raw.bell) + mediaPlayer.setVolume(SLEEP_TIMER_CHIME_SOUND_VOLUME, SLEEP_TIMER_CHIME_SOUND_VOLUME) + mediaPlayer.start() + mediaPlayer.setOnCompletionListener { + AbsLogger.info(tag, "playChimeSound: Releasing mediaPlayer after chime sound") + mediaPlayer.release() + } + } + /** * Gets the chapter end time for use in End of Chapter timers. If less than 10 seconds remain in * the chapter, then use the next chapter. diff --git a/android/app/src/main/java/com/audiobookshelf/app/player/ShakeDetector.kt b/android/app/src/main/java/com/audiobookshelf/app/player/ShakeDetector.kt index 331543db..d25206d1 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/player/ShakeDetector.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/player/ShakeDetector.kt @@ -5,6 +5,7 @@ import android.hardware.SensorEvent import android.hardware.SensorEventListener import android.hardware.SensorManager import com.audiobookshelf.app.device.DeviceManager +import com.audiobookshelf.app.plugins.AbsLogger import kotlin.math.sqrt class ShakeDetector : SensorEventListener { @@ -46,6 +47,7 @@ class ShakeDetector : SensorEventListener { if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) { mShakeCount = 0 } + AbsLogger.info("ShakeDetector", "Device shake above threshold ($gForce > $shakeThreshold)") mShakeTimestamp = now mShakeCount++ mListener!!.onShake(mShakeCount) diff --git a/android/app/src/main/res/raw/bell.mp3 b/android/app/src/main/res/raw/bell.mp3 new file mode 100644 index 00000000..c14bd84f Binary files /dev/null and b/android/app/src/main/res/raw/bell.mp3 differ diff --git a/pages/settings.vue b/pages/settings.vue index 5c3c75ae..660d6a6a 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -100,6 +100,13 @@

{{ $strings.LabelDisableVibrateOnReset }}

info +
+
+ +
+

{{ $strings.LabelSleepTimerAlmostDoneChime }}

+ info +
@@ -207,6 +214,7 @@ export default { sleepTimerLength: 900000, // 15 minutes disableSleepTimerFadeOut: false, disableSleepTimerResetFeedback: false, + enableSleepTimerAlmostDoneChime: false, autoSleepTimerAutoRewind: false, autoSleepTimerAutoRewindTime: 300000, // 5 minutes languageCode: 'en-us', @@ -234,6 +242,10 @@ export default { name: this.$strings.LabelDisableVibrateOnReset, message: this.$strings.LabelDisableVibrateOnResetHelp }, + enableSleepTimerAlmostDoneChime: { + name: this.$strings.LabelSleepTimerAlmostDoneChime, + message: this.$strings.LabelSleepTimerAlmostDoneChimeHelp + }, autoSleepTimerAutoRewind: { name: this.$strings.LabelAutoSleepTimerAutoRewind, message: this.$strings.LabelAutoSleepTimerAutoRewindHelp @@ -549,6 +561,10 @@ export default { this.settings.disableSleepTimerResetFeedback = !this.settings.disableSleepTimerResetFeedback this.saveSettings() }, + toggleSleepTimerAlmostDoneChime() { + this.settings.enableSleepTimerAlmostDoneChime = !this.settings.enableSleepTimerAlmostDoneChime + this.saveSettings() + }, toggleDisableAutoRewind() { this.settings.disableAutoRewind = !this.settings.disableAutoRewind this.saveSettings() @@ -620,6 +636,7 @@ export default { this.settings.sleepTimerLength = !isNaN(deviceSettings.sleepTimerLength) ? deviceSettings.sleepTimerLength : 900000 // 15 minutes this.settings.disableSleepTimerFadeOut = !!deviceSettings.disableSleepTimerFadeOut this.settings.disableSleepTimerResetFeedback = !!deviceSettings.disableSleepTimerResetFeedback + this.settings.enableSleepTimerAlmostDoneChime = !!deviceSettings.enableSleepTimerAlmostDoneChime this.settings.autoSleepTimerAutoRewind = !!deviceSettings.autoSleepTimerAutoRewind this.settings.autoSleepTimerAutoRewindTime = !isNaN(deviceSettings.autoSleepTimerAutoRewindTime) ? deviceSettings.autoSleepTimerAutoRewindTime : 300000 // 5 minutes diff --git a/strings/en-us.json b/strings/en-us.json index 0330a661..25c742cd 100644 --- a/strings/en-us.json +++ b/strings/en-us.json @@ -241,6 +241,8 @@ "LabelShowAll": "Show All", "LabelSize": "Size", "LabelSleepTimer": "Sleep timer", + "LabelSleepTimerAlmostDoneChime": "Play a chime when almost finished", + "LabelSleepTimerAlmostDoneChimeHelp": "Play a chime when the sleep timer has 30 seconds remaining", "LabelStart": "Start", "LabelStartTime": "Start time", "LabelStatsBestDay": "Best Day",