Opera8 commited on
Commit
5aea58d
·
verified ·
1 Parent(s): a6d25fc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -56
app.py CHANGED
@@ -2319,7 +2319,7 @@ def apply_example(idx: str):
2319
 
2320
 
2321
  ####################################################################################################
2322
- ### PART 20: Gradio UI Layout & Launch (FINAL & PICKLE-SAFE VERSION)
2323
  ####################################################################################################
2324
  import requests
2325
  import time
@@ -2343,25 +2343,47 @@ async (video) => {
2343
  }
2344
  """
2345
 
2346
- def enhance_prompt_api(image_path: str, prompt: str, mode: str) -> str:
2347
- """این تابع از بک اند پایتون، API بهینه ساز را فراخوانی می کند."""
2348
- if mode not in ['تبدیل تصویر به ویدیو', 'تکمیل فریم‌های میانی'] or not image_path:
2349
- return prompt
 
 
 
 
 
2350
 
2351
- url = 'https://ezmarynoori-vidtolani.hf.space/api/enhance-animation-prompt'
2352
- try:
2353
- with open(image_path, 'rb') as f:
2354
- files = {'image': f}
2355
- data = {'prompt': prompt, 'is_extension': 'false'}
2356
- response = requests.post(url, files=files, data=data, timeout=45)
2357
- response.raise_for_status()
2358
- result = response.json()
2359
- enhanced = result.get("animation_prompt", prompt)
2360
- print(f"Prompt enhanced successfully: {enhanced}")
2361
- return enhanced
2362
- except Exception as e:
2363
- print(f"Could not enhance prompt, falling back to original. Error: {e}")
2364
- return prompt
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2365
 
2366
  def apply_example(idx: str):
2367
  idx = int(idx)
@@ -2375,48 +2397,35 @@ def apply_example(idx: str):
2375
 
2376
  # --- توابع کنترل کننده در سطح گلوبال تعریف شده اند ---
2377
 
2378
- @spaces.GPU(duration=60)
2379
- def enhancement_step(first_frame, prompt, mode):
2380
- """رویداد اول: UI را قفل کرده، بهینه سازی را انجام داده و محرک را به روز می کند."""
2381
- # به‌روزرسانی اول: شروع فرآیند
2382
- yield (
2383
- gr.Button(value="⏳ در حال بهینه سازی پرامپت...", interactive=False),
2384
- None, # output_video
2385
- gr.Button(visible=False), # download_btn
2386
- gr.update(), # prompt_ui
2387
- gr.update() # enhanced_prompt_trigger
2388
- )
2389
-
2390
- enhanced_prompt = enhance_prompt_api(first_frame, prompt, mode)
2391
-
2392
- # به‌روزرسانی دوم: پایان بهینه سازی و آماده سازی برای ساخت
2393
- yield (
2394
- gr.Button(value="🚀 آماده سازی برای ساخت...", interactive=False),
2395
- gr.update(),
2396
- gr.update(),
2397
- gr.update(value=enhanced_prompt),
2398
- enhanced_prompt # مقدار دهی محرک برای شروع رویداد بعدی
2399
- )
2400
 
2401
  @spaces.GPU(duration=get_duration)
2402
- def generation_step(
2403
  first_frame, end_frame, enhanced_prompt, duration, input_video,
2404
  radioanimated_mode, enhance_prompt_flag, seed, randomize_seed,
2405
  height, width, camera_lora, audio_input, progress=gr.Progress(track_tqdm=True)
2406
  ):
2407
- """رویداد دوم: ویدیو را می سازد."""
 
 
 
 
 
 
2408
  video_path = generate_video(
2409
  first_frame, end_frame, enhanced_prompt, duration, input_video,
2410
  radioanimated_mode, enhance_prompt_flag, seed, randomize_seed,
2411
  height, width, camera_lora, audio_input, progress
2412
  )
2413
- # پس از اتمام، UI را نهایی می کند
2414
- return (
2415
- gr.Button(value="🤩 ساخت ویدیو", interactive=True),
2416
- video_path,
2417
- gr.Button(visible=True)
2418
- )
2419
-
2420
 
2421
  with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
2422
  gr.HTML(
@@ -2477,22 +2486,28 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
2477
  audio_ui.change(fn=lambda v: None if v == "__CLEAR__" or not v else gr.update(), inputs=audio_ui, outputs=audio_input, api_visibility="private")
2478
  download_btn.click(fn=None, inputs=[output_video], js=js_download_video)
2479
 
2480
- # رویداد اول: با کلیک کاربر شروع می شود
 
2481
  generate_btn.click(
2482
- fn=enhancement_step,
 
 
 
2483
  inputs=[first_frame, prompt, radioanimated_mode],
2484
- outputs=[generate_btn, output_video, download_btn, prompt_ui, enhanced_prompt_trigger]
 
2485
  )
2486
 
2487
- # رویداد دوم: با تغییر مقدار محرک پنهان شروع می شود
 
2488
  enhanced_prompt_trigger.change(
2489
- fn=generation_step,
2490
  inputs=[
2491
  first_frame, end_frame, enhanced_prompt_trigger, duration, input_video,
2492
  radioanimated_mode, enhance_prompt_flag_input, seed, randomize_seed,
2493
  height, width, camera_lora, audio_input
2494
  ],
2495
- outputs=[generate_btn, output_video, download_btn]
2496
  )
2497
 
2498
  # منطق نمونه ها
 
2319
 
2320
 
2321
  ####################################################################################################
2322
+ ### PART 20: Gradio UI Layout & Launch (FINAL, CLIENT-SIDE, DUAL-EVENT)
2323
  ####################################################################################################
2324
  import requests
2325
  import time
 
2343
  }
2344
  """
