fix(gateway-chat): resume AudioContext on user gesture (no-sound / autoplay)
Browsers suspend the Web Audio AudioContext until a user gesture; speakQuotes fires on reply-complete (no active gesture), so a suspended context played silently. Prime/resume the context on any click or keydown (capture phase) so it's running before playback. Server side was fine throughout (/tts + /tts/stream both 200 with valid audio).
This commit is contained in:
@@ -147,6 +147,12 @@ function showErr(text){ const m = addMsg('error','err'); m.body.className = 'err
|
|||||||
// --- mOrpheus TTS: streaming-decode auto-voice of quoted text (Web Audio, low TTFA) ---
|
// --- mOrpheus TTS: streaming-decode auto-voice of quoted text (Web Audio, low TTFA) ---
|
||||||
let audioCtx = null; // shared AudioContext
|
let audioCtx = null; // shared AudioContext
|
||||||
let ttsGen = 0; // generation counter — a newer reply's stream supersedes older ones
|
let ttsGen = 0; // generation counter — a newer reply's stream supersedes older ones
|
||||||
|
function primeAudio(){ // browsers suspend the AudioContext until a user gesture; resume on ANY
|
||||||
|
if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
if (audioCtx.state === 'suspended') audioCtx.resume(); // interaction so async playback isn't silent
|
||||||
|
}
|
||||||
|
document.addEventListener('click', primeAudio, true);
|
||||||
|
document.addEventListener('keydown', primeAudio, true);
|
||||||
function extractQuotes(text){
|
function extractQuotes(text){
|
||||||
const re = /“([^”]+)”|"([^"]+)"/g; // typographic "…" or straight "…"
|
const re = /“([^”]+)”|"([^"]+)"/g; // typographic "…" or straight "…"
|
||||||
const out = []; let m;
|
const out = []; let m;
|
||||||
|
|||||||
@@ -147,6 +147,12 @@ function showErr(text){ const m = addMsg('error','err'); m.body.className = 'err
|
|||||||
// --- mOrpheus TTS: streaming-decode auto-voice of quoted text (Web Audio, low TTFA) ---
|
// --- mOrpheus TTS: streaming-decode auto-voice of quoted text (Web Audio, low TTFA) ---
|
||||||
let audioCtx = null; // shared AudioContext
|
let audioCtx = null; // shared AudioContext
|
||||||
let ttsGen = 0; // generation counter — a newer reply's stream supersedes older ones
|
let ttsGen = 0; // generation counter — a newer reply's stream supersedes older ones
|
||||||
|
function primeAudio(){ // browsers suspend the AudioContext until a user gesture; resume on ANY
|
||||||
|
if (!audioCtx) audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||||||
|
if (audioCtx.state === 'suspended') audioCtx.resume(); // interaction so async playback isn't silent
|
||||||
|
}
|
||||||
|
document.addEventListener('click', primeAudio, true);
|
||||||
|
document.addEventListener('keydown', primeAudio, true);
|
||||||
function extractQuotes(text){
|
function extractQuotes(text){
|
||||||
const re = /“([^”]+)”|"([^"]+)"/g; // typographic "…" or straight "…"
|
const re = /“([^”]+)”|"([^"]+)"/g; // typographic "…" or straight "…"
|
||||||
const out = []; let m;
|
const out = []; let m;
|
||||||
|
|||||||
Reference in New Issue
Block a user