videosdk-plugins-resemble 0.0.17__py3-none-any.whl
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-resemble might be problematic. Click here for more details.
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, AsyncIterator, Optional
|
|
4
|
+
import os
|
|
5
|
+
import asyncio
|
|
6
|
+
import httpx
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
from videosdk.agents import TTS
|
|
10
|
+
|
|
11
|
+
RESEMBLE_HTTP_STREAMING_URL = "https://f.cluster.resemble.ai/stream"
|
|
12
|
+
DEFAULT_VOICE_UUID = "55592656"
|
|
13
|
+
DEFAULT_SAMPLE_RATE = 22050
|
|
14
|
+
DEFAULT_PRECISION = "PCM_16"
|
|
15
|
+
|
|
16
|
+
class ResembleTTS(TTS):
|
|
17
|
+
def __init__(
|
|
18
|
+
self,
|
|
19
|
+
*,
|
|
20
|
+
api_key: str | None = None,
|
|
21
|
+
voice_uuid: str = DEFAULT_VOICE_UUID,
|
|
22
|
+
sample_rate: int = DEFAULT_SAMPLE_RATE,
|
|
23
|
+
precision: str = DEFAULT_PRECISION,
|
|
24
|
+
) -> None:
|
|
25
|
+
super().__init__(sample_rate=sample_rate, num_channels=1)
|
|
26
|
+
|
|
27
|
+
self.api_key = api_key or os.getenv("RESEMBLE_API_KEY")
|
|
28
|
+
if not self.api_key:
|
|
29
|
+
raise ValueError("Resemble API key is required. Provide either `api_key` or set `RESEMBLE_API_KEY` environment variable.")
|
|
30
|
+
|
|
31
|
+
self.voice_uuid = voice_uuid
|
|
32
|
+
self.precision = precision
|
|
33
|
+
|
|
34
|
+
self.audio_track = None
|
|
35
|
+
self.loop = None
|
|
36
|
+
self._http_client = httpx.AsyncClient(
|
|
37
|
+
timeout=httpx.Timeout(connect=15.0, read=30.0, write=5.0, pool=5.0),
|
|
38
|
+
follow_redirects=True,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
async def synthesize(
|
|
42
|
+
self,
|
|
43
|
+
text: AsyncIterator[str] | str,
|
|
44
|
+
**kwargs: Any,
|
|
45
|
+
) -> None:
|
|
46
|
+
try:
|
|
47
|
+
if isinstance(text, AsyncIterator):
|
|
48
|
+
full_text = ""
|
|
49
|
+
async for chunk in text:
|
|
50
|
+
full_text += chunk
|
|
51
|
+
else:
|
|
52
|
+
full_text = text
|
|
53
|
+
|
|
54
|
+
if not self.audio_track or not self.loop:
|
|
55
|
+
self.emit("error", "Audio track or event loop not set")
|
|
56
|
+
return
|
|
57
|
+
|
|
58
|
+
await self._http_stream_synthesis(full_text)
|
|
59
|
+
|
|
60
|
+
except Exception as e:
|
|
61
|
+
self.emit("error", f"Resemble TTS synthesis failed: {str(e)}")
|
|
62
|
+
|
|
63
|
+
async def _http_stream_synthesis(self, text: str) -> None:
|
|
64
|
+
headers = {
|
|
65
|
+
"Authorization": f"Token {self.api_key}",
|
|
66
|
+
"Content-Type": "application/json",
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
payload = {
|
|
70
|
+
"voice_uuid": self.voice_uuid,
|
|
71
|
+
"data": text,
|
|
72
|
+
"precision": self.precision,
|
|
73
|
+
"sample_rate": self.sample_rate,
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
async with self._http_client.stream(
|
|
78
|
+
"POST",
|
|
79
|
+
RESEMBLE_HTTP_STREAMING_URL,
|
|
80
|
+
headers=headers,
|
|
81
|
+
json=payload
|
|
82
|
+
) as response:
|
|
83
|
+
response.raise_for_status()
|
|
84
|
+
|
|
85
|
+
header_processed = False
|
|
86
|
+
buffer = b''
|
|
87
|
+
|
|
88
|
+
async for chunk in response.aiter_bytes():
|
|
89
|
+
if not header_processed:
|
|
90
|
+
buffer += chunk
|
|
91
|
+
data_pos = buffer.find(b'data')
|
|
92
|
+
if data_pos != -1:
|
|
93
|
+
header_size = data_pos + 8
|
|
94
|
+
audio_data = buffer[header_size:]
|
|
95
|
+
if audio_data:
|
|
96
|
+
self.loop.create_task(self.audio_track.add_new_bytes(audio_data))
|
|
97
|
+
header_processed = True
|
|
98
|
+
else:
|
|
99
|
+
if chunk:
|
|
100
|
+
self.loop.create_task(self.audio_track.add_new_bytes(chunk))
|
|
101
|
+
|
|
102
|
+
except httpx.HTTPStatusError as e:
|
|
103
|
+
self.emit("error", f"HTTP error {e.response.status_code}: {e.response.text}")
|
|
104
|
+
except Exception as e:
|
|
105
|
+
self.emit("error", f"HTTP streaming synthesis failed: {str(e)}")
|
|
106
|
+
|
|
107
|
+
async def aclose(self) -> None:
|
|
108
|
+
if self._http_client:
|
|
109
|
+
await self._http_client.aclose()
|
|
110
|
+
await super().aclose()
|
|
111
|
+
|
|
112
|
+
async def interrupt(self) -> None:
|
|
113
|
+
if self.audio_track:
|
|
114
|
+
self.audio_track.interrupt()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.0.17"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: videosdk-plugins-resemble
|
|
3
|
+
Version: 0.0.17
|
|
4
|
+
Summary: VideoSDK Agent Framework plugin for Resemble
|
|
5
|
+
Author: videosdk
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Keywords: ai,audio,resemble,video,videosdk
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Developers
|
|
10
|
+
Classifier: Topic :: Communications :: Conferencing
|
|
11
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
12
|
+
Classifier: Topic :: Multimedia :: Video
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Requires-Dist: videosdk-agents>=0.0.17
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
VideoSDK Resemble Plugin
|
|
19
|
+
|
|
20
|
+
Agent Framework plugin for tts services from Resemble.
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install videosdk-plugins-resemble
|
|
26
|
+
```
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
videosdk/plugins/resemble/__init__.py,sha256=V4pLV2GncUWcXNFXea8Gtf7hbRYKBQSLkW2DsyxW2ks,55
|
|
2
|
+
videosdk/plugins/resemble/tts.py,sha256=DplAv3MHqrTONOsNgngoVy6EX0d-Z7YkBhq0ZPPoifY,3819
|
|
3
|
+
videosdk/plugins/resemble/version.py,sha256=Sd6j21A3v31CfSZ7ASugNxkOYAo0W0NUqcHuzfW7jJA,22
|
|
4
|
+
videosdk_plugins_resemble-0.0.17.dist-info/METADATA,sha256=zICeqp8NFeulvwuehUVb3X0SZAMFkZPc3kQXn8GuznQ,765
|
|
5
|
+
videosdk_plugins_resemble-0.0.17.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
6
|
+
videosdk_plugins_resemble-0.0.17.dist-info/RECORD,,
|