Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -151,17 +151,20 @@ def detect_aspect_ratio(image) -> str:
|
|
| 151 |
return min(candidates, key=lambda k: abs(ratio - candidates[k]))
|
| 152 |
|
| 153 |
|
| 154 |
-
def on_image_upload(
|
| 155 |
-
"""Auto-set resolution when image is uploaded."""
|
| 156 |
-
aspect
|
|
|
|
|
|
|
| 157 |
tier = "high" if high_res else "low"
|
| 158 |
w, h = RESOLUTIONS[tier][aspect]
|
| 159 |
return gr.update(value=w), gr.update(value=h)
|
| 160 |
|
| 161 |
|
| 162 |
-
def on_highres_toggle(
|
| 163 |
"""Update resolution when high-res toggle changes."""
|
| 164 |
-
|
|
|
|
| 165 |
tier = "high" if high_res else "low"
|
| 166 |
w, h = RESOLUTIONS[tier][aspect]
|
| 167 |
return gr.update(value=w), gr.update(value=h)
|
|
@@ -170,7 +173,8 @@ def on_highres_toggle(image, high_res):
|
|
| 170 |
@spaces.GPU(duration=75)
|
| 171 |
@torch.inference_mode()
|
| 172 |
def generate_video(
|
| 173 |
-
|
|
|
|
| 174 |
prompt: str,
|
| 175 |
duration: float,
|
| 176 |
enhance_prompt: bool = True,
|
|
@@ -193,15 +197,24 @@ def generate_video(
|
|
| 193 |
print(f"Generating: {height}x{width}, {num_frames} frames ({duration}s), seed={current_seed}")
|
| 194 |
|
| 195 |
images = []
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 202 |
else:
|
| 203 |
-
|
| 204 |
-
images
|
| 205 |
|
| 206 |
tiling_config = TilingConfig.default()
|
| 207 |
video_chunks_number = get_video_chunks_number(num_frames, tiling_config)
|
|
@@ -251,7 +264,9 @@ with gr.Blocks(title="LTX-2.3 Distilled") as demo:
|
|
| 251 |
|
| 252 |
with gr.Row():
|
| 253 |
with gr.Column():
|
| 254 |
-
|
|
|
|
|
|
|
| 255 |
prompt = gr.Textbox(
|
| 256 |
label="Prompt",
|
| 257 |
info="for best results - make it as elaborate as possible",
|
|
@@ -279,23 +294,29 @@ with gr.Blocks(title="LTX-2.3 Distilled") as demo:
|
|
| 279 |
output_video = gr.Video(label="Generated Video", autoplay=True)
|
| 280 |
|
| 281 |
# Auto-detect aspect ratio from uploaded image and set resolution
|
| 282 |
-
|
| 283 |
fn=on_image_upload,
|
| 284 |
-
inputs=[
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 285 |
outputs=[width, height],
|
| 286 |
)
|
| 287 |
|
| 288 |
# Update resolution when high-res toggle changes
|
| 289 |
high_res.change(
|
| 290 |
fn=on_highres_toggle,
|
| 291 |
-
inputs=[
|
| 292 |
outputs=[width, height],
|
| 293 |
)
|
| 294 |
|
| 295 |
generate_btn.click(
|
| 296 |
fn=generate_video,
|
| 297 |
inputs=[
|
| 298 |
-
|
| 299 |
seed, randomize_seed, height, width,
|
| 300 |
],
|
| 301 |
outputs=[output_video, seed],
|
|
@@ -307,5 +328,4 @@ css = """
|
|
| 307 |
"""
|
| 308 |
|
| 309 |
if __name__ == "__main__":
|
| 310 |
-
demo.launch(theme=gr.themes.Citrus(), css=css)
|
| 311 |
-
|
|
|
|
| 151 |
return min(candidates, key=lambda k: abs(ratio - candidates[k]))
|
| 152 |
|
| 153 |
|
| 154 |
+
def on_image_upload(first_image, last_image, high_res):
|
| 155 |
+
"""Auto-set resolution when an image is uploaded."""
|
| 156 |
+
# Use first image for aspect ratio detection, fall back to last image
|
| 157 |
+
ref_image = first_image if first_image is not None else last_image
|
| 158 |
+
aspect = detect_aspect_ratio(ref_image)
|
| 159 |
tier = "high" if high_res else "low"
|
| 160 |
w, h = RESOLUTIONS[tier][aspect]
|
| 161 |
return gr.update(value=w), gr.update(value=h)
|
| 162 |
|
| 163 |
|
| 164 |
+
def on_highres_toggle(first_image, last_image, high_res):
|
| 165 |
"""Update resolution when high-res toggle changes."""
|
| 166 |
+
ref_image = first_image if first_image is not None else last_image
|
| 167 |
+
aspect = detect_aspect_ratio(ref_image)
|
| 168 |
tier = "high" if high_res else "low"
|
| 169 |
w, h = RESOLUTIONS[tier][aspect]
|
| 170 |
return gr.update(value=w), gr.update(value=h)
|
|
|
|
| 173 |
@spaces.GPU(duration=75)
|
| 174 |
@torch.inference_mode()
|
| 175 |
def generate_video(
|
| 176 |
+
first_image,
|
| 177 |
+
last_image,
|
| 178 |
prompt: str,
|
| 179 |
duration: float,
|
| 180 |
enhance_prompt: bool = True,
|
|
|
|
| 197 |
print(f"Generating: {height}x{width}, {num_frames} frames ({duration}s), seed={current_seed}")
|
| 198 |
|
| 199 |
images = []
|
| 200 |
+
output_dir = Path("outputs")
|
| 201 |
+
output_dir.mkdir(exist_ok=True)
|
| 202 |
+
|
| 203 |
+
if first_image is not None:
|
| 204 |
+
temp_first_path = output_dir / f"temp_first_{current_seed}.jpg"
|
| 205 |
+
if hasattr(first_image, "save"):
|
| 206 |
+
first_image.save(temp_first_path)
|
| 207 |
+
else:
|
| 208 |
+
temp_first_path = Path(first_image)
|
| 209 |
+
images.append(ImageConditioningInput(path=str(temp_first_path), frame_idx=0, strength=1.0))
|
| 210 |
+
|
| 211 |
+
if last_image is not None:
|
| 212 |
+
temp_last_path = output_dir / f"temp_last_{current_seed}.jpg"
|
| 213 |
+
if hasattr(last_image, "save"):
|
| 214 |
+
last_image.save(temp_last_path)
|
| 215 |
else:
|
| 216 |
+
temp_last_path = Path(last_image)
|
| 217 |
+
images.append(ImageConditioningInput(path=str(temp_last_path), frame_idx=num_frames - 1, strength=1.0))
|
| 218 |
|
| 219 |
tiling_config = TilingConfig.default()
|
| 220 |
video_chunks_number = get_video_chunks_number(num_frames, tiling_config)
|
|
|
|
| 264 |
|
| 265 |
with gr.Row():
|
| 266 |
with gr.Column():
|
| 267 |
+
with gr.Row():
|
| 268 |
+
first_image = gr.Image(label="First Frame (Optional)", type="pil")
|
| 269 |
+
last_image = gr.Image(label="Last Frame (Optional)", type="pil")
|
| 270 |
prompt = gr.Textbox(
|
| 271 |
label="Prompt",
|
| 272 |
info="for best results - make it as elaborate as possible",
|
|
|
|
| 294 |
output_video = gr.Video(label="Generated Video", autoplay=True)
|
| 295 |
|
| 296 |
# Auto-detect aspect ratio from uploaded image and set resolution
|
| 297 |
+
first_image.change(
|
| 298 |
fn=on_image_upload,
|
| 299 |
+
inputs=[first_image, last_image, high_res],
|
| 300 |
+
outputs=[width, height],
|
| 301 |
+
)
|
| 302 |
+
|
| 303 |
+
last_image.change(
|
| 304 |
+
fn=on_image_upload,
|
| 305 |
+
inputs=[first_image, last_image, high_res],
|
| 306 |
outputs=[width, height],
|
| 307 |
)
|
| 308 |
|
| 309 |
# Update resolution when high-res toggle changes
|
| 310 |
high_res.change(
|
| 311 |
fn=on_highres_toggle,
|
| 312 |
+
inputs=[first_image, last_image, high_res],
|
| 313 |
outputs=[width, height],
|
| 314 |
)
|
| 315 |
|
| 316 |
generate_btn.click(
|
| 317 |
fn=generate_video,
|
| 318 |
inputs=[
|
| 319 |
+
first_image, last_image, prompt, duration, enhance_prompt,
|
| 320 |
seed, randomize_seed, height, width,
|
| 321 |
],
|
| 322 |
outputs=[output_video, seed],
|
|
|
|
| 328 |
"""
|
| 329 |
|
| 330 |
if __name__ == "__main__":
|
| 331 |
+
demo.launch(theme=gr.themes.Citrus(), css=css)
|
|
|