Opera8 commited on
Commit
a1efa23
·
verified ·
1 Parent(s): 0b650eb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +53 -61
app.py CHANGED
@@ -38,12 +38,7 @@ def download_weights():
38
  if not os.path.exists(motion_model_file):
39
  print("📥 در حال دانلود مدل‌ها...")
40
  try:
41
- snapshot_download(
42
- repo_id=REPO_ID,
43
- local_dir=WEIGHTS_DIR,
44
- local_dir_use_symlinks=False,
45
- resume_download=True,
46
- )
47
  except Exception as e:
48
  print(f"Error downloading: {e}")
49
 
@@ -75,37 +70,52 @@ except Exception as e:
75
 
76
  emo_name_to_id = {v: k for k, v in emo_map.items()}
77
 
78
- # --- جاوا اسکریپت برای ترجمه خطای ZeroGPU ---
79
- # این اسکریپت دائماً صفحه را چک می‌کند و اگر خطای انگلیسی را دید، آن را فارسی می‌کند
80
  js_func = """
81
- function refresh() {
82
- const url = new URL(window.location);
83
- if (url.searchParams.get('__theme') !== 'light') {
84
- url.searchParams.set('__theme', 'light');
85
- window.location.href = url.href;
86
- }
87
-
88
- // Observer برای پیدا کردن پیام خطا و ترجمه آن
89
- const observer = new MutationObserver(() => {
90
- document.querySelectorAll('.toast-body, .error, .prose').forEach(el => {
91
- if (el.innerText.includes('ZeroGPU quota exceeded')) {
92
- el.innerHTML = '<b>🔴 سهمیه GPU شما تمام شده است!</b><br>لطفاً مدتی صبر کنید تا سهمیه شما شارژ شود و دوباره تلاش کنید.';
93
- el.style.direction = 'rtl';
94
- el.style.textAlign = 'right';
95
- el.style.fontSize = '1.1em';
96
- }
97
- if (el.innerText.includes('exceeded your GPU quota')) {
98
- el.style.display = 'none'; // مخفی کردن متن انگلیسی اضافی
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  }
100
  });
101
  });
 
102
  observer.observe(document.body, { childList: true, subtree: true });
103
  }
104
  """
105
 
106
  # --- تابع اصلی ---
107
- # نکته مهم: duration را به 60 کاهش دادم تا با سهمیه باقی‌مانده شما یکی باشد و کمتر ارور بدهد
108
- @spaces.GPU(duration=60)
109
  def generate_motion(source_image_path, driving_audio_path, persian_emotion_name, cfg_scale, progress=gr.Progress(track_tqdm=True)):
110
  if pipeline is None:
111
  raise gr.Error("❌ مدل هنوز بارگذاری نشده است. لطفاً صفحه را رفرش کنید.")
