webscout 8.2.6__py3-none-any.whl → 8.2.8__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 webscout might be problematic. Click here for more details.

Files changed (150) hide show
  1. webscout/AIauto.py +1 -1
  2. webscout/AIutel.py +298 -239
  3. webscout/Extra/Act.md +309 -0
  4. webscout/Extra/GitToolkit/gitapi/README.md +110 -0
  5. webscout/Extra/YTToolkit/README.md +375 -0
  6. webscout/Extra/YTToolkit/ytapi/README.md +44 -0
  7. webscout/Extra/YTToolkit/ytapi/extras.py +92 -19
  8. webscout/Extra/autocoder/autocoder.py +309 -114
  9. webscout/Extra/autocoder/autocoder_utiles.py +15 -15
  10. webscout/Extra/gguf.md +430 -0
  11. webscout/Extra/tempmail/README.md +488 -0
  12. webscout/Extra/weather.md +281 -0
  13. webscout/Litlogger/Readme.md +175 -0
  14. webscout/Provider/AISEARCH/DeepFind.py +41 -37
  15. webscout/Provider/AISEARCH/README.md +279 -0
  16. webscout/Provider/AISEARCH/__init__.py +0 -1
  17. webscout/Provider/AISEARCH/genspark_search.py +228 -86
  18. webscout/Provider/AISEARCH/hika_search.py +11 -11
  19. webscout/Provider/AISEARCH/scira_search.py +324 -322
  20. webscout/Provider/AllenAI.py +7 -14
  21. webscout/Provider/Blackboxai.py +518 -74
  22. webscout/Provider/Cloudflare.py +0 -1
  23. webscout/Provider/Deepinfra.py +23 -21
  24. webscout/Provider/Flowith.py +217 -0
  25. webscout/Provider/FreeGemini.py +250 -0
  26. webscout/Provider/GizAI.py +15 -5
  27. webscout/Provider/Glider.py +11 -8
  28. webscout/Provider/HeckAI.py +80 -52
  29. webscout/Provider/Koboldai.py +7 -4
  30. webscout/Provider/LambdaChat.py +2 -2
  31. webscout/Provider/Marcus.py +10 -18
  32. webscout/Provider/OPENAI/BLACKBOXAI.py +735 -0
  33. webscout/Provider/OPENAI/Cloudflare.py +378 -0
  34. webscout/Provider/OPENAI/FreeGemini.py +282 -0
  35. webscout/Provider/OPENAI/NEMOTRON.py +244 -0
  36. webscout/Provider/OPENAI/README.md +1253 -0
  37. webscout/Provider/OPENAI/__init__.py +8 -0
  38. webscout/Provider/OPENAI/ai4chat.py +293 -286
  39. webscout/Provider/OPENAI/api.py +810 -0
  40. webscout/Provider/OPENAI/base.py +217 -14
  41. webscout/Provider/OPENAI/c4ai.py +373 -367
  42. webscout/Provider/OPENAI/chatgpt.py +7 -0
  43. webscout/Provider/OPENAI/chatgptclone.py +7 -0
  44. webscout/Provider/OPENAI/chatsandbox.py +172 -0
  45. webscout/Provider/OPENAI/deepinfra.py +30 -20
  46. webscout/Provider/OPENAI/e2b.py +6 -0
  47. webscout/Provider/OPENAI/exaai.py +7 -0
  48. webscout/Provider/OPENAI/exachat.py +6 -0
  49. webscout/Provider/OPENAI/flowith.py +162 -0
  50. webscout/Provider/OPENAI/freeaichat.py +359 -352
  51. webscout/Provider/OPENAI/glider.py +323 -316
  52. webscout/Provider/OPENAI/groq.py +361 -354
  53. webscout/Provider/OPENAI/heckai.py +30 -64
  54. webscout/Provider/OPENAI/llmchatco.py +8 -0
  55. webscout/Provider/OPENAI/mcpcore.py +7 -0
  56. webscout/Provider/OPENAI/multichat.py +8 -0
  57. webscout/Provider/OPENAI/netwrck.py +356 -350
  58. webscout/Provider/OPENAI/opkfc.py +8 -0
  59. webscout/Provider/OPENAI/scirachat.py +471 -462
  60. webscout/Provider/OPENAI/sonus.py +9 -0
  61. webscout/Provider/OPENAI/standardinput.py +9 -1
  62. webscout/Provider/OPENAI/textpollinations.py +339 -329
  63. webscout/Provider/OPENAI/toolbaz.py +7 -0
  64. webscout/Provider/OPENAI/typefully.py +355 -0
  65. webscout/Provider/OPENAI/typegpt.py +358 -346
  66. webscout/Provider/OPENAI/uncovrAI.py +7 -0
  67. webscout/Provider/OPENAI/utils.py +103 -7
  68. webscout/Provider/OPENAI/venice.py +12 -0
  69. webscout/Provider/OPENAI/wisecat.py +19 -19
  70. webscout/Provider/OPENAI/writecream.py +7 -0
  71. webscout/Provider/OPENAI/x0gpt.py +7 -0
  72. webscout/Provider/OPENAI/yep.py +50 -21
  73. webscout/Provider/OpenGPT.py +1 -1
  74. webscout/Provider/TTI/AiForce/README.md +159 -0
  75. webscout/Provider/TTI/FreeAIPlayground/README.md +99 -0
  76. webscout/Provider/TTI/ImgSys/README.md +174 -0
  77. webscout/Provider/TTI/MagicStudio/README.md +101 -0
  78. webscout/Provider/TTI/Nexra/README.md +155 -0
  79. webscout/Provider/TTI/PollinationsAI/README.md +146 -0
  80. webscout/Provider/TTI/README.md +128 -0
  81. webscout/Provider/TTI/aiarta/README.md +134 -0
  82. webscout/Provider/TTI/artbit/README.md +100 -0
  83. webscout/Provider/TTI/fastflux/README.md +129 -0
  84. webscout/Provider/TTI/huggingface/README.md +114 -0
  85. webscout/Provider/TTI/piclumen/README.md +161 -0
  86. webscout/Provider/TTI/pixelmuse/README.md +79 -0
  87. webscout/Provider/TTI/talkai/README.md +139 -0
  88. webscout/Provider/TTS/README.md +192 -0
  89. webscout/Provider/TTS/__init__.py +2 -1
  90. webscout/Provider/TTS/speechma.py +500 -100
  91. webscout/Provider/TTS/sthir.py +94 -0
  92. webscout/Provider/TeachAnything.py +3 -7
  93. webscout/Provider/TextPollinationsAI.py +4 -2
  94. webscout/Provider/{aimathgpt.py → UNFINISHED/ChatHub.py} +88 -68
  95. webscout/Provider/UNFINISHED/liner_api_request.py +263 -0
  96. webscout/Provider/UNFINISHED/oivscode.py +351 -0
  97. webscout/Provider/UNFINISHED/test_lmarena.py +119 -0
  98. webscout/Provider/Writecream.py +11 -2
  99. webscout/Provider/__init__.py +8 -14
  100. webscout/Provider/ai4chat.py +4 -58
  101. webscout/Provider/asksteve.py +17 -9
  102. webscout/Provider/cerebras.py +3 -1
  103. webscout/Provider/koala.py +170 -268
  104. webscout/Provider/llmchat.py +3 -0
  105. webscout/Provider/lmarena.py +198 -0
  106. webscout/Provider/meta.py +7 -4
  107. webscout/Provider/samurai.py +223 -0
  108. webscout/Provider/scira_chat.py +4 -2
  109. webscout/Provider/typefully.py +23 -151
  110. webscout/__init__.py +4 -2
  111. webscout/cli.py +3 -28
  112. webscout/conversation.py +35 -35
  113. webscout/litagent/Readme.md +276 -0
  114. webscout/scout/README.md +402 -0
  115. webscout/swiftcli/Readme.md +323 -0
  116. webscout/version.py +1 -1
  117. webscout/webscout_search.py +2 -182
  118. webscout/webscout_search_async.py +1 -179
  119. webscout/zeroart/README.md +89 -0
  120. webscout/zeroart/__init__.py +134 -54
  121. webscout/zeroart/base.py +19 -13
  122. webscout/zeroart/effects.py +101 -99
  123. webscout/zeroart/fonts.py +1239 -816
  124. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/METADATA +116 -74
  125. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/RECORD +130 -103
  126. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/WHEEL +1 -1
  127. webscout-8.2.8.dist-info/entry_points.txt +3 -0
  128. webscout-8.2.8.dist-info/top_level.txt +1 -0
  129. webscout/Provider/AISEARCH/ISou.py +0 -256
  130. webscout/Provider/ElectronHub.py +0 -773
  131. webscout/Provider/Free2GPT.py +0 -241
  132. webscout/Provider/GPTWeb.py +0 -249
  133. webscout/Provider/bagoodex.py +0 -145
  134. webscout/Provider/geminiprorealtime.py +0 -160
  135. webscout/scout/core.py +0 -881
  136. webscout-8.2.6.dist-info/entry_points.txt +0 -3
  137. webscout-8.2.6.dist-info/top_level.txt +0 -2
  138. webstoken/__init__.py +0 -30
  139. webstoken/classifier.py +0 -189
  140. webstoken/keywords.py +0 -216
  141. webstoken/language.py +0 -128
  142. webstoken/ner.py +0 -164
  143. webstoken/normalizer.py +0 -35
  144. webstoken/processor.py +0 -77
  145. webstoken/sentiment.py +0 -206
  146. webstoken/stemmer.py +0 -73
  147. webstoken/tagger.py +0 -60
  148. webstoken/tokenizer.py +0 -158
  149. /webscout/Provider/{Youchat.py → UNFINISHED/Youchat.py} +0 -0
  150. {webscout-8.2.6.dist-info → webscout-8.2.8.dist-info}/licenses/LICENSE.md +0 -0
