diff --git a/src/bot/audioProcedure.ts b/src/bot/audioProcedure.ts index 8f32732..128fe17 100644 --- a/src/bot/audioProcedure.ts +++ b/src/bot/audioProcedure.ts @@ -22,6 +22,7 @@ export class AudioProcedure { private _initScriptInjected: boolean = false; private _audioQueue: Array<{ audioData: string; format: 'mp3' | 'wav' | 'pcm' }> = []; private _isPlaying: boolean = false; + private _stopRequested: boolean = false; constructor(page: Page, logger: Logger) { this._page = page; @@ -138,8 +139,9 @@ export class AudioProcedure { private async _processAudioQueue(): Promise { if (this._isPlaying) return; this._isPlaying = true; + this._stopRequested = false; - while (this._audioQueue.length > 0) { + while (this._audioQueue.length > 0 && !this._stopRequested) { const item = this._audioQueue.shift()!; try { await this._playAudioInternal(item.audioData, item.format); @@ -148,7 +150,37 @@ export class AudioProcedure { } } + if (this._stopRequested) { + this._audioQueue = []; + this._logger.info('Audio queue cleared due to stop request'); + } + this._isPlaying = false; + this._stopRequested = false; + } + + /** + * Stop all audio immediately: stop current playback and clear the queue. + * Called when a user says " STOP" or similar. + */ + async stopAllAudio(): Promise { + this._logger.info('Stop all audio requested'); + this._stopRequested = true; + this._audioQueue = []; + + try { + await this._page.evaluate(() => { + const ctx = (window as any).__ttsAudioContext as AudioContext; + if (ctx) { + // Suspend immediately stops all audio output + ctx.suspend(); + // Resume after a short delay so future audio can play + setTimeout(() => ctx.resume(), 100); + } + }); + } catch { + // Page might not be ready + } } /** diff --git a/src/bot/orchestrator.ts b/src/bot/orchestrator.ts index 389bf96..468e1d7 100644 --- a/src/bot/orchestrator.ts +++ b/src/bot/orchestrator.ts @@ -334,6 +334,13 @@ export class BotOrchestrator { this.sendChatMessageToMeeting(chatMsg.text); break; + case 'stopAudio': + this._logger.info('Stop audio command received from Gateway'); + if (this._audioProcedure) { + this._audioProcedure.stopAllAudio(); + } + break; + case 'pong': // Heartbeat response break;