Fix:Sleep timer volume reset #10, Change:Sleep timer resets to originally selected time only if less than 30s or finished within 2m #10, Add:Sleep timer +/- buttons

This commit is contained in:
advplyr 2021-11-27 12:15:17 -06:00
parent edc45addc9
commit a7de535123
7 changed files with 115 additions and 26 deletions

View file

@ -13,8 +13,8 @@ android {
applicationId "com.audiobookshelf.app" applicationId "com.audiobookshelf.app"
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 47 versionCode 48
versionName "0.9.28-beta" versionName "0.9.29-beta"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions { aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.

View file

@ -194,6 +194,30 @@ class MyNativeAudio : Plugin() {
call.resolve(ret) 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 @PluginMethod
fun cancelSleepTimer(call: PluginCall) { fun cancelSleepTimer(call: PluginCall) {
playerNotificationService.cancelSleepTimer() playerNotificationService.cancelSleepTimer()

View file

@ -69,7 +69,6 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
fun onSleepTimerSet(sleepTimerEndTime:Long) fun onSleepTimerSet(sleepTimerEndTime:Long)
} }
private val tag = "PlayerService" private val tag = "PlayerService"
private var listener:MyCustomObjectListener? = null private var listener:MyCustomObjectListener? = null
@ -106,6 +105,8 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
private var sleepTimerTask:TimerTask? = null private var sleepTimerTask:TimerTask? = null
private var sleepTimerRunning:Boolean = false private var sleepTimerRunning:Boolean = false
private var sleepTimerEndTime:Long = 0L private var sleepTimerEndTime:Long = 0L
private var sleepTimerExtensionTime:Long = 0L
private var sleepTimerFinishedAt:Long = 0L
private lateinit var audiobookManager:AudiobookManager private lateinit var audiobookManager:AudiobookManager
private var newConnectionListener:SessionListener? = null private var newConnectionListener:SessionListener? = null
@ -496,9 +497,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
KeyEvent.KEYCODE_MEDIA_PLAY -> { KeyEvent.KEYCODE_MEDIA_PLAY -> {
if (0 == mediaButtonClickCount) { if (0 == mediaButtonClickCount) {
play() play()
if (sleepTimerRunning) { if (sleepTimerRunning || sleepTimerFinishedAt > 0L) checkShouldExtendSleepTimer()
extendSleepTime()
}
} }
handleMediaButtonClickCount() handleMediaButtonClickCount()
} }
@ -522,9 +521,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
} else { } else {
if (0 == mediaButtonClickCount) { if (0 == mediaButtonClickCount) {
play() play()
if (sleepTimerRunning) { if (sleepTimerRunning || sleepTimerFinishedAt > 0L) checkShouldExtendSleepTimer()
extendSleepTime()
}
} }
handleMediaButtonClickCount() handleMediaButtonClickCount()
} }
@ -810,6 +807,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
Log.d(tag, "Already playing") Log.d(tag, "Already playing")
return return
} }
currentPlayer.volume = 1F
if (currentPlayer == castPlayer) { if (currentPlayer == castPlayer) {
Log.d(tag, "CAST Player set on play ${currentPlayer.isLoading} || ${currentPlayer.duration} | ${currentPlayer.currentPosition}") Log.d(tag, "CAST Player set on play ${currentPlayer.isLoading} || ${currentPlayer.duration} | ${currentPlayer.currentPosition}")
} }
@ -1000,10 +998,17 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
// SLEEP TIMER STUFF // 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 { fun setSleepTimer(time: Long, isChapterTime: Boolean) : Boolean {
Log.d(tag, "Setting Sleep Timer for $time is chapter time $isChapterTime") Log.d(tag, "Setting Sleep Timer for $time is chapter time $isChapterTime")
sleepTimerTask?.cancel() sleepTimerTask?.cancel()
sleepTimerRunning = false sleepTimerRunning = false
sleepTimerFinishedAt = 0L
var currentTime = getCurrentTime() var currentTime = getCurrentTime()
if (isChapterTime) { if (isChapterTime) {
@ -1012,34 +1017,33 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
return false return false
} }
sleepTimerEndTime = time sleepTimerEndTime = time
sleepTimerExtensionTime = SLEEP_EXTENSION_TIME
} else { } else {
sleepTimerEndTime = currentTime + time sleepTimerEndTime = currentTime + time
sleepTimerExtensionTime = time
} }
if (sleepTimerEndTime > getDuration()) { if (sleepTimerEndTime > getDuration()) {
sleepTimerEndTime = getDuration() sleepTimerEndTime = getDuration()
} }
Log.d(tag, "SLEEP VOLUME ${currentPlayer.volume} | ${currentPlayer.deviceVolume}")
// if (isChapterTime) {
// sleepChapterTime = time
listener?.onSleepTimerSet(sleepTimerEndTime) listener?.onSleepTimerSet(sleepTimerEndTime)
sleepTimerRunning = true sleepTimerRunning = true
sleepTimerTask = Timer("SleepTimer", false).schedule(0L, 1000L) { sleepTimerTask = Timer("SleepTimer", false).schedule(0L, 1000L) {
Handler(Looper.getMainLooper()).post() { Handler(Looper.getMainLooper()).post() {
if (currentPlayer.isPlaying) { if (currentPlayer.isPlaying) {
var sleepTimeRemaining = sleepTimerEndTime - getCurrentTime() var sleepTimeSecondsRemaining = getSleepTimerTimeRemainingSeconds()
var sleepTimeSecondsRemaining = ((sleepTimeRemaining / 1000).toDouble()).roundToInt()
Log.d(tag, "Sleep TIMER time remaining $sleepTimeSecondsRemaining s") Log.d(tag, "Sleep TIMER time remaining $sleepTimeSecondsRemaining s")
if (sleepTimeRemaining <= 0) { if (sleepTimeSecondsRemaining <= 0) {
Log.d(tag, "Sleep Timer Pausing Player on Chapter") Log.d(tag, "Sleep Timer Pausing Player on Chapter")
currentPlayer.pause() currentPlayer.pause()
listener?.onSleepTimerEnded(currentPlayer.currentPosition) listener?.onSleepTimerEnded(currentPlayer.currentPosition)
sleepTimerTask?.cancel() sleepTimerTask?.cancel()
sleepTimerRunning = false sleepTimerRunning = false
sleepTimerFinishedAt = System.currentTimeMillis()
} else if (sleepTimeSecondsRemaining <= 30) { } else if (sleepTimeSecondsRemaining <= 30) {
// Start fading out audio // Start fading out audio
var volume = sleepTimeSecondsRemaining / 30F var volume = sleepTimeSecondsRemaining / 30F
@ -1068,19 +1072,62 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
private fun extendSleepTime() { private fun extendSleepTime() {
if (!sleepTimerRunning) return if (!sleepTimerRunning) return
currentPlayer.volume = 1F currentPlayer.volume = 1F
sleepTimerEndTime += SLEEP_EXTENSION_TIME sleepTimerEndTime += sleepTimerExtensionTime
if (sleepTimerEndTime > getDuration()) sleepTimerEndTime = getDuration() if (sleepTimerEndTime > getDuration()) sleepTimerEndTime = getDuration()
listener?.onSleepTimerSet(sleepTimerEndTime) listener?.onSleepTimerSet(sleepTimerEndTime)
} }
fun handleShake() { private fun checkShouldExtendSleepTimer() {
Log.d(tag, "HANDLE SHAKE HERE") if (!sleepTimerRunning) {
if (sleepTimerRunning) { var finishedAtDistance = System.currentTimeMillis() - sleepTimerFinishedAt
Log.d(tag, "Sleep Timer is Running, EXTEND TIME") if (finishedAtDistance > 120000) // 2 minutes
extendSleepTime() {
} 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 CAST STUFF

View file

@ -60,7 +60,7 @@ class ShakeDetector : SensorEventListener {
* from the Google Play Store and run it to see how * from the Google Play Store and run it to see how
* many G's it takes to register a shake * 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_SLOP_TIME_MS = 500
private const val SHAKE_COUNT_RESET_TIME_MS = 3000 private const val SHAKE_COUNT_RESET_TIME_MS = 3000
} }

View file

@ -24,7 +24,7 @@
<modals-playback-speed-modal v-model="showPlaybackSpeedModal" :playback-speed.sync="playbackSpeed" @change="changePlaybackSpeed" /> <modals-playback-speed-modal v-model="showPlaybackSpeedModal" :playback-speed.sync="playbackSpeed" @change="changePlaybackSpeed" />
<modals-chapters-modal v-model="showChapterModal" :current-chapter="currentChapter" :chapters="chapters" @select="selectChapter" /> <modals-chapters-modal v-model="showChapterModal" :current-chapter="currentChapter" :chapters="chapters" @select="selectChapter" />
<modals-sleep-timer-modal v-model="showSleepTimerModal" :current-time="sleepTimeRemaining" :sleep-timer-running="isSleepTimerRunning" :current-end-of-chapter-time="currentEndOfChapterTime" @change="selectSleepTimeout" @cancel="cancelSleepTimer" /> <modals-sleep-timer-modal v-model="showSleepTimerModal" :current-time="sleepTimeRemaining" :sleep-timer-running="isSleepTimerRunning" :current-end-of-chapter-time="currentEndOfChapterTime" @change="selectSleepTimeout" @cancel="cancelSleepTimer" @increase="increaseSleepTimer" @decrease="decreaseSleepTimer" />
<modals-bookmarks-modal v-model="showBookmarksModal" :audiobook-id="audiobookId" :bookmarks="bookmarks" :current-time="currentTime" @select="selectBookmark" /> <modals-bookmarks-modal v-model="showBookmarksModal" :audiobook-id="audiobookId" :bookmarks="bookmarks" :current-time="currentTime" @select="selectBookmark" />
</div> </div>
</template> </template>
@ -192,6 +192,13 @@ export default {
return this.$toast.error('Sleep timer did not set, invalid time') 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() { async cancelSleepTimer() {
console.log('Canceling sleep timer') console.log('Canceling sleep timer')
await MyNativeAudio.cancelSleepTimer() await MyNativeAudio.cancelSleepTimer()

View file

@ -23,7 +23,12 @@
</li> </li>
</ul> </ul>
<div v-else class="px-2 py-4"> <div v-else class="px-2 py-4">
<p class="mb-4 text-2xl font-mono text-center">{{ timeRemainingPretty }}</p> <div class="flex my-2 justify-between">
<ui-btn @click="decreaseSleepTime" class="w-9 h-9" :padding-x="0" small style="max-width: 36px"><span class="material-icons">remove</span></ui-btn>
<p class="text-2xl font-mono text-center">{{ timeRemainingPretty }}</p>
<ui-btn @click="increaseSleepTime" class="w-9 h-9" :padding-x="0" small style="max-width: 36px"><span class="material-icons">add</span></ui-btn>
</div>
<ui-btn @click="cancelSleepTimer" class="w-full">Cancel Timer</ui-btn> <ui-btn @click="cancelSleepTimer" class="w-full">Cancel Timer</ui-btn>
</div> </div>
</div> </div>
@ -52,7 +57,7 @@ export default {
} }
}, },
timeouts() { timeouts() {
return [1, 15, 30, 45, 60, 75, 90, 120] return [1, 5, 10, 15, 30, 45, 60, 90]
}, },
timeRemainingPretty() { timeRemainingPretty() {
return this.$secondsToTimestamp(this.currentTime) return this.$secondsToTimestamp(this.currentTime)
@ -71,6 +76,12 @@ export default {
cancelSleepTimer() { cancelSleepTimer() {
this.$emit('cancel') this.$emit('cancel')
this.show = false this.show = false
},
increaseSleepTime() {
this.$emit('increase')
},
decreaseSleepTime() {
this.$emit('decrease')
} }
}, },
mounted() {} mounted() {}

View file

@ -1,6 +1,6 @@
{ {
"name": "audiobookshelf-app", "name": "audiobookshelf-app",
"version": "v0.9.28-beta", "version": "v0.9.29-beta",
"author": "advplyr", "author": "advplyr",
"scripts": { "scripts": {
"dev": "nuxt --hostname localhost --port 1337", "dev": "nuxt --hostname localhost --port 1337",