Spaces:
Sleeping
Sleeping
matdmiller
commited on
Commit
·
0edab04
1
Parent(s):
2bf4613
created basic text to speech app - first commit
Browse files- .gitignore +162 -0
- app.ipynb +254 -0
- app.py +62 -0
- requirements.txt +2 -0
.gitignore
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
tts_openai_secrets.py
|
2 |
+
|
3 |
+
# Byte-compiled / optimized / DLL files
|
4 |
+
__pycache__/
|
5 |
+
*.py[cod]
|
6 |
+
*$py.class
|
7 |
+
|
8 |
+
# C extensions
|
9 |
+
*.so
|
10 |
+
|
11 |
+
# Distribution / packaging
|
12 |
+
.Python
|
13 |
+
build/
|
14 |
+
develop-eggs/
|
15 |
+
dist/
|
16 |
+
downloads/
|
17 |
+
eggs/
|
18 |
+
.eggs/
|
19 |
+
lib/
|
20 |
+
lib64/
|
21 |
+
parts/
|
22 |
+
sdist/
|
23 |
+
var/
|
24 |
+
wheels/
|
25 |
+
share/python-wheels/
|
26 |
+
*.egg-info/
|
27 |
+
.installed.cfg
|
28 |
+
*.egg
|
29 |
+
MANIFEST
|
30 |
+
|
31 |
+
# PyInstaller
|
32 |
+
# Usually these files are written by a python script from a template
|
33 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
34 |
+
*.manifest
|
35 |
+
*.spec
|
36 |
+
|
37 |
+
# Installer logs
|
38 |
+
pip-log.txt
|
39 |
+
pip-delete-this-directory.txt
|
40 |
+
|
41 |
+
# Unit test / coverage reports
|
42 |
+
htmlcov/
|
43 |
+
.tox/
|
44 |
+
.nox/
|
45 |
+
.coverage
|
46 |
+
.coverage.*
|
47 |
+
.cache
|
48 |
+
nosetests.xml
|
49 |
+
coverage.xml
|
50 |
+
*.cover
|
51 |
+
*.py,cover
|
52 |
+
.hypothesis/
|
53 |
+
.pytest_cache/
|
54 |
+
cover/
|
55 |
+
|
56 |
+
# Translations
|
57 |
+
*.mo
|
58 |
+
*.pot
|
59 |
+
|
60 |
+
# Django stuff:
|
61 |
+
*.log
|
62 |
+
local_settings.py
|
63 |
+
db.sqlite3
|
64 |
+
db.sqlite3-journal
|
65 |
+
|
66 |
+
# Flask stuff:
|
67 |
+
instance/
|
68 |
+
.webassets-cache
|
69 |
+
|
70 |
+
# Scrapy stuff:
|
71 |
+
.scrapy
|
72 |
+
|
73 |
+
# Sphinx documentation
|
74 |
+
docs/_build/
|
75 |
+
|
76 |
+
# PyBuilder
|
77 |
+
.pybuilder/
|
78 |
+
target/
|
79 |
+
|
80 |
+
# Jupyter Notebook
|
81 |
+
.ipynb_checkpoints
|
82 |
+
|
83 |
+
# IPython
|
84 |
+
profile_default/
|
85 |
+
ipython_config.py
|
86 |
+
|
87 |
+
# pyenv
|
88 |
+
# For a library or package, you might want to ignore these files since the code is
|
89 |
+
# intended to run in multiple environments; otherwise, check them in:
|
90 |
+
# .python-version
|
91 |
+
|
92 |
+
# pipenv
|
93 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
94 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
95 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
96 |
+
# install all needed dependencies.
|
97 |
+
#Pipfile.lock
|
98 |
+
|
99 |
+
# poetry
|
100 |
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
101 |
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
102 |
+
# commonly ignored for libraries.
|
103 |
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
104 |
+
#poetry.lock
|
105 |
+
|
106 |
+
# pdm
|
107 |
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
108 |
+
#pdm.lock
|
109 |
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
110 |
+
# in version control.
|
111 |
+
# https://pdm.fming.dev/#use-with-ide
|
112 |
+
.pdm.toml
|
113 |
+
|
114 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
115 |
+
__pypackages__/
|
116 |
+
|
117 |
+
# Celery stuff
|
118 |
+
celerybeat-schedule
|
119 |
+
celerybeat.pid
|
120 |
+
|
121 |
+
# SageMath parsed files
|
122 |
+
*.sage.py
|
123 |
+
|
124 |
+
# Environments
|
125 |
+
.env
|
126 |
+
.venv
|
127 |
+
env/
|
128 |
+
venv/
|
129 |
+
ENV/
|
130 |
+
env.bak/
|
131 |
+
venv.bak/
|
132 |
+
|
133 |
+
# Spyder project settings
|
134 |
+
.spyderproject
|
135 |
+
.spyproject
|
136 |
+
|
137 |
+
# Rope project settings
|
138 |
+
.ropeproject
|
139 |
+
|
140 |
+
# mkdocs documentation
|
141 |
+
/site
|
142 |
+
|
143 |
+
# mypy
|
144 |
+
.mypy_cache/
|
145 |
+
.dmypy.json
|
146 |
+
dmypy.json
|
147 |
+
|
148 |
+
# Pyre type checker
|
149 |
+
.pyre/
|
150 |
+
|
151 |
+
# pytype static type analyzer
|
152 |
+
.pytype/
|
153 |
+
|
154 |
+
# Cython debug symbols
|
155 |
+
cython_debug/
|
156 |
+
|
157 |
+
# PyCharm
|
158 |
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
159 |
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
160 |
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
161 |
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
162 |
+
#.idea/
|
app.ipynb
ADDED
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"cells": [
|
3 |
+
{
|
4 |
+
"cell_type": "code",
|
5 |
+
"execution_count": null,
|
6 |
+
"id": "3bedf0dc-8d8e-4ede-a9e6-b8f35136aa00",
|
7 |
+
"metadata": {},
|
8 |
+
"outputs": [],
|
9 |
+
"source": [
|
10 |
+
"#|default_exp app"
|
11 |
+
]
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"cell_type": "code",
|
15 |
+
"execution_count": null,
|
16 |
+
"id": "667802a7-0f36-4136-a381-e66210b20462",
|
17 |
+
"metadata": {},
|
18 |
+
"outputs": [],
|
19 |
+
"source": [
|
20 |
+
"#| export\n",
|
21 |
+
"#tts_openai_secrets.py content:\n",
|
22 |
+
"#import os\n",
|
23 |
+
"#os.environ['OPENAI_API_KEY'] = 'sk-XXXXXXXXXXXXXXXXXXXXXX'\n",
|
24 |
+
"try:\n",
|
25 |
+
" import tts_openai_secrets\n",
|
26 |
+
"except:\n",
|
27 |
+
" print('secret import from tts_openai_secrets.py failed - env var must be previously set')"
|
28 |
+
]
|
29 |
+
},
|
30 |
+
{
|
31 |
+
"cell_type": "code",
|
32 |
+
"execution_count": null,
|
33 |
+
"id": "4d9863fc-969e-409b-8e20-b9c3cd2cc3e7",
|
34 |
+
"metadata": {},
|
35 |
+
"outputs": [],
|
36 |
+
"source": [
|
37 |
+
"#| hide\n",
|
38 |
+
"try:\n",
|
39 |
+
" import nbdev\n",
|
40 |
+
"except:\n",
|
41 |
+
" print('to convert this notebook to app.py you need to pip install nbdev')"
|
42 |
+
]
|
43 |
+
},
|
44 |
+
{
|
45 |
+
"cell_type": "code",
|
46 |
+
"execution_count": null,
|
47 |
+
"id": "4f486d3a",
|
48 |
+
"metadata": {},
|
49 |
+
"outputs": [],
|
50 |
+
"source": [
|
51 |
+
"#| export\n",
|
52 |
+
"import gradio as gr\n",
|
53 |
+
"import openai"
|
54 |
+
]
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"cell_type": "code",
|
58 |
+
"execution_count": null,
|
59 |
+
"id": "0ffd33b4-cb9b-4c01-bff6-4c3102854ab6",
|
60 |
+
"metadata": {},
|
61 |
+
"outputs": [
|
62 |
+
{
|
63 |
+
"name": "stdout",
|
64 |
+
"output_type": "stream",
|
65 |
+
"text": [
|
66 |
+
"['tts-1-hd', 'tts-1-hd-1106', 'canary-tts', 'tts-1', 'tts-1-1106']\n"
|
67 |
+
]
|
68 |
+
}
|
69 |
+
],
|
70 |
+
"source": [
|
71 |
+
"#| export\n",
|
72 |
+
"tts_models = [o.id for o in openai.models.list().data if 'tts' in o.id]\n",
|
73 |
+
"print(tts_models)"
|
74 |
+
]
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"cell_type": "code",
|
78 |
+
"execution_count": null,
|
79 |
+
"id": "2ddbca5d-4b04-43ab-afaf-430802980e78",
|
80 |
+
"metadata": {},
|
81 |
+
"outputs": [],
|
82 |
+
"source": [
|
83 |
+
"#| export\n",
|
84 |
+
"tts_voices = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer']"
|
85 |
+
]
|
86 |
+
},
|
87 |
+
{
|
88 |
+
"cell_type": "code",
|
89 |
+
"execution_count": null,
|
90 |
+
"id": "c4e3957f-b97a-4aee-933d-44bfba60b633",
|
91 |
+
"metadata": {},
|
92 |
+
"outputs": [],
|
93 |
+
"source": [
|
94 |
+
"#| export\n",
|
95 |
+
"client = openai.OpenAI()"
|
96 |
+
]
|
97 |
+
},
|
98 |
+
{
|
99 |
+
"cell_type": "code",
|
100 |
+
"execution_count": null,
|
101 |
+
"id": "5388e860",
|
102 |
+
"metadata": {},
|
103 |
+
"outputs": [],
|
104 |
+
"source": [
|
105 |
+
"#| export\n",
|
106 |
+
"def create_speech(input_text, model='tts-1', voice='alloy'):\n",
|
107 |
+
" response = client.audio.speech.create(\n",
|
108 |
+
" model=model,\n",
|
109 |
+
" voice=voice,\n",
|
110 |
+
" input=input_text,\n",
|
111 |
+
" speed=1.0\n",
|
112 |
+
" )\n",
|
113 |
+
" return response.content"
|
114 |
+
]
|
115 |
+
},
|
116 |
+
{
|
117 |
+
"cell_type": "code",
|
118 |
+
"execution_count": null,
|
119 |
+
"id": "236dd8d3-4364-4731-af93-7dcdec6f18a1",
|
120 |
+
"metadata": {},
|
121 |
+
"outputs": [],
|
122 |
+
"source": [
|
123 |
+
"#| export\n",
|
124 |
+
"def get_input_text_len(input_text):\n",
|
125 |
+
" return len(input_text)"
|
126 |
+
]
|
127 |
+
},
|
128 |
+
{
|
129 |
+
"cell_type": "code",
|
130 |
+
"execution_count": null,
|
131 |
+
"id": "e4fb3159-579b-4271-bc96-4cd1e2816eca",
|
132 |
+
"metadata": {},
|
133 |
+
"outputs": [],
|
134 |
+
"source": [
|
135 |
+
"#| export\n",
|
136 |
+
"with gr.Blocks(title='OpenAI TTS', head='OpenAI TTS') as app:\n",
|
137 |
+
" gr.Markdown(\"# OpenAI TTS\")\n",
|
138 |
+
" gr.Markdown(\"Start typing below and then click **Go** to create the speech from your text. The current limit is 4,000 characters.\")\n",
|
139 |
+
" with gr.Row():\n",
|
140 |
+
" input_text = gr.Textbox(max_lines=100, label=\"Enter text here\")\n",
|
141 |
+
" with gr.Row():\n",
|
142 |
+
" tts_model_dropdown = gr.Dropdown(value='tts-1',choices=tts_models, label='Model')\n",
|
143 |
+
" tts_voice_dropdown = gr.Dropdown(value='alloy',choices=tts_voices,label='Voice')\n",
|
144 |
+
" input_text_length = gr.Label(label=\"Number of characters\")\n",
|
145 |
+
" output_audio = gr.Audio()\n",
|
146 |
+
" input_text.input(fn=get_input_text_len, inputs=input_text, outputs=input_text_length)\n",
|
147 |
+
" go_btn = gr.Button(\"Go\")\n",
|
148 |
+
" go_btn.click(fn=create_speech, inputs=[input_text, tts_model_dropdown, tts_voice_dropdown], outputs=[output_audio])\n",
|
149 |
+
" clear_btn = gr.Button('Clear')\n",
|
150 |
+
" clear_btn.click(fn=lambda: '', outputs=input_text)\n",
|
151 |
+
" "
|
152 |
+
]
|
153 |
+
},
|
154 |
+
{
|
155 |
+
"cell_type": "code",
|
156 |
+
"execution_count": null,
|
157 |
+
"id": "cb886d45",
|
158 |
+
"metadata": {},
|
159 |
+
"outputs": [
|
160 |
+
{
|
161 |
+
"name": "stdout",
|
162 |
+
"output_type": "stream",
|
163 |
+
"text": [
|
164 |
+
"Running on local URL: http://0.0.0.0:7860\n",
|
165 |
+
"\n",
|
166 |
+
"To create a public link, set `share=True` in `launch()`.\n"
|
167 |
+
]
|
168 |
+
},
|
169 |
+
{
|
170 |
+
"data": {
|
171 |
+
"text/html": [
|
172 |
+
"<div><iframe src=\"http://localhost:7860/\" width=\"100%\" height=\"500\" allow=\"autoplay; camera; microphone; clipboard-read; clipboard-write;\" frameborder=\"0\" allowfullscreen></iframe></div>"
|
173 |
+
],
|
174 |
+
"text/plain": [
|
175 |
+
"<IPython.core.display.HTML object>"
|
176 |
+
]
|
177 |
+
},
|
178 |
+
"metadata": {},
|
179 |
+
"output_type": "display_data"
|
180 |
+
},
|
181 |
+
{
|
182 |
+
"data": {
|
183 |
+
"text/plain": []
|
184 |
+
},
|
185 |
+
"execution_count": null,
|
186 |
+
"metadata": {},
|
187 |
+
"output_type": "execute_result"
|
188 |
+
}
|
189 |
+
],
|
190 |
+
"source": [
|
191 |
+
"#| export\n",
|
192 |
+
"app.launch()"
|
193 |
+
]
|
194 |
+
},
|
195 |
+
{
|
196 |
+
"cell_type": "code",
|
197 |
+
"execution_count": null,
|
198 |
+
"id": "28e8d888-e790-46fa-bbac-4511b9ab796c",
|
199 |
+
"metadata": {},
|
200 |
+
"outputs": [
|
201 |
+
{
|
202 |
+
"name": "stdout",
|
203 |
+
"output_type": "stream",
|
204 |
+
"text": [
|
205 |
+
"Closing server running on port: 7860\n"
|
206 |
+
]
|
207 |
+
}
|
208 |
+
],
|
209 |
+
"source": [
|
210 |
+
"#| hide\n",
|
211 |
+
"app.close()"
|
212 |
+
]
|
213 |
+
},
|
214 |
+
{
|
215 |
+
"cell_type": "code",
|
216 |
+
"execution_count": null,
|
217 |
+
"id": "afbc9699-4d16-4060-88f4-cd1251754cbd",
|
218 |
+
"metadata": {},
|
219 |
+
"outputs": [],
|
220 |
+
"source": [
|
221 |
+
"#| hide\n",
|
222 |
+
"gr.close_all()"
|
223 |
+
]
|
224 |
+
},
|
225 |
+
{
|
226 |
+
"cell_type": "code",
|
227 |
+
"execution_count": null,
|
228 |
+
"id": "0420310d-930b-4904-8bd4-3458ad8bdbd3",
|
229 |
+
"metadata": {},
|
230 |
+
"outputs": [],
|
231 |
+
"source": [
|
232 |
+
"#| hide\n",
|
233 |
+
"nbdev.export.nb_export('app.ipynb',lib_path='.')"
|
234 |
+
]
|
235 |
+
},
|
236 |
+
{
|
237 |
+
"cell_type": "code",
|
238 |
+
"execution_count": null,
|
239 |
+
"id": "9869749d-bc7c-4e24-9dbc-403f665d6200",
|
240 |
+
"metadata": {},
|
241 |
+
"outputs": [],
|
242 |
+
"source": []
|
243 |
+
}
|
244 |
+
],
|
245 |
+
"metadata": {
|
246 |
+
"kernelspec": {
|
247 |
+
"display_name": "python3",
|
248 |
+
"language": "python",
|
249 |
+
"name": "python3"
|
250 |
+
}
|
251 |
+
},
|
252 |
+
"nbformat": 4,
|
253 |
+
"nbformat_minor": 5
|
254 |
+
}
|
app.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# AUTOGENERATED! DO NOT EDIT! File to edit: app.ipynb.
|
2 |
+
|
3 |
+
# %% auto 0
|
4 |
+
__all__ = ['tts_models', 'tts_voices', 'client', 'create_speech', 'get_input_text_len']
|
5 |
+
|
6 |
+
# %% app.ipynb 1
|
7 |
+
#tts_openai_secrets.py content:
|
8 |
+
#import os
|
9 |
+
#os.environ['OPENAI_API_KEY'] = 'sk-XXXXXXXXXXXXXXXXXXXXXX'
|
10 |
+
try:
|
11 |
+
import tts_openai_secrets
|
12 |
+
except:
|
13 |
+
print('secret import from tts_openai_secrets.py failed - env var must be previously set')
|
14 |
+
|
15 |
+
# %% app.ipynb 3
|
16 |
+
import gradio as gr
|
17 |
+
import openai
|
18 |
+
|
19 |
+
# %% app.ipynb 4
|
20 |
+
tts_models = [o.id for o in openai.models.list().data if 'tts' in o.id]
|
21 |
+
print(tts_models)
|
22 |
+
|
23 |
+
# %% app.ipynb 5
|
24 |
+
tts_voices = ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer']
|
25 |
+
|
26 |
+
# %% app.ipynb 6
|
27 |
+
client = openai.OpenAI()
|
28 |
+
|
29 |
+
# %% app.ipynb 7
|
30 |
+
def create_speech(input_text, model='tts-1', voice='alloy'):
|
31 |
+
response = client.audio.speech.create(
|
32 |
+
model=model,
|
33 |
+
voice=voice,
|
34 |
+
input=input_text,
|
35 |
+
speed=1.0
|
36 |
+
)
|
37 |
+
return response.content
|
38 |
+
|
39 |
+
# %% app.ipynb 8
|
40 |
+
def get_input_text_len(input_text):
|
41 |
+
return len(input_text)
|
42 |
+
|
43 |
+
# %% app.ipynb 9
|
44 |
+
with gr.Blocks(title='OpenAI TTS', head='OpenAI TTS') as app:
|
45 |
+
gr.Markdown("# OpenAI TTS")
|
46 |
+
gr.Markdown("Start typing below and then click **Go** to create the speech from your text. The current limit is 4,000 characters.")
|
47 |
+
with gr.Row():
|
48 |
+
input_text = gr.Textbox(max_lines=100, label="Enter text here")
|
49 |
+
with gr.Row():
|
50 |
+
tts_model_dropdown = gr.Dropdown(value='tts-1',choices=tts_models, label='Model')
|
51 |
+
tts_voice_dropdown = gr.Dropdown(value='alloy',choices=tts_voices,label='Voice')
|
52 |
+
input_text_length = gr.Label(label="Number of characters")
|
53 |
+
output_audio = gr.Audio()
|
54 |
+
input_text.input(fn=get_input_text_len, inputs=input_text, outputs=input_text_length)
|
55 |
+
go_btn = gr.Button("Go")
|
56 |
+
go_btn.click(fn=create_speech, inputs=[input_text, tts_model_dropdown, tts_voice_dropdown], outputs=[output_audio])
|
57 |
+
clear_btn = gr.Button('Clear')
|
58 |
+
clear_btn.click(fn=lambda: '', outputs=input_text)
|
59 |
+
|
60 |
+
|
61 |
+
# %% app.ipynb 10
|
62 |
+
app.launch()
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
openai==1.3.5
|
2 |
+
gradio==4.7.1
|