@@ -122,8 +132,6 @@ def generate_motion(source_image_path, driving_audio_path, persian_emotion_name,
122
 
123
  wav_audio_path = ensure_wav_format(driving_audio_path)
124
 
125
- print(f"🚀 شروع پردازش: {english_emo_name}, CFG: {cfg_scale}")
126
-
127
  result_video_path = pipeline.driven_sample(
128
  image_path=source_image_path,
129
  audio_path=wav_audio_path,
@@ -143,32 +151,14 @@ def generate_motion(source_image_path, driving_audio_path, persian_emotion_name,
143
  except Exception as e:
144
  print(f"Error Detail: {e}")
145
  traceback.print_exc()
146
- error_str = str(e).lower()
147
-
148
- if "quota" in error_str:
149
- raise gr.Error("⏳ سهمیه GPU شما تمام شده است.")
150
- elif "cuda" in error_str:
151
- raise gr.Error("💥 خطای سیستم. لطفاً دوباره تلاش کنید.")
152
- else:
153
- raise gr.Error(f"❌ خطا: {e}")
154
 
155
  # --- رابط کاربری ---
156
  css = """
157
  .gradio-container {max-width: 900px !important; margin: auto !important; font-family: 'Tahoma', sans-serif;}
158
  h1, h2, h3, p, span, div {direction: rtl; text-align: right;}
159
  .center-text {text-align: center !important;}
160
-
161
- /* استایل مخصوص برای راست‌چین کردن پیام‌های خطا */
162
- .toast-wrap {
163
- direction: rtl !important;
164
- text-align: right !important;
165
- font-family: 'Tahoma', sans-serif !important;
166
- right: 20px !important;
167
- left: auto !important;
168
- }
169
- .toast-body {
170
- font-size: 16px !important;
171
- }
172
  """
173
 
174
  with gr.Blocks(theme=gr.themes.Soft(), css=css, title="MoDA Farsi", js=js_func) as demo:
@@ -183,10 +173,20 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css, title="MoDA Farsi", js=js_func)
183
 
184
  with gr.Row():
185
  with gr.Column():
186
- source_image = gr.Image(label="۱. تصویر چهره", type="filepath", height=250)
187
- driving_audio = gr.Audio(label="۲. فایل صوتی", type="filepath")
 
 
 
 
 
 
 
 
 
 
188
 
189
- with gr.Accordion("⚙️ تنظیمات پیشرفته", open=False):
190
  with gr.Row():
191
  emotion_dropdown = gr.Dropdown(
192
  label="حالت چهره",
@@ -195,14 +195,6 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css, title="MoDA Farsi", js=js_func)
195
  )
196
  cfg_slider = gr.Slider(label="دقت (CFG)", minimum=1.0, maximum=3.0, value=1.2, step=0.1)
197
 
198
- gr.Markdown(
199
- """
200
- <div style="background-color: #fff3cd; color: #856404; padding: 10px; border-radius: 5px; margin-top: 10px; font-size: 0.9em; text-align: right;">
201
- ⚠️ <b>نکته:</b> اگر ارور <b>Quota Exceeded</b> دیدید، یعنی سهمیه رایگان تمام شده است.
202
- </div>
203
- """
204
- )
205
-
206
  submit_btn = gr.Button("🎥 ساخت ویدیو", variant="primary", size="lg")
207
 
208
  with gr.Column():
 
38
  if not os.path.exists(motion_model_file):
39
  print("📥 در حال دانلود مدل‌ها...")
40
  try:
41
+ snapshot_download(repo_id=REPO_ID, local_dir=WEIGHTS_DIR, local_dir_use_symlinks=False, resume_download=True)
 
 
 
 
 
42
  except Exception as e:
43
  print(f"Error downloading: {e}")
44
 
 
70
 
71
  emo_name_to_id = {v: k for k, v in emo_map.items()}
72
 
73
+ # --- جاوا اسکریپت هوشمند برای ترجمه خطای ZeroGPU ---
 
74
  js_func = """
75
+ () => {
76
+ const observer = new MutationObserver((mutations) => {
77
+ mutations.forEach((mutation) => {
78
+ if (mutation.addedNodes.length) {
79
+ mutation.addedNodes.forEach((node) => {
80
+ if (node.nodeType === 1 && (node.classList.contains('toast-body') || node.classList.contains('error'))) {
81
+ const originalText = node.innerText;
82
+
83
+ // Regex برای پیدا کردن اعداد در متن خطا
84
+ const regex = /(\d+)s requested vs. (\d+)s left/;
85
+ const match = originalText.match(regex);
86
+
87
+ if (match && !node.dataset.translated) {
88
+ const requested = match[1];
89
+ const left = match[2];
90
+
91
+ // ساخت پیام فارسی با استفاده از اعداد استخراج شده
92
+ node.innerHTML = `
93
+ <b>🔴 سهمیه GPU کافی نیست!</b>
94
+ <hr style='margin: 5px 0; border-top: 1px solid #c82333;'>
95
+ <div style='font-size: 0.9em;'>
96
+ زمان درخواستی شما: <b>${requested} ثانیه</b><br>
97
+ اعتبار باقیمانده: <b>${left} ثانیه</b>
98
+ </div>
99
+ `;
100
+
101
+ node.style.direction = 'rtl';
102
+ node.style.textAlign = 'right';
103
+ node.style.fontFamily = 'Tahoma, sans-serif';
104
+ node.dataset.translated = 'true'; // جلوگیری از ترجمه مجدد
105
+ }
106
+ }
107
+ });
108
  }
109
  });
110
  });
111
+
112
  observer.observe(document.body, { childList: true, subtree: true });
113
  }
114
  """
115
 
116
  # --- تابع اصلی ---
117
+ # زمان را روی ۱۲۰ ثانیه تنظیم می‌کنیم تا حداکثر مقدار ممکن باشد
118
+ @spaces.GPU(duration=120)
119
  def generate_motion(source_image_path, driving_audio_path, persian_emotion_name, cfg_scale, progress=gr.Progress(track_tqdm=True)):
120
  if pipeline is None:
121
  raise gr.Error("❌ مدل هنوز بارگذاری نشده است. لطفاً صفحه را رفرش کنید.")
 
132
 
133
  wav_audio_path = ensure_wav_format(driving_audio_path)
134
 
 
 
135
  result_video_path = pipeline.driven_sample(
136
  image_path=source_image_path,
137
  audio_path=wav_audio_path,
 
151
  except Exception as e:
152
  print(f"Error Detail: {e}")
153
  traceback.print_exc()
154
+ raise gr.Error(f"❌ خطا در پردازش: {e}")
 
 
 
 
 
 
 
155
 
156
  # --- رابط کاربری ---
157
  css = """
158
  .gradio-container {max-width: 900px !important; margin: auto !important; font-family: 'Tahoma', sans-serif;}
159
  h1, h2, h3, p, span, div {direction: rtl; text-align: right;}
160
  .center-text {text-align: center !important;}
161
+ .toast-wrap { direction: rtl !important; }
 
 
 
 
 
 
 
 
 
 
 
162
  """
163
 
164
  with gr.Blocks(theme=gr.themes.Soft(), css=css, title="MoDA Farsi", js=js_func) as demo:
 
173
 
174
  with gr.Row():
175
  with gr.Column():
176
+ # **اضافه شدن مقادیر پیش‌فرض**
177
+ source_image = gr.Image(
178
+ label="۱. تصویر چهره",
179
+ type="filepath",
180
+ value="src/examples/reference_images/7.jpg",
181
+ height=250
182
+ )
183
+ driving_audio = gr.Audio(
184
+ label="۲. فایل صوتی",
185
+ type="filepath",
186
+ value="src/examples/driving_audios/5.wav"
187
+ )
188
 
189
+ with gr.Accordion("⚙️ تنظیمات پیشرفته", open=True):
190
  with gr.Row():
191
  emotion_dropdown = gr.Dropdown(
192
  label="حالت چهره",
 
195
  )
196
  cfg_slider = gr.Slider(label="دقت (CFG)", minimum=1.0, maximum=3.0, value=1.2, step=0.1)
197
 
 
 
 
 
 
 
 
 
198
  submit_btn = gr.Button("🎥 ساخت ویدیو", variant="primary", size="lg")
199
 
200
  with gr.Column():