testwan / app.py
Aleksmorshen's picture
Update app.py
5c4ebcf verified
import gradio as gr
from gradio_client import Client, handle_file
import shutil
import os
# Создаем клиент один раз, на глобальном уровне, чтобы избежать повторных подключений
client = Client("r3gm/wan2-2-fp8da-aoti-preview")
def generate_video(input_image, last_image, prompt, steps, negative_prompt, duration_seconds, guidance_scale, guidance_scale_2, seed, randomize_seed, quality, scheduler, flow_shift, frame_multiplier):
if not input_image:
raise gr.Error("Please upload an input image.")
processed_last_image = last_image if last_image else input_image
frame_multiplier_int = int(frame_multiplier)
# Используем глобальный клиент для выполнения предсказания
# Результат - это путь к временному файлу, управляемому gradio_client
client_temp_file_path = client.predict(
input_image=handle_file(input_image),
last_image=handle_file(processed_last_image),
prompt=prompt,
steps=steps,
negative_prompt=negative_prompt,
duration_seconds=duration_seconds,
guidance_scale=guidance_scale,
guidance_scale_2=guidance_scale_2,
seed=seed,
randomize_seed=randomize_seed,
quality=quality,
scheduler=scheduler,
flow_shift=flow_shift,
frame_multiplier=frame_multiplier_int,
video_component=True,
api_name="/generate_video"
)
# --- КЛЮЧЕВОЕ ИЗМЕНЕНИЕ ---
# Копируем результат в новый файл, который находится под нашим контролем.
# Это предотвращает его преждевременное удаление.
# Gradio автоматически управляет очисткой файлов, которые он кэширует,
# поэтому нам не нужно беспокоиться об утечке дискового пространства.
final_video_path = shutil.copy(client_temp_file_path, ".")
# Возвращаем путь к нашей стабильной копии
return final_video_path
with gr.Blocks() as demo:
gr.Markdown("# Video Generation Interface")
with gr.Row():
with gr.Column():
input_image = gr.Image(type="filepath", label="Input Image")
last_image = gr.Image(type="filepath", label="Last Image (optional, uses Input Image if empty)")
prompt = gr.Textbox(label="Prompt", value="make this image come alive, cinematic motion, smooth animation")
negative_prompt = gr.Textbox(label="Negative Prompt", value="色调艳丽, 过曝, 静态, 细节模糊不清, 字幕, 风格, 作品, 画作, 画面, 静止, 整体发灰, 最差质量, 低质量, JPEG压缩残留, 丑陋的, 残缺的, 多余的手指, 画得不好的手部, 画得不好的脸部, 畸形的, 毁容的, 形态畸形的肢体, 手指融合, 静止不动的画面, 杂乱的背景, 三条腿, 背景人很多, 倒着走")
with gr.Row():
steps = gr.Slider(minimum=1, maximum=20, step=1, label="Steps", value=6)
duration_seconds = gr.Slider(minimum=1.0, maximum=10.0, step=0.1, label="Duration (seconds)", value=3.5)
with gr.Row():
guidance_scale = gr.Slider(minimum=0.0, maximum=5.0, step=0.1, label="Guidance Scale", value=1.0)
guidance_scale_2 = gr.Slider(minimum=0.0, maximum=5.0, step=0.1, label="Guidance Scale 2", value=1.0)
with gr.Row():
seed = gr.Number(label="Seed", value=42)
randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
with gr.Row():
quality = gr.Slider(minimum=1, maximum=10, step=1, label="Quality", value=6)
scheduler = gr.Dropdown(choices=["UniPCMultistep"], label="Scheduler", value="UniPCMultistep")
with gr.Row():
flow_shift = gr.Slider(minimum=0, maximum=10, step=1, label="Flow Shift", value=3)
frame_multiplier = gr.Dropdown(choices=["16", "32", "64"], label="Frame Multiplier", value="16")
generate_button = gr.Button("Generate Video")
with gr.Column():
output_video = gr.Video(label="Generated Video")
generate_button.click(
fn=generate_video,
inputs=[
input_image,
last_image,
prompt,
steps,
negative_prompt,
duration_seconds,
guidance_scale,
guidance_scale_2,
seed,
randomize_seed,
quality,
scheduler,
flow_shift,
frame_multiplier
],
outputs=output_video
)
demo.launch()