Hamed744 commited on
Commit
dec8bb3
·
verified ·
1 Parent(s): 169ec87

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +41 -45
app.py CHANGED
@@ -1,12 +1,12 @@
1
  # app.py
2
  import gradio as gr
3
  import google.generativeai as genai
4
- from google.generativeai import types # برای استفاده از types.GenerationConfig
5
  import os
6
  import io
7
  from scipy.io.wavfile import write as write_wav
8
  import numpy as np
9
- import traceback # برای چاپ کامل خطا
10
 
11
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
12
  if not GOOGLE_API_KEY:
@@ -14,11 +14,7 @@ if not GOOGLE_API_KEY:
14
  genai.configure(api_key=GOOGLE_API_KEY)
15
 
16
  TTS_MODEL_NAME = "gemini-2.5-flash-preview-tts"
17
-
18
  AVAILABLE_VOICES = ["پیش‌فرض (مدل انتخاب کند)"]
19
- # اگر نام‌های واقعی را پیدا کردید، اینجا اضافه کنید:
20
- # AVAILABLE_VOICES.extend(["voice-name-1", "voice-name-2"])
21
-
22
 
23
  def generate_audio(text_to_speak, selected_voice_name="پیش‌فرض (مدل انتخاب کند)"):
24
  if not text_to_speak:
