From e1299d59bf2234968f03d6dcda1d28b5dc00b866 Mon Sep 17 00:00:00 2001 From: Severin Klingler Date: Mon, 19 May 2025 15:22:13 +0200 Subject: [PATCH 1/2] fix(elevenlabs tts): Fix message paramter naming and make use of contexts to send out TTSStoppedFrames() --- src/pipecat/services/elevenlabs/tts.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/pipecat/services/elevenlabs/tts.py b/src/pipecat/services/elevenlabs/tts.py index 5e5a97e75..c9b51e7de 100644 --- a/src/pipecat/services/elevenlabs/tts.py +++ b/src/pipecat/services/elevenlabs/tts.py @@ -276,8 +276,16 @@ class ElevenLabsTTSService(AudioContextWordTTSService): async def flush_audio(self): if self._websocket and self._context_id: - msg = {"context_id": self._context_id, "flush": True} + self._context_id_to_close = self._context_id + msg = {"context_id": self._context_id, "flush": True, "xi_api_key": self._api_key} await self._websocket.send(json.dumps(msg)) + msg = { + "context_id": self._context_id, + "close_context": True, + "xi_api_key": self._api_key, + } + await self._websocket.send(json.dumps(msg)) + self._context_id = None async def push_frame(self, frame: Frame, direction: FrameDirection = FrameDirection.DOWNSTREAM): await super().push_frame(frame, direction) @@ -386,7 +394,7 @@ class ElevenLabsTTSService(AudioContextWordTTSService): msg = json.loads(message) # Check if this message belongs to the current context # The default context may return null/None for context_id - received_ctx_id = msg.get("context_id") + received_ctx_id = msg.get("contextId") if ( self._context_id is not None and received_ctx_id is not None @@ -406,12 +414,17 @@ class ElevenLabsTTSService(AudioContextWordTTSService): word_times = calculate_word_times(msg["alignment"], self._cumulative_time) await self.add_word_timestamps(word_times) self._cumulative_time = word_times[-1][1] - if msg.get("is_final"): + if msg.get("isFinal"): logger.trace(f"Received final message for context {received_ctx_id}") # Context has finished - if self._context_id == received_ctx_id: + if ( + self._context_id == received_ctx_id + or self._context_id_to_close == received_ctx_id + ): self._context_id = None + self._context_id_to_close = None self._started = False + await self.push_frame(TTSStoppedFrame()) async def _keepalive_task_handler(self): while True: From e74b9009147f626c63db45794e8e625ceb5089dd Mon Sep 17 00:00:00 2001 From: Severin Klingler Date: Wed, 21 May 2025 09:24:03 +0200 Subject: [PATCH 2/2] revert most of the changes except keyword naming fix --- src/pipecat/services/elevenlabs/tts.py | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/src/pipecat/services/elevenlabs/tts.py b/src/pipecat/services/elevenlabs/tts.py index c9b51e7de..6f03cf59a 100644 --- a/src/pipecat/services/elevenlabs/tts.py +++ b/src/pipecat/services/elevenlabs/tts.py @@ -276,16 +276,8 @@ class ElevenLabsTTSService(AudioContextWordTTSService): async def flush_audio(self): if self._websocket and self._context_id: - self._context_id_to_close = self._context_id - msg = {"context_id": self._context_id, "flush": True, "xi_api_key": self._api_key} + msg = {"context_id": self._context_id, "flush": True} await self._websocket.send(json.dumps(msg)) - msg = { - "context_id": self._context_id, - "close_context": True, - "xi_api_key": self._api_key, - } - await self._websocket.send(json.dumps(msg)) - self._context_id = None async def push_frame(self, frame: Frame, direction: FrameDirection = FrameDirection.DOWNSTREAM): await super().push_frame(frame, direction) @@ -417,14 +409,9 @@ class ElevenLabsTTSService(AudioContextWordTTSService): if msg.get("isFinal"): logger.trace(f"Received final message for context {received_ctx_id}") # Context has finished - if ( - self._context_id == received_ctx_id - or self._context_id_to_close == received_ctx_id - ): + if self._context_id == received_ctx_id: self._context_id = None - self._context_id_to_close = None self._started = False - await self.push_frame(TTSStoppedFrame()) async def _keepalive_task_handler(self): while True: