Spaces:
Running
Running
jonathanagustin
commited on
Commit
•
a9471a7
1
Parent(s):
3dad746
Upload folder using huggingface_hub
Browse files
app.py
CHANGED
@@ -4,8 +4,23 @@ import openai
|
|
4 |
import requests
|
5 |
import os
|
6 |
|
|
|
7 |
def tts(input_text: str, model: str, voice: str, api_key: str) -> str:
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
if not api_key.strip():
|
10 |
raise gr.Error(
|
11 |
"API key is required. Get an API key at: https://platform.openai.com/account/api-keys"
|
@@ -19,8 +34,10 @@ def tts(input_text: str, model: str, voice: str, api_key: str) -> str:
|
|
19 |
try:
|
20 |
response = openai.Audio.create(text=input_text, voice=voice, model=model)
|
21 |
except openai.OpenAIError as e:
|
|
|
22 |
raise gr.Error(f"An OpenAI error occurred: {e}")
|
23 |
except Exception as e:
|
|
|
24 |
raise gr.Error(f"An unexpected error occurred: {e}")
|
25 |
|
26 |
if not hasattr(response, "audio"):
|
@@ -34,7 +51,11 @@ def tts(input_text: str, model: str, voice: str, api_key: str) -> str:
|
|
34 |
|
35 |
return temp_file_path
|
36 |
|
|
|
37 |
def main():
|
|
|
|
|
|
|
38 |
MODEL_OPTIONS = ["tts-1", "tts-1-hd"]
|
39 |
VOICE_OPTIONS = ["alloy", "echo", "fable", "onyx", "nova", "shimmer"]
|
40 |
|
@@ -62,99 +83,10 @@ def main():
|
|
62 |
VOICE_PREVIEW_FILES[voice] = local_file_path
|
63 |
|
64 |
# Set static paths for Gradio to serve
|
65 |
-
|
66 |
-
|
67 |
-
with gr.Blocks(theme=gr.themes.Default()) as demo:
|
68 |
-
# Include global CSS styles for the audio elements
|
69 |
-
gr.HTML("""
|
70 |
-
<style>
|
71 |
-
.audio-player {
|
72 |
-
width: 5rem;
|
73 |
-
height: 5rem;
|
74 |
-
margin-bottom: 10px;
|
75 |
-
cursor: pointer;
|
76 |
-
}
|
77 |
-
|
78 |
-
.icon-container {
|
79 |
-
width: 100%;
|
80 |
-
height: 100%;
|
81 |
-
background-color: var(--color-background-secondary);
|
82 |
-
color: var(--color-text-inverse);
|
83 |
-
display: flex;
|
84 |
-
justify-content: center;
|
85 |
-
align-items: center;
|
86 |
-
border-radius: 50%;
|
87 |
-
position: relative;
|
88 |
-
}
|
89 |
-
|
90 |
-
.audio-icon {
|
91 |
-
width: 50%;
|
92 |
-
height: 50%;
|
93 |
-
}
|
94 |
-
|
95 |
-
.audio-player.playing .icon-container {
|
96 |
-
background-color: var(--color-brand-primary);
|
97 |
-
}
|
98 |
-
|
99 |
-
.voice-preview {
|
100 |
-
display: flex;
|
101 |
-
align-items: center;
|
102 |
-
margin-bottom: 1rem;
|
103 |
-
}
|
104 |
-
|
105 |
-
.voice-preview p {
|
106 |
-
margin-left: 10px;
|
107 |
-
font-weight: bold;
|
108 |
-
color: var(--color-text-primary);
|
109 |
-
}
|
110 |
-
</style>
|
111 |
-
""")
|
112 |
-
|
113 |
-
# Add JavaScript for handling play/pause
|
114 |
-
gr.HTML("""
|
115 |
-
<script>
|
116 |
-
function togglePlay(voice) {
|
117 |
-
const player = document.getElementById('audio-player-' + voice);
|
118 |
-
const container = document.getElementById('icon-container-' + voice);
|
119 |
-
const icon = document.getElementById('audio-icon-' + voice);
|
120 |
-
if (player.paused) {
|
121 |
-
// Pause any other playing audios
|
122 |
-
const audios = document.querySelectorAll('audio');
|
123 |
-
audios.forEach(function(audio) {
|
124 |
-
if (audio !== player) {
|
125 |
-
audio.pause();
|
126 |
-
audio.currentTime = 0;
|
127 |
-
const otherVoice = audio.id.replace('audio-player-', '');
|
128 |
-
document.getElementById('icon-container-' + otherVoice).classList.remove('playing');
|
129 |
-
document.getElementById('audio-icon-' + otherVoice).innerHTML = playIcon;
|
130 |
-
}
|
131 |
-
});
|
132 |
-
player.play();
|
133 |
-
container.classList.add('playing');
|
134 |
-
icon.innerHTML = pauseIcon;
|
135 |
-
} else {
|
136 |
-
player.pause();
|
137 |
-
container.classList.remove('playing');
|
138 |
-
icon.innerHTML = playIcon;
|
139 |
-
}
|
140 |
-
player.onended = function() {
|
141 |
-
container.classList.remove('playing');
|
142 |
-
icon.innerHTML = playIcon;
|
143 |
-
};
|
144 |
-
}
|
145 |
-
|
146 |
-
const playIcon = `
|
147 |
-
<svg class="audio-icon" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
148 |
-
<path d="M6.5 5.5v9l7-4.5-7-4.5z"/>
|
149 |
-
</svg>`;
|
150 |
-
|
151 |
-
const pauseIcon = `
|
152 |
-
<svg class="audio-icon" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
|
153 |
-
<path d="M6 5h3v10H6V5zm5 0h3v10h-3V5z"/>
|
154 |
-
</svg>`;
|
155 |
-
</script>
|
156 |
-
""")
|
157 |
|
|
|
158 |
with gr.Row():
|
159 |
with gr.Column(scale=1):
|
160 |
api_key_input = gr.Textbox(
|
@@ -170,29 +102,19 @@ def main():
|
|
170 |
choices=VOICE_OPTIONS, label="Voice Options", value="echo"
|
171 |
)
|
172 |
|
173 |
-
# Add voice previews using
|
174 |
gr.Markdown("### Voice Previews")
|
175 |
for voice in VOICE_OPTIONS:
|
176 |
# Use the relative path for the audio file
|
177 |
audio_url = f"file/{PREVIEW_DIR}/{voice}.wav"
|
178 |
-
# Create
|
179 |
html_snippet = f'''
|
180 |
-
<div
|
181 |
-
<
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
<path d="M6.5 5.5v9l7-4.5-7-4.5z"/>
|
187 |
-
</svg>
|
188 |
-
</div>
|
189 |
-
</div>
|
190 |
-
<audio id="audio-player-{voice}" style="display:none;">
|
191 |
-
<source src="{audio_url}" type="audio/wav">
|
192 |
-
Your browser does not support the audio element.
|
193 |
-
</audio>
|
194 |
-
</div>
|
195 |
-
<p>{voice.capitalize()}</p>
|
196 |
</div>
|
197 |
'''
|
198 |
gr.HTML(html_snippet)
|
@@ -224,4 +146,4 @@ def main():
|
|
224 |
|
225 |
|
226 |
if __name__ == "__main__":
|
227 |
-
main()
|
|
|
4 |
import requests
|
5 |
import os
|
6 |
|
7 |
+
|
8 |
def tts(input_text: str, model: str, voice: str, api_key: str) -> str:
|
9 |
+
"""
|
10 |
+
Convert input text to speech using OpenAI's Text-to-Speech API.
|
11 |
+
|
12 |
+
Parameters:
|
13 |
+
input_text (str): The text to be converted to speech.
|
14 |
+
model (str): The model to use for synthesis (e.g., 'tts-1', 'tts-1-hd').
|
15 |
+
voice (str): The voice profile to use (e.g., 'alloy', 'echo', 'fable', etc.).
|
16 |
+
api_key (str): OpenAI API key.
|
17 |
+
|
18 |
+
Returns:
|
19 |
+
str: File path to the generated audio file.
|
20 |
+
|
21 |
+
Raises:
|
22 |
+
gr.Error: If input parameters are invalid or API call fails.
|
23 |
+
"""
|
24 |
if not api_key.strip():
|
25 |
raise gr.Error(
|
26 |
"API key is required. Get an API key at: https://platform.openai.com/account/api-keys"
|
|
|
34 |
try:
|
35 |
response = openai.Audio.create(text=input_text, voice=voice, model=model)
|
36 |
except openai.OpenAIError as e:
|
37 |
+
# Catch-all for OpenAI exceptions
|
38 |
raise gr.Error(f"An OpenAI error occurred: {e}")
|
39 |
except Exception as e:
|
40 |
+
# Catch any other exceptions
|
41 |
raise gr.Error(f"An unexpected error occurred: {e}")
|
42 |
|
43 |
if not hasattr(response, "audio"):
|
|
|
51 |
|
52 |
return temp_file_path
|
53 |
|
54 |
+
|
55 |
def main():
|
56 |
+
"""
|
57 |
+
Main function to create and launch the Gradio interface.
|
58 |
+
"""
|
59 |
MODEL_OPTIONS = ["tts-1", "tts-1-hd"]
|
60 |
VOICE_OPTIONS = ["alloy", "echo", "fable", "onyx", "nova", "shimmer"]
|
61 |
|
|
|
83 |
VOICE_PREVIEW_FILES[voice] = local_file_path
|
84 |
|
85 |
# Set static paths for Gradio to serve
|
86 |
+
# This needs to be done before creating the Gradio app
|
87 |
+
gr.set_static_paths([PREVIEW_DIR])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
+
with gr.Blocks() as demo:
|
90 |
with gr.Row():
|
91 |
with gr.Column(scale=1):
|
92 |
api_key_input = gr.Textbox(
|
|
|
102 |
choices=VOICE_OPTIONS, label="Voice Options", value="echo"
|
103 |
)
|
104 |
|
105 |
+
# Add voice previews using HTML for minimal audio interface
|
106 |
gr.Markdown("### Voice Previews")
|
107 |
for voice in VOICE_OPTIONS:
|
108 |
# Use the relative path for the audio file
|
109 |
audio_url = f"file/{PREVIEW_DIR}/{voice}.wav"
|
110 |
+
# Create an HTML audio player with minimal controls
|
111 |
html_snippet = f'''
|
112 |
+
<div>
|
113 |
+
<p><strong>{voice.capitalize()}</strong></p>
|
114 |
+
<audio controls preload="auto">
|
115 |
+
<source src="{audio_url}" type="audio/wav">
|
116 |
+
Your browser does not support the audio element.
|
117 |
+
</audio>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
118 |
</div>
|
119 |
'''
|
120 |
gr.HTML(html_snippet)
|
|
|
146 |
|
147 |
|
148 |
if __name__ == "__main__":
|
149 |
+
main()
|