mirror of
https://github.com/twinksoftware/Gearslip.git
synced 2026-11-10 16:02:25 +01:00
voice: "pause" keeps the music paused after the mic lets go
This commit is contained in:
1 parent
62b1835444
commit
01a41c01c8
3 files changed
+31
-5
No files matched your search
@@ -2,6 +2,7 @@ package app.seb3thehacker.gearslip.car
|
||||
|
||||
import android.content.Context
|
||||
import app.seb3thehacker.gearslip.media.CarMedia
|
||||
import app.seb3thehacker.gearslip.speech.VoiceFocus
|
||||
import java.text.DateFormat
|
||||
import java.util.Date
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -215,7 +216,8 @@ object AssistantCommands {
|
||||
val media = CarServices.media
|
||||
return when {
|
||||
"pause" in heard || heard.startsWith("stop") || heard == "quiet" || heard == "shut up" -> {
|
||||
if (media.now.value.playing) media.togglePlay()
|
||||
media.pause()
|
||||
VoiceFocus.afterRelease { media.pause() }
|
||||
"Paused."
|
||||
}
|
||||
"resume" in heard || "unpause" in heard || heard in RESUME_PHRASES ||
|
||||
|
||||
@@ -433,6 +433,12 @@ class CarMedia(private val context: Context) {
|
||||
val controls = controller?.transportControls ?: return
|
||||
if (_now.value.playing) controls.pause() else controls.play()
|
||||
}
|
||||
/**
|
||||
* Pauses whatever the app thinks it's doing. Voice pauses the music to listen, so by the time
|
||||
* "pause" is heard the app already looks stopped; a toggle did nothing and the song came back
|
||||
* as soon as the microphone let go. A real pause tells the app to stay stopped.
|
||||
*/
|
||||
fun pause() = controller?.transportControls?.pause()
|
||||
fun next() = controller?.transportControls?.skipToNext()
|
||||
fun previous() = controller?.transportControls?.skipToPrevious()
|
||||
fun seek(ms: Long) = controller?.transportControls?.seekTo(ms)
|
||||
|
||||
@@ -19,17 +19,35 @@ import app.seb3thehacker.gearslip.GearslipLog
|
||||
object VoiceFocus {
|
||||
|
||||
private const val RELEASE_DELAY_MS = 1_500L
|
||||
private const val AFTER_RELEASE_MS = 300L
|
||||
|
||||
private val main = Handler(Looper.getMainLooper())
|
||||
private var request: AudioFocusRequest? = null
|
||||
private var audio: AudioManager? = null
|
||||
private var holders = 0
|
||||
private val afterRelease = mutableListOf<() -> Unit>()
|
||||
|
||||
private val releaseNow = Runnable {
|
||||
val r = request ?: return@Runnable
|
||||
audio?.abandonAudioFocusRequest(r)
|
||||
request = null
|
||||
GearslipLog.i("voice: gave audio focus back")
|
||||
request?.let { r ->
|
||||
audio?.abandonAudioFocusRequest(r)
|
||||
request = null
|
||||
GearslipLog.i("voice: gave audio focus back")
|
||||
}
|
||||
val pending = afterRelease.toList()
|
||||
afterRelease.clear()
|
||||
// Just after the music app has had its focus back and acted on it.
|
||||
if (pending.isNotEmpty()) main.postDelayed({ pending.forEach { it() } }, AFTER_RELEASE_MS)
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs [action] once the music has its focus back, or now if Gearslip isn't holding it.
|
||||
* Metrolist takes a pause sent while it's held as nothing and resumes when focus returns,
|
||||
* so "pause" sends it again from here.
|
||||
*/
|
||||
fun afterRelease(action: () -> Unit) {
|
||||
main.post {
|
||||
if (request == null && holders == 0) action() else afterRelease += action
|
||||
}
|
||||
}
|
||||
|
||||
/** Pauses the music until a matching [release]. Safe from any thread. */
|
||||
|
||||
Reference in new issue
Block a user