2345
 
2346
+ # این تابع جاوااسکریپت در مرورگر کاربر اجرا می شود
2347
+ # و نتیجه را برای فعال کردن رویداد بعدی برمی گرداند
2348
+ js_enhancer_api_call = """
2349
+ async (firstFrame, promptText, mode) => {
2350
+ // اگر بهینه سازی لازم نیست، پرامپت اصلی را برگردان
2351
+ if (mode !== 'تبدیل تصویر به ویدیو' && mode !== 'تکمیل فریم‌های میانی' || !firstFrame) {
2352
+ if (!firstFrame) console.warn("Enhancement skipped: First frame image is required.");
2353
+ return promptText;
2354
+ }
2355
 
2356
+ try {
2357
+ const response = await fetch(firstFrame.url);
2358
+ const imageBlob = await response.blob();
2359
+
2360
+ const formData = new FormData();
2361
+ const imageFile = new File([imageBlob], "image.jpg", { type: "image/jpeg" });
2362
+ formData.append('image', imageFile);
2363
+ formData.append('prompt', promptText);
2364
+ formData.append('is_extension', 'false');
2365
+
2366
+ const apiResponse = await fetch('https://ezmarynoori-vidtolani.hf.space/api/enhance-animation-prompt', {
2367
+ method: 'POST',
2368
+ body: formData
2369
+ });
2370
+
2371
+ if (!apiResponse.ok) {
2372
+ const errorData = await apiResponse.json();
2373
+ throw new Error(errorData.error || 'خطای ناشناخته از سرور بهینه ساز.');
2374
+ }
2375
+
2376
+ const data = await apiResponse.json();
2377
+ console.log("Enhanced Prompt received:", data.animation_prompt);
2378
+ return data.animation_prompt;
2379
+
2380
+ } catch (error) {
2381
+ console.error("Enhancement API Error:", error);
2382
+ // در صورت خطا، پرامپت اصلی را برگردان تا فرآیند متوقف نشود
2383
+ return promptText;
2384
+ }
2385
+ }
2386
+ """
2387
 
2388
  def apply_example(idx: str):
2389
  idx = int(idx)
 
2397
 
2398
  # --- توابع کنترل کننده در سطح گلوبال تعریف شده اند ---
2399
 
2400
+ def start_enhancement_ui():
2401
+ """فقط UI را برای شروع بهینه سازی آماده می کند."""
2402
+ return gr.Button(value="در حال بهینه سازی پرامپت...", interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2403
 
2404
  @spaces.GPU(duration=get_duration)
2405
+ def run_generation_from_trigger(
2406
  first_frame, end_frame, enhanced_prompt, duration, input_video,
2407
  radioanimated_mode, enhance_prompt_flag, seed, randomize_seed,
2408
  height, width, camera_lora, audio_input, progress=gr.Progress(track_tqdm=True)
2409
  ):
2410
+ """رویداد دوم: ویدیو را می سازد و UI را در هر مرحله آپدیت می کند."""
2411
+ # به‌روزرسانی اول: شروع ساخت ویدیو
2412
+ yield {
2413
+ generate_btn: gr.Button(value="🚀 در حال ساخت ویدیو...", interactive=False),
2414
+ prompt_ui: gr.update(value=enhanced_prompt)
2415
+ }
2416
+
2417
  video_path = generate_video(
2418
  first_frame, end_frame, enhanced_prompt, duration, input_video,
2419
  radioanimated_mode, enhance_prompt_flag, seed, randomize_seed,
2420
  height, width, camera_lora, audio_input, progress
2421
  )
2422
+
2423
+ # به‌روزرسانی نهایی: پایان کار
2424
+ yield {
2425
+ generate_btn: gr.Button(value="🤩 ساخت ویدیو", interactive=True),
2426
+ output_video: video_path,
2427
+ download_btn: gr.Button(visible=True)
2428
+ }
2429
 
2430
  with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
2431
  gr.HTML(
 
2486
  audio_ui.change(fn=lambda v: None if v == "__CLEAR__" or not v else gr.update(), inputs=audio_ui, outputs=audio_input, api_visibility="private")
2487
  download_btn.click(fn=None, inputs=[output_video], js=js_download_video)
2488
 
2489
+ # رویداد اول: با کلیک کاربر، UI بلافاصله آپدیت شده و سپس JS فراخوانی می شود
2490
+ # این رویداد دکوراتور @spaces.GPU ندارد و بسیار سریع است.
2491
  generate_btn.click(
2492
+ fn=start_enhancement_ui,
2493
+ outputs=[generate_btn]
2494
+ ).then(
2495
+ fn=None, # هیچ تابع پایتونی در این مرحله اجرا نمی شود
2496
  inputs=[first_frame, prompt, radioanimated_mode],
2497
+ outputs=[enhanced_prompt_trigger], # نتیجه JS در این محرک ذخیره می شود
2498
+ js=js_enhancer_api_call
2499
  )
2500
 
2501
+ # رویداد دوم: با تغییر مقدار محرک پنهان (بعد از اتمام کار JS) شروع می شود
2502
+ # این رویداد دکوراتور @spaces.GPU دارد و بودجه زمانی کامل خود را دریافت می کند.
2503
  enhanced_prompt_trigger.change(
2504
+ fn=run_generation_from_trigger,
2505
  inputs=[
2506
  first_frame, end_frame, enhanced_prompt_trigger, duration, input_video,
2507
  radioanimated_mode, enhance_prompt_flag_input, seed, randomize_seed,
2508
  height, width, camera_lora, audio_input
2509
  ],
2510
+ outputs=[generate_btn, prompt_ui, output_video, download_btn]
2511
  )
2512
 
2513
  # منطق نمونه ها