Skip to content

Commit b813b99

Browse files
Create edge-tts.py
1 parent bb8baca commit b813b99

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

tts/edge-tts.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# Moon-Userbot - telegram userbot
2+
# Copyright (C) 2020-present Moon Userbot Organization
3+
#
4+
# This program is free software: you can redistribute it and/or modify
5+
# it under the terms of the GNU General Public License as published by
6+
# the Free Software Foundation, either version 3 of the License, or
7+
# (at your option) any later version.
8+
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
import os
18+
19+
from tabulate import tabulate
20+
21+
from pyrogram import Client, filters
22+
from pyrogram.types import Message
23+
24+
from utils.misc import modules_help, prefix
25+
from utils.scripts import format_exc, import_library
26+
27+
edge_tts = import_library("edge_tts", "edge-tts")
28+
29+
from edge_tts import Communicate, list_voices
30+
from edge_tts.constants import DEFAULT_VOICE
31+
32+
33+
async def all_voices(*, proxy: str | None) -> None:
34+
"""All available voices."""
35+
voices = await list_voices(proxy=proxy)
36+
voices = sorted(voices, key=lambda voice: voice["ShortName"])
37+
headers = ["Name", "Gender", "ContentCategories", "VoicePersonalities"]
38+
table = [
39+
[
40+
voice["ShortName"],
41+
voice["Gender"],
42+
", ".join(voice["VoiceTag"]["ContentCategories"]),
43+
", ".join(voice["VoiceTag"]["VoicePersonalities"]),
44+
]
45+
for voice in voices
46+
]
47+
return tabulate(table, headers)
48+
49+
50+
@Client.on_message(filters.command("etts", prefix) & filters.me)
51+
async def etts(client: Client, message: Message):
52+
if message.reply_to_message:
53+
lang = message.command[1]
54+
text = message.reply_to_message.text
55+
else:
56+
lang = message.command[1]
57+
text = " ".join(message.command[2:])
58+
59+
await message.edit("<b>Speech synthesis...</b>")
60+
61+
try:
62+
if lang == "all":
63+
voices = await all_voices(proxy=None)
64+
if len(voices) <= 4096:
65+
await message.edit(voices)
66+
else:
67+
with open("edge-voices.txt", "w") as f:
68+
f.write(voices)
69+
await message.reply_document("edge-voices.txt")
70+
await message.delete()
71+
os.remove("edge-voices.txt")
72+
return
73+
if lang == "d" or lang == "default":
74+
lang = DEFAULT_VOICE
75+
if not text:
76+
await message.edit("<b>No text to speech</b>")
77+
return
78+
communicate = Communicate(text=text, voice=lang)
79+
communicate.save_sync("voice.ogg")
80+
81+
await message.delete()
82+
if message.reply_to_message:
83+
await message.reply_to_message.reply_audio("voice.ogg")
84+
else:
85+
await client.send_audio(message.chat.id, "voice.ogg")
86+
os.remove("voice.ogg")
87+
except Exception as e:
88+
await message.edit(format_exc(e))
89+
90+
91+
@Client.on_message(filters.command("estts", prefix) & filters.me)
92+
async def estts(client: Client, message: Message):
93+
if message.reply_to_message:
94+
lang = message.command[1]
95+
text = message.reply_to_message.text
96+
else:
97+
lang = message.command[1]
98+
text = " ".join(message.command[2:])
99+
100+
await message.edit("<b>Speech synthesis...</b>")
101+
102+
try:
103+
if lang == "all":
104+
voices = await all_voices(proxy=None)
105+
if len(voices) <= 4096:
106+
await message.edit(voices)
107+
else:
108+
with open("edge-voices.txt", "w") as f:
109+
f.write(voices)
110+
await message.reply_document("edge-voices.txt")
111+
await message.delete()
112+
os.remove("edge-voices.txt")
113+
return
114+
if lang == "d" or lang == "default":
115+
lang = DEFAULT_VOICE
116+
if not text:
117+
await message.edit("<b>No text to speech</b>")
118+
return
119+
communicate = Communicate(text=text, voice=lang)
120+
submaker = edge_tts.SubMaker()
121+
with open("voice.ogg", "wb") as file:
122+
for chunk in communicate.stream_sync():
123+
if chunk["type"] == "audio":
124+
file.write(chunk["data"])
125+
elif chunk["type"] == "WordBoundary":
126+
submaker.feed(chunk)
127+
128+
with open("voice.srt", "w", encoding="utf-8") as file:
129+
file.write(submaker.get_srt())
130+
131+
await message.delete()
132+
if message.reply_to_message:
133+
await message.reply_to_message.reply_audio("voice.ogg")
134+
await message.reply_to_message.reply_document("voice.srt")
135+
else:
136+
await client.send_audio(message.chat.id, "voice.ogg")
137+
await client.send_document(message.chat.id, "voice.srt")
138+
os.remove("voice.ogg")
139+
os.remove("voice.srt")
140+
except Exception as e:
141+
await message.edit(format_exc(e))
142+
143+
144+
modules_help["edge-tts"] = {
145+
"etts [lang]* [text]*": "Say text",
146+
"etts [lang]* replied message": "Say text",
147+
"etts all": "Get all voices",
148+
"estts [lang]* [text]*": "Say text & Generate subtitles",
149+
"estts [lang]* replied message": "Say text & Generate subtitles"
150+
f"\n for default lang (en-US-EmmaMultilingualNeural) use 'd' or 'default' in lang place, for e.g., <code>{prefix}etts d hello</code>"
151+
"\n\n<b>Example:</b>\n<code>{prefix}etts en-US-AriaNeural Hello world</code>",
152+
}

0 commit comments

Comments
 (0)