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 (REVISED & FIXED)
|
| 2323 |
####################################################################################################
|
| 2324 |
|
| 2325 |
# JS Function to handle download request via PostMessage
|
|
@@ -2341,19 +2341,13 @@ async (video) => {
|
|
| 2341 |
}
|
| 2342 |
"""
|
| 2343 |
|
| 2344 |
-
# این تابع
|
| 2345 |
-
#
|
| 2346 |
js_enhancer_api_call = """
|
| 2347 |
async (firstFrame, promptText, mode) => {
|
| 2348 |
// اگر حالت انتخابی نیازی به بهینه سازی ندارد، پرامپت اصلی را برگردان
|
| 2349 |
-
if (mode !== 'تبدیل تصویر به ویدیو' && mode !== 'تکمیل فریمهای میانی') {
|
| 2350 |
-
|
| 2351 |
-
}
|
| 2352 |
-
|
| 2353 |
-
// API بهینه ساز به تصویر نیاز دارد
|
| 2354 |
-
if (!firstFrame) {
|
| 2355 |
-
// چون این مرحله در میانه راه است، به کاربر اطلاع داده و با پرامپت اصلی ادامه می دهیم
|
| 2356 |
-
console.warn("Enhancement skipped: First frame image is required.");
|
| 2357 |
return promptText;
|
| 2358 |
}
|
| 2359 |
|
|
@@ -2379,12 +2373,11 @@ async (firstFrame, promptText, mode) => {
|
|
| 2379 |
|
| 2380 |
const data = await apiResponse.json();
|
| 2381 |
console.log("Enhanced Prompt received:", data.animation_prompt);
|
| 2382 |
-
// پرامپت بهینه شده را بر
|
| 2383 |
-
return data.animation_prompt;
|
| 2384 |
|
| 2385 |
} catch (error) {
|
| 2386 |
console.error("Enhancement API Error:", error);
|
| 2387 |
-
// در صورت خطا، پرامپت اصلی را برگردان تا فرآیند
|
| 2388 |
return promptText;
|
| 2389 |
}
|
| 2390 |
}
|
|
@@ -2395,17 +2388,10 @@ def apply_example(idx: str):
|
|
| 2395 |
idx = int(idx)
|
| 2396 |
img, prompt_txt, cam, res, mode, vid, aud, end_img = examples_list[idx]
|
| 2397 |
return (
|
| 2398 |
-
img or None,
|
| 2399 |
-
prompt_txt,
|
| 2400 |
-
cam,
|
| 2401 |
-
res,
|
| 2402 |
-
mode,
|
| 2403 |
gr.update(value=vid or None, visible=(mode == "Motion Control")),
|
| 2404 |
-
aud or None,
|
| 2405 |
-
|
| 2406 |
-
end_img or None,
|
| 2407 |
-
gr.update(value=None),
|
| 2408 |
-
gr.update(visible=False)
|
| 2409 |
)
|
| 2410 |
|
| 2411 |
with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
@@ -2423,90 +2409,65 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2423 |
"""
|
| 2424 |
)
|
| 2425 |
|
| 2426 |
-
# State
|
| 2427 |
-
# این کامپوننت ها برای کاربر قابل مشاهده نیستند
|
| 2428 |
enhanced_prompt_state = gr.State("")
|
| 2429 |
|
| 2430 |
with gr.Column(elem_id="col-container"):
|
|
|
|
| 2431 |
with gr.Row(elem_id="mode-row"):
|
| 2432 |
-
radioanimated_mode = RadioAnimated(
|
| 2433 |
-
choices=["تبدیل تصویر به ویدیو", "تکمیل فریمهای میانی"],
|
| 2434 |
-
value="تبدیل تصویر به ویدیو",
|
| 2435 |
-
elem_id="radioanimated_mode"
|
| 2436 |
-
)
|
| 2437 |
with gr.Row():
|
| 2438 |
with gr.Column(elem_id="step-column"):
|
| 2439 |
with gr.Row():
|
| 2440 |
-
first_frame = gr.Image(
|
| 2441 |
-
|
| 2442 |
-
type="filepath",
|
| 2443 |
-
height=256
|
| 2444 |
-
)
|
| 2445 |
-
end_frame = gr.Image(
|
| 2446 |
-
label="تصویر آخر (اختیاری)",
|
| 2447 |
-
type="filepath",
|
| 2448 |
-
height=256,
|
| 2449 |
-
visible=False,
|
| 2450 |
-
)
|
| 2451 |
input_video = gr.Video(label="Motion Reference Video", height=256, visible=False)
|
| 2452 |
-
|
| 2453 |
-
relocate = gr.HTML(value="", html_template="<div></div>", js_on_load=r"""
|
| 2454 |
-
(() => {
|
| 2455 |
-
function moveIntoFooter() {
|
| 2456 |
-
const promptRoot = document.querySelector("#prompt_ui"); if (!promptRoot) return false;
|
| 2457 |
-
const footer = promptRoot.querySelector(".ds-footer"); if (!footer) return false;
|
| 2458 |
-
const dur = document.querySelector("#duration_ui .cd-wrap");
|
| 2459 |
-
const res = document.querySelector("#resolution_ui .cd-wrap");
|
| 2460 |
-
const cam = document.querySelector("#camera_ui .cd-wrap");
|
| 2461 |
-
if (!dur || !res || !cam) return false;
|
| 2462 |
-
footer.appendChild(dur); footer.appendChild(res); footer.appendChild(cam);
|
| 2463 |
-
return true;
|
| 2464 |
-
}
|
| 2465 |
-
const tick = () => { if (!moveIntoFooter()) requestAnimationFrame(tick); };
|
| 2466 |
-
requestAnimationFrame(tick);
|
| 2467 |
-
})();
|
| 2468 |
-
""")
|
| 2469 |
-
|
| 2470 |
prompt_ui = PromptBox(value="این تصویر را با حرکت سینمایی و انیمیشن روان زنده کن", elem_id="prompt_ui")
|
| 2471 |
audio_input = gr.File(label="Audio (Optional)", file_types=["audio"], type="filepath", elem_id="audio_input_hidden")
|
| 2472 |
audio_ui = AudioDropUpload(target_audio_elem_id="audio_input_hidden", elem_id="audio_ui")
|
| 2473 |
-
prompt = gr.Textbox(label="Prompt", value="این تصویر را با حرکت سینمایی و انیمیشن روان زنده کن", lines=3, max_lines=3,
|
| 2474 |
enhance_prompt = gr.Checkbox(label="Enhance Prompt", value=True, visible=False)
|
| 2475 |
-
|
| 2476 |
with gr.Accordion("تنظیمات پیشرفته", open=False, visible=False):
|
| 2477 |
seed = gr.Slider(label="سید (Seed)", minimum=0, maximum=MAX_SEED, value=DEFAULT_SEED, step=1)
|
| 2478 |
randomize_seed = gr.Checkbox(label="استفاده از سید تصادفی", value=True)
|
| 2479 |
-
|
| 2480 |
with gr.Column(elem_id="step-column"):
|
| 2481 |
output_video = gr.Video(label="ویدیوی ساخته شده", autoplay=True, height=512)
|
| 2482 |
with gr.Row():
|
| 2483 |
download_btn = gr.Button("📥 دانلود ویدیو", variant="secondary", size="sm", scale=0, visible=False)
|
| 2484 |
|
| 2485 |
with gr.Row(elem_id="controls-row"):
|
| 2486 |
-
|
| 2487 |
-
|
| 2488 |
-
|
| 2489 |
-
|
| 2490 |
-
|
| 2491 |
-
|
| 2492 |
-
|
| 2493 |
-
|
| 2494 |
-
choices=[{"label": "16:9", "value": "16:9", "icon": ICON_16_9}, {"label": "1:1", "value": "1:1", "icon": ICON_1_1}, {"label": "9:16", "value": "9:16", "icon": ICON_9_16}],
|
| 2495 |
-
value="16:9", title="ابعاد تصویر", elem_id="resolution_ui"
|
| 2496 |
-
)
|
| 2497 |
-
width = gr.Number(label="Width", value=DEFAULT_1_STAGE_WIDTH, precision=0, visible=False)
|
| 2498 |
-
height = gr.Number(label="Height", value=DEFAULT_1_STAGE_HEIGHT, precision=0, visible=False)
|
| 2499 |
-
camera_ui = CameraDropdown(choices=[name for name, _ in VISIBLE_RUNTIME_LORA_CHOICES], value="No LoRA", title="افکت دوربین (LoRA)", elem_id="camera_ui")
|
| 2500 |
-
camera_lora = gr.Dropdown(label="Camera Control LoRA", choices=[name for name, _ in VISIBLE_RUNTIME_LORA_CHOICES], value="No LoRA", visible=False)
|
| 2501 |
|
| 2502 |
generate_btn = gr.Button("🤩 ساخت ویدیو", variant="primary", elem_classes="button-gradient")
|
| 2503 |
|
| 2504 |
-
# توابع کمکی برای بهروزرسانی UI
|
| 2505 |
-
def
|
|
|
|
| 2506 |
return gr.Button(value="⏳ در حال بهینه سازی پرامپت...", interactive=False)
|
| 2507 |
|
| 2508 |
-
def
|
| 2509 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2510 |
|
| 2511 |
# اتصال رویدادها
|
| 2512 |
camera_ui.change(fn=lambda x: x, inputs=camera_ui, outputs=camera_lora, api_visibility="private")
|
|
@@ -2519,22 +2480,24 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2519 |
|
| 2520 |
# --- زنجیره اصلی رویداد ساخت ویدیو ---
|
| 2521 |
|
| 2522 |
-
# 1.
|
| 2523 |
-
# این تابع پایتون هیچ کاری جز آماده سازی UI انجام نمی دهد.
|
| 2524 |
generate_btn.click(
|
| 2525 |
-
fn=
|
| 2526 |
outputs=[generate_btn]
|
| 2527 |
-
)
|
| 2528 |
-
|
| 2529 |
-
#
|
| 2530 |
-
|
| 2531 |
-
fn=None,
|
| 2532 |
inputs=[first_frame, prompt, radioanimated_mode],
|
| 2533 |
outputs=[enhanced_prompt_state],
|
| 2534 |
js=js_enhancer_api_call
|
| 2535 |
-
)
|
| 2536 |
-
|
| 2537 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2538 |
fn=generate_video,
|
| 2539 |
inputs=[
|
| 2540 |
first_frame, end_frame, enhanced_prompt_state, duration, input_video,
|
|
@@ -2542,16 +2505,10 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2542 |
height, width, camera_lora, audio_input
|
| 2543 |
],
|
| 2544 |
outputs=[output_video]
|
| 2545 |
-
)
|
| 2546 |
-
|
| 2547 |
-
|
| 2548 |
-
|
| 2549 |
-
outputs=[download_btn]
|
| 2550 |
-
) \
|
| 2551 |
-
.then(
|
| 2552 |
-
# 5. در نهایت، UI را دوباره فعال می کنیم.
|
| 2553 |
-
fn=re_enable_ui,
|
| 2554 |
-
outputs=[generate_btn]
|
| 2555 |
)
|
| 2556 |
|
| 2557 |
# منطق نمونه ها
|
|
@@ -2565,25 +2522,14 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 2565 |
]
|
| 2566 |
|
| 2567 |
preset_gallery = PresetGallery(
|
| 2568 |
-
items=[
|
| 2569 |
-
{"thumb": "examples/supergirl-2.png", "label": "تصویر و صدا به ویدیو"},
|
| 2570 |
-
{"thumb": "examples/frame3.png", "label": "تصویر اول و آخر"},
|
| 2571 |
-
{"thumb": "examples/supergirl.png", "label": "تصویر به ویدیو (عروسک)"},
|
| 2572 |
-
{"thumb": "examples/highland.png", "label": "تصویر به ویدیو (گاو)"},
|
| 2573 |
-
{"thumb": "examples/wednesday.png", "label": "تصویر به ویدیو (ونزدی)"},
|
| 2574 |
-
{"thumb": "examples/astronaut.png", "label": "تصویر به ویدیو (فضانورد)"},
|
| 2575 |
-
],
|
| 2576 |
title="برای شروع روی یکی از نمونهها کلیک کنید",
|
| 2577 |
)
|
| 2578 |
|
| 2579 |
preset_gallery.change(
|
| 2580 |
fn=apply_example,
|
| 2581 |
inputs=preset_gallery,
|
| 2582 |
-
outputs=[
|
| 2583 |
-
first_frame, prompt_ui, camera_ui, resolution_ui, radioanimated_mode,
|
| 2584 |
-
input_video, audio_input, audio_ui, end_frame,
|
| 2585 |
-
output_video, download_btn
|
| 2586 |
-
],
|
| 2587 |
api_visibility="private",
|
| 2588 |
)
|
| 2589 |
|
|
|
|
| 2319 |
|
| 2320 |
|
| 2321 |
####################################################################################################
|
| 2322 |
+
### PART 20: Gradio UI Layout & Launch (REVISED & FIXED for Step-by-Step Feedback)
|
| 2323 |
####################################################################################################
|
| 2324 |
|
| 2325 |
# JS Function to handle download request via PostMessage
|
|
|
|
| 2341 |
}
|
| 2342 |
"""
|
| 2343 |
|
| 2344 |
+
# این تابع JS فقط مسئول فراخوانی API بهینه ساز است
|
| 2345 |
+
# خروجی آن (پرامپت بهینه شده) به مرحله بعدی در زنجیره گرادیو ارسال می شود
|
| 2346 |
js_enhancer_api_call = """
|
| 2347 |
async (firstFrame, promptText, mode) => {
|
| 2348 |
// اگر حالت انتخابی نیازی به بهینه سازی ندارد، پرامپت اصلی را برگردان
|
| 2349 |
+
if (mode !== 'تبدیل تصویر به ویدیو' && mode !== 'تکمیل فریمهای میانی' || !firstFrame) {
|
| 2350 |
+
if (!firstFrame) console.warn("Enhancement skipped: First frame image is required.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2351 |
return promptText;
|
| 2352 |
}
|
| 2353 |
|
|
|
|
| 2373 |
|
| 2374 |
const data = await apiResponse.json();
|
| 2375 |
console.log("Enhanced Prompt received:", data.animation_prompt);
|
| 2376 |
+
return data.animation_prompt; // پرامپت بهینه شده را برگردان
|
|
|
|
| 2377 |
|
| 2378 |
} catch (error) {
|
| 2379 |
console.error("Enhancement API Error:", error);
|
| 2380 |
+
// در صورت خطا، پرامپت اصلی را برگردان تا فرآیند متوقف نشود
|
| 2381 |
return promptText;
|
| 2382 |
}
|
| 2383 |
}
|
|
|
|
| 2388 |
idx = int(idx)
|
| 2389 |
img, prompt_txt, cam, res, mode, vid, aud, end_img = examples_list[idx]
|
| 2390 |
return (
|
| 2391 |
+
img or None, prompt_txt, cam, res, mode,
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2392 |
gr.update(value=vid or None, visible=(mode == "Motion Control")),
|
| 2393 |
+
aud or None, aud or None, end_img or None,
|
| 2394 |
+
gr.update(value=None), gr.update(visible=False)
|
|
|
|
|
|
|
|
|
|
| 2395 |
)
|
| 2396 |
|
| 2397 |
with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
|
|
| 2409 |
"""
|
| 2410 |
)
|
| 2411 |
|
| 2412 |
+
# کامپوننت State برای نگهداری پرامپت بهینه شده
|
|
|
|
| 2413 |
enhanced_prompt_state = gr.State("")
|
| 2414 |
|
| 2415 |
with gr.Column(elem_id="col-container"):
|
| 2416 |
+
# ... تعریف بقیه UI ...
|
| 2417 |
with gr.Row(elem_id="mode-row"):
|
| 2418 |
+
radioanimated_mode = RadioAnimated(choices=["تبدیل تصویر به ویدیو", "تکمیل فریمهای میانی"], value="تبدیل تصویر به ویدیو", elem_id="radioanimated_mode")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2419 |
with gr.Row():
|
| 2420 |
with gr.Column(elem_id="step-column"):
|
| 2421 |
with gr.Row():
|
| 2422 |
+
first_frame = gr.Image(label="تصویر اول (برای بهینهسازی پرامپت الزامی است)", type="filepath", height=256)
|
| 2423 |
+
end_frame = gr.Image(label="تصویر آخر (اختیاری)", type="filepath", height=256, visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2424 |
input_video = gr.Video(label="Motion Reference Video", height=256, visible=False)
|
| 2425 |
+
relocate = gr.HTML(value="", html_template="<div></div>", js_on_load=r"""(() => { function moveIntoFooter() { const p = document.querySelector("#prompt_ui"), f = p ? p.querySelector(".ds-footer") : null; if (!f) return false; const d = document.querySelector("#duration_ui .cd-wrap"), r = document.querySelector("#resolution_ui .cd-wrap"), c = document.querySelector("#camera_ui .cd-wrap"); if (!d || !r || !c) return false; f.appendChild(d); f.appendChild(r); f.appendChild(c); return true; } const tick = () => { if (!moveIntoFooter()) requestAnimationFrame(tick); }; requestAnimationFrame(tick); })();""")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2426 |
prompt_ui = PromptBox(value="این تصویر را با حرکت سینمایی و انیمیشن روان زنده کن", elem_id="prompt_ui")
|
| 2427 |
audio_input = gr.File(label="Audio (Optional)", file_types=["audio"], type="filepath", elem_id="audio_input_hidden")
|
| 2428 |
audio_ui = AudioDropUpload(target_audio_elem_id="audio_input_hidden", elem_id="audio_ui")
|
| 2429 |
+
prompt = gr.Textbox(label="Prompt", value="این تصویر را با حرکت سینمایی و انیمیشن روان زنده کن", lines=3, max_lines=3, visible=False)
|
| 2430 |
enhance_prompt = gr.Checkbox(label="Enhance Prompt", value=True, visible=False)
|
|
|
|
| 2431 |
with gr.Accordion("تنظیمات پیشرفته", open=False, visible=False):
|
| 2432 |
seed = gr.Slider(label="سید (Seed)", minimum=0, maximum=MAX_SEED, value=DEFAULT_SEED, step=1)
|
| 2433 |
randomize_seed = gr.Checkbox(label="استفاده از سید تصادفی", value=True)
|
| 2434 |
+
|
| 2435 |
with gr.Column(elem_id="step-column"):
|
| 2436 |
output_video = gr.Video(label="ویدیوی ساخته شده", autoplay=True, height=512)
|
| 2437 |
with gr.Row():
|
| 2438 |
download_btn = gr.Button("📥 دانلود ویدیو", variant="secondary", size="sm", scale=0, visible=False)
|
| 2439 |
|
| 2440 |
with gr.Row(elem_id="controls-row"):
|
| 2441 |
+
duration_ui = CameraDropdown(choices=["3s", "5s", "10s"], value="5s", title="مدت زمان ویدیو", elem_id="duration_ui")
|
| 2442 |
+
duration = gr.Slider(label="Duration (seconds)", minimum=1.0, maximum=10.0, value=5.0, step=0.1, visible=False)
|
| 2443 |
+
ICON_16_9, ICON_1_1, ICON_9_16 = ("<svg viewBox='0 0 24 24' fill='none' aria-hidden='true'><rect x='3' y='7' width='18' height='10' rx='2' stroke='currentColor' stroke-width='2'/></svg>", "<svg viewBox='0 0 24 24' fill='none' aria-hidden='true'><rect x='6' y='6' width='12' height='12' rx='2' stroke='currentColor' stroke-width='2'/></svg>", "<svg viewBox='0 0 24 24' fill='none' aria-hidden='true'><rect x='7' y='3' width='10' height='18' rx='2' stroke='currentColor' stroke-width='2'/></svg>")
|
| 2444 |
+
resolution_ui = CameraDropdown(choices=[{"label": "16:9", "value": "16:9", "icon": ICON_16_9}, {"label": "1:1", "value": "1:1", "icon": ICON_1_1}, {"label": "9:16", "value": "9:16", "icon": ICON_9_16}], value="16:9", title="ابعاد تصویر", elem_id="resolution_ui")
|
| 2445 |
+
width = gr.Number(label="Width", value=DEFAULT_1_STAGE_WIDTH, precision=0, visible=False)
|
| 2446 |
+
height = gr.Number(label="Height", value=DEFAULT_1_STAGE_HEIGHT, precision=0, visible=False)
|
| 2447 |
+
camera_ui = CameraDropdown(choices=[name for name, _ in VISIBLE_RUNTIME_LORA_CHOICES], value="No LoRA", title="افکت دوربین (LoRA)", elem_id="camera_ui")
|
| 2448 |
+
camera_lora = gr.Dropdown(label="Camera Control LoRA", choices=[name for name, _ in VISIBLE_RUNTIME_LORA_CHOICES], value="No LoRA", visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2449 |
|
| 2450 |
generate_btn = gr.Button("🤩 ساخت ویدیو", variant="primary", elem_classes="button-gradient")
|
| 2451 |
|
| 2452 |
+
# توابع کمکی برای کنترل جریان و بهروزرسانی UI
|
| 2453 |
+
def start_process():
|
| 2454 |
+
"""مرحله ۱: UI را برای شروع فرآیند آماده می کند."""
|
| 2455 |
return gr.Button(value="⏳ در حال بهینه سازی پرامپت...", interactive=False)
|
| 2456 |
|
| 2457 |
+
def prepare_for_generation(enhanced_prompt):
|
| 2458 |
+
"""مرحله ۳: UI را برای شروع ساخت ویدیو آماده می کند."""
|
| 2459 |
+
# پرامپت بهینه شده را در UI نمایش می دهیم
|
| 2460 |
+
return {
|
| 2461 |
+
generate_btn: gr.Button(value="🚀 در حال ساخت ویدیو...", interactive=False),
|
| 2462 |
+
prompt_ui: gr.update(value=enhanced_prompt)
|
| 2463 |
+
}
|
| 2464 |
+
|
| 2465 |
+
def finalize_process():
|
| 2466 |
+
"""مرحله ۵: UI را پس از اتمام کار به حالت اولیه برمی گرداند."""
|
| 2467 |
+
return {
|
| 2468 |
+
generate_btn: gr.Button(value="🤩 ساخت ویدیو", interactive=True),
|
| 2469 |
+
download_btn: gr.Button(visible=True)
|
| 2470 |
+
}
|
| 2471 |
|
| 2472 |
# اتصال رویدادها
|
| 2473 |
camera_ui.change(fn=lambda x: x, inputs=camera_ui, outputs=camera_lora, api_visibility="private")
|
|
|
|
| 2480 |
|
| 2481 |
# --- زنجیره اصلی رویداد ساخت ویدیو ---
|
| 2482 |
|
| 2483 |
+
# 1. کلیک کاربر: تابع پایتون start_process را برای قفل کردن UI اجرا می کند.
|
|
|
|
| 2484 |
generate_btn.click(
|
| 2485 |
+
fn=start_process,
|
| 2486 |
outputs=[generate_btn]
|
| 2487 |
+
).then(
|
| 2488 |
+
# 2. سپس: تابع جاوااسکریپت js_enhancer_api_call برای گرفتن پرامپت بهینه شده اجرا می شود.
|
| 2489 |
+
# خروجی آن به طور خودکار به ورودی تابع بعدی در زنجیره داده می شود.
|
| 2490 |
+
fn=None,
|
|
|
|
| 2491 |
inputs=[first_frame, prompt, radioanimated_mode],
|
| 2492 |
outputs=[enhanced_prompt_state],
|
| 2493 |
js=js_enhancer_api_call
|
| 2494 |
+
).then(
|
| 2495 |
+
# 3. سپس: تابع پایتون prepare_for_generation برای بهروزرسانی UI با وضعیت جدید اجرا می شود.
|
| 2496 |
+
fn=prepare_for_generation,
|
| 2497 |
+
inputs=[enhanced_prompt_state],
|
| 2498 |
+
outputs=[generate_btn, prompt_ui]
|
| 2499 |
+
).then(
|
| 2500 |
+
# 4. سپس: تابع اصلی ساخت ویدیو با پرامپت بهینه شده اجرا می شود.
|
| 2501 |
fn=generate_video,
|
| 2502 |
inputs=[
|
| 2503 |
first_frame, end_frame, enhanced_prompt_state, duration, input_video,
|
|
|
|
| 2505 |
height, width, camera_lora, audio_input
|
| 2506 |
],
|
| 2507 |
outputs=[output_video]
|
| 2508 |
+
).then(
|
| 2509 |
+
# 5. در نهایت: تابع پایتون finalize_process برای باز کردن قفل UI و نمایش دکمه دانلود اجرا می شود.
|
| 2510 |
+
fn=finalize_process,
|
| 2511 |
+
outputs=[generate_btn, download_btn]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2512 |
)
|
| 2513 |
|
| 2514 |
# منطق نمونه ها
|
|
|
|
| 2522 |
]
|
| 2523 |
|
| 2524 |
preset_gallery = PresetGallery(
|
| 2525 |
+
items=[{"thumb": "examples/supergirl-2.png", "label": "تصویر و صدا به ویدیو"}, {"thumb": "examples/frame3.png", "label": "تصویر اول و آخر"}, {"thumb": "examples/supergirl.png", "label": "تصویر به ویدیو (عروسک)"}, {"thumb": "examples/highland.png", "label": "تصویر به ویدیو (گاو)"}, {"thumb": "examples/wednesday.png", "label": "تصویر به ویدیو (ونزدی)"}, {"thumb": "examples/astronaut.png", "label": "تصویر به ویدیو (فضانورد)"}],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2526 |
title="برای شروع روی یکی از نمونهها کلیک کنید",
|
| 2527 |
)
|
| 2528 |
|
| 2529 |
preset_gallery.change(
|
| 2530 |
fn=apply_example,
|
| 2531 |
inputs=preset_gallery,
|
| 2532 |
+
outputs=[first_frame, prompt_ui, camera_ui, resolution_ui, radioanimated_mode, input_video, audio_input, audio_ui, end_frame, output_video, download_btn],
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2533 |
api_visibility="private",
|
| 2534 |
)
|
| 2535 |
|