PlotweaverModel commited on
Commit
be31881
·
verified ·
1 Parent(s): 420461f

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +40 -19
app.py CHANGED
@@ -115,13 +115,9 @@ PRESET_VOICES = [
115
  ]
116
 
117
  # YourVoic voices mapped by language
118
- # Confirmed voice names from yourvoic.com
119
  YOURVOIC_VOICE_MAP = {
120
- # African
121
- "Afrikaans": ["Annika", "Willem"],
122
- "Amharic": ["Abebe", "Meron"],
123
- "Swahili": ["Jabari", "Amara"],
124
- # Indian
125
  "Hindi": ["Rahul", "Deepika", "Aditya"],
126
  "Bengali": ["Sneha", "Aryan"],
127
  "Marathi": ["Anjali", "Rohan"],
@@ -131,6 +127,10 @@ YOURVOIC_VOICE_MAP = {
131
  "Kannada": ["Divya", "Karthik"],
132
  "Malayalam": ["Nikhil", "Ammu"],
133
  "Punjabi": ["Vikram", "Simran"],
 
 
 
 
134
  # English fallback
135
  "English": ["Peter", "Sarah", "Caleb"],
136
  }
@@ -146,21 +146,25 @@ for lang, voices in YOURVOIC_VOICE_MAP.items():
146
 
147
  def get_yourvoic_voice_for_language(language, selected_voice):
148
  """Get a valid voice name for the given language.
149
- First tries the selected voice, then hardcoded map, then queries the API."""
150
  voice_name = get_voice_name(selected_voice)
151
  valid_voices = YOURVOIC_VOICE_MAP.get(language, [])
152
 
153
- # If selected voice is in the valid list, use it
154
  if voice_name in valid_voices:
155
  return voice_name
156
 
157
- # Try first valid voice from hardcoded map
158
  if valid_voices:
159
  return valid_voices[0]
160
 
161
- # Fallback: query the YourVoic API for valid voices
162
  yourvoic_lang = LANGUAGES.get(language, {}).get("yourvoic", "en-US")
163
- return _fetch_yourvoic_voice(yourvoic_lang)
 
 
 
 
164
 
165
 
166
  # Cache for API-fetched voices
@@ -173,7 +177,7 @@ def _fetch_yourvoic_voice(yourvoic_lang):
173
 
174
  yv_key = os.environ.get("YOURVOIC_API_KEY", "")
175
  if not yv_key:
176
- return "Peter" # fallback
177
 
178
  try:
179
  resp = http_requests.get(
@@ -182,22 +186,24 @@ def _fetch_yourvoic_voice(yourvoic_lang):
182
  timeout=15,
183
  )
184
  print(f"[YourVoic] Voices API for {yourvoic_lang}: status={resp.status_code}")
 
185
  if resp.status_code == 200:
186
  data = resp.json()
 
187
  voices = data if isinstance(data, list) else data.get("voices", data.get("data", []))
188
  if voices:
189
- # Get first voice name
190
  if isinstance(voices[0], dict):
191
- voice_name = voices[0].get("name", voices[0].get("voice_id", "Peter"))
192
  else:
193
  voice_name = str(voices[0])
194
- print(f"[YourVoic] Found voice for {yourvoic_lang}: {voice_name}")
195
- _yourvoic_voice_cache[yourvoic_lang] = voice_name
196
- return voice_name
 
197
  except Exception as e:
198
  print(f"[YourVoic] Voice lookup failed for {yourvoic_lang}: {e}")
199
 
200
- return "Peter" # ultimate fallback
201
 
202
  YOURVOIC_MODELS = [
203
  "aura-prime -- Balanced quality and speed (recommended)",
@@ -715,6 +721,15 @@ And he would smile - that slow, careful smile that seemed to cost him something
715
  DESCRIPTION = """
716
  # Audiobook Generator
717
  ### English Text to Multi-Language Audiobook
 
 
 
 
 
 
 
 
 
718
  """
719
 
720
  # Build language dropdown
@@ -868,7 +883,13 @@ with gr.Blocks(title="Audiobook Generator") as demo:
868
 
869
  gr.Markdown(
870
  "---\n"
871
- )
 
 
 
 
 
 
872
 
873
  if __name__ == "__main__":
874
  demo.launch()
 
115
  ]
116
 
117
  # YourVoic voices mapped by language
118
+ # Only include CONFIRMED working voice names
119
  YOURVOIC_VOICE_MAP = {
120
+ # Indian - confirmed working
 
 
 
 
121
  "Hindi": ["Rahul", "Deepika", "Aditya"],
122
  "Bengali": ["Sneha", "Aryan"],
123
  "Marathi": ["Anjali", "Rohan"],
 
127
  "Kannada": ["Divya", "Karthik"],
128
  "Malayalam": ["Nikhil", "Ammu"],
129
  "Punjabi": ["Vikram", "Simran"],
130
+ # African - NOT confirmed, will use API lookup
131
+ # "Afrikaans": [], # unknown - use API
132
+ # "Amharic": [], # unknown - use API
133
+ # "Swahili": [], # unknown - use API
134
  # English fallback
135
  "English": ["Peter", "Sarah", "Caleb"],
136
  }
 
146
 
147
  def get_yourvoic_voice_for_language(language, selected_voice):
148
  """Get a valid voice name for the given language.
149
+ Uses API lookup for languages without confirmed voices."""
150
  voice_name = get_voice_name(selected_voice)
151
  valid_voices = YOURVOIC_VOICE_MAP.get(language, [])
152
 
153
+ # If selected voice is confirmed valid for this language, use it
154
  if voice_name in valid_voices:
155
  return voice_name
156
 
157
+ # If we have confirmed voices for this language, use the first one
158
  if valid_voices:
159
  return valid_voices[0]
160
 
161
+ # No confirmed voices - query the API
162
  yourvoic_lang = LANGUAGES.get(language, {}).get("yourvoic", "en-US")
163
+ api_voice = _fetch_yourvoic_voice(yourvoic_lang)
164
+ if api_voice:
165
+ return api_voice
166
+
167
+ return "Peter" # ultimate fallback
168
 
169
 
170
  # Cache for API-fetched voices
 
177
 
178
  yv_key = os.environ.get("YOURVOIC_API_KEY", "")
179
  if not yv_key:
180
+ return None
181
 
182
  try:
183
  resp = http_requests.get(
 
186
  timeout=15,
187
  )
188
  print(f"[YourVoic] Voices API for {yourvoic_lang}: status={resp.status_code}")
189
+ print(f"[YourVoic] Voices response: {resp.text[:500]}")
190
  if resp.status_code == 200:
191
  data = resp.json()
192
+ # Handle different response formats
193
  voices = data if isinstance(data, list) else data.get("voices", data.get("data", []))
194
  if voices:
 
195
  if isinstance(voices[0], dict):
196
+ voice_name = voices[0].get("name", voices[0].get("voice_id", voices[0].get("voice", None)))
197
  else:
198
  voice_name = str(voices[0])
199
+ if voice_name:
200
+ print(f"[YourVoic] Found voice for {yourvoic_lang}: {voice_name}")
201
+ _yourvoic_voice_cache[yourvoic_lang] = voice_name
202
+ return voice_name
203
  except Exception as e:
204
  print(f"[YourVoic] Voice lookup failed for {yourvoic_lang}: {e}")
205
 
206
+ return None
207
 
208
  YOURVOIC_MODELS = [
209
  "aura-prime -- Balanced quality and speed (recommended)",
 
721
  DESCRIPTION = """
722
  # Audiobook Generator
723
  ### English Text to Multi-Language Audiobook
724
+ **Three Voice Engines**
725
+
726
+ | Engine | Languages | Best for |
727
+ |--------|-----------|----------|
728
+ | **Qwen Preset** (20 voices) | English, Chinese, Japanese, Korean, German, French, Russian, Portuguese, Spanish, Italian, Arabic | General audiobooks |
729
+ | **Qwen Clone** (your voice) | Same 10 core (excl. Arabic) | Personalized narration |
730
+ | **YourVoic** (1000+ emotional voices) | Hindi, Bengali, Marathi, Telugu, Tamil, Gujarati, Kannada, Malayalam, Punjabi, Swahili, Amharic, Afrikaans | Indian/African languages |
731
+
732
+ The app automatically selects the right engine based on your chosen language.
733
  """
734
 
735
  # Build language dropdown
 
883
 
884
  gr.Markdown(
885
  "---\n"
886
+ "**Engines:**\n\n"
887
+ "**Qwen Preset:** 11 languages (EN, ZH, JA, KO, DE, FR, RU, PT, ES, IT, AR) via Qwen3.5-Omni-Plus\n\n"
888
+ "**Qwen Clone:** 10 languages (same minus Arabic) via Qwen3-TTS-VC\n\n"
889
+ "**YourVoic:** Hindi, Bengali, Marathi, Telugu, Tamil, Gujarati, Kannada, Malayalam, Punjabi, "
890
+ "Swahili, Amharic, Afrikaans via YourVoic API with emotional voices\n\n"
891
+ "Built with Gradio | Qwen by Alibaba | YourVoic by YourVoic Private Limited"
892
+ )
893
 
894
  if __name__ == "__main__":
895
  demo.launch()