@@ -9,8 +9,8 @@ from io import BytesIO
9
9
  from webscout import exceptions
10
10
  from webscout.litagent import LitAgent
11
11
  from concurrent.futures import ThreadPoolExecutor, as_completed
12
- from . import utils
13
- from .base import BaseTTSProvider
12
+ from webscout.Provider.TTS import utils
13
+ from webscout.Provider.TTS.base import BaseTTSProvider
14
14
 
15
15
  class SpeechMaTTS(BaseTTSProvider):
16
16
  """
@@ -28,10 +28,463 @@ class SpeechMaTTS(BaseTTSProvider):
28
28
 
29
29
  # Available voices with their IDs
30
30
  all_voices = {
31
- "Ava": "voice-110", # Multilingual female voice
32
- "Emma": "voice-115", # Multilingual female voice
33
- "Andrew": "voice-107", # Multilingual male voice
34
- "Brian": "voice-112" # Multilingual male voice
31
+ # Multilingual voices
32
+ "Andrew Multilingual": "voice-107", # Male, Multilingual, United States
33
+ "Ava Multilingual": "voice-110", # Female, Multilingual, United States
34
+ "Brian Multilingual": "voice-112", # Male, Multilingual, United States
35
+ "Emma Multilingual": "voice-115", # Female, Multilingual, United States
36
+ "Remy Multilingual": "voice-142", # Male, Multilingual, France
37
+ "Vivienne Multilingual": "voice-143", # Female, Multilingual, France
38
+ "Florian Multilingual": "voice-154", # Male, Multilingual, Germany
39
+ "Seraphina Multilingual": "voice-157", # Female, Multilingual, Germany
40
+ "Giuseppe Multilingual": "voice-177", # Male, Multilingual, Italy
41
+ "Hyunsu Multilingual": "voice-189", # Male, Multilingual, South Korea
42
+ "Thalita Multilingual": "voice-222", # Female, Multilingual, Brazil
43
+ # English (US)
44
+ "Ana": "voice-106", # Female, English, United States
45
+ "Andrew": "voice-108", # Male, English, United States
46
+ "Aria": "voice-109", # Female, English, United States
47
+ "Ava": "voice-111", # Female, English, United States
48
+ "Brian": "voice-113", # Male, English, United States
49
+ "Christopher": "voice-114", # Male, English, United States
50
+ "Emma": "voice-116", # Female, English, United States
51
+ "Eric": "voice-117", # Male, English, United States
52
+ "Guy": "voice-118", # Male, English, United States
53
+ "Jenny": "voice-119", # Female, English, United States
54
+ "Michelle": "voice-120", # Female, English, United States
55
+ "Roger": "voice-121", # Male, English, United States
56
+ "Steffan": "voice-122", # Male, English, United States
57
+ # English (UK)
58
+ "Libby": "voice-82", # Female, English, United Kingdom
59
+ "Maisie": "voice-83", # Female, English, United Kingdom
60
+ "Ryan": "voice-84", # Male, English, United Kingdom
61
+ "Sonia": "voice-85", # Female, English, United Kingdom
62
+ "Thomas": "voice-86", # Male, English, United Kingdom
63
+ # English (Australia)
64
+ "Natasha": "voice-78", # Female, English, Australia
65
+ "William": "voice-79", # Male, English, Australia
66
+ # English (Canada)
67
+ "Clara": "voice-80", # Female, English, Canada
68
+ "Liam": "voice-81", # Male, English, Canada
69
+ # English (India)
70
+ "Neerja Expressive": "voice-91", # Female, English, India
71
+ "Neerja": "voice-92", # Female, English, India
72
+ "Prabhat": "voice-93", # Male, English, India
73
+ # English (Hong Kong)
74
+ "Sam": "voice-87", # Male, English, Hong Kong
75
+ "Yan": "voice-88", # Female, English, Hong Kong
76
+ # English (Ireland)
77
+ "Connor": "voice-89", # Male, English, Ireland
78
+ "Emily": "voice-90", # Female, English, Ireland
79
+ # English (Kenya)
80
+ "Asilia": "voice-94", # Female, English, Kenya
81
+ "Chilemba": "voice-95", # Male, English, Kenya
82
+ # English (Nigeria)
83
+ "Abeo": "voice-96", # Male, English, Nigeria
84
+ "Ezinne": "voice-97", # Female, English, Nigeria
85
+ # English (New Zealand)
86
+ "Mitchell": "voice-98", # Male, English, New Zealand
87
+ "Molly": "voice-99", # Female, English, New Zealand
88
+ # English (Philippines)
89
+ "James": "voice-100", # Male, English, Philippines
90
+ "Rosa": "voice-101", # Female, English, Philippines
91
+ # English (Singapore)
92
+ "Luna": "voice-102", # Female, English, Singapore
93
+ "Wayne": "voice-103", # Male, English, Singapore
94
+ # English (Tanzania)
95
+ "Elimu": "voice-104", # Male, English, Tanzania
96
+ "Imani": "voice-105", # Female, English, Tanzania
97
+ # English (South Africa)
98
+ "Leah": "voice-123", # Female, English, South Africa
99
+ "Luke": "voice-124", # Male, English, South Africa
100
+ # Spanish (Argentina)
101
+ "Elena": "voice-239", # Female, Spanish, Argentina
102
+ "Tomas": "voice-240", # Male, Spanish, Argentina
103
+ # Spanish (Bolivia)
104
+ "Marcelo": "voice-241", # Male, Spanish, Bolivia
105
+ "Sofia": "voice-242", # Female, Spanish, Bolivia
106
+ # Spanish (Chile)
107
+ "Catalina": "voice-243", # Female, Spanish, Chile
108
+ "Lorenzo": "voice-244", # Male, Spanish, Chile
109
+ # Spanish (Colombia)
110
+ "Gonzalo": "voice-245", # Male, Spanish, Colombia
111
+ "Salome": "voice-246", # Female, Spanish, Colombia
112
+ # Spanish (Costa Rica)
113
+ "Juan": "voice-247", # Male, Spanish, Costa Rica
114
+ "Maria": "voice-248", # Female, Spanish, Costa Rica
115
+ # Spanish (Cuba)
116
+ "Belkys": "voice-249", # Female, Spanish, Cuba
117
+ "Manuel": "voice-250", # Male, Spanish, Cuba
118
+ # Spanish (Dominican Republic)
119
+ "Emilio": "voice-251", # Male, Spanish, Dominican Republic
120
+ "Ramona": "voice-252", # Female, Spanish, Dominican Republic
121
+ # Spanish (Ecuador)
122
+ "Andrea": "voice-253", # Female, Spanish, Ecuador
123
+ "Luis": "voice-254", # Male, Spanish, Ecuador
124
+ # Spanish (Spain)
125
+ "Alvaro": "voice-255", # Male, Spanish, Spain
126
+ "Elvira": "voice-256", # Female, Spanish, Spain
127
+ "Ximena": "voice-257", # Female, Spanish, Spain
128
+ # Spanish (Equatorial Guinea)
129
+ "Javier": "voice-258", # Male, Spanish, Equatorial Guinea
130
+ "Teresa": "voice-259", # Female, Spanish, Equatorial Guinea
131
+ # Spanish (Guatemala)
132
+ "Andres": "voice-260", # Male, Spanish, Guatemala
133
+ "Marta": "voice-261", # Female, Spanish, Guatemala
134
+ # Spanish (Honduras)
135
+ "Carlos": "voice-262", # Male, Spanish, Honduras
136
+ "Karla": "voice-263", # Female, Spanish, Honduras
137
+ # Spanish (Mexico)
138
+ "Dalia": "voice-264", # Female, Spanish, Mexico
139
+ "Jorge": "voice-265", # Male, Spanish, Mexico
140
+ # Spanish (Nicaragua)
141
+ "Federico": "voice-266", # Male, Spanish, Nicaragua
142
+ "Yolanda": "voice-267", # Female, Spanish, Nicaragua
143
+ # Spanish (Panama)
144
+ "Margarita": "voice-268", # Female, Spanish, Panama
145
+ "Roberto": "voice-269", # Male, Spanish, Panama
146
+ # Spanish (Peru)
147
+ "Alex": "voice-270", # Male, Spanish, Peru
148
+ "Camila": "voice-271", # Female, Spanish, Peru
149
+ # Spanish (Puerto Rico)
150
+ "Karina": "voice-272", # Female, Spanish, Puerto Rico
151
+ "Victor": "voice-273", # Male, Spanish, Puerto Rico
152
+ # Spanish (Paraguay)
153
+ "Mario": "voice-274", # Male, Spanish, Paraguay
154
+ "Tania": "voice-275", # Female, Spanish, Paraguay
155
+ # Spanish (El Salvador)
156
+ "Lorena": "voice-276", # Female, Spanish, El Salvador
157
+ "Rodrigo": "voice-277", # Male, Spanish, El Salvador
158
+ # Spanish (United States)
159
+ "Alonso": "voice-278", # Male, Spanish, United States
160
+ "Paloma": "voice-279", # Female, Spanish, United States
161
+ # Spanish (Uruguay)
162
+ "Mateo": "voice-280", # Male, Spanish, Uruguay
163
+ "Valentina": "voice-281", # Female, Spanish, Uruguay
164
+ # Spanish (Venezuela)
165
+ "Paola": "voice-282", # Female, Spanish, Venezuela
166
+ "Sebastian": "voice-283", # Male, Spanish, Venezuela
167
+ # Chinese (China)
168
+ "Xiaoxiao": "voice-53", # Female, Chinese, China
169
+ "Xiaoyi": "voice-54", # Female, Chinese, China
170
+ "Yunjian": "voice-55", # Male, Chinese, China
171
+ "Yunxi": "voice-56", # Male, Chinese, China
172
+ "Yunxia": "voice-57", # Male, Chinese, China
173
+ "Yunyang": "voice-58", # Male, Chinese, China
174
+ "Xiaobei": "voice-59", # Female, Chinese, China
175
+ "Xiaoni": "voice-60", # Female, Chinese, China
176
+ # Chinese (Hong Kong)
177
+ "HiuGaai": "voice-61", # Female, Chinese, Hong Kong
178
+ "HiuMaan": "voice-62", # Female, Chinese, Hong Kong
179
+ "WanLung": "voice-63", # Male, Chinese, Hong Kong
180
+ # Chinese (Taiwan)
181
+ "HsiaoChen": "voice-64", # Female, Chinese, Taiwan
182
+ "HsiaoYu": "voice-65", # Female, Chinese, Taiwan
183
+ "YunJhe": "voice-66", # Male, Chinese, Taiwan
184
+ # French (Belgium)
185
+ "Charline": "voice-131", # Female, French, Belgium
186
+ "Gerard": "voice-132", # Male, French, Belgium
187
+ # French (Canada)
188
+ "Antoine": "voice-133", # Male, French, Canada
189
+ "Jean": "voice-134", # Male, French, Canada
190
+ "Sylvie": "voice-135", # Female, French, Canada
191
+ "Thierry": "voice-136", # Male, French, Canada
192
+ # French (Switzerland)
193
+ "Ariane": "voice-137", # Female, French, Switzerland
194
+ "Fabrice": "voice-138", # Male, French, Switzerland
195
+ # French (France)
196
+ "Denise": "voice-139", # Female, French, France
197
+ "Eloise": "voice-140", # Female, French, France
198
+ "Henri": "voice-141", # Male, French, France
199
+ # German (Austria)
200
+ "Ingrid": "voice-148", # Female, German, Austria
201
+ "Jonas": "voice-149", # Male, German, Austria
202
+ # German (Switzerland)
203
+ "Jan": "voice-150", # Male, German, Switzerland
204
+ "Leni": "voice-151", # Female, German, Switzerland
205
+ # German (Germany)
206
+ "Amala": "voice-152", # Female, German, Germany
207
+ "Conrad": "voice-153", # Male, German, Germany
208
+ "Katja": "voice-155", # Female, German, Germany
209
+ "Killian": "voice-156", # Male, German, Germany
210
+ # Arabic (United Arab Emirates)
211
+ "Fatima": "voice-7", # Female, Arabic, United Arab Emirates
212
+ "Hamdan": "voice-8", # Male, Arabic, United Arab Emirates
213
+ # Arabic (Bahrain)
214
+ "Ali": "voice-9", # Male, Arabic, Bahrain
215
+ "Laila": "voice-10", # Female, Arabic, Bahrain
216
+ # Arabic (Algeria)
217
+ "Amina": "voice-11", # Female, Arabic, Algeria
218
+ "Ismael": "voice-12", # Male, Arabic, Algeria
219
+ # Arabic (Egypt)
220
+ "Salma": "voice-13", # Female, Arabic, Egypt
221
+ "Shakir": "voice-14", # Male, Arabic, Egypt
222
+ # Arabic (Iraq)
223
+ "Bassel": "voice-15", # Male, Arabic, Iraq
224
+ "Rana": "voice-16", # Female, Arabic, Iraq
225
+ # Arabic (Jordan)
226
+ "Sana": "voice-17", # Female, Arabic, Jordan
227
+ "Taim": "voice-18", # Male, Arabic, Jordan
228
+ # Arabic (Kuwait)
229
+ "Fahed": "voice-19", # Male, Arabic, Kuwait
230
+ "Noura": "voice-20", # Female, Arabic, Kuwait
231
+ # Arabic (Lebanon)
232
+ "Layla": "voice-21", # Female, Arabic, Lebanon
233
+ "Rami": "voice-22", # Male, Arabic, Lebanon
234
+ # Arabic (Libya)
235
+ "Iman": "voice-23", # Female, Arabic, Libya
236
+ "Omar": "voice-24", # Male, Arabic, Libya
237
+ # Arabic (Morocco)
238
+ "Jamal": "voice-25", # Male, Arabic, Morocco
239
+ "Mouna": "voice-26", # Female, Arabic, Morocco
240
+ # Arabic (Oman)
241
+ "Abdullah": "voice-27", # Male, Arabic, Oman
242
+ "Aysha": "voice-28", # Female, Arabic, Oman
243
+ # Arabic (Qatar)
244
+ "Amal": "voice-29", # Female, Arabic, Qatar
245
+ "Moaz": "voice-30", # Male, Arabic, Qatar
246
+ # Arabic (Saudi Arabia)
247
+ "Hamed": "voice-31", # Male, Arabic, Saudi Arabia
248
+ "Zariyah": "voice-32", # Female, Arabic, Saudi Arabia
249
+ # Arabic (Syria)
250
+ "Amany": "voice-33", # Female, Arabic, Syria
251
+ "Laith": "voice-34", # Male, Arabic, Syria
252
+ # Arabic (Tunisia)
253
+ "Hedi": "voice-35", # Male, Arabic, Tunisia
254
+ "Reem": "voice-36", # Female, Arabic, Tunisia
255
+ # Arabic (Yemen)
256
+ "Maryam": "voice-37", # Female, Arabic, Yemen
257
+ "Saleh": "voice-38", # Male, Arabic, Yemen
258
+ # Afrikaans (South Africa)
259
+ "Adri": "voice-1", # Female, Afrikaans, South Africa
260
+ "Willem": "voice-2", # Male, Afrikaans, South Africa
261
+ # Albanian (Albania)
262
+ "Anila": "voice-3", # Female, Albanian, Albania
263
+ "Ilir": "voice-4", # Male, Albanian, Albania
264
+ # Amharic (Ethiopia)
265
+ "Ameha": "voice-5", # Male, Amharic, Ethiopia
266
+ "Mekdes": "voice-6", # Female, Amharic, Ethiopia
267
+ # Azerbaijani (Azerbaijan)
268
+ "Babek": "voice-39", # Male, Azerbaijani, Azerbaijan
269
+ "Banu": "voice-40", # Female, Azerbaijani, Azerbaijan
270
+ # Bengali (Bangladesh)
271
+ "Nabanita": "voice-41", # Female, Bengali, Bangladesh
272
+ "Pradeep": "voice-42", # Male, Bengali, Bangladesh
273
+ # Bengali (India)
274
+ "Bashkar": "voice-43", # Male, Bengali, India
275
+ "Tanishaa": "voice-44", # Female, Bengali, India
276
+ # Bosnian (Bosnia and Herzegovina)
277
+ "Goran": "voice-45", # Male, Bosnian, Bosnia and Herzegovina
278
+ "Vesna": "voice-46", # Female, Bosnian, Bosnia and Herzegovina
279
+ # Bulgarian (Bulgaria)
280
+ "Borislav": "voice-47", # Male, Bulgarian, Bulgaria
281
+ "Kalina": "voice-48", # Female, Bulgarian, Bulgaria
282
+ # Burmese (Myanmar)
283
+ "Nilar": "voice-49", # Female, Burmese, Myanmar
284
+ "Thiha": "voice-50", # Male, Burmese, Myanmar
285
+ # Catalan (Spain)
286
+ "Enric": "voice-51", # Male, Catalan, Spain
287
+ "Joana": "voice-52", # Female, Catalan, Spain
288
+ # Croatian (Croatia)
289
+ "Gabrijela": "voice-67", # Female, Croatian, Croatia
290
+ "Srecko": "voice-68", # Male, Croatian, Croatia
291
+ # Czech (Czech Republic)
292
+ "Antonin": "voice-69", # Male, Czech, Czech Republic
293
+ "Vlasta": "voice-70", # Female, Czech, Czech Republic
294
+ # Danish (Denmark)
295
+ "Christel": "voice-71", # Female, Danish, Denmark
296
+ "Jeppe": "voice-72", # Male, Danish, Denmark
297
+ # Dutch (Belgium)
298
+ "Arnaud": "voice-73", # Male, Dutch, Belgium
299
+ "Dena": "voice-74", # Female, Dutch, Belgium
300
+ # Dutch (Netherlands)
301
+ "Colette": "voice-75", # Female, Dutch, Netherlands
302
+ "Fenna": "voice-76", # Female, Dutch, Netherlands
303
+ "Maarten": "voice-77", # Male, Dutch, Netherlands
304
+ # Estonian (Estonia)
305
+ "Anu": "voice-125", # Female, Estonian, Estonia
306
+ "Kert": "voice-126", # Male, Estonian, Estonia
307
+ # Filipino (Philippines)
308
+ "Angelo": "voice-127", # Male, Filipino, Philippines
309
+ "Blessica": "voice-128", # Female, Filipino, Philippines
310
+ # Finnish (Finland)
311
+ "Harri": "voice-129", # Male, Finnish, Finland
312
+ "Noora": "voice-130", # Female, Finnish, Finland
313
+ # Galician (Spain)
314
+ "Roi": "voice-144", # Male, Galician, Spain
315
+ "Sabela": "voice-145", # Female, Galician, Spain
316
+ # Georgian (Georgia)
317
+ "Eka": "voice-146", # Female, Georgian, Georgia
318
+ "Giorgi": "voice-147", # Male, Georgian, Georgia
319
+ # Greek (Greece)
320
+ "Athina": "voice-158", # Female, Greek, Greece
321
+ "Nestoras": "voice-159", # Male, Greek, Greece (Note: voice-160 is a duplicate name)
322
+ # Gujarati (India)
323
+ "Dhwani": "voice-161", # Female, Gujarati, India
324
+ "Niranjan": "voice-162", # Male, Gujarati, India
325
+ # Hebrew (Israel)
326
+ "Avri": "voice-163", # Male, Hebrew, Israel
327
+ "Hila": "voice-164", # Female, Hebrew, Israel
328
+ # Hindi (India)
329
+ "Madhur": "voice-165", # Male, Hindi, India
330
+ "Swara": "voice-166", # Female, Hindi, India
331
+ # Hungarian (Hungary)
332
+ "Noemi": "voice-167", # Female, Hungarian, Hungary
333
+ "Tamas": "voice-168", # Male, Hungarian, Hungary
334
+ # Icelandic (Iceland)
335
+ "Gudrun": "voice-169", # Female, Icelandic, Iceland
336
+ "Gunnar": "voice-170", # Male, Icelandic, Iceland
337
+ # Indonesian (Indonesia)
338
+ "Ardi": "voice-171", # Male, Indonesian, Indonesia
339
+ "Gadis": "voice-172", # Female, Indonesian, Indonesia
340
+ # Irish (Ireland)
341
+ "Colm": "voice-173", # Male, Irish, Ireland
342
+ "Orla": "voice-174", # Female, Irish, Ireland
343
+ # Italian (Italy)
344
+ "Diego": "voice-175", # Male, Italian, Italy
345
+ "Elsa": "voice-176", # Female, Italian, Italy
346
+ "Isabella": "voice-178", # Female, Italian, Italy
347
+ # Japanese (Japan)
348
+ "Keita": "voice-179", # Male, Japanese, Japan
349
+ "Nanami": "voice-180", # Female, Japanese, Japan
350
+ # Javanese (Indonesia)
351
+ "Dimas": "voice-181", # Male, Javanese, Indonesia
352
+ "Siti": "voice-182", # Female, Javanese, Indonesia
353
+ # Kannada (India)
354
+ "Gagan": "voice-183", # Male, Kannada, India
355
+ "Sapna": "voice-184", # Female, Kannada, India
356
+ # Kazakh (Kazakhstan)
357
+ "Aigul": "voice-185", # Female, Kazakh, Kazakhstan
358
+ "Daulet": "voice-186", # Male, Kazakh, Kazakhstan
359
+ # Khmer (Cambodia)
360
+ "Piseth": "voice-187", # Male, Khmer, Cambodia
361
+ "Sreymom": "voice-188", # Female, Khmer, Cambodia
362
+ # Korean (South Korea)
363
+ "InJoon": "voice-190", # Male, Korean, South Korea
364
+ "SunHi": "voice-191", # Female, Korean, South Korea
365
+ # Lao (Laos)
366
+ "Chanthavong": "voice-192", # Male, Lao, Laos
367
+ "Keomany": "voice-193", # Female, Lao, Laos
368
+ # Latvian (Latvia)
369
+ "Everita": "voice-194", # Female, Latvian, Latvia
370
+ "Nils": "voice-195", # Male, Latvian, Latvia
371
+ # Lithuanian (Lithuania)
372
+ "Leonas": "voice-196", # Male, Lithuanian, Lithuania
373
+ "Ona": "voice-197", # Female, Lithuanian, Lithuania
374
+ # Macedonian (North Macedonia)
375
+ "Aleksandar": "voice-198", # Male, Macedonian, North Macedonia
376
+ "Marija": "voice-199", # Female, Macedonian, North Macedonia
377
+ # Malay (Malaysia)
378
+ "Osman": "voice-200", # Male, Malay, Malaysia
379
+ "Yasmin": "voice-201", # Female, Malay, Malaysia
380
+ # Malayalam (India)
381
+ "Midhun": "voice-202", # Male, Malayalam, India
382
+ "Sobhana": "voice-203", # Female, Malayalam, India
383
+ # Maltese (Malta)
384
+ "Grace": "voice-204", # Female, Maltese, Malta
385
+ "Joseph": "voice-205", # Male, Maltese, Malta
386
+ # Marathi (India)
387
+ "Aarohi": "voice-206", # Female, Marathi, India
388
+ "Manohar": "voice-207", # Male, Marathi, India
389
+ # Mongolian (Mongolia)
390
+ "Bataa": "voice-208", # Male, Mongolian, Mongolia
391
+ "Yesui": "voice-209", # Female, Mongolian, Mongolia
392
+ # Nepali (Nepal)
393
+ "Hemkala": "voice-210", # Female, Nepali, Nepal
394
+ "Sagar": "voice-211", # Male, Nepali, Nepal
395
+ # Norwegian (Norway)
396
+ "Finn": "voice-212", # Male, Norwegian, Norway
397
+ "Pernille": "voice-213", # Female, Norwegian, Norway
398
+ # Pashto (Afghanistan)
399
+ "GulNawaz": "voice-214", # Male, Pashto, Afghanistan
400
+ "Latifa": "voice-215", # Female, Pashto, Afghanistan
401
+ # Persian (Iran)
402
+ "Dilara": "voice-216", # Female, Persian, Iran
403
+ "Farid": "voice-217", # Male, Persian, Iran
404
+ # Polish (Poland)
405
+ "Marek": "voice-218", # Male, Polish, Poland
406
+ "Zofia": "voice-219", # Female, Polish, Poland
407
+ # Portuguese (Brazil)
408
+ "Antonio": "voice-220", # Male, Portuguese, Brazil
409
+ "Francisca": "voice-221", # Female, Portuguese, Brazil
410
+ # Portuguese (Portugal)
411
+ "Duarte": "voice-223", # Male, Portuguese, Portugal
412
+ "Raquel": "voice-224", # Female, Portuguese, Portugal
413
+ # Romanian (Romania)
414
+ "Alina": "voice-225", # Female, Romanian, Romania
415
+ "Emil": "voice-226", # Male, Romanian, Romania
416
+ # Russian (Russia)
417
+ "Dmitry": "voice-227", # Male, Russian, Russia
418
+ "Svetlana": "voice-228", # Female, Russian, Russia
419
+ # Serbian (Serbia)
420
+ "Nicholas": "voice-229", # Male, Serbian, Serbia
421
+ "Sophie": "voice-230", # Female, Serbian, Serbia
422
+ # Sinhala (Sri Lanka)
423
+ "Sameera": "voice-231", # Male, Sinhala, Sri Lanka
424
+ "Thilini": "voice-232", # Female, Sinhala, Sri Lanka
425
+ # Slovak (Slovakia)
426
+ "Lukas": "voice-233", # Male, Slovak, Slovakia
427
+ "Viktoria": "voice-234", # Female, Slovak, Slovakia
428
+ # Slovenian (Slovenia)
429
+ "Petra": "voice-235", # Female, Slovenian, Slovenia
430
+ "Rok": "voice-236", # Male, Slovenian, Slovenia
431
+ # Somali (Somalia)
432
+ "Muuse": "voice-237", # Male, Somali, Somalia
433
+ "Ubax": "voice-238", # Female, Somali, Somalia
434
+ # Sundanese (Indonesia)
435
+ "Jajang": "voice-284", # Male, Sundanese, Indonesia
436
+ "Tuti": "voice-285", # Female, Sundanese, Indonesia
437
+ # Swahili (Kenya)
438
+ "Rafiki": "voice-286", # Male, Swahili, Kenya
439
+ "Zuri": "voice-287", # Female, Swahili, Kenya
440
+ # Swahili (Tanzania)
441
+ "Daudi": "voice-288", # Male, Swahili, Tanzania
442
+ "Rehema": "voice-289", # Female, Swahili, Tanzania
443
+ # Swedish (Sweden)
444
+ "Mattias": "voice-290", # Male, Swedish, Sweden
445
+ "Sofie": "voice-291", # Female, Swedish, Sweden
446
+ # Tamil (India)
447
+ "Pallavi": "voice-292", # Female, Tamil, India
448
+ "Valluvar": "voice-293", # Male, Tamil, India
449
+ # Tamil (Sri Lanka)
450
+ "Kumar": "voice-294", # Male, Tamil, Sri Lanka
451
+ "Saranya": "voice-295", # Female, Tamil, Sri Lanka
452
+ # Tamil (Malaysia)
453
+ "Kani": "voice-296", # Female, Tamil, Malaysia
454
+ "Surya": "voice-297", # Male, Tamil, Malaysia
455
+ # Tamil (Singapore)
456
+ "Anbu": "voice-298", # Male, Tamil, Singapore
457
+ "Venba": "voice-299", # Female, Tamil, Singapore
458
+ # Telugu (India)
459
+ "Mohan": "voice-300", # Male, Telugu, India
460
+ "Shruti": "voice-301", # Female, Telugu, India
461
+ # Thai (Thailand)
462
+ "Niwat": "voice-302", # Male, Thai, Thailand
463
+ "Premwadee": "voice-303", # Female, Thai, Thailand
464
+ # Turkish (Turkey)
465
+ "Ahmet": "voice-304", # Male, Turkish, Turkey
466
+ "Emel": "voice-305", # Female, Turkish, Turkey
467
+ # Ukrainian (Ukraine)
468
+ "Ostap": "voice-306", # Male, Ukrainian, Ukraine
469
+ "Polina": "voice-307", # Female, Ukrainian, Ukraine
470
+ # Urdu (India)
471
+ "Gul": "voice-308", # Female, Urdu, India
472
+ "Salman": "voice-309", # Male, Urdu, India
473
+ # Urdu (Pakistan)
474
+ "Asad": "voice-310", # Male, Urdu, Pakistan
475
+ "Uzma": "voice-311", # Female, Urdu, Pakistan
476
+ # Uzbek (Uzbekistan)
477
+ "Madina": "voice-312", # Female, Uzbek, Uzbekistan
478
+ "Sardor": "voice-313", # Male, Uzbek, Uzbekistan
479
+ # Vietnamese (Vietnam)
480
+ "HoaiMy": "voice-314", # Female, Vietnamese, Vietnam
481
+ "NamMinh": "voice-315", # Male, Vietnamese, Vietnam
482
+ # Welsh (United Kingdom)
483
+ "Aled": "voice-316", # Male, Welsh, United Kingdom
484
+ "Nia": "voice-317", # Female, Welsh, United Kingdom
485
+ # Zulu (South Africa)
486
+ "Thando": "voice-318", # Female, Zulu, South Africa
487
+ "Themba": "voice-319", # Male, Zulu, South Africa
35
488
  }
36
489
 
37
490
  def __init__(self, timeout: int = 20, proxies: dict = None):
@@ -44,7 +497,7 @@ class SpeechMaTTS(BaseTTSProvider):
44
497
  self.session.proxies.update(proxies)
45
498
  self.timeout = timeout
46
499
 
47
- def tts(self, text: str, voice: str = "Emma", pitch: int = 0, rate: int = 0, verbose: bool = False) -> str:
500
+ def tts(self, text: str, voice: str = "Emma", pitch: int = 0, rate: int = 0) -> str:
48
501
  """
