Release GPS2Audio v2.7.39 remove manual playback gap
This commit is contained in:
@@ -197,18 +197,14 @@ class WaypointViewModel(application: Application) : AndroidViewModel(application
|
||||
private val _manualPlaying = MutableStateFlow(false)
|
||||
val manualPlaying: StateFlow<Boolean> = _manualPlaying.asStateFlow()
|
||||
|
||||
// v2.7.37 — Kurze Stille zwischen Clips/Wegpunkten bei der manuellen
|
||||
// Sequenz-Wiedergabe ("Hörbuch-Gefühl"). Nur im Auto-Advance-Pfad der
|
||||
// Tour-/Sequenz-Wiedergabe; NICHT bei GPS, PTT, Atmo oder Einzelclip-Vorschau.
|
||||
// Bewusst kein UI-Setting und keine Persistenz — fester interner Wert.
|
||||
private var manualGapJob: Job? = null
|
||||
|
||||
/** Bricht eine laufende Auto-Advance-Pause ab, sodass kein verzögerter
|
||||
* Start nach Stop/Pause/Skip/Tour-Wechsel mehr feuert. */
|
||||
private fun cancelManualGap() {
|
||||
manualGapJob?.cancel()
|
||||
manualGapJob = null
|
||||
}
|
||||
// v2.7.39 — Die in v2.7.37 eingeführte feste Stille-Pause zwischen
|
||||
// manuellen Clips/Wegpunkten ist aus Stabilitätsgründen wieder entfernt.
|
||||
// Auf einigen Samsung-Geräten führte der verzögerte Auto-Advance zu
|
||||
// uneindeutigem Player-State und konnte fälschlich "Audio konnte nicht
|
||||
// abgespielt werden" auslösen. Die Methode bleibt als No-op bestehen,
|
||||
// damit bestehende Stop-/Skip-/Tourwechsel-Pfade ohne strukturelles Risiko
|
||||
// weiter denselben Aufräumaufruf verwenden können.
|
||||
private fun cancelManualGap() = Unit
|
||||
|
||||
/** Name of the waypoint currently loaded in the manual player (null = nothing loaded). */
|
||||
private val _manualCurrentName = MutableStateFlow<String?>(null)
|
||||
@@ -601,10 +597,9 @@ class WaypointViewModel(application: Application) : AndroidViewModel(application
|
||||
if (safeTarget != de.waypointaudio.data.Waypoint.DEFAULT_TOUR_NAME) {
|
||||
_neutralExplorerMode = false
|
||||
}
|
||||
// v2.7.38 — Audio-Zuverlässigkeit: Ein evtl. anstehender Auto-Advance-
|
||||
// Gap-Job gehört zur alten Tour. Beim Tour-Wechsel abbrechen, damit kein
|
||||
// verspäteter Start in der falschen Tour feuert. Aktiv laufende
|
||||
// Wiedergabe bleibt davon unberührt (Persistenz, s. u.).
|
||||
// v2.7.39 — Legacy-Aufräumaufruf bleibt erhalten, ist nach Entfernen
|
||||
// der festen manuellen Pause aber ein No-op. Aktiv laufende Wiedergabe
|
||||
// bleibt vom bloßen Tour-Wechsel weiterhin unberührt (Persistenz, s. u.).
|
||||
if (safeTarget != _selectedTour.value) {
|
||||
cancelManualGap()
|
||||
}
|
||||
@@ -978,9 +973,8 @@ class WaypointViewModel(application: Application) : AndroidViewModel(application
|
||||
val nextTour = current.firstOrNull() ?: Waypoint.DEFAULT_TOUR_NAME
|
||||
if (_selectedTour.value == tourName) {
|
||||
// Reset manual player state
|
||||
// v2.7.38 — Auch den anstehenden Auto-Advance-Gap-Job abbrechen,
|
||||
// sonst startet er 1,7 s nach dem Stop fälschlich erneut Audio
|
||||
// gegen die gerade gelöschte Tour.
|
||||
// v2.7.39 — Legacy-Aufräumaufruf; nach Entfernen der festen
|
||||
// manuellen Pause gibt es keinen verzögerten Auto-Advance-Job mehr.
|
||||
cancelManualGap()
|
||||
manualPlayer.stop()
|
||||
_manualPlaying.value = false
|
||||
@@ -1857,17 +1851,6 @@ class WaypointViewModel(application: Application) : AndroidViewModel(application
|
||||
_singlePlayingActive.value = false
|
||||
}
|
||||
|
||||
// v2.7.37 — Während der Stille-Pause läuft kein MediaPlayer, der State
|
||||
// ist aber "playing". Pause-Tippen soll dann die Auto-Advance-Pause
|
||||
// abbrechen und nicht neu starten.
|
||||
if (manualGapJob != null) {
|
||||
cancelManualGap()
|
||||
_manualPlaying.value = false
|
||||
stopProgressTicker(keepSnapshot = true)
|
||||
musicManager.afterWaypointAudio()
|
||||
return
|
||||
}
|
||||
|
||||
if (manualPlayer.isPlaying) {
|
||||
manualPlayer.pause()
|
||||
_manualPlaying.value = false
|
||||
@@ -2028,57 +2011,27 @@ class WaypointViewModel(application: Application) : AndroidViewModel(application
|
||||
return@play
|
||||
}
|
||||
val nextItem = nextSeq[nextIdx]
|
||||
// v2.7.37 — Kurze Stille vor dem nächsten Eintrag (Hörbuch-Gefühl).
|
||||
// Läuft als abbrechbarer Job: Pause/Stop/Skip/Tour-Wechsel rufen
|
||||
// cancelManualGap() und verhindern so einen verspäteten Auto-Start.
|
||||
// Die Sequenz wird NACH der Pause erneut ausgewertet, da sich der
|
||||
// Zustand (PTT, gelöschte Wegpunkte, deaktivierte Clips) während der
|
||||
// Wartezeit ändern kann.
|
||||
//
|
||||
// v2.7.38 — Audio-Zuverlässigkeit (Samsung-Regressionsfix):
|
||||
// Die Gap ist STRIKT auf den Auto-Advance NACH einem natürlich
|
||||
// beendeten Clip beschränkt. Sie darf den Folge-Clip nur dann
|
||||
// starten, wenn währenddessen weder die Tour gewechselt wurde noch
|
||||
// der Nutzer pausiert/gestoppt hat. Andernfalls wird der verzögerte
|
||||
// Start verworfen, statt den Zustand fälschlich auf "spielt" zu
|
||||
// lassen oder Audio in der falschen Tour zu starten.
|
||||
val gapTour = _selectedTour.value
|
||||
cancelManualGap()
|
||||
manualGapJob = viewModelScope.launch {
|
||||
delay(MANUAL_GAP_MS)
|
||||
manualGapJob = null
|
||||
// Tour gewechselt während der Stille → kein Auto-Advance.
|
||||
// Laufende/zukünftige Wiedergabe der anderen Tour nicht stören;
|
||||
// nur den eigenen verspäteten Start verwerfen.
|
||||
if (_selectedTour.value != gapTour) {
|
||||
return@launch
|
||||
}
|
||||
// Nutzer hat während der Stille pausiert/gestoppt
|
||||
// (z. B. Pause-Tippen, Stop, neuer Single-Clip) → nicht starten.
|
||||
if (!_manualPlaying.value || manualPlayer.isSingleMode) {
|
||||
return@launch
|
||||
}
|
||||
if (pttManager.pttActive.value) {
|
||||
_manualPlaying.value = false
|
||||
stopProgressTicker(keepSnapshot = true)
|
||||
return@launch
|
||||
}
|
||||
val seqAfterGap = playableSequence()
|
||||
val resolvedIdx = seqAfterGap.indexOfFirst { it.compoundId == nextItem.compoundId }
|
||||
if (resolvedIdx < 0) {
|
||||
// Nächster Eintrag existiert nicht mehr → sauber stoppen.
|
||||
_manualPlaying.value = false
|
||||
_manualCurrentName.value = null
|
||||
_currentPlayable.value = null
|
||||
stopProgressTicker(keepSnapshot = false)
|
||||
musicManager.afterWaypointAudio()
|
||||
return@launch
|
||||
}
|
||||
val resolved = seqAfterGap[resolvedIdx]
|
||||
_currentPlayable.value = resolved
|
||||
_manualIndex.value = resolved.waypointIndex - 1
|
||||
playFromCurrentPlayable(autoAdvance = true)
|
||||
// v2.7.39 — Keine feste Stille-Pause mehr: Der nächste Eintrag wird
|
||||
// direkt gestartet. Dadurch gibt es keinen verzögerten Job mehr, der
|
||||
// auf Samsung-Geräten oder nach Tour-/GPS-State-Wechseln in einen
|
||||
// veralteten Player-Zustand feuern könnte.
|
||||
if (!_manualPlaying.value || manualPlayer.isSingleMode) {
|
||||
return@play
|
||||
}
|
||||
val seqNow = playableSequence()
|
||||
val resolvedIdx = seqNow.indexOfFirst { it.compoundId == nextItem.compoundId }
|
||||
if (resolvedIdx < 0) {
|
||||
_manualPlaying.value = false
|
||||
_manualCurrentName.value = null
|
||||
_currentPlayable.value = null
|
||||
stopProgressTicker(keepSnapshot = false)
|
||||
musicManager.afterWaypointAudio()
|
||||
return@play
|
||||
}
|
||||
val resolved = seqNow[resolvedIdx]
|
||||
_currentPlayable.value = resolved
|
||||
_manualIndex.value = resolved.waypointIndex - 1
|
||||
playFromCurrentPlayable(autoAdvance = true)
|
||||
}
|
||||
startProgressTicker()
|
||||
}
|
||||
@@ -2733,11 +2686,5 @@ class WaypointViewModel(application: Application) : AndroidViewModel(application
|
||||
*/
|
||||
private const val PROGRESS_TICK_MS = 500L
|
||||
|
||||
/**
|
||||
* v2.7.37 — Feste Stille-Pause vor dem automatischen Start des nächsten
|
||||
* Eintrags in der manuellen Sequenz-Wiedergabe (Clip→Clip und
|
||||
* Wegpunkt→Wegpunkt). Gibt der Wiedergabe ein hörbuchartiges Gefühl.
|
||||
*/
|
||||
private const val MANUAL_GAP_MS = 1700L
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user