From 9d9ddc730b295cbf1006b0f3b88e021ed3612897 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 10 May 2026 15:20:43 +0200 Subject: [PATCH] debug+fix(audio): mehr Anruf-Logs + Tracking auch beim Resume-Sound MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Im Test 2 (zweiter Anruf in derselben Antwort) kam weder captureInterruption noch resumeFromInterruption als Log — beide returnen frueh ohne Hinweis warum. Jetzt loggen sie auch den Skip-Pfad damit man sieht ob's der idempotent-Guard oder fehlende playbackStartTime ist. Plus: _playFromPathAtPosition aktualisiert jetzt currentPlaybackMsgId und playbackStartTime — sonst stehen die auf den Werten der ersten TTS-Wiedergabe und ein zweiter Anruf-captureInterruption wuerde mit veraltetem Stand laufen. Co-Authored-By: Claude Opus 4.7 (1M context) --- android/src/services/audio.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/android/src/services/audio.ts b/android/src/services/audio.ts index 60f6d45..7c1eef7 100644 --- a/android/src/services/audio.ts +++ b/android/src/services/audio.ts @@ -399,10 +399,13 @@ class AudioService { * weiter obwohl das Audio gestoppt ist — der erste Halt ist der echte. */ captureInterruption(): number { if (this.pausedMessageId) { - // Schon erfasst — nicht ueberschreiben (zweiter Aufruf bei offhook). + console.log('[Audio] captureInterruption: bereits erfasst (msgId=%s pos=%ss) — skip', + this.pausedMessageId, this.pausedPosition.toFixed(2)); return this.pausedPosition; } if (!this.playbackStartTime || !this.currentPlaybackMsgId) { + console.log('[Audio] captureInterruption: nichts spielte (startTime=%s, msgId=%s)', + this.playbackStartTime, this.currentPlaybackMsgId || '(leer)'); this.pausedPosition = 0; this.pausedMessageId = ''; return 0; @@ -422,7 +425,12 @@ class AudioService { async resumeFromInterruption(maxWaitMs: number = 30000): Promise { const msgId = this.pausedMessageId; const position = this.pausedPosition; - if (!msgId) return false; + if (!msgId) { + console.log('[Audio] resumeFromInterruption: kein gemerkter Stand — skip'); + return false; + } + console.log('[Audio] resumeFromInterruption: starte fuer msgId=%s pos=%ss', + msgId, position.toFixed(2)); this.pausedMessageId = ''; // konsumieren const cachePath = `${RNFS.DocumentDirectoryPath}/tts_cache/${msgId}.wav`; const startTime = Date.now(); @@ -456,6 +464,14 @@ class AudioService { this._firePlaybackStarted(); this.isPlaying = true; this.resumeSound = sound; + // Tracking auch fuer den Resume-Sound aktualisieren — sonst kann + // captureInterruption bei einem zweiten Anruf die Position nicht + // mehr ermitteln (playbackStartTime waere von der ersten Wiedergabe). + const msgIdMatch = path.match(/([0-9a-f-]+)\.wav$/i); + if (msgIdMatch) this.currentPlaybackMsgId = msgIdMatch[1]; + // Virtuelle Start-Zeit so setzen, dass captureInterruption (das den + // Leading-Silence-Offset wieder abzieht) die korrekte Position liefert. + this.playbackStartTime = Date.now() - (positionSec + this.LEADING_SILENCE_SEC) * 1000; console.log('[Audio] Resume von Position %ss aus %s', positionSec.toFixed(2), path); sound.setCurrentTime(Math.max(0, positionSec));