@@ -26,35 +22,39 @@ def generate_audio(text_to_speak, selected_voice_name="پیش‌فرض (مدل
26
  print(f"درخواست TTS برای متن: '{text_to_speak[:50]}...' با گوینده: {selected_voice_name}")
27
 
28
  try:
 
29
  model = genai.GenerativeModel(f"models/{TTS_MODEL_NAME}")
30
 
31
- generation_config_params = {
32
- "response_modalities": ["AUDIO"]
33
- }
 
34
 
35
  # برای انتخاب گوینده، این بخش نیاز به اطلاعات از مستندات دارد
36
  if selected_voice_name != "پیش‌فرض (مدل انتخاب کند)":
37
  # مثال: generation_config_params["voice"] = selected_voice_name
38
- # یا اگر ساختار speech_config لازم است:
39
- # generation_config_params["speech_config"] = types.SpeechConfig(
40
- # voice_config=types.VoiceConfig(
41
- # prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name=selected_voice_name)
42
- # )
43
- # )
44
- print(f"توجه: انتخاب گوینده ('{selected_voice_name}') هنوز به طور کامل پیاده‌سازی نشده است. از تنظیمات پیش‌فرض مدل برای گوینده استفاده می‌شود.")
45
-
46
- generation_config = genai.types.GenerationConfig(**generation_config_params)
 
47
 
48
- print(f"ارسال درخواست به Gemini با generation_config: {generation_config_params}")
49
 
50
  response = model.generate_content(
51
  text_to_speak,
52
- generation_config=generation_config
53
  )
 
54
 
 
55
  audio_bytes = None
56
  generated_mime_type = None
57
- sample_rate = 24000 # پیش‌فرض، از مستندات چک شود
58
 
59
  if hasattr(response, 'candidates') and response.candidates and \
60
  response.candidates[0].content and response.candidates[0].content.parts:
@@ -104,45 +104,43 @@ def generate_audio(text_to_speak, selected_voice_name="پیش‌فرض (مدل
104
  except genai.types.BlockedPromptException as bpe:
105
  print(f"درخواست توسط مدل بلاک شد: {bpe}")
106
  raise gr.Error(f"محتوای شما توسط مدل پذیرفته نشد. لطفاً متن دیگری را امتحان کنید. دلیل: {bpe}")
107
- except Exception as e: # این بلوک except باید دارای بدنه با تورفتگی باشد
108
  print(f"خطای کلی در تولید صدا: {e}")
109
- traceback.print_exc() # چاپ کامل traceback برای دیباگ
110
  error_message_from_api = ""
111
- # تلاش برای استخراج پیام خطای دقیق‌تر از آبجکت خطای google-generativeai
112
  if hasattr(e, 'args') and e.args:
113
- # خطاهای API گوگل معمولاً جزئیات را در e.args[0] یا یک ساختار پیچیده‌تر دارند
114
- # برای خطای 400 که قبلاً دیدیم، پیام در e.args[0] بود.
115
- if isinstance(e.args[0], str) and "HttpError" in e.args[0]:
116
  try:
117
- # پیام خطا ممکن است شامل یک رشته JSON باشد
118
- msg_str = str(e.args[0])
119
- # استخراج بخش JSON مانند قبل
120
- details_start = msg_str.find('{')
121
  if details_start != -1:
122
- error_details_json = msg_str[details_start:]
123
- # حذف کاراکترهای کنترلی احتمالی و تلاش برای parse
124
- cleaned_json_str = ''.join(c for c in error_details_json if ord(c) >= 32 or c in ('\t', '\n', '\r'))
 
125
  error_obj = json.loads(cleaned_json_str)
126
  if 'error' in error_obj and 'message' in error_obj['error']:
127
  error_message_from_api = error_obj['error']['message']
128
- elif 'message' in error_obj: # گاهی اوقات پیام مستقیم در آبجکت خطا است
129
- error_message_from_api = error_obj['message']
 
130
  except Exception as json_e:
131
- print(f"خطا در parse کردن جزئیات خطای API: {json_e}")
132
- error_message_from_api = str(e.args[0]) # اگر parse نشد، خود پیام اصلی را بگیر
133
  else:
134
  error_message_from_api = str(e.args[0])
 
 
 
135
 
136
  final_error_message = f"خطا در ارتباط با Gemini API یا پردازش صدا: {str(e)}"
137
- if error_message_from_api and error_message_from_api not in final_error_message:
138
  final_error_message += f" | پیام دقیق‌تر API: {error_message_from_api}"
139
- elif not error_message_from_api and hasattr(e, 'message') and isinstance(e.message, str): # fallback
140
- final_error_message += f" | {e.message}"
141
-
142
 
143
  raise gr.Error(final_error_message)
144
 
145
 
 
146
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
147
  gr.Markdown("# تبدیل متن به صدا با Gemini ♊")
148
  gr.Markdown("متن خود را وارد کنید تا با استفاده از مدل‌های جدید Gemini به صدا تبدیل شود.")
@@ -150,7 +148,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
150
  with gr.Row():
151
  with gr.Column(scale=2):
152
  text_input = gr.Textbox(lines=5, label="متن ورودی", placeholder="متن خود را اینجا بنویسید...")
153
- # voice_dropdown = gr.Dropdown(choices=AVAILABLE_VOICES, value=AVAILABLE_VOICES[0], label="انتخاب گوینده") # در آینده فعال شود
154
  submit_button = gr.Button("🔊 تبدیل به صدا", variant="primary")
155
  with gr.Column(scale=1):
156
  audio_output = gr.Audio(label="خروجی صدا", type="filepath")
@@ -166,7 +163,6 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
166
 
167
  submit_button.click(
168
  fn=generate_audio,
169
- # inputs=[text_input, voice_dropdown], # اگر voice_dropdown فعال است
170
  inputs=[text_input],
171
  outputs=[audio_output],
172
  api_name="text_to_speech"
@@ -177,4 +173,4 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
177
  gr.Markdown("توجه: برای انتخاب گوینده‌های مختلف، نیاز به بررسی مستندات دقیق مدل TTS و بروزرسانی کد است.")
178
 
179
  if __name__ == "__main__":
180
- demo.launch(debug=True) # debug=True برای دیدن لاگ‌های دقیق‌تر در کنسول هاگینگ فیس
 
1
  # app.py
2
  import gradio as gr
3
  import google.generativeai as genai
4
+ # from google.generativeai import types # دیگر نیازی به types برای GenerationConfig با response_modalities نیست
5
  import os
6
  import io
7
  from scipy.io.wavfile import write as write_wav
8
  import numpy as np
9
+ import traceback
10
 
11
  GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
12
  if not GOOGLE_API_KEY:
 
14
  genai.configure(api_key=GOOGLE_API_KEY)
15
 
16
  TTS_MODEL_NAME = "gemini-2.5-flash-preview-tts"
 
17
  AVAILABLE_VOICES = ["پیش‌فرض (مدل انتخاب کند)"]
 
 
 
18
 
19
  def generate_audio(text_to_speak, selected_voice_name="پیش‌فرض (مدل انتخاب کند)"):
20
  if not text_to_speak:
 
22
  print(f"درخواست TTS برای متن: '{text_to_speak[:50]}...' با گوینده: {selected_voice_name}")
23
 
24
  try:
25
+ # اطمینان از اینکه نام مدل با پیشوند models/ ارسال می‌شود، همانطور که پیام خطای قبلی نشان داد
26
  model = genai.GenerativeModel(f"models/{TTS_MODEL_NAME}")
27
 
28
+ # --- حذف response_modalities از generation_config ---
29
+ # مدل TTS باید به طور خودکار بداند که خروجی صوتی تولید کند.
30
+ # اگر نیاز به تنظیمات خاصی برای voice یا کیفیت باشد، باید در اینجا اضافه شود.
31
+ generation_config_params = {}
32
 
33
  # برای انتخاب گوینده، این بخش نیاز به اطلاعات از مستندات دارد
34
  if selected_voice_name != "پیش‌فرض (مدل انتخاب کند)":
35
  # مثال: generation_config_params["voice"] = selected_voice_name
36
+ # یا ساختار دقیق‌تری اگر مستندات مشخص کند.
37
+ print(f"توجه: انتخاب گوینده ('{selected_voice_name}') هنوز به طور کامل پیاده‌سازی نشده است.")
38
+
39
+ # فقط اگر generation_config_params خالی نیست، آن را بسازید
40
+ generation_config_to_pass = None
41
+ if generation_config_params:
42
+ generation_config_to_pass = genai.types.GenerationConfig(**generation_config_params)
43
+ print(f"ارسال درخواست به Gemini با generation_config: {generation_config_params}")
44
+ else:
45
+ print("ارسال درخواست به Gemini بدون generation_config خاص (با تنظیمات پیش‌فرض مدل).")
46
 
 
47
 
48
  response = model.generate_content(
49
  text_to_speak,
50
+ generation_config=generation_config_to_pass # می‌تواند None باشد
51
  )
52
+ # --- پایان تغییرات ---
53
 
54
+ # ... (بقیه کد پردازش پاسخ و ذخیره فایل صوتی بدون تغییر نسبت به نسخه قبلی که تورفتگی‌اش درست بود) ...
55
  audio_bytes = None
56
  generated_mime_type = None
57
+ sample_rate = 24000
58
 
59
  if hasattr(response, 'candidates') and response.candidates and \
60
  response.candidates[0].content and response.candidates[0].content.parts:
 
104
  except genai.types.BlockedPromptException as bpe:
105
  print(f"درخواست توسط مدل بلاک شد: {bpe}")
106
  raise gr.Error(f"محتوای شما توسط مدل پذیرفته نشد. لطفاً متن دیگری را امتحان کنید. دلیل: {bpe}")
107
+ except Exception as e:
108
  print(f"خطای کلی در تولید صدا: {e}")
109
+ traceback.print_exc()
110
  error_message_from_api = ""
 
111
  if hasattr(e, 'args') and e.args:
112
+ if isinstance(e.args[0], str) and "HttpError" in e.args[0]: # خطاهای HTTP از API
113
+ error_message_from_api = str(e.args[0]) # کل پیام خطا را بگیرید
114
+ # تلاش برای استخراج جزئیات بیشتر اگر JSON است
115
  try:
116
+ details_start = error_message_from_api.find('{')
 
 
 
117
  if details_start != -1:
118
+ json_str_candidate = error_message_from_api[details_start:]
119
+ # تمیز کردن رشته JSON از کاراکترهای کنترلی ناخواسته
120
+ import json
121
+ cleaned_json_str = ''.join(c for c in json_str_candidate if ord(c) >= 32 or c in ('\t','\r','\n')).strip()
122
  error_obj = json.loads(cleaned_json_str)
123
  if 'error' in error_obj and 'message' in error_obj['error']:
124
  error_message_from_api = error_obj['error']['message']
125
+ elif 'message' in error_obj : # برخی API ها مستقیم پیام خطا دارند
126
+ error_message_from_api = error_obj['message']
127
+
128
  except Exception as json_e:
129
+ print(f"خطا در parse کردن جزئیات JSON از پیام خطای API: {json_e}")
 
130
  else:
131
  error_message_from_api = str(e.args[0])
132
+ elif hasattr(e, 'message') and isinstance(e.message, str): # fallback برای خطاهای دیگر
133
+ error_message_from_api = e.message
134
+
135
 
136
  final_error_message = f"خطا در ارتباط با Gemini API یا پردازش صدا: {str(e)}"
137
+ if error_message_from_api and error_message_from_api not in final_error_message :
138
  final_error_message += f" | پیام دقیق‌تر API: {error_message_from_api}"
 
 
 
139
 
140
  raise gr.Error(final_error_message)
141
 
142
 
143
+ # --- رابط کاربری Gradio بدون تغییر ---
144
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
145
  gr.Markdown("# تبدیل متن به صدا با Gemini ♊")
146
  gr.Markdown("متن خود را وارد کنید تا با استفاده از مدل‌های جدید Gemini به صدا تبدیل شود.")
 
148
  with gr.Row():
149
  with gr.Column(scale=2):
150
  text_input = gr.Textbox(lines=5, label="متن ورودی", placeholder="متن خود را اینجا بنویسید...")
 
151
  submit_button = gr.Button("🔊 تبدیل به صدا", variant="primary")
152
  with gr.Column(scale=1):
153
  audio_output = gr.Audio(label="خروجی صدا", type="filepath")
 
163
 
164
  submit_button.click(
165
  fn=generate_audio,
 
166
  inputs=[text_input],
167
  outputs=[audio_output],
168
  api_name="text_to_speech"
 
173
  gr.Markdown("توجه: برای انتخاب گوینده‌های مختلف، نیاز به بررسی مستندات دقیق مدل TTS و بروزرسانی کد است.")
174
 
175
  if __name__ == "__main__":
176
+ demo.launch(debug=True)