Deforum_Soonr / dev /app4.py
AlekseyCalvin's picture
Rename app4.py to dev/app4.py
7ca7944 verified
import gradio as gr
import json
from deforum_engine import DeforumRunner
# Initialize Engine
runner = DeforumRunner(device="cpu")
def process(
prompts_json, neg_prompt, max_frames,
width, height,
zoom, angle, tx, ty,
strength, noise,
fps, steps
):
# Validate JSON
try:
# Convert single quotes to double if user messed up
prompts_json = prompts_json.replace("'", '"')
# Ensure keys are integers
prompts_dict = json.loads(prompts_json)
prompts_fixed = {int(k): v for k, v in prompts_dict.items()}
except:
# Fallback manual parse
try:
prompts_fixed = eval(prompts_json)
except:
return None, None, None, "Error parsing prompts JSON"
yield from runner.render(
prompts_fixed, neg_prompt, int(max_frames),
int(width), int(height),
zoom, angle, tx, ty,
strength, noise,
int(fps), int(steps)
)
css = """
#col-container {max_width: 900px; margin-left: auto; margin-right: auto;}
"""
with gr.Blocks() as demo:
gr.Markdown("# 🌀 Authentic Deforum (CPU/SDXS)")
gr.Markdown("""
**Core Config:**
* **Model:** SDXS-512-0.9 (Fast 1-step capable).
* **Authenticity:** Full 2D Warping, Noise Schedules, and Img2Img Loopback.
* **Tip:** Keep `Steps` around 3-4. If you use 1 step, 'Strength' (fade) will not work and frames will look disjointed.
""")
with gr.Row():
with gr.Column():
# Prompts
prompts_input = gr.Code(
label="Prompts (JSON format)",
value='{\n "0": "tiny cute swamp bunny, highly detailed, intricate, 8k",\n "30": "anthro swamp bunny, cyberpunk city background, neon lights"\n}',
language="json"
)
neg_prompt = gr.Textbox(label="Negative Prompt", value="watermark, text, blurry")
with gr.Row():
max_frames = gr.Number(label="Max Frames", value=120, precision=0)
fps = gr.Number(label="FPS", value=12, precision=0)
steps = gr.Slider(1, 10, value=3, step=1, label="Steps (Rec: 3+)")
with gr.Accordion("Motion Settings", open=True):
gr.Markdown("Supports Math: `sin(t/10)`, `t*0.5`, etc. `t` = frame index.")
angle = gr.Textbox(label="Angle (deg)", value="0:(0)")
zoom = gr.Textbox(label="Zoom (1.0 = static)", value="0:(1.0 + 0.01*sin(t/20))")
tx = gr.Textbox(label="Translation X", value="0:(2*sin(t/10))")
ty = gr.Textbox(label="Translation Y", value="0:(0)")
with gr.Accordion("Coherence (The 'Glue')", open=True):
strength = gr.Textbox(label="Strength Schedule (0.0-1.0)", value="0:(0.65)")
noise = gr.Textbox(label="Noise Schedule (0.0-1.0)", value="0:(0.04)")
run_btn = gr.Button("Generate Animation", variant="primary")
with gr.Column():
out_image = gr.Image(label="Last Frame", type="pil")
out_video = gr.Video(label="Video Output")
out_zip = gr.File(label="Download Frames")
run_btn.click(
fn=process,
inputs=[
prompts_input, neg_prompt, max_frames,
gr.State(256), gr.State(256), # Fixed resolution for CPU speed
zoom, angle, tx, ty,
strength, noise,
fps, steps
],
outputs=[out_image, out_video, out_zip]
)
if __name__ == "__main__":
demo.launch(css=css, theme=gr.themes.Glass())