Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import torch | |
| from diffusers import StableDiffusionPipeline | |
| import os | |
| import uuid | |
| import animation_logic as anim | |
| import video_utils as vid | |
| # --- Model Config (SDXS Optimized) --- | |
| device = "cpu" | |
| model_id = "IDKiro/sdxs-512-dreamshaper" | |
| # Using float32 for CPU stability | |
| pipe = StableDiffusionPipeline.from_pretrained(model_id, torch_dtype=torch.float32) | |
| pipe.to(device) | |
| def run_deforum( | |
| prompt_list_str, neg_prompt, max_frames, | |
| zoom_str, angle_str, tx_str, ty_str, | |
| cadence, fps, color_match | |
| ): | |
| width, height = 256, 256 | |
| try: | |
| # Expected format: {0: "prompt", 10: "prompt"} | |
| prompts = eval(prompt_list_str) | |
| except Exception as e: | |
| return None, None, f"Error parsing prompts: {str(e)}" | |
| # Parse Schedules | |
| zoom_s = anim.parse_keyframe_string(zoom_str, int(max_frames)) | |
| angle_s = anim.parse_keyframe_string(angle_str, int(max_frames)) | |
| tx_s = anim.parse_keyframe_string(tx_str, int(max_frames)) | |
| ty_s = anim.parse_keyframe_string(ty_str, int(max_frames)) | |
| all_frames = [] | |
| prev_gen_frame = None | |
| first_frame = None | |
| for f in range(int(max_frames)): | |
| if f % cadence == 0: | |
| current_prompt = prompts[max(k for k in prompts.keys() if k <= f)] | |
| if prev_gen_frame is not None: | |
| # Warp | |
| init_image = anim.anim_frame_warp(prev_gen_frame, angle_s[f], zoom_s[f], tx_s[f], ty_s[f]) | |
| # SDXS 1-step Inference | |
| new_frame = pipe( | |
| current_prompt, | |
| image=init_image, | |
| negative_prompt=neg_prompt, | |
| num_inference_steps=1, | |
| guidance_scale=0.0, | |
| width=width, height=height | |
| ).images[0] | |
| if color_match and first_frame is not None: | |
| new_frame = anim.maintain_colors(first_frame, new_frame) | |
| else: | |
| # First frame base generation | |
| new_frame = pipe( | |
| current_prompt, | |
| negative_prompt=neg_prompt, | |
| num_inference_steps=1, | |
| guidance_scale=0.0, | |
| width=width, height=height | |
| ).images[0] | |
| first_frame = new_frame | |
| # Cadence Interpolation | |
| if cadence > 1 and prev_gen_frame is not None: | |
| for i in range(1, cadence): | |
| alpha = i / cadence | |
| interp_frame = anim.lerp_frames(prev_gen_frame, new_frame, alpha) | |
| all_frames.append(interp_frame) | |
| all_frames.append(new_frame) | |
| prev_gen_frame = new_frame | |
| yield new_frame, None, None | |
| # Post-Processing | |
| unique_id = uuid.uuid4().hex[:6] | |
| video_file = vid.frames_to_video(all_frames, f"deforum_{unique_id}.mp4", fps) | |
| zip_file = vid.export_to_zip(all_frames, f"frames_{unique_id}.zip") | |
| yield all_frames[-1], video_file, zip_file | |
| # --- UI Setup --- | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# 🚀 Deforum SOON® Animator") | |
| with gr.Row(): | |
| with gr.Column(): | |
| p_input = gr.Textbox(label="Prompt Map", value='{0: "hyperrealistic forest", 10: "burning forest"}') | |
| n_input = gr.Textbox(label="Negative Prompt", value="blurry, text, watermark") | |
| with gr.Row(): | |
| f_count = gr.Slider(5, 100, value=20, step=1, label="Frames") | |
| c_val = gr.Slider(1, 5, value=1, step=1, label="Cadence") | |
| fps_val = gr.Number(label="FPS", value=10) | |
| color_check = gr.Checkbox(label="Color Match", value=True) | |
| with gr.Accordion("2D Motion (Keyframes)", open=False): | |
| z_in = gr.Textbox(label="Zoom", value="0:(1.03)") | |
| a_in = gr.Textbox(label="Angle", value="0:(0)") | |
| tx_in = gr.Textbox(label="TX", value="0:(0)") | |
| ty_in = gr.Textbox(label="TY", value="0:(0)") | |
| run_btn = gr.Button("Generate", variant="primary") | |
| with gr.Column(): | |
| preview = gr.Image(label="Live Stream") | |
| video_out = gr.Video(label="Final Render") | |
| file_out = gr.File(label="Batch PNGs") | |
| run_btn.click( | |
| fn=run_deforum, | |
| inputs=[p_input, n_input, f_count, z_in, a_in, tx_in, ty_in, c_val, fps_val, color_check], | |
| outputs=[preview, video_out, file_out] | |
| ) | |
| demo.launch(theme='SebastianBravo/simci_css') |