fix: mute sends silence frames instead of dropping uplink

#12
by sseregin - opened
Files changed (1) hide show
  1. ws/s2s-ws-client.js +7 -2
ws/s2s-ws-client.js CHANGED
@@ -578,8 +578,13 @@ export class S2sWsRealtimeClient extends EventTarget {
578
  _onMicChunk(pcm16Buffer) {
579
  if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
580
  if (!this._sessionConfigured) return; // Server rejects audio before session.update.
581
- if (this._muted) return;
582
- const b64 = base64FromArrayBuffer(pcm16Buffer);
 
 
 
 
 
583
  this._send({ type: "input_audio_buffer.append", audio: b64 });
584
  }
585
 
 
578
  _onMicChunk(pcm16Buffer) {
579
  if (!this._ws || this._ws.readyState !== WebSocket.OPEN) return;
580
  if (!this._sessionConfigured) return; // Server rejects audio before session.update.
581
+ // While muted, keep the uplink flowing as pure silence instead of dropping
582
+ // frames. Privacy is preserved (no real mic audio leaves), while the
583
+ // server's audio clock keeps advancing so VAD sees trailing silence,
584
+ // soft-ends, and commits the pending turn. Mute thus acts as end-of-turn
585
+ // without stalling / disconnecting the session.
586
+ const buffer = this._muted ? new ArrayBuffer(pcm16Buffer.byteLength) : pcm16Buffer;
587
+ const b64 = base64FromArrayBuffer(buffer);
588
  this._send({ type: "input_audio_buffer.append", audio: b64 });
589
  }
590