videosdk-plugins-elevenlabs 0.0.19__tar.gz → 0.0.21__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of videosdk-plugins-elevenlabs might be problematic. Click here for more details.
- {videosdk_plugins_elevenlabs-0.0.19 → videosdk_plugins_elevenlabs-0.0.21}/PKG-INFO +2 -2
- {videosdk_plugins_elevenlabs-0.0.19 → videosdk_plugins_elevenlabs-0.0.21}/pyproject.toml +1 -1
- {videosdk_plugins_elevenlabs-0.0.19 → videosdk_plugins_elevenlabs-0.0.21}/videosdk/plugins/elevenlabs/tts.py +25 -2
- videosdk_plugins_elevenlabs-0.0.21/videosdk/plugins/elevenlabs/version.py +1 -0
- videosdk_plugins_elevenlabs-0.0.19/videosdk/plugins/elevenlabs/version.py +0 -1
- {videosdk_plugins_elevenlabs-0.0.19 → videosdk_plugins_elevenlabs-0.0.21}/.gitignore +0 -0
- {videosdk_plugins_elevenlabs-0.0.19 → videosdk_plugins_elevenlabs-0.0.21}/README.md +0 -0
- {videosdk_plugins_elevenlabs-0.0.19 → videosdk_plugins_elevenlabs-0.0.21}/videosdk/plugins/elevenlabs/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: videosdk-plugins-elevenlabs
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.21
|
|
4
4
|
Summary: VideoSDK Agent Framework plugin for ElevenLabs
|
|
5
5
|
Author: videosdk
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -12,7 +12,7 @@ Classifier: Topic :: Multimedia :: Sound/Audio
|
|
|
12
12
|
Classifier: Topic :: Multimedia :: Video
|
|
13
13
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
14
|
Requires-Python: >=3.11
|
|
15
|
-
Requires-Dist: videosdk-agents>=0.0.
|
|
15
|
+
Requires-Dist: videosdk-agents>=0.0.21
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
|
|
18
18
|
# VideoSDK ElevenLabs Plugin
|
|
@@ -122,9 +122,13 @@ class ElevenLabsTTS(TTS):
|
|
|
122
122
|
) as response:
|
|
123
123
|
response.raise_for_status()
|
|
124
124
|
|
|
125
|
+
audio_data = b""
|
|
125
126
|
async for chunk in response.aiter_bytes():
|
|
126
127
|
if chunk:
|
|
127
|
-
|
|
128
|
+
audio_data += chunk
|
|
129
|
+
|
|
130
|
+
if audio_data:
|
|
131
|
+
await self._stream_audio_chunks(audio_data)
|
|
128
132
|
|
|
129
133
|
except httpx.HTTPStatusError as e:
|
|
130
134
|
self.emit("error", f"HTTP error {e.response.status_code}: {e.response.text}")
|
|
@@ -165,13 +169,14 @@ class ElevenLabsTTS(TTS):
|
|
|
165
169
|
eos_message = {"text": ""}
|
|
166
170
|
await ws.send_str(json.dumps(eos_message))
|
|
167
171
|
|
|
172
|
+
audio_data = b""
|
|
168
173
|
async for msg in ws:
|
|
169
174
|
if msg.type == aiohttp.WSMsgType.TEXT:
|
|
170
175
|
data = json.loads(msg.data)
|
|
171
176
|
if data.get("audio"):
|
|
172
177
|
import base64
|
|
173
178
|
audio_chunk = base64.b64decode(data["audio"])
|
|
174
|
-
|
|
179
|
+
audio_data += audio_chunk
|
|
175
180
|
elif data.get("isFinal"):
|
|
176
181
|
break
|
|
177
182
|
elif data.get("error"):
|
|
@@ -180,10 +185,28 @@ class ElevenLabsTTS(TTS):
|
|
|
180
185
|
elif msg.type == aiohttp.WSMsgType.ERROR:
|
|
181
186
|
self.emit("error", f"WebSocket connection error: {ws.exception()}")
|
|
182
187
|
break
|
|
188
|
+
|
|
189
|
+
if audio_data:
|
|
190
|
+
await self._stream_audio_chunks(audio_data)
|
|
183
191
|
|
|
184
192
|
except Exception as e:
|
|
185
193
|
self.emit("error", f"Streaming synthesis failed: {str(e)}")
|
|
186
194
|
|
|
195
|
+
async def _stream_audio_chunks(self, audio_bytes: bytes) -> None:
|
|
196
|
+
"""Stream audio data in chunks for smooth playback"""
|
|
197
|
+
chunk_size = int(ELEVENLABS_SAMPLE_RATE * ELEVENLABS_CHANNELS * 2 * 20 / 1000)
|
|
198
|
+
|
|
199
|
+
for i in range(0, len(audio_bytes), chunk_size):
|
|
200
|
+
chunk = audio_bytes[i:i + chunk_size]
|
|
201
|
+
|
|
202
|
+
if len(chunk) < chunk_size and len(chunk) > 0:
|
|
203
|
+
padding_needed = chunk_size - len(chunk)
|
|
204
|
+
chunk += b'\x00' * padding_needed
|
|
205
|
+
|
|
206
|
+
if len(chunk) == chunk_size:
|
|
207
|
+
self.loop.create_task(self.audio_track.add_new_bytes(chunk))
|
|
208
|
+
await asyncio.sleep(0.001)
|
|
209
|
+
|
|
187
210
|
async def aclose(self) -> None:
|
|
188
211
|
"""Cleanup resources"""
|
|
189
212
|
if self._session:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.21"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.0.19"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|