49
502
  Converts text to speech using the SpeechMa API and saves it to a file.
50
503
 
@@ -53,7 +506,6 @@ class SpeechMaTTS(BaseTTSProvider):
53
506
  voice (str): The voice to use for TTS (default: "Emma")
54
507
  pitch (int): Voice pitch adjustment (-10 to 10, default: 0)
55
508
  rate (int): Voice rate/speed adjustment (-10 to 10, default: 0)
56
- verbose (bool): Whether to print progress messages (default: True)
57
509
 
58
510
  Returns:
59
511
  str: Path to the generated audio file
@@ -66,108 +518,56 @@ class SpeechMaTTS(BaseTTSProvider):
66
518
  ), f"Voice '{voice}' not one of [{', '.join(self.all_voices.keys())}]"
67
519
 
68
520
  filename = pathlib.Path(tempfile.mktemp(suffix=".mp3", dir=self.temp_dir))
69
-
70
- # Get the voice ID
71
521
  voice_id = self.all_voices[voice]
72
522
 
73
- if verbose:
74
- print(f"[debug] Using voice: {voice} (ID: {voice_id})")
75
-
76
- # Split text into sentences for better processing
77
- sentences = utils.split_sentences(text)
78
-
79
- if verbose:
80
- print(f"[debug] Text split into {len(sentences)} sentences")
81
-
82
- # Function to request audio for each chunk
83
- def generate_audio_for_chunk(part_text: str, part_number: int):
84
- while True:
85
- try:
86
- if verbose:
87
- print(f"[debug] Processing chunk {part_number}: '{part_text[:30]}...'")
88
-
89
- # Prepare payload for this sentence
90
- payload = {
91
- "text": part_text,
92
- "voice": voice_id,
93
- "pitch": pitch,
94
- "rate": rate
95
- }
96
-
97
- response = self.session.post(
98
- self.api_url,
99
- headers=self.headers,
100
- json=payload,
101
- timeout=self.timeout
102
- )
103
- response.raise_for_status()
104
-
105
- # Check if the request was successful
106
- if response.ok and response.status_code == 200:
107
- # Ensure we got audio data
108
- if len(response.content) > 100: # Basic check for actual content
109
- if verbose:
110
- print(f"[debug] Chunk {part_number} processed successfully")
111
- return part_number, response.content
112
- else:
113
- if verbose:
114
- print(f"[debug] Received too small response for chunk {part_number}. Retrying...")
115
- else:
116
- if verbose:
117
- print(f"[debug] Failed request for chunk {part_number} (status code: {response.status_code}). Retrying...")
118
-
119
- # If we get here, something went wrong with the request
120
- time.sleep(1)
121
- except requests.RequestException as e:
122
- if verbose:
123
- print(f"[debug] Error for chunk {part_number}: {e}. Retrying...")
124
- time.sleep(1)
523
+ # Prepare payload for the job-based API
524
+ payload = {
525
+ "text": text,
526
+ "voice": voice_id,
527
+ "pitch": pitch,
528
+ "rate": rate,
529
+ "volume": 100
530
+ }
125
531
 
