Merge pull request #228 from pipecat-ai/aleix/websocket-fixes

websocket fixes
This commit is contained in:
Aleix Conchillo Flaqué
2024-06-13 01:30:21 +08:00
committed by GitHub
5 changed files with 13 additions and 16 deletions

View File

@@ -19,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Fixed a couple of issues with `WebsocketServerTransport`. It needed to use
`push_audio_frame()` and also VAD was not working properly.
- Fixed an issue that would cause LLM aggregator to fail with small - Fixed an issue that would cause LLM aggregator to fail with small
`VADParams.stop_secs` values. `VADParams.stop_secs` values.

View File

@@ -12,14 +12,14 @@ import sys
from pipecat.frames.frames import LLMMessagesFrame from pipecat.frames.frames import LLMMessagesFrame
from pipecat.pipeline.pipeline import Pipeline from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.runner import PipelineRunner from pipecat.pipeline.runner import PipelineRunner
from pipecat.pipeline.task import PipelineParams, PipelineTask from pipecat.pipeline.task import PipelineTask
from pipecat.processors.aggregators.llm_response import ( from pipecat.processors.aggregators.llm_response import (
LLMAssistantResponseAggregator, LLMAssistantResponseAggregator,
LLMUserResponseAggregator LLMUserResponseAggregator
) )
from pipecat.services.deepgram import DeepgramSTTService
from pipecat.services.elevenlabs import ElevenLabsTTSService from pipecat.services.elevenlabs import ElevenLabsTTSService
from pipecat.services.openai import OpenAILLMService from pipecat.services.openai import OpenAILLMService
from pipecat.services.whisper import WhisperSTTService
from pipecat.transports.network.websocket_server import WebsocketServerParams, WebsocketServerTransport from pipecat.transports.network.websocket_server import WebsocketServerParams, WebsocketServerTransport
from pipecat.vad.silero import SileroVADAnalyzer from pipecat.vad.silero import SileroVADAnalyzer
@@ -36,7 +36,6 @@ async def main():
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
transport = WebsocketServerTransport( transport = WebsocketServerTransport(
params=WebsocketServerParams( params=WebsocketServerParams(
audio_in_enabled=True,
audio_out_enabled=True, audio_out_enabled=True,
add_wav_header=True, add_wav_header=True,
vad_enabled=True, vad_enabled=True,
@@ -49,7 +48,7 @@ async def main():
api_key=os.getenv("OPENAI_API_KEY"), api_key=os.getenv("OPENAI_API_KEY"),
model="gpt-4o") model="gpt-4o")
stt = WhisperSTTService() stt = DeepgramSTTService(api_key=os.getenv("DEEPGRAM_API_KEY"))
tts = ElevenLabsTTSService( tts = ElevenLabsTTSService(
aiohttp_session=session, aiohttp_session=session,

View File

@@ -25,6 +25,7 @@ from pipecat.services.ai_services import AIService, TTSService
from deepgram import ( from deepgram import (
DeepgramClient, DeepgramClient,
DeepgramClientOptions,
LiveTranscriptionEvents, LiveTranscriptionEvents,
LiveOptions, LiveOptions,
) )
@@ -92,7 +93,8 @@ class DeepgramSTTService(AIService):
self._live_options = live_options self._live_options = live_options
self._client = DeepgramClient(api_key) self._client = DeepgramClient(
api_key, config=DeepgramClientOptions(options={"keepalive": "true"}))
self._connection = self._client.listen.asynclive.v("1") self._connection = self._client.listen.asynclive.v("1")
self._connection.on(LiveTranscriptionEvents.Transcript, self._on_message) self._connection.on(LiveTranscriptionEvents.Transcript, self._on_message)

View File

@@ -70,7 +70,8 @@ class BaseInputTransport(FrameProcessor):
return self._params.vad_analyzer return self._params.vad_analyzer
def push_audio_frame(self, frame: AudioRawFrame): def push_audio_frame(self, frame: AudioRawFrame):
self._audio_in_queue.put_nowait(frame) if self._params.audio_in_enabled or self._params.vad_enabled:
self._audio_in_queue.put_nowait(frame)
# #
# Frame processor # Frame processor

View File

@@ -7,7 +7,6 @@
import asyncio import asyncio
import io import io
import queue
import wave import wave
import websockets import websockets
@@ -53,7 +52,6 @@ class WebsocketServerInputTransport(BaseInputTransport):
self._websocket: websockets.WebSocketServerProtocol | None = None self._websocket: websockets.WebSocketServerProtocol | None = None
self._client_audio_queue = queue.Queue()
self._stop_server_event = asyncio.Event() self._stop_server_event = asyncio.Event()
async def start(self, frame: StartFrame): async def start(self, frame: StartFrame):
@@ -65,12 +63,6 @@ class WebsocketServerInputTransport(BaseInputTransport):
await self._server_task await self._server_task
await super().stop() await super().stop()
def read_next_audio_frame(self) -> AudioRawFrame | None:
try:
return self._client_audio_queue.get(timeout=1)
except queue.Empty:
return None
async def _server_task_handler(self): async def _server_task_handler(self):
logger.info(f"Starting websocket server on {self._host}:{self._port}") logger.info(f"Starting websocket server on {self._host}:{self._port}")
async with websockets.serve(self._client_handler, self._host, self._port) as server: async with websockets.serve(self._client_handler, self._host, self._port) as server:
@@ -90,8 +82,8 @@ class WebsocketServerInputTransport(BaseInputTransport):
# Handle incoming messages # Handle incoming messages
async for message in websocket: async for message in websocket:
frame = self._params.serializer.deserialize(message) frame = self._params.serializer.deserialize(message)
if isinstance(frame, AudioRawFrame) and self._params.audio_in_enabled: if isinstance(frame, AudioRawFrame):
self._client_audio_queue.put_nowait(frame) self.push_audio_frame(frame)
else: else:
await self._internal_push_frame(frame) await self._internal_push_frame(frame)