AlekseyCalvin commited on
Commit
238498e
·
verified ·
1 Parent(s): 47d0bc8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +117 -0
app.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ from diffusers import StableDiffusionPipeline
4
+ import os
5
+ import uuid
6
+ import animation_logic as anim
7
+ import video_utils as vid
8
+
9
+ # --- Model Config (SDXS Optimized) ---
10
+ device = "cpu"
11
+ model_id = "IDKiro/sdxs-512-dreamshaper"
12
+ pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float32)
13
+ pipe.to(device)
14
+
15
+ def run_deforum(
16
+ prompt_list_str, neg_prompt, max_frames,
17
+ zoom_str, angle_str, tx_str, ty_str,
18
+ cadence, fps
19
+ ):
20
+ # Setup
21
+ width, height = 256, 256
22
+ try:
23
+ prompts = eval(prompt_list_str)
24
+ except:
25
+ return None, None, "Error: Prompt dictionary format invalid."
26
+
27
+ # Parse Schedules
28
+ zoom_s = anim.parse_keyframe_string(zoom_str, max_frames)
29
+ angle_s = anim.parse_keyframe_string(angle_str, max_frames)
30
+ tx_s = anim.parse_keyframe_string(tx_str, max_frames)
31
+ ty_s = anim.parse_keyframe_string(ty_str, max_frames)
32
+
33
+ all_frames = []
34
+ prev_gen_frame = None
35
+
36
+ # Generation Loop
37
+ for f in range(max_frames):
38
+ if f % cadence == 0:
39
+ # Determine prompt
40
+ current_prompt = prompts[max(k for k in prompts.keys() if k <= f)]
41
+
42
+ # Warp previous frame if it exists
43
+ if prev_gen_frame is not None:
44
+ # We warp the frame based on the cumulative motion across the cadence gap
45
+ init_image = anim.anim_frame_warp(prev_gen_frame, angle_s[f], zoom_s[f], tx_s[f], ty_s[f])
46
+ # SDXS Inference (1-step, 0 guidance)
47
+ new_frame = pipe(
48
+ current_prompt,
49
+ image=init_image, # This mimics the 'strength' logic
50
+ negative_prompt=neg_prompt,
51
+ num_inference_steps=1,
52
+ guidance_scale=0.0,
53
+ width=width, height=height
54
+ ).images[0]
55
+ else:
56
+ # First frame
57
+ new_frame = pipe(
58
+ current_prompt,
59
+ negative_prompt=neg_prompt,
60
+ num_inference_steps=1,
61
+ guidance_scale=0.0,
62
+ width=width, height=height
63
+ ).images[0]
64
+
65
+ # Handle Cadence Interpolation for the gap behind us
66
+ if cadence > 1 and prev_gen_frame is not None:
67
+ start_gap = f - cadence
68
+ for i in range(1, cadence):
69
+ alpha = i / cadence
70
+ interp_frame = anim.lerp_frames(prev_gen_frame, new_frame, alpha)
71
+ all_frames.append(interp_frame)
72
+
73
+ all_frames.append(new_frame)
74
+ prev_gen_frame = new_frame
75
+ yield new_frame, None, None
76
+
77
+ # Finalize Video and Zip
78
+ video_file = vid.frames_to_video(all_frames, f"output_{uuid.uuid4().hex[:6]}.mp4", fps)
79
+ zip_file = vid.export_to_zip(all_frames, f"frames_{uuid.uuid4().hex[:6]}.zip")
80
+
81
+ yield all_frames[-1], video_file, zip_file
82
+
83
+ # --- Gradio Interface ---
84
+ with gr.Blocks(theme=gr.themes.Glass()) as demo:
85
+ gr.Markdown("# 🎨 Deforum Soonr Variant 2")
86
+
87
+ with gr.Row():
88
+ with gr.Column(scale=1):
89
+ prompts = gr.Textbox(label="Prompts (Frame: Prompt Dict)",
90
+ value='{0: "a snowy mountain", 15: "a fiery volcano"}', lines=3)
91
+ neg_p = gr.Textbox(label="Negative Prompt", value="blur, lowres, text")
92
+
93
+ with gr.Row():
94
+ frames_n = gr.Number(label="Max Frames", value=20)
95
+ cadence_n = gr.Slider(1, 4, value=2, step=1, label="Cadence (Skip Steps)")
96
+ fps_n = gr.Number(label="FPS", value=10)
97
+
98
+ with gr.Accordion("Motion Parameters", open=False):
99
+ zoom = gr.Textbox(label="Zoom", value="0:(1.04)")
100
+ angle = gr.Textbox(label="Angle", value="0:(2*sin(t/5))")
101
+ tx = gr.Textbox(label="Translation X", value="0:(0)")
102
+ ty = gr.Textbox(label="Translation Y", value="0:(0)")
103
+
104
+ btn = gr.Button("Generate", variant="primary")
105
+
106
+ with gr.Column(scale=1):
107
+ preview = gr.Image(label="Live Frame Preview")
108
+ video_out = gr.Video(label="Rendered Animation")
109
+ file_out = gr.File(label="Download Batch (ZIP)")
110
+
111
+ btn.click(
112
+ fn=run_deforum,
113
+ inputs=[prompts, neg_p, frames_n, zoom, angle, tx, ty, cadence_n, fps_n],
114
+ outputs=[preview, video_out, file_out]
115
+ )
116
+
117
+ demo.launch()