diff --git a/android/app/build.gradle b/android/app/build.gradle index 28213273..d9575023 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "com.audiobookshelf.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 47 - versionName "0.9.28-beta" + versionCode 48 + versionName "0.9.29-beta" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/src/main/java/com/audiobookshelf/app/MyNativeAudio.kt b/android/app/src/main/java/com/audiobookshelf/app/MyNativeAudio.kt index 551024ba..81526dc1 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/MyNativeAudio.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/MyNativeAudio.kt @@ -194,6 +194,30 @@ class MyNativeAudio : Plugin() { call.resolve(ret) } + @PluginMethod + fun increaseSleepTime(call: PluginCall) { + var time:Long = call.getString("time", "300000")!!.toLong() + + Handler(Looper.getMainLooper()).post() { + playerNotificationService.increaseSleepTime(time) + val ret = JSObject() + ret.put("success", true) + call.resolve() + } + } + + @PluginMethod + fun decreaseSleepTime(call: PluginCall) { + var time:Long = call.getString("time", "300000")!!.toLong() + + Handler(Looper.getMainLooper()).post() { + playerNotificationService.decreaseSleepTime(time) + val ret = JSObject() + ret.put("success", true) + call.resolve() + } + } + @PluginMethod fun cancelSleepTimer(call: PluginCall) { playerNotificationService.cancelSleepTimer() diff --git a/android/app/src/main/java/com/audiobookshelf/app/PlayerNotificationService.kt b/android/app/src/main/java/com/audiobookshelf/app/PlayerNotificationService.kt index b66ab10b..c6e9c751 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/PlayerNotificationService.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/PlayerNotificationService.kt @@ -69,7 +69,6 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { fun onSleepTimerSet(sleepTimerEndTime:Long) } - private val tag = "PlayerService" private var listener:MyCustomObjectListener? = null @@ -106,6 +105,8 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { private var sleepTimerTask:TimerTask? = null private var sleepTimerRunning:Boolean = false private var sleepTimerEndTime:Long = 0L + private var sleepTimerExtensionTime:Long = 0L + private var sleepTimerFinishedAt:Long = 0L private lateinit var audiobookManager:AudiobookManager private var newConnectionListener:SessionListener? = null @@ -496,9 +497,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { KeyEvent.KEYCODE_MEDIA_PLAY -> { if (0 == mediaButtonClickCount) { play() - if (sleepTimerRunning) { - extendSleepTime() - } + if (sleepTimerRunning || sleepTimerFinishedAt > 0L) checkShouldExtendSleepTimer() } handleMediaButtonClickCount() } @@ -522,9 +521,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { } else { if (0 == mediaButtonClickCount) { play() - if (sleepTimerRunning) { - extendSleepTime() - } + if (sleepTimerRunning || sleepTimerFinishedAt > 0L) checkShouldExtendSleepTimer() } handleMediaButtonClickCount() } @@ -810,6 +807,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { Log.d(tag, "Already playing") return } + currentPlayer.volume = 1F if (currentPlayer == castPlayer) { Log.d(tag, "CAST Player set on play ${currentPlayer.isLoading} || ${currentPlayer.duration} | ${currentPlayer.currentPosition}") } @@ -1000,10 +998,17 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { // SLEEP TIMER STUFF // + private fun getSleepTimerTimeRemainingSeconds():Int { + if (sleepTimerEndTime <= 0) return 0 + var sleepTimeRemaining = sleepTimerEndTime - getCurrentTime() + return ((sleepTimeRemaining / 1000).toDouble()).roundToInt() + } + fun setSleepTimer(time: Long, isChapterTime: Boolean) : Boolean { Log.d(tag, "Setting Sleep Timer for $time is chapter time $isChapterTime") sleepTimerTask?.cancel() sleepTimerRunning = false + sleepTimerFinishedAt = 0L var currentTime = getCurrentTime() if (isChapterTime) { @@ -1012,34 +1017,33 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { return false } sleepTimerEndTime = time + sleepTimerExtensionTime = SLEEP_EXTENSION_TIME } else { sleepTimerEndTime = currentTime + time + sleepTimerExtensionTime = time } if (sleepTimerEndTime > getDuration()) { sleepTimerEndTime = getDuration() } - Log.d(tag, "SLEEP VOLUME ${currentPlayer.volume} | ${currentPlayer.deviceVolume}") -// if (isChapterTime) { -// sleepChapterTime = time listener?.onSleepTimerSet(sleepTimerEndTime) sleepTimerRunning = true sleepTimerTask = Timer("SleepTimer", false).schedule(0L, 1000L) { Handler(Looper.getMainLooper()).post() { if (currentPlayer.isPlaying) { - var sleepTimeRemaining = sleepTimerEndTime - getCurrentTime() - var sleepTimeSecondsRemaining = ((sleepTimeRemaining / 1000).toDouble()).roundToInt() + var sleepTimeSecondsRemaining = getSleepTimerTimeRemainingSeconds() Log.d(tag, "Sleep TIMER time remaining $sleepTimeSecondsRemaining s") - if (sleepTimeRemaining <= 0) { + if (sleepTimeSecondsRemaining <= 0) { Log.d(tag, "Sleep Timer Pausing Player on Chapter") currentPlayer.pause() listener?.onSleepTimerEnded(currentPlayer.currentPosition) sleepTimerTask?.cancel() sleepTimerRunning = false + sleepTimerFinishedAt = System.currentTimeMillis() } else if (sleepTimeSecondsRemaining <= 30) { // Start fading out audio var volume = sleepTimeSecondsRemaining / 30F @@ -1068,19 +1072,62 @@ class PlayerNotificationService : MediaBrowserServiceCompat() { private fun extendSleepTime() { if (!sleepTimerRunning) return currentPlayer.volume = 1F - sleepTimerEndTime += SLEEP_EXTENSION_TIME + sleepTimerEndTime += sleepTimerExtensionTime if (sleepTimerEndTime > getDuration()) sleepTimerEndTime = getDuration() listener?.onSleepTimerSet(sleepTimerEndTime) } - fun handleShake() { - Log.d(tag, "HANDLE SHAKE HERE") - if (sleepTimerRunning) { - Log.d(tag, "Sleep Timer is Running, EXTEND TIME") - extendSleepTime() + private fun checkShouldExtendSleepTimer() { + if (!sleepTimerRunning) { + var finishedAtDistance = System.currentTimeMillis() - sleepTimerFinishedAt + if (finishedAtDistance > 120000) // 2 minutes + { + Log.d(tag, "Sleep timer finished over 2 mins ago, clearing it") + sleepTimerFinishedAt = 0L + return + } + + var newSleepTime = if (sleepTimerExtensionTime >= 0) sleepTimerExtensionTime else SLEEP_EXTENSION_TIME + setSleepTimer(newSleepTime, false) + play() + return } + // Only extend if within 30 seconds of finishing + var sleepTimeRemaining = getSleepTimerTimeRemainingSeconds() + if (sleepTimeRemaining <= 30) extendSleepTime() } + fun handleShake() { + Log.d(tag, "HANDLE SHAKE HERE") + if (sleepTimerRunning || sleepTimerFinishedAt > 0L) checkShouldExtendSleepTimer() + } + + fun increaseSleepTime(time:Long) { + Log.d(tag, "Increase Sleep time $time") + if (!sleepTimerRunning) return + var newSleepEndTime = sleepTimerEndTime + time + sleepTimerEndTime = if (newSleepEndTime >= getDuration()) { + getDuration() + } else { + newSleepEndTime + } + currentPlayer.volume = 1F + listener?.onSleepTimerSet(sleepTimerEndTime) + } + + fun decreaseSleepTime(time:Long) { + Log.d(tag, "Decrease Sleep time $time") + if (!sleepTimerRunning) return + var newSleepEndTime = sleepTimerEndTime - time + sleepTimerEndTime = if (newSleepEndTime <= 1000) { + // End sleep timer in 1 second + getCurrentTime() + 1000 + } else { + newSleepEndTime + } + currentPlayer.volume = 1F + listener?.onSleepTimerSet(sleepTimerEndTime) + } /* CAST STUFF diff --git a/android/app/src/main/java/com/audiobookshelf/app/ShakeDetector.kt b/android/app/src/main/java/com/audiobookshelf/app/ShakeDetector.kt index ac2b31b9..c61974a5 100644 --- a/android/app/src/main/java/com/audiobookshelf/app/ShakeDetector.kt +++ b/android/app/src/main/java/com/audiobookshelf/app/ShakeDetector.kt @@ -60,7 +60,7 @@ class ShakeDetector : SensorEventListener { * from the Google Play Store and run it to see how * many G's it takes to register a shake */ - private const val SHAKE_THRESHOLD_GRAVITY = 2.7f + private const val SHAKE_THRESHOLD_GRAVITY = 1.5f // orig 2.7f private const val SHAKE_SLOP_TIME_MS = 500 private const val SHAKE_COUNT_RESET_TIME_MS = 3000 } diff --git a/components/app/AudioPlayerContainer.vue b/components/app/AudioPlayerContainer.vue index 33bd810c..f2b57ce7 100644 --- a/components/app/AudioPlayerContainer.vue +++ b/components/app/AudioPlayerContainer.vue @@ -24,7 +24,7 @@ - + @@ -192,6 +192,13 @@ export default { return this.$toast.error('Sleep timer did not set, invalid time') } }, + increaseSleepTimer() { + // Default time to increase = 5 min + MyNativeAudio.increaseSleepTime({ time: '300000' }) + }, + decreaseSleepTimer() { + MyNativeAudio.decreaseSleepTime({ time: '300000' }) + }, async cancelSleepTimer() { console.log('Canceling sleep timer') await MyNativeAudio.cancelSleepTimer() diff --git a/components/modals/SleepTimerModal.vue b/components/modals/SleepTimerModal.vue index 1cd47f63..e3765e44 100644 --- a/components/modals/SleepTimerModal.vue +++ b/components/modals/SleepTimerModal.vue @@ -23,7 +23,12 @@
-

{{ timeRemainingPretty }}

+
+ remove +

{{ timeRemainingPretty }}

+ add +
+ Cancel Timer
@@ -52,7 +57,7 @@ export default { } }, timeouts() { - return [1, 15, 30, 45, 60, 75, 90, 120] + return [1, 5, 10, 15, 30, 45, 60, 90] }, timeRemainingPretty() { return this.$secondsToTimestamp(this.currentTime) @@ -71,6 +76,12 @@ export default { cancelSleepTimer() { this.$emit('cancel') this.show = false + }, + increaseSleepTime() { + this.$emit('increase') + }, + decreaseSleepTime() { + this.$emit('decrease') } }, mounted() {} diff --git a/package.json b/package.json index e5955473..91adff23 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "audiobookshelf-app", - "version": "v0.9.28-beta", + "version": "v0.9.29-beta", "author": "advplyr", "scripts": { "dev": "nuxt --hostname localhost --port 1337",