126
532
  try:
127
- if verbose:
128
- print(f"[debug] Starting concurrent audio generation for {len(sentences)} chunks")
129
-
130
- # Using ThreadPoolExecutor to handle requests concurrently
131
- with ThreadPoolExecutor() as executor:
132
- futures = {executor.submit(generate_audio_for_chunk, sentence.strip(), chunk_num): chunk_num
133
- for chunk_num, sentence in enumerate(sentences, start=1)}
134
-
135
- # Dictionary to store results with order preserved
136
- audio_chunks = {}
137
-
138
- for future in as_completed(futures):
139
- chunk_num = futures[future]
140
- try:
141
- part_number, audio_data = future.result()
142
- audio_chunks[part_number] = audio_data # Store the audio data in correct sequence
143
- if verbose:
144
- print(f"[debug] Received audio data for chunk {part_number}")
145
- except Exception as e:
146
- if verbose:
147
- print(f"[debug] Failed to generate audio for chunk {chunk_num}: {e}")
148
-
149
- if verbose:
150
- print(f"[debug] Successfully processed {len(audio_chunks)}/{len(sentences)} chunks")
533
+ response = self.session.post(
534
+ self.api_url,
535
+ headers=self.headers,
536
+ json=payload,
537
+ timeout=self.timeout
538
+ )
539
+ response.raise_for_status()
540
+ resp_json = response.json()
541
+ if not resp_json.get("success") or "data" not in resp_json or "job_id" not in resp_json["data"]:
542
+ raise exceptions.FailedToGenerateResponseError(f"SpeechMa API error: {resp_json}")
543
+ job_id = resp_json["data"]["job_id"]
151
544
 
