jonathanagustin commited on
Commit
3dad746
1 Parent(s): 32d9c19

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +112 -34
app.py CHANGED
@@ -4,23 +4,8 @@ import openai
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,10 +19,8 @@ def tts(input_text: str, model: str, voice: str, api_key: str) -> str:
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,11 +34,7 @@ def tts(input_text: str, model: str, voice: str, api_key: str) -> str:
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,10 +62,99 @@ def main():
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,19 +170,29 @@ def main():
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 style="margin-bottom: 10px;">
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,4 +224,4 @@ def main():
146
 
147
 
148
  if __name__ == "__main__":
149
- main()
 
4
  import requests
5
  import os
6
 
 
7
  def tts(input_text: str, model: str, voice: str, api_key: str) -> str:
8
+ # (Same as before)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
  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
 
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
  VOICE_PREVIEW_FILES[voice] = local_file_path
63
 
64
  # Set static paths for Gradio to serve
65
+ gr.static(PREVIEW_DIR)
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
  choices=VOICE_OPTIONS, label="Voice Options", value="echo"
171
  )
172
 
173
+ # Add voice previews using custom HTML audio players
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 custom HTML audio player
179
  html_snippet = f'''
180
+ <div class="voice-preview">
181
+ <div class="audio-player" onclick="togglePlay('{voice}')">
182
+ <div class="icon-container" id="icon-container-{voice}">
183
+ <div id="audio-icon-{voice}">
184
+ <!-- Heroicon Play Button SVG -->
185
+ <svg class="audio-icon" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20">
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
 
225
 
226
  if __name__ == "__main__":
227
+ main()