Merge pull request #2168 from pipecat-ai/mb/fix-neuophonic-tts
Fix: NeuphonicTTSService to use latest websocket API
This commit is contained in:
@@ -33,6 +33,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
`UserIdleProcessor` in conjunction with function calls that take a while to
|
`UserIdleProcessor` in conjunction with function calls that take a while to
|
||||||
return a result.
|
return a result.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Updated the `NeuphonicTTSService` to work with the updated websocket API.
|
||||||
|
|
||||||
### Performance
|
### Performance
|
||||||
|
|
||||||
- Remove unncessary push task in each `FrameProcessor`.
|
- Remove unncessary push task in each `FrameProcessor`.
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ class NeuphonicTTSService(InterruptibleTTSService):
|
|||||||
*,
|
*,
|
||||||
api_key: str,
|
api_key: str,
|
||||||
voice_id: Optional[str] = None,
|
voice_id: Optional[str] = None,
|
||||||
url: str = "wss://api.neuphonic.com",
|
url: str = "wss://eu-west-1.api.neuphonic.com",
|
||||||
sample_rate: Optional[int] = 22050,
|
sample_rate: Optional[int] = 22050,
|
||||||
encoding: str = "pcm_linear",
|
encoding: str = "pcm_linear",
|
||||||
params: Optional[InputParams] = None,
|
params: Optional[InputParams] = None,
|
||||||
@@ -281,14 +281,18 @@ class NeuphonicTTSService(InterruptibleTTSService):
|
|||||||
"voice_id": self._voice_id,
|
"voice_id": self._voice_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
query_params = [f"api_key={self._api_key}"]
|
query_params = []
|
||||||
for key, value in tts_config.items():
|
for key, value in tts_config.items():
|
||||||
if value is not None:
|
if value is not None:
|
||||||
query_params.append(f"{key}={value}")
|
query_params.append(f"{key}={value}")
|
||||||
|
|
||||||
url = f"{self._url}/speak/{self._settings['lang_code']}?{'&'.join(query_params)}"
|
url = f"{self._url}/speak/{self._settings['lang_code']}"
|
||||||
|
if query_params:
|
||||||
|
url += f"?{'&'.join(query_params)}"
|
||||||
|
|
||||||
self._websocket = await websockets.connect(url)
|
headers = {"x-api-key": self._api_key}
|
||||||
|
|
||||||
|
self._websocket = await websockets.connect(url, extra_headers=headers)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self} initialization error: {e}")
|
logger.error(f"{self} initialization error: {e}")
|
||||||
self._websocket = None
|
self._websocket = None
|
||||||
@@ -313,7 +317,7 @@ class NeuphonicTTSService(InterruptibleTTSService):
|
|||||||
async for message in WatchdogAsyncIterator(self._websocket, manager=self.task_manager):
|
async for message in WatchdogAsyncIterator(self._websocket, manager=self.task_manager):
|
||||||
if isinstance(message, str):
|
if isinstance(message, str):
|
||||||
msg = json.loads(message)
|
msg = json.loads(message)
|
||||||
if msg.get("data", {}).get("audio") is not None:
|
if msg.get("data") and msg["data"].get("audio"):
|
||||||
await self.stop_ttfb_metrics()
|
await self.stop_ttfb_metrics()
|
||||||
|
|
||||||
audio = base64.b64decode(msg["data"]["audio"])
|
audio = base64.b64decode(msg["data"]["audio"])
|
||||||
@@ -326,12 +330,19 @@ class NeuphonicTTSService(InterruptibleTTSService):
|
|||||||
while True:
|
while True:
|
||||||
self.reset_watchdog()
|
self.reset_watchdog()
|
||||||
await asyncio.sleep(KEEPALIVE_SLEEP)
|
await asyncio.sleep(KEEPALIVE_SLEEP)
|
||||||
await self._send_text("")
|
await self._send_keepalive()
|
||||||
|
|
||||||
|
async def _send_keepalive(self):
|
||||||
|
"""Send keepalive message to maintain connection."""
|
||||||
|
if self._websocket:
|
||||||
|
# Send empty text for keepalive
|
||||||
|
msg = {"text": ""}
|
||||||
|
await self._websocket.send(json.dumps(msg))
|
||||||
|
|
||||||
async def _send_text(self, text: str):
|
async def _send_text(self, text: str):
|
||||||
"""Send text to Neuphonic WebSocket for synthesis."""
|
"""Send text to Neuphonic WebSocket for synthesis."""
|
||||||
if self._websocket:
|
if self._websocket:
|
||||||
msg = {"text": text}
|
msg = {"text": f"{text} <STOP>"}
|
||||||
logger.debug(f"Sending text to websocket: {msg}")
|
logger.debug(f"Sending text to websocket: {msg}")
|
||||||
await self._websocket.send(json.dumps(msg))
|
await self._websocket.send(json.dumps(msg))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user