152
- # Combine audio chunks in the correct sequence
153
- combined_audio = BytesIO()
154
- for part_number in sorted(audio_chunks.keys()):
155
- combined_audio.write(audio_chunks[part_number])
156
- if verbose:
157
- print(f"[debug] Added chunk {part_number} to the combined file")
545
+ # Poll for job completion
546
+ status_url = f"https://speechma.com/com.api/tts-api.php/status/{job_id}"
547
+ for _ in range(30): # up to ~30 seconds
548
+ status_resp = self.session.get(
549
+ status_url,
550
+ headers=self.headers,
551
+ timeout=self.timeout
552
+ )
553
+ status_resp.raise_for_status()
554
+ status_json = status_resp.json()
555
+ if status_json.get("success") and status_json.get("data", {}).get("status") == "completed":
556
+ break
557
+ time.sleep(1)
558
+ else:
559
+ raise exceptions.FailedToGenerateResponseError("TTS job did not complete in time.")
158
560
 
159
- # Save the combined audio data to a single file
561
+ # Download the audio file (API provides a URL in the status response)
562
+ data = status_json["data"]
563
+ audio_url = f"https://speechma.com/com.api/tts-api.php/audio/{job_id}"
564
+ audio_resp = self.session.get(audio_url, timeout=self.timeout)
565
+ audio_resp.raise_for_status()
160
566
  with open(filename, 'wb') as f:
161
- f.write(combined_audio.getvalue())
162
-
163
- if verbose:
164
- print(f"[debug] Final audio saved as {filename}")
165
-
567
+ f.write(audio_resp.content)
166
568
  return filename.as_posix()
167
569
 
168
570
  except requests.exceptions.RequestException as e:
169
- if verbose:
170
- print(f"[debug] Failed to perform the operation: {e}")
171
571
  raise exceptions.FailedToGenerateResponseError(
172
572
  f"Failed to perform the operation: {e}"
173
573
  )