Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -2360,6 +2360,58 @@ async (video) => {
|
|
| 2360 |
}
|
| 2361 |
"""
|
| 2362 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2363 |
def apply_example(idx: str):
|
| 2364 |
idx = int(idx)
|
| 2365 |
|
|
@@ -2530,10 +2582,7 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2530 |
with gr.Column(elem_id="step-column"):
|
| 2531 |
output_video = gr.Video(label="ویدیوی ساخته شده", autoplay=True, height=512)
|
| 2532 |
|
| 2533 |
-
# --- دکمه دانلود
|
| 2534 |
-
# scale=0 باعث میشود دکمه تمام عرض را نگیرد
|
| 2535 |
-
# variant="secondary" رنگ متفاوت (معمولا خاکستری/سفید)
|
| 2536 |
-
# visible=False به صورت پیشفرض مخفی است
|
| 2537 |
with gr.Row():
|
| 2538 |
download_btn = gr.Button(
|
| 2539 |
"📥 دانلود ویدیو",
|
|
@@ -2641,8 +2690,15 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2641 |
api_visibility="private"
|
| 2642 |
)
|
| 2643 |
|
| 2644 |
-
# --- منطق
|
|
|
|
| 2645 |
generate_btn.click(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2646 |
fn=generate_video,
|
| 2647 |
inputs=[
|
| 2648 |
first_frame,
|
|
@@ -2651,7 +2707,7 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2651 |
duration,
|
| 2652 |
input_video,
|
| 2653 |
radioanimated_mode,
|
| 2654 |
-
enhance_prompt,
|
| 2655 |
seed,
|
| 2656 |
randomize_seed,
|
| 2657 |
height,
|
|
@@ -2661,7 +2717,7 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2661 |
],
|
| 2662 |
outputs=[output_video]
|
| 2663 |
).then(
|
| 2664 |
-
fn=lambda: gr.update(visible=True), #
|
| 2665 |
outputs=[download_btn]
|
| 2666 |
)
|
| 2667 |
|
|
|
|
| 2360 |
}
|
| 2361 |
"""
|
| 2362 |
|
| 2363 |
+
# JS Function to Optimize Prompt Client-Side via External API
|
| 2364 |
+
# This prevents using the Space's GPU for prompt enhancement
|
| 2365 |
+
js_enhance_prompt = """
|
| 2366 |
+
async (image, prompt, enhance_enabled) => {
|
| 2367 |
+
// اگر بهینهسازی غیرفعال باشد یا تصویری وجود نداشته باشد، تغییری نده
|
| 2368 |
+
if (!enhance_enabled || !image) {
|
| 2369 |
+
return [prompt, enhance_enabled];
|
| 2370 |
+
}
|
| 2371 |
+
|
| 2372 |
+
try {
|
| 2373 |
+
// تبدیل آدرس فایل گرادیو به Blob برای ارسال به API
|
| 2374 |
+
let blob = null;
|
| 2375 |
+
if (typeof image === 'string') {
|
| 2376 |
+
const res = await fetch(image);
|
| 2377 |
+
blob = await res.blob();
|
| 2378 |
+
} else if (image instanceof File || image instanceof Blob) {
|
| 2379 |
+
blob = image;
|
| 2380 |
+
}
|
| 2381 |
+
|
| 2382 |
+
if (!blob) return [prompt, enhance_enabled];
|
| 2383 |
+
|
| 2384 |
+
// آمادهسازی دادهها طبق الگوی HTML ارسالی کاربر
|
| 2385 |
+
const formData = new FormData();
|
| 2386 |
+
formData.append('image', blob);
|
| 2387 |
+
formData.append('prompt', prompt);
|
| 2388 |
+
formData.append('is_extension', 'false');
|
| 2389 |
+
|
| 2390 |
+
// ارسال به سرور خارجی جهت بهینهسازی (سمت کلاینت)
|
| 2391 |
+
const response = await fetch('https://ezmarynoori-vidtolani.hf.space/api/enhance-animation-prompt', {
|
| 2392 |
+
method: 'POST',
|
| 2393 |
+
body: formData
|
| 2394 |
+
});
|
| 2395 |
+
|
| 2396 |
+
const data = await response.json();
|
| 2397 |
+
|
| 2398 |
+
if (data.animation_prompt) {
|
| 2399 |
+
// 1. بازگرداندن پرامپت بهینه شده
|
| 2400 |
+
// 2. بازگرداندن مقدار False برای چکباکس enhance_prompt
|
| 2401 |
+
// این کار باعث میشود تابع پایتون تصور کند بهینهسازی خاموش است و از GPU استفاده نکند
|
| 2402 |
+
return [data.animation_prompt, false];
|
| 2403 |
+
} else {
|
| 2404 |
+
console.error("External API Error:", data);
|
| 2405 |
+
return [prompt, enhance_enabled];
|
| 2406 |
+
}
|
| 2407 |
+
|
| 2408 |
+
} catch (error) {
|
| 2409 |
+
console.error("Enhance Prompt Failed:", error);
|
| 2410 |
+
return [prompt, enhance_enabled];
|
| 2411 |
+
}
|
| 2412 |
+
}
|
| 2413 |
+
"""
|
| 2414 |
+
|
| 2415 |
def apply_example(idx: str):
|
| 2416 |
idx = int(idx)
|
| 2417 |
|
|
|
|
| 2582 |
with gr.Column(elem_id="step-column"):
|
| 2583 |
output_video = gr.Video(label="ویدیوی ساخته شده", autoplay=True, height=512)
|
| 2584 |
|
| 2585 |
+
# --- دکمه دانلود ---
|
|
|
|
|
|
|
|
|
|
| 2586 |
with gr.Row():
|
| 2587 |
download_btn = gr.Button(
|
| 2588 |
"📥 دانلود ویدیو",
|
|
|
|
| 2690 |
api_visibility="private"
|
| 2691 |
)
|
| 2692 |
|
| 2693 |
+
# --- منطق اصلی (بهینه سازی سمت کلاینت + اجرا) ---
|
| 2694 |
+
# مرحله 1: اجرای جاوااسکریپت برای بهینهسازی پرامپت (بدون درگیری GPU سرور)
|
| 2695 |
generate_btn.click(
|
| 2696 |
+
fn=None, # تابع پایتونی ندارد
|
| 2697 |
+
inputs=[first_frame, prompt, enhance_prompt],
|
| 2698 |
+
outputs=[prompt, enhance_prompt], # خروجی: پرامپت جدید و خاموش کردن تیک بهینهسازی
|
| 2699 |
+
js=js_enhance_prompt,
|
| 2700 |
+
).then(
|
| 2701 |
+
# مرحله 2: اجرای تابع ساخت ویدیو (با پرامپت بهینه شده و enhance=False)
|
| 2702 |
fn=generate_video,
|
| 2703 |
inputs=[
|
| 2704 |
first_frame,
|
|
|
|
| 2707 |
duration,
|
| 2708 |
input_video,
|
| 2709 |
radioanimated_mode,
|
| 2710 |
+
enhance_prompt, # مقدار این الان False شده است (توسط مرحله 1)
|
| 2711 |
seed,
|
| 2712 |
randomize_seed,
|
| 2713 |
height,
|
|
|
|
| 2717 |
],
|
| 2718 |
outputs=[output_video]
|
| 2719 |
).then(
|
| 2720 |
+
fn=lambda: gr.update(visible=True), # نمایش دکمه دانلود
|
| 2721 |
outputs=[download_btn]
|
| 2722 |
)
|
| 2723 |
|