Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -2319,7 +2319,7 @@ def apply_example(idx: str):
|
|
| 2319 |
|
| 2320 |
|
| 2321 |
####################################################################################################
|
| 2322 |
-
### PART 20: Gradio UI Layout & Launch (FINAL
|
| 2323 |
####################################################################################################
|
| 2324 |
import requests
|
| 2325 |
import time
|
|
@@ -2343,25 +2343,47 @@ async (video) => {
|
|
| 2343 |
}
|
| 2344 |
"""
|
| 2345 |
|
| 2346 |
-
|
| 2347 |
-
|
| 2348 |
-
|
| 2349 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2350 |
|
| 2351 |
-
|
| 2352 |
-
|
| 2353 |
-
|
| 2354 |
-
|
| 2355 |
-
|
| 2356 |
-
|
| 2357 |
-
|
| 2358 |
-
|
| 2359 |
-
|
| 2360 |
-
|
| 2361 |
-
|
| 2362 |
-
|
| 2363 |
-
|
| 2364 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2365 |
|
| 2366 |
def apply_example(idx: str):
|
| 2367 |
idx = int(idx)
|
|
@@ -2375,48 +2397,35 @@ def apply_example(idx: str):
|
|
| 2375 |
|
| 2376 |
# --- توابع کنترل کننده در سطح گلوبال تعریف شده اند ---
|
| 2377 |
|
| 2378 |
-
|
| 2379 |
-
|
| 2380 |
-
"
|
| 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
|
| 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 |
-
|
| 2414 |
-
|
| 2415 |
-
|
| 2416 |
-
|
| 2417 |
-
|
| 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=
|
|
|
|
|
|
|
|
|
|
| 2483 |
inputs=[first_frame, prompt, radioanimated_mode],
|
| 2484 |
-
outputs=[
|
|
|
|
| 2485 |
)
|
| 2486 |
|
| 2487 |
-
# رویداد دوم: با تغییر مقدار محرک پنهان شروع می شود
|
|
|
|
| 2488 |
enhanced_prompt_trigger.change(
|
| 2489 |
-
fn=
|
| 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 |
# منطق نمونه ها
|