Update app.py
Browse files
app.py
CHANGED
|
@@ -108,7 +108,7 @@ def get_user_ip():
|
|
| 108 |
return request.headers.getlist("X-Forwarded-For")[0].split(',')[0].strip()
|
| 109 |
return request.remote_addr
|
| 110 |
|
| 111 |
-
# --- TTS HELPER FUNCTIONS (
|
| 112 |
def call_worker(index, chunk_payload):
|
| 113 |
text_length = len(chunk_payload.get("text", ""))
|
| 114 |
use_live = True if text_length <= 500 else False
|
|
@@ -126,16 +126,18 @@ def call_worker(index, chunk_payload):
|
|
| 126 |
"fallback_to_live": True
|
| 127 |
}
|
| 128 |
|
| 129 |
-
|
|
|
|
| 130 |
|
| 131 |
for attempt in range(max_attempts):
|
| 132 |
workers = list(WORKER_URLS)
|
| 133 |
-
random.shuffle(workers)
|
| 134 |
|
| 135 |
for worker_url in workers:
|
| 136 |
try:
|
| 137 |
-
logging.info(f"Chunk {index} -> Sending to {worker_url} (Attempt {attempt+1})")
|
| 138 |
-
|
|
|
|
| 139 |
|
| 140 |
if response.status_code == 200:
|
| 141 |
audio_data = io.BytesIO(response.content)
|
|
@@ -143,28 +145,26 @@ def call_worker(index, chunk_payload):
|
|
| 143 |
return index, audio_segment
|
| 144 |
|
| 145 |
elif response.status_code == 429:
|
| 146 |
-
|
| 147 |
-
time.sleep(1 + random.uniform(0, 1.5)) # زمانبندی تصادفی برای جلوگیری از همزمانی مطلق
|
| 148 |
continue
|
| 149 |
|
| 150 |
else:
|
| 151 |
-
|
| 152 |
-
time.sleep(1)
|
| 153 |
continue
|
| 154 |
|
| 155 |
except Exception as e:
|
| 156 |
-
|
| 157 |
-
time.sleep(1)
|
| 158 |
continue
|
| 159 |
|
| 160 |
-
# اس
|
| 161 |
-
|
| 162 |
-
|
|
|
|
| 163 |
time.sleep(sleep_time)
|
| 164 |
|
| 165 |
return index, None
|
| 166 |
|
| 167 |
-
# --- AI PODCAST SCRIPT LOGIC ---
|
| 168 |
def generate_podcast_in_background(task_id, system_prompt, safety_settings):
|
| 169 |
try:
|
| 170 |
AYA_SPACE_URL = "https://coherelabs-aya-expanse.hf.space/gradio_api"
|
|
@@ -235,7 +235,7 @@ def generate_podcast_in_background(task_id, system_prompt, safety_settings):
|
|
| 235 |
except Exception as e:
|
| 236 |
with tasks_lock: tasks[task_id].update({'status': 'failed', 'error': str(e)})
|
| 237 |
|
| 238 |
-
# --- FULL AUTO PODCAST LOGIC ---
|
| 239 |
def generate_full_podcast_audio_background(task_id, prompt, speakers):
|
| 240 |
try:
|
| 241 |
with tasks_lock:
|
|
@@ -309,7 +309,7 @@ Dialogue rules: No stage directions like [laugh], (sigh). Just spoken words."""
|
|
| 309 |
with tasks_lock:
|
| 310 |
tasks[task_id] = {'status': 'generating_audio', 'progress': f'در حال تولید همزمان صداها (0 از {total_turns} تکمیل شده)'}
|
| 311 |
|
| 312 |
-
# --- سیستم پردازش موازی
|
| 313 |
audio_results = [None] * total_turns
|
| 314 |
completed_count = 0
|
| 315 |
|
|
@@ -322,8 +322,9 @@ Dialogue rules: No stage directions like [laugh], (sigh). Just spoken words."""
|
|
| 322 |
raise ValueError(f"خطا در تولید صدای نوبت {index+1}")
|
| 323 |
return idx, audio_seg
|
| 324 |
|
| 325 |
-
#
|
| 326 |
-
|
|
|
|
| 327 |
future_to_index = {executor.submit(process_single_chunk, i, turn): i for i, turn in enumerate(script_turns)}
|
| 328 |
|
| 329 |
for future in concurrent.futures.as_completed(future_to_index):
|
|
@@ -332,7 +333,7 @@ Dialogue rules: No stage directions like [laugh], (sigh). Just spoken words."""
|
|
| 332 |
audio_results[idx] = audio_seg
|
| 333 |
completed_count += 1
|
| 334 |
with tasks_lock:
|
| 335 |
-
tasks[task_id]['progress'] = f'در حال تولید
|
| 336 |
except Exception as exc:
|
| 337 |
raise Exception(str(exc))
|
| 338 |
|
|
|
|
| 108 |
return request.headers.getlist("X-Forwarded-For")[0].split(',')[0].strip()
|
| 109 |
return request.remote_addr
|
| 110 |
|
| 111 |
+
# --- TTS HELPER FUNCTIONS (Optimized: Jitter + Safe Retries) ---
|
| 112 |
def call_worker(index, chunk_payload):
|
| 113 |
text_length = len(chunk_payload.get("text", ""))
|
| 114 |
use_live = True if text_length <= 500 else False
|
|
|
|
| 126 |
"fallback_to_live": True
|
| 127 |
}
|
| 128 |
|
| 129 |
+
# افزایش سماجت به 40 بار تلاش
|
| 130 |
+
max_attempts = 40
|
| 131 |
|
| 132 |
for attempt in range(max_attempts):
|
| 133 |
workers = list(WORKER_URLS)
|
| 134 |
+
random.shuffle(workers) # کارگرها هر بار رندوم چیده میشوند
|
| 135 |
|
| 136 |
for worker_url in workers:
|
| 137 |
try:
|
| 138 |
+
logging.info(f"Chunk {index} -> Sending to {worker_url} (Attempt {attempt+1}/{max_attempts})")
|
| 139 |
+
# افزایش تایم اوت به 150 ثانیه
|
| 140 |
+
response = requests.post(worker_url, json=worker_payload, timeout=150)
|
| 141 |
|
| 142 |
if response.status_code == 200:
|
| 143 |
audio_data = io.BytesIO(response.content)
|
|
|
|
| 145 |
return index, audio_segment
|
| 146 |
|
| 147 |
elif response.status_code == 429:
|
| 148 |
+
# 429 یعنی شلوغی، پس بدون معطلی میریم کارگر بعدی
|
|
|
|
| 149 |
continue
|
| 150 |
|
| 151 |
else:
|
| 152 |
+
# ارور 500 و بقیه، میریم کارگر بعدی
|
|
|
|
| 153 |
continue
|
| 154 |
|
| 155 |
except Exception as e:
|
| 156 |
+
# تایم اوت یا خطای شبکه، میریم کارگر بعدی
|
|
|
|
| 157 |
continue
|
| 158 |
|
| 159 |
+
# اگر هر سه کارگر خطا دادند، اینجا Jitter (تاخیر تصادفی) اعمال میکنیم
|
| 160 |
+
# این کار باعث میشه Thread ها همزمان بیدار نشن
|
| 161 |
+
sleep_time = 4 + (attempt * 1.5) + random.uniform(0.5, 3.5)
|
| 162 |
+
logging.warning(f"All workers busy/failed for Chunk {index}. Sleeping for {sleep_time:.2f}s...")
|
| 163 |
time.sleep(sleep_time)
|
| 164 |
|
| 165 |
return index, None
|
| 166 |
|
| 167 |
+
# --- AI PODCAST SCRIPT LOGIC (Cohere Labs Space) ---
|
| 168 |
def generate_podcast_in_background(task_id, system_prompt, safety_settings):
|
| 169 |
try:
|
| 170 |
AYA_SPACE_URL = "https://coherelabs-aya-expanse.hf.space/gradio_api"
|
|
|
|
| 235 |
except Exception as e:
|
| 236 |
with tasks_lock: tasks[task_id].update({'status': 'failed', 'error': str(e)})
|
| 237 |
|
| 238 |
+
# --- FULL AUTO PODCAST LOGIC (پردازش موازی مدیریت شده) ---
|
| 239 |
def generate_full_podcast_audio_background(task_id, prompt, speakers):
|
| 240 |
try:
|
| 241 |
with tasks_lock:
|
|
|
|
| 309 |
with tasks_lock:
|
| 310 |
tasks[task_id] = {'status': 'generating_audio', 'progress': f'در حال تولید همزمان صداها (0 از {total_turns} تکمیل شده)'}
|
| 311 |
|
| 312 |
+
# --- سیستم پردازش موازی بهینهشده ---
|
| 313 |
audio_results = [None] * total_turns
|
| 314 |
completed_count = 0
|
| 315 |
|
|
|
|
| 322 |
raise ValueError(f"خطا در تولید صدای نوبت {index+1}")
|
| 323 |
return idx, audio_seg
|
| 324 |
|
| 325 |
+
# 🚨 کاهش فشار: اجرای درخواستها تا سقف ۴ فایل موازی (جلوگیری از خفگی کارگرها)
|
| 326 |
+
max_concurrent_workers = min(4, total_turns)
|
| 327 |
+
with concurrent.futures.ThreadPoolExecutor(max_workers=max_concurrent_workers) as executor:
|
| 328 |
future_to_index = {executor.submit(process_single_chunk, i, turn): i for i, turn in enumerate(script_turns)}
|
| 329 |
|
| 330 |
for future in concurrent.futures.as_completed(future_to_index):
|
|
|
|
| 333 |
audio_results[idx] = audio_seg
|
| 334 |
completed_count += 1
|
| 335 |
with tasks_lock:
|
| 336 |
+
tasks[task_id]['progress'] = f'در حال تولید صداها ({completed_count} از {total_turns} تکمیل شده)'
|
| 337 |
except Exception as exc:
|
| 338 |
raise Exception(str(exc))
|
| 339 |
|