Spaces:
Running
Running
Commit ·
e97a206
1
Parent(s): 6b06635
init
Browse files- .gitignore +2 -0
- README.md +39 -13
- app.py +99 -0
- collab.ipynb +254 -0
- install.bat +3 -0
- requirements.txt +3 -0
- start.bat +2 -0
- style.css +19 -0
- /320/270/320/275/321/202/320/265/321/200/321/204/320/265/320/271/321/201.jpg +0 -0
.gitignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/venv
|
| 2 |
+
output.mp3
|
README.md
CHANGED
|
@@ -1,13 +1,39 @@
|
|
| 1 |
-
---
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# rus-edge-tts-webui
|
| 2 |
+
Русскоязычный интерфейс для edge tts
|
| 3 |
+
Код взят у https://github.com/ycyy/edge-tts-webui и локализован мной.
|
| 4 |
+
|
| 5 |
+

|
| 6 |
+
|
| 7 |
+
# О файлах
|
| 8 |
+
```
|
| 9 |
+
Файлы интерфейс.jpg и реадми можете удалять они вам не нужны.
|
| 10 |
+
app.py - код нейронки.
|
| 11 |
+
example - записи голосов для нейронки. Без этой папки и записей в ней работать ничего не будет!!!
|
| 12 |
+
style.css - размеры и цвета кнопок и окон.
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
# Установка
|
| 16 |
+
```
|
| 17 |
+
d: (если хотите устанавливать на диск d или любой другой смените букву d на нужную)
|
| 18 |
+
git clone https://github.com/hinaichigo-fox/rus-edge-tts-webui.git
|
| 19 |
+
cd rus-edge-tts-webui
|
| 20 |
+
pip install edge-tts
|
| 21 |
+
pip install gradio
|
| 22 |
+
pip install asyncio
|
| 23 |
+
```
|
| 24 |
+
|
| 25 |
+
# Запуск
|
| 26 |
+
```
|
| 27 |
+
d: (если установлено не на диск c, если на диск с то пропускаем)
|
| 28 |
+
cd rus-edge-tts-webui
|
| 29 |
+
python app.py
|
| 30 |
+
далее в консоли появится строчка Running on local URL: http://0.0.0.0:7860 у вас будут другие цифры. Копируем адрес и вводим в браузер.
|
| 31 |
+
```
|
| 32 |
+
|
| 33 |
+
Вроде все понятно объяснил. Всем удачи!
|
| 34 |
+
```
|
| 35 |
+
Планы на будущее:
|
| 36 |
+
1.Добавить словарь
|
| 37 |
+
2.Добавить формат .wav на выход.
|
| 38 |
+
3.Автоматическое открытие браузера.
|
| 39 |
+
```
|
app.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import edge_tts
|
| 3 |
+
import asyncio
|
| 4 |
+
import os
|
| 5 |
+
# https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4 - там голоса брать. думаю поймете. ShortName короче
|
| 6 |
+
SUPPORTED_VOICES = {
|
| 7 |
+
'DmitryNeural-Руский(муж.)': 'ru-RU-DmitryNeural',
|
| 8 |
+
'SvetlanaNeural-Русский(жен.)': 'ru-RU-SvetlanaNeural',
|
| 9 |
+
'OstapNeural-Украинский(муж.)': 'uk-UA-OstapNeural',
|
| 10 |
+
'PolinaNeural-Украинский(жен.)': 'uk-UA-PolinaNeural'
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
# Смена голоса
|
| 14 |
+
def changeVoice(voices):
|
| 15 |
+
example = SUPPORTED_VOICES[voices]
|
| 16 |
+
example_file = os.path.join(os.path.dirname(__file__), "example/"+example+".wav")
|
| 17 |
+
return example_file
|
| 18 |
+
|
| 19 |
+
# Преобразование текста в речь
|
| 20 |
+
async def textToSpeech(text, voices, rate, volume):
|
| 21 |
+
output_file = "output.mp3"
|
| 22 |
+
voices = SUPPORTED_VOICES[voices]
|
| 23 |
+
if (rate >= 0):
|
| 24 |
+
rates = rate = "+" + str(rate) + "%"
|
| 25 |
+
else:
|
| 26 |
+
rates = str(rate) + "%"
|
| 27 |
+
if (volume >= 0):
|
| 28 |
+
volumes = "+" + str(volume) + "%"
|
| 29 |
+
else:
|
| 30 |
+
volumes = str(volume) + "%"
|
| 31 |
+
communicate = edge_tts.Communicate(text,
|
| 32 |
+
voices,
|
| 33 |
+
rate=rates,
|
| 34 |
+
volume=volumes,
|
| 35 |
+
proxy=None)
|
| 36 |
+
await communicate.save(output_file)
|
| 37 |
+
audio_file = os.path.join(os.path.dirname(__file__), "output.mp3")
|
| 38 |
+
if (os.path.exists(audio_file)):
|
| 39 |
+
return audio_file
|
| 40 |
+
else:
|
| 41 |
+
raise gr.Error("Преобразование не удалось!")
|
| 42 |
+
return FileNotFoundError
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
# Сбросить результат конвертации
|
| 46 |
+
def clearSpeech():
|
| 47 |
+
output_file = os.path.join(os.path.dirname(__file__), "output.mp3")
|
| 48 |
+
if (os.path.exists(output_file)):
|
| 49 |
+
os.remove(output_file)
|
| 50 |
+
return None, None
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
with gr.Blocks(css="style.css", title="Преобразование текста в речь") as demo:
|
| 54 |
+
gr.Markdown("""
|
| 55 |
+
# Преобразование текста в речь через Microsoft Edge
|
| 56 |
+
""")
|
| 57 |
+
with gr.Row():
|
| 58 |
+
with gr.Column():
|
| 59 |
+
text = gr.TextArea(label="Текст", elem_classes="text-area")
|
| 60 |
+
btn = gr.Button("Сгенерировать", elem_id="submit-btn")
|
| 61 |
+
with gr.Column():
|
| 62 |
+
voices = gr.Dropdown(choices=[
|
| 63 |
+
"DmitryNeural-Руский(муж.)", "SvetlanaNeural-Русский(жен.)", "OstapNeural-Украинский(муж.)", "PolinaNeural-Украинский(жен.)"
|
| 64 |
+
],
|
| 65 |
+
value="DmitryNeural-Руский(муж.)",
|
| 66 |
+
label="Голос",
|
| 67 |
+
info="Пожалуйста, выберите голос",
|
| 68 |
+
interactive=True)
|
| 69 |
+
|
| 70 |
+
example = gr.Audio(label="Пример голоса",
|
| 71 |
+
value="example/ru-RU-DmitryNeural.wav",
|
| 72 |
+
interactive=False,
|
| 73 |
+
elem_classes="example")
|
| 74 |
+
|
| 75 |
+
voices.change(fn=changeVoice,inputs=voices,outputs=example)
|
| 76 |
+
rate = gr.Slider(-100,
|
| 77 |
+
100,
|
| 78 |
+
step=1,
|
| 79 |
+
value=0,
|
| 80 |
+
label="Увеличение / уменьшение скорости речи",
|
| 81 |
+
info="Скорость речи быстрее / медленнее",
|
| 82 |
+
interactive=True)
|
| 83 |
+
|
| 84 |
+
volume = gr.Slider(-100,
|
| 85 |
+
100,
|
| 86 |
+
step=1,
|
| 87 |
+
value=0,
|
| 88 |
+
label="Увеличение / уменьшение громкости звука",
|
| 89 |
+
info="Увеличить / уменьшить громкость звука",
|
| 90 |
+
interactive=True)
|
| 91 |
+
audio = gr.Audio(label="Результат",
|
| 92 |
+
interactive=False,
|
| 93 |
+
elem_classes="audio")
|
| 94 |
+
btn.click(fn=textToSpeech,
|
| 95 |
+
inputs=[text, voices, rate, volume],
|
| 96 |
+
outputs=[audio])
|
| 97 |
+
|
| 98 |
+
if __name__ == "__main__":
|
| 99 |
+
demo.launch()
|
collab.ipynb
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"nbformat": 4,
|
| 3 |
+
"nbformat_minor": 0,
|
| 4 |
+
"metadata": {
|
| 5 |
+
"colab": {
|
| 6 |
+
"provenance": []
|
| 7 |
+
},
|
| 8 |
+
"kernelspec": {
|
| 9 |
+
"name": "python3",
|
| 10 |
+
"display_name": "Python 3"
|
| 11 |
+
},
|
| 12 |
+
"language_info": {
|
| 13 |
+
"name": "python"
|
| 14 |
+
}
|
| 15 |
+
},
|
| 16 |
+
"cells": [
|
| 17 |
+
{
|
| 18 |
+
"cell_type": "code",
|
| 19 |
+
"source": [
|
| 20 |
+
"!pip install edge-tts\n",
|
| 21 |
+
"!pip install gradio\n",
|
| 22 |
+
"!pip install asyncio\n",
|
| 23 |
+
"!git clone https://github.com/hinaichigo-fox/rus-edge-tts-webui.git"
|
| 24 |
+
],
|
| 25 |
+
"metadata": {
|
| 26 |
+
"colab": {
|
| 27 |
+
"base_uri": "https://localhost:8080/"
|
| 28 |
+
},
|
| 29 |
+
"id": "yV2b2V2vH896",
|
| 30 |
+
"outputId": "c279c37c-3310-4e83-f823-4e78555271ae"
|
| 31 |
+
},
|
| 32 |
+
"execution_count": 3,
|
| 33 |
+
"outputs": [
|
| 34 |
+
{
|
| 35 |
+
"output_type": "stream",
|
| 36 |
+
"name": "stdout",
|
| 37 |
+
"text": [
|
| 38 |
+
"Requirement already satisfied: edge-tts in /usr/local/lib/python3.10/dist-packages (6.1.8)\n",
|
| 39 |
+
"Requirement already satisfied: aiohttp>=3.8.0 in /usr/local/lib/python3.10/dist-packages (from edge-tts) (3.8.5)\n",
|
| 40 |
+
"Requirement already satisfied: certifi==2023.07.22 in /usr/local/lib/python3.10/dist-packages (from edge-tts) (2023.7.22)\n",
|
| 41 |
+
"Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp>=3.8.0->edge-tts) (23.1.0)\n",
|
| 42 |
+
"Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp>=3.8.0->edge-tts) (3.2.0)\n",
|
| 43 |
+
"Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp>=3.8.0->edge-tts) (6.0.4)\n",
|
| 44 |
+
"Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /usr/local/lib/python3.10/dist-packages (from aiohttp>=3.8.0->edge-tts) (4.0.3)\n",
|
| 45 |
+
"Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp>=3.8.0->edge-tts) (1.9.2)\n",
|
| 46 |
+
"Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp>=3.8.0->edge-tts) (1.4.0)\n",
|
| 47 |
+
"Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp>=3.8.0->edge-tts) (1.3.1)\n",
|
| 48 |
+
"Requirement already satisfied: idna>=2.0 in /usr/local/lib/python3.10/dist-packages (from yarl<2.0,>=1.0->aiohttp>=3.8.0->edge-tts) (3.4)\n",
|
| 49 |
+
"Requirement already satisfied: gradio in /usr/local/lib/python3.10/dist-packages (3.43.2)\n",
|
| 50 |
+
"Requirement already satisfied: aiofiles<24.0,>=22.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (23.2.1)\n",
|
| 51 |
+
"Requirement already satisfied: altair<6.0,>=4.2.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (4.2.2)\n",
|
| 52 |
+
"Requirement already satisfied: fastapi in /usr/local/lib/python3.10/dist-packages (from gradio) (0.103.1)\n",
|
| 53 |
+
"Requirement already satisfied: ffmpy in /usr/local/lib/python3.10/dist-packages (from gradio) (0.3.1)\n",
|
| 54 |
+
"Requirement already satisfied: gradio-client==0.5.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (0.5.0)\n",
|
| 55 |
+
"Requirement already satisfied: httpx in /usr/local/lib/python3.10/dist-packages (from gradio) (0.24.1)\n",
|
| 56 |
+
"Requirement already satisfied: huggingface-hub>=0.14.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (0.16.4)\n",
|
| 57 |
+
"Requirement already satisfied: importlib-resources<7.0,>=1.3 in /usr/local/lib/python3.10/dist-packages (from gradio) (6.0.1)\n",
|
| 58 |
+
"Requirement already satisfied: jinja2<4.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (3.1.2)\n",
|
| 59 |
+
"Requirement already satisfied: markupsafe~=2.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (2.1.3)\n",
|
| 60 |
+
"Requirement already satisfied: matplotlib~=3.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (3.7.1)\n",
|
| 61 |
+
"Requirement already satisfied: numpy~=1.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (1.23.5)\n",
|
| 62 |
+
"Requirement already satisfied: orjson~=3.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (3.9.7)\n",
|
| 63 |
+
"Requirement already satisfied: packaging in /usr/local/lib/python3.10/dist-packages (from gradio) (23.1)\n",
|
| 64 |
+
"Requirement already satisfied: pandas<3.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (1.5.3)\n",
|
| 65 |
+
"Requirement already satisfied: pillow<11.0,>=8.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (9.4.0)\n",
|
| 66 |
+
"Requirement already satisfied: pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,<3.0.0,>=1.7.4 in /usr/local/lib/python3.10/dist-packages (from gradio) (1.10.12)\n",
|
| 67 |
+
"Requirement already satisfied: pydub in /usr/local/lib/python3.10/dist-packages (from gradio) (0.25.1)\n",
|
| 68 |
+
"Requirement already satisfied: python-multipart in /usr/local/lib/python3.10/dist-packages (from gradio) (0.0.6)\n",
|
| 69 |
+
"Requirement already satisfied: pyyaml<7.0,>=5.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (6.0.1)\n",
|
| 70 |
+
"Requirement already satisfied: requests~=2.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (2.31.0)\n",
|
| 71 |
+
"Requirement already satisfied: semantic-version~=2.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (2.10.0)\n",
|
| 72 |
+
"Requirement already satisfied: typing-extensions~=4.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (4.5.0)\n",
|
| 73 |
+
"Requirement already satisfied: uvicorn>=0.14.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (0.23.2)\n",
|
| 74 |
+
"Requirement already satisfied: websockets<12.0,>=10.0 in /usr/local/lib/python3.10/dist-packages (from gradio) (11.0.3)\n",
|
| 75 |
+
"Requirement already satisfied: fsspec in /usr/local/lib/python3.10/dist-packages (from gradio-client==0.5.0->gradio) (2023.6.0)\n",
|
| 76 |
+
"Requirement already satisfied: entrypoints in /usr/local/lib/python3.10/dist-packages (from altair<6.0,>=4.2.0->gradio) (0.4)\n",
|
| 77 |
+
"Requirement already satisfied: jsonschema>=3.0 in /usr/local/lib/python3.10/dist-packages (from altair<6.0,>=4.2.0->gradio) (4.19.0)\n",
|
| 78 |
+
"Requirement already satisfied: toolz in /usr/local/lib/python3.10/dist-packages (from altair<6.0,>=4.2.0->gradio) (0.12.0)\n",
|
| 79 |
+
"Requirement already satisfied: filelock in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.14.0->gradio) (3.12.2)\n",
|
| 80 |
+
"Requirement already satisfied: tqdm>=4.42.1 in /usr/local/lib/python3.10/dist-packages (from huggingface-hub>=0.14.0->gradio) (4.66.1)\n",
|
| 81 |
+
"Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (1.1.0)\n",
|
| 82 |
+
"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (0.11.0)\n",
|
| 83 |
+
"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (4.42.1)\n",
|
| 84 |
+
"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (1.4.5)\n",
|
| 85 |
+
"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (3.1.1)\n",
|
| 86 |
+
"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.10/dist-packages (from matplotlib~=3.0->gradio) (2.8.2)\n",
|
| 87 |
+
"Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.10/dist-packages (from pandas<3.0,>=1.0->gradio) (2023.3.post1)\n",
|
| 88 |
+
"Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests~=2.0->gradio) (3.2.0)\n",
|
| 89 |
+
"Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests~=2.0->gradio) (3.4)\n",
|
| 90 |
+
"Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests~=2.0->gradio) (2.0.4)\n",
|
| 91 |
+
"Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests~=2.0->gradio) (2023.7.22)\n",
|
| 92 |
+
"Requirement already satisfied: click>=7.0 in /usr/local/lib/python3.10/dist-packages (from uvicorn>=0.14.0->gradio) (8.1.7)\n",
|
| 93 |
+
"Requirement already satisfied: h11>=0.8 in /usr/local/lib/python3.10/dist-packages (from uvicorn>=0.14.0->gradio) (0.14.0)\n",
|
| 94 |
+
"Requirement already satisfied: anyio<4.0.0,>=3.7.1 in /usr/local/lib/python3.10/dist-packages (from fastapi->gradio) (3.7.1)\n",
|
| 95 |
+
"Requirement already satisfied: starlette<0.28.0,>=0.27.0 in /usr/local/lib/python3.10/dist-packages (from fastapi->gradio) (0.27.0)\n",
|
| 96 |
+
"Requirement already satisfied: httpcore<0.18.0,>=0.15.0 in /usr/local/lib/python3.10/dist-packages (from httpx->gradio) (0.17.3)\n",
|
| 97 |
+
"Requirement already satisfied: sniffio in /usr/local/lib/python3.10/dist-packages (from httpx->gradio) (1.3.0)\n",
|
| 98 |
+
"Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<4.0.0,>=3.7.1->fastapi->gradio) (1.1.3)\n",
|
| 99 |
+
"Requirement already satisfied: attrs>=22.2.0 in /usr/local/lib/python3.10/dist-packages (from jsonschema>=3.0->altair<6.0,>=4.2.0->gradio) (23.1.0)\n",
|
| 100 |
+
"Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /usr/local/lib/python3.10/dist-packages (from jsonschema>=3.0->altair<6.0,>=4.2.0->gradio) (2023.7.1)\n",
|
| 101 |
+
"Requirement already satisfied: referencing>=0.28.4 in /usr/local/lib/python3.10/dist-packages (from jsonschema>=3.0->altair<6.0,>=4.2.0->gradio) (0.30.2)\n",
|
| 102 |
+
"Requirement already satisfied: rpds-py>=0.7.1 in /usr/local/lib/python3.10/dist-packages (from jsonschema>=3.0->altair<6.0,>=4.2.0->gradio) (0.10.2)\n",
|
| 103 |
+
"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.10/dist-packages (from python-dateutil>=2.7->matplotlib~=3.0->gradio) (1.16.0)\n",
|
| 104 |
+
"Requirement already satisfied: asyncio in /usr/local/lib/python3.10/dist-packages (3.4.3)\n",
|
| 105 |
+
"Cloning into 'rus-edge-tts-webui'...\n",
|
| 106 |
+
"remote: Enumerating objects: 39, done.\u001b[K\n",
|
| 107 |
+
"remote: Counting objects: 100% (39/39), done.\u001b[K\n",
|
| 108 |
+
"remote: Compressing objects: 100% (37/37), done.\u001b[K\n",
|
| 109 |
+
"remote: Total 39 (delta 16), reused 0 (delta 0), pack-reused 0\u001b[K\n",
|
| 110 |
+
"Receiving objects: 100% (39/39), 9.08 MiB | 14.64 MiB/s, done.\n",
|
| 111 |
+
"Resolving deltas: 100% (16/16), done.\n"
|
| 112 |
+
]
|
| 113 |
+
}
|
| 114 |
+
]
|
| 115 |
+
},
|
| 116 |
+
{
|
| 117 |
+
"cell_type": "code",
|
| 118 |
+
"execution_count": 5,
|
| 119 |
+
"metadata": {
|
| 120 |
+
"colab": {
|
| 121 |
+
"base_uri": "https://localhost:8080/",
|
| 122 |
+
"height": 591
|
| 123 |
+
},
|
| 124 |
+
"id": "hsOlLAjoH8O_",
|
| 125 |
+
"outputId": "775fa791-4c89-4563-97cf-6cb95a271c04"
|
| 126 |
+
},
|
| 127 |
+
"outputs": [
|
| 128 |
+
{
|
| 129 |
+
"output_type": "stream",
|
| 130 |
+
"name": "stdout",
|
| 131 |
+
"text": [
|
| 132 |
+
"Colab notebook detected. To show errors in colab notebook, set debug=True in launch()\n",
|
| 133 |
+
"Running on public URL: https://129c5d18926c205c8c.gradio.live\n",
|
| 134 |
+
"\n",
|
| 135 |
+
"This share link expires in 72 hours. For free permanent hosting and GPU upgrades, run `gradio deploy` from Terminal to deploy to Spaces (https://huggingface.co/spaces)\n"
|
| 136 |
+
]
|
| 137 |
+
},
|
| 138 |
+
{
|
| 139 |
+
"output_type": "display_data",
|
| 140 |
+
"data": {
|
| 141 |
+
"text/plain": [
|
| 142 |
+
"<IPython.core.display.HTML object>"
|
| 143 |
+
],
|
| 144 |
+
"text/html": [
|
| 145 |
+
"<div><iframe src=\"https://129c5d18926c205c8c.gradio.live\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
|
| 146 |
+
]
|
| 147 |
+
},
|
| 148 |
+
"metadata": {}
|
| 149 |
+
}
|
| 150 |
+
],
|
| 151 |
+
"source": [
|
| 152 |
+
"import gradio as gr\n",
|
| 153 |
+
"import edge_tts\n",
|
| 154 |
+
"import asyncio\n",
|
| 155 |
+
"import os\n",
|
| 156 |
+
"# https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4 - там голоса брать. думаю поймете. ShortName короче\n",
|
| 157 |
+
"SUPPORTED_VOICES = {\n",
|
| 158 |
+
" 'DmitryNeural-Руский(муж.)': 'ru-RU-DmitryNeural',\n",
|
| 159 |
+
" 'SvetlanaNeural-Русский(жен.)': 'ru-RU-SvetlanaNeural',\n",
|
| 160 |
+
" 'OstapNeural-Украинский(муж.)': 'uk-UA-OstapNeural',\n",
|
| 161 |
+
" 'PolinaNeural-Украинский(жен.)': 'uk-UA-PolinaNeural'\n",
|
| 162 |
+
"}\n",
|
| 163 |
+
"\n",
|
| 164 |
+
"# Смена голоса\n",
|
| 165 |
+
"def changeVoice(voices):\n",
|
| 166 |
+
" example = SUPPORTED_VOICES[voices]\n",
|
| 167 |
+
" example_file = os.path.join(os.path.dirname(__file__), \"example/\"+example+\".wav\")\n",
|
| 168 |
+
" return example_file\n",
|
| 169 |
+
"\n",
|
| 170 |
+
"# Преобразование текста в речь\n",
|
| 171 |
+
"async def textToSpeech(text, voices, rate, volume):\n",
|
| 172 |
+
" output_file = \"output.mp3\"\n",
|
| 173 |
+
" voices = SUPPORTED_VOICES[voices]\n",
|
| 174 |
+
" if (rate >= 0):\n",
|
| 175 |
+
" rates = rate = \"+\" + str(rate) + \"%\"\n",
|
| 176 |
+
" else:\n",
|
| 177 |
+
" rates = str(rate) + \"%\"\n",
|
| 178 |
+
" if (volume >= 0):\n",
|
| 179 |
+
" volumes = \"+\" + str(volume) + \"%\"\n",
|
| 180 |
+
" else:\n",
|
| 181 |
+
" volumes = str(volume) + \"%\"\n",
|
| 182 |
+
" communicate = edge_tts.Communicate(text,\n",
|
| 183 |
+
" voices,\n",
|
| 184 |
+
" rate=rates,\n",
|
| 185 |
+
" volume=volumes,\n",
|
| 186 |
+
" proxy=None)\n",
|
| 187 |
+
" await communicate.save(output_file)\n",
|
| 188 |
+
" audio_file = os.path.join(os.path.dirname(__file__), \"output.mp3\")\n",
|
| 189 |
+
" if (os.path.exists(audio_file)):\n",
|
| 190 |
+
" return audio_file\n",
|
| 191 |
+
" else:\n",
|
| 192 |
+
" raise gr.Error(\"Преобразование не удалось!\")\n",
|
| 193 |
+
" return FileNotFoundError\n",
|
| 194 |
+
"\n",
|
| 195 |
+
"\n",
|
| 196 |
+
"# Сбросить результат конвертации\n",
|
| 197 |
+
"def clearSpeech():\n",
|
| 198 |
+
" output_file = os.path.join(os.path.dirname(__file__), \"output.mp3\")\n",
|
| 199 |
+
" if (os.path.exists(output_file)):\n",
|
| 200 |
+
" os.remove(output_file)\n",
|
| 201 |
+
" return None, None\n",
|
| 202 |
+
"\n",
|
| 203 |
+
"\n",
|
| 204 |
+
"with gr.Blocks(css=\"style.css\", title=\"Преобразование текста в речь\") as demo:\n",
|
| 205 |
+
" gr.Markdown(\"\"\"\n",
|
| 206 |
+
" # Преобразование текста в речь через Microsoft Edge\n",
|
| 207 |
+
" \"\"\")\n",
|
| 208 |
+
" with gr.Row():\n",
|
| 209 |
+
" with gr.Column():\n",
|
| 210 |
+
" text = gr.TextArea(label=\"Текст\", elem_classes=\"text-area\")\n",
|
| 211 |
+
" btn = gr.Button(\"Сгенерировать\", elem_id=\"submit-btn\")\n",
|
| 212 |
+
" with gr.Column():\n",
|
| 213 |
+
" voices = gr.Dropdown(choices=[\n",
|
| 214 |
+
" \"DmitryNeural-Руский(муж.)\", \"SvetlanaNeural-Русский(жен.)\", \"OstapNeural-Украинский(муж.)\", \"PolinaNeural-Украинский(жен.)\"\n",
|
| 215 |
+
" ],\n",
|
| 216 |
+
" value=\"DmitryNeural-Руский(муж.)\",\n",
|
| 217 |
+
" label=\"Голос\",\n",
|
| 218 |
+
" info=\"Пожалуйста, выберите голос\",\n",
|
| 219 |
+
" interactive=True)\n",
|
| 220 |
+
"\n",
|
| 221 |
+
" example = gr.Audio(label=\"Пример голоса\",\n",
|
| 222 |
+
" value=\"/content/rus-edge-tts-webui/example/ru-RU-DmitryNeural.wav\",\n",
|
| 223 |
+
" interactive=False,\n",
|
| 224 |
+
" elem_classes=\"example\")\n",
|
| 225 |
+
"\n",
|
| 226 |
+
" voices.change(fn=changeVoice,inputs=voices,outputs=example)\n",
|
| 227 |
+
" rate = gr.Slider(-100,\n",
|
| 228 |
+
" 100,\n",
|
| 229 |
+
" step=1,\n",
|
| 230 |
+
" value=0,\n",
|
| 231 |
+
" label=\"Увеличение / уменьшение скорости речи\",\n",
|
| 232 |
+
" info=\"Скорость речи быстрее / медленнее\",\n",
|
| 233 |
+
" interactive=True)\n",
|
| 234 |
+
"\n",
|
| 235 |
+
" volume = gr.Slider(-100,\n",
|
| 236 |
+
" 100,\n",
|
| 237 |
+
" step=1,\n",
|
| 238 |
+
" value=0,\n",
|
| 239 |
+
" label=\"Увеличение / уменьшение громкости звука\",\n",
|
| 240 |
+
" info=\"Увеличить / уменьшить громкость звука\",\n",
|
| 241 |
+
" interactive=True)\n",
|
| 242 |
+
" audio = gr.Audio(label=\"Результат\",\n",
|
| 243 |
+
" interactive=False,\n",
|
| 244 |
+
" elem_classes=\"audio\")\n",
|
| 245 |
+
" btn.click(fn=textToSpeech,\n",
|
| 246 |
+
" inputs=[text, voices, rate, volume],\n",
|
| 247 |
+
" outputs=[audio])\n",
|
| 248 |
+
"\n",
|
| 249 |
+
"if __name__ == \"__main__\":\n",
|
| 250 |
+
" demo.launch(share=True)\n"
|
| 251 |
+
]
|
| 252 |
+
}
|
| 253 |
+
]
|
| 254 |
+
}
|
install.bat
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
python -m venv ./venv
|
| 2 |
+
call .\venv\Scripts\activate.bat
|
| 3 |
+
pip install -r requirements.txt
|
requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
edge-tts
|
| 2 |
+
gradio
|
| 3 |
+
asyncio
|
start.bat
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
call .\venv\Scripts\activate.bat
|
| 2 |
+
python app.py
|
style.css
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
.audio {
|
| 3 |
+
height: 80px;
|
| 4 |
+
}
|
| 5 |
+
#submit-btn {
|
| 6 |
+
color: #fff;
|
| 7 |
+
background: #409eff;
|
| 8 |
+
border-color: #409eff;
|
| 9 |
+
}
|
| 10 |
+
#submit-btn:hover{
|
| 11 |
+
background: #66b1ff;
|
| 12 |
+
border-color: #66b1ff;
|
| 13 |
+
color: #fff;
|
| 14 |
+
}
|
| 15 |
+
#clear-btn {
|
| 16 |
+
color: #fff;
|
| 17 |
+
background: #e6a23c;
|
| 18 |
+
border-color: #e6a23c;
|
| 19 |
+
}
|
/320/270/320/275/321/202/320/265/321/200/321/204/320/265/320/271/321/201.jpg
ADDED
|