HAL1993 commited on
Commit
73073f0
·
verified ·
1 Parent(s): 2b355b6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +303 -288
app.py CHANGED
@@ -1,8 +1,11 @@
1
  # ------------------------------------------------------------
2
- # IMPORTS
3
  # ------------------------------------------------------------
4
  import os
5
- os.environ["HF_HUB_ENABLE_HF_TRANSFER"] = "1"
 
 
 
6
 
7
  import spaces
8
  import torch
@@ -46,7 +49,7 @@ default_negative_prompt = (
46
  )
47
 
48
  # ------------------------------------------------------------
49
- # UNIVERSAL TRANSLATOR (ALBANIAN → ENGLISH + FALLBACK)
50
  # ------------------------------------------------------------
51
  def translate_albanian_to_english(text: str) -> str:
52
  if not text.strip():
@@ -70,11 +73,12 @@ def translate_albanian_to_english(text: str) -> str:
70
  return text
71
 
72
  # ------------------------------------------------------------
73
- # MODEL LOADING — BULLETPROOF ZEROGPU 2025
74
  # ------------------------------------------------------------
75
  pipe = WanImageToVideoPipeline.from_pretrained(
76
  "Wan-AI/Wan2.2-I2V-A14B-Diffusers",
77
  torch_dtype=torch.bfloat16,
 
78
  ).to("cuda")
79
 
80
  pipe.transformer = WanTransformer3DModel.from_pretrained(
@@ -82,12 +86,15 @@ pipe.transformer = WanTransformer3DModel.from_pretrained(
82
  subfolder="transformer",
83
  torch_dtype=torch.bfloat16,
84
  device_map="cuda",
 
85
  )
 
86
  pipe.transformer_2 = WanTransformer3DModel.from_pretrained(
87
  "cbensimon/Wan2.2-I2V-A14B-bf16-Diffusers",
88
  subfolder="transformer_2",
89
  torch_dtype=torch.bfloat16,
90
  device_map="cuda",
 
91
  )
92
 
93
  # ---- LoRA -------------------------------------------------
@@ -96,12 +103,14 @@ pipe.load_lora_weights(
96
  weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
97
  adapter_name="lightx2v",
98
  )
 
99
  pipe.load_lora_weights(
100
  "Kijai/WanVideo_comfy",
101
  weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
102
  adapter_name="lightx2v_2",
103
  load_into_transformer_2=True,
104
  )
 
105
  pipe.set_adapters(["lightx2v", "lightx2v_2"], adapter_weights=[1.0, 1.0])
106
  pipe.fuse_lora(adapter_names=["lightx2v"], lora_scale=3.0, components=["transformer"])
107
  pipe.fuse_lora(adapter_names=["lightx2v_2"], lora_scale=1.0, components=["transformer_2"])
@@ -223,12 +232,12 @@ def generate_video(
223
  raise gr.Error("Please upload an input image.")
224
 
225
  # -----------------------------------------------------------------
226
- # Prompt translation (Albanian → English)
227
  # -----------------------------------------------------------------
228
  prompt = translate_albanian_to_english(prompt_input)
229
 
230
  # -----------------------------------------------------------------
231
- # Prepare model inputs
232
  # -----------------------------------------------------------------
233
  current_seed = random.randint(0, MAX_SEED) if randomize_seed else int(seed)
234
  resized = resize_image(input_image)
@@ -249,17 +258,23 @@ def generate_video(
249
  num_inference_steps=int(steps),
250
  generator=torch.Generator(device="cuda").manual_seed(current_seed),
251
  )
252
- output_frames = out.frames[0]
253
 
254
  # -----------------------------------------------------------------
255
- # Write temporary mp4
256
  # -----------------------------------------------------------------
257
- with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
258
  video_path = tmp.name
259
- export_to_video(output_frames, video_path, fps=FIXED_FPS)
 
 
 
 
 
 
260
 
261
  # -----------------------------------------------------------------
262
- # Cleanup
263
  # -----------------------------------------------------------------
264
  gc.collect()
265
  torch.cuda.empty_cache()
@@ -272,283 +287,283 @@ def generate_video(
272
  # ------------------------------------------------------------
273
  with gr.Blocks(
274
  css="""
275
- @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;700&display=swap');
276
- @keyframes glow {0%{box-shadow:0 0 14px rgba(0,255,128,0.5);}50%{box-shadow:0 0 14px rgba(0,255,128,0.7);}100%{box-shadow:0 0 14px rgba(0,255,128,0.5);}}
277
- @keyframes glow-hover {0%{box-shadow:0 0 20px rgba(0,255,128,0.7);}50%{box-shadow:0 0 20px rgba(0,255,128,0.9);}100%{box-shadow:0 0 20px rgba(0,255,128,0.7);}}
278
- @keyframes slide {0%{background-position:0% 50%;}50%{background-position:100% 50%;}100%{background-position:0% 50%;}}
279
- @keyframes pulse {0%,100%{opacity:0.7;}50%{opacity:1;}}
280
- body{
281
- background:#000 !important;
282
- color:#FFF !important;
283
- font-family:'Orbitron',sans-serif;
284
- min-height:100vh;
285
- margin:0 !important;
286
- padding:0 !important;
287
- overflow-x:hidden !important;
288
- display:flex !important;
289
- justify-content:center;
290
- align-items:center;
291
- flex-direction:column;
292
- }
293
- body::before{
294
- content:"";
295
- display:block;
296
- height:600px; /* <-- top gap you asked for */
297
- background:#000 !important;
298
- }
299
- .gr-blocks,.container{
300
- width:100% !important;
301
- max-width:100vw !important;
302
- margin:0 !important;
303
- padding:0 !important;
304
- box-sizing:border-box !important;
305
- overflow-x:hidden !important;
306
- background:#000 !important;
307
- color:#FFF !important;
308
- }
309
- #general_items{
310
- width:100% !important;
311
- max-width:100vw !important;
312
- margin:2rem 0 !important;
313
- display:flex !important;
314
- flex-direction:column;
315
- align-items:center;
316
- justify-content:center;
317
- background:#000 !important;
318
- color:#FFF !important;
319
- }
320
- #input_column{
321
- background:#000 !important;
322
- border:none !important;
323
- border-radius:8px;
324
- padding:1rem !important;
325
- box-shadow:0 0 10px rgba(255,255,255,0.3) !important;
326
- width:100% !important;
327
- max-width:100vw !important;
328
- box-sizing:border-box !important;
329
- color:#FFF !important;
330
- }
331
- h1{
332
- font-size:5rem;
333
- font-weight:700;
334
- text-align:center;
335
- color:#FFF !important;
336
- text-shadow:0 0 8px rgba(255,255,255,0.3) !important;
337
- margin:0 auto .5rem auto;
338
- display:block;
339
- max-width:100%;
340
- }
341
- #subtitle{
342
- font-size:1rem;
343
- text-align:center;
344
- color:#FFF !important;
345
- opacity:0.8;
346
- margin-bottom:1rem;
347
- display:block;
348
- max-width:100%;
349
- }
350
- .gradio-component{
351
- background:#000 !important;
352
- border:none;
353
- margin:.75rem 0;
354
- width:100% !important;
355
- max-width:100vw !important;
356
- color:#FFF !important;
357
- }
358
- .image-container{
359
- aspect-ratio:1/1;
360
- width:100% !important;
361
- max-width:100vw !important;
362
- min-height:500px;
363
- height:auto;
364
- border:0.5px solid #FFF !important;
365
- border-radius:4px;
366
- box-sizing:border-box !important;
367
- background:#000 !important;
368
- box-shadow:0 0 10px rgba(255,255,255,0.3) !important;
369
- position:relative;
370
- color:#FFF !important;
371
- overflow:hidden !important;
372
- }
373
- .image-container img,.image-container video{
374
- width:100% !important;
375
- height:auto;
376
- box-sizing:border-box !important;
377
- display:block !important;
378
- }
379
- /* HIDE ALL GRADIO PROCESSING UI – 100+ SELECTORS */
380
- .image-container[aria-label="Generated Video"] .progress-text,
381
- .image-container[aria-label="Generated Video"] .gr-progress,
382
- .image-container[aria-label="Generated Video"] .gr-progress-bar,
383
- .image-container[aria-label="Generated Video"] .progress-bar,
384
- .image-container[aria-label="Generated Video"] [data-testid="progress"],
385
- .image-container[aria-label="Generated Video"] .status,
386
- .image-container[aria-label="Generated Video"] .loading,
387
- .image-container[aria-label="Generated Video"] .spinner,
388
- .image-container[aria-label="Generated Video"] .gr-spinner,
389
- .image-container[aria-label="Generated Video"] .gr-loading,
390
- .image-container[aria-label="Generated Video"] .gr-status,
391
- .image-container[aria-label="Generated Video"] .gpu-init,
392
- .image-container[aria-label="Generated Video"] .initializing,
393
- .image-container[aria-label="Generated Video"] .queue,
394
- .image-container[aria-label="Generated Video"] .queued,
395
- .image-container[aria-label="Generated Video"] .waiting,
396
- .image-container[aria-label="Generated Video"] .processing,
397
- .image-container[aria-label="Generated Video"] .gradio-progress,
398
- .image-container[aria-label="Generated Video"] .gradio-status,
399
- .image-container[aria-label="Generated Video"] div[class*="progress"],
400
- .image-container[aria-label="Generated Video"] div[class*="loading"],
401
- .image-container[aria-label="Generated Video"] div[class*="status"],
402
- .image-container[aria-label="Generated Video"] div[class*="spinner"],
403
- .image-container[aria-label="Generated Video"] *[class*="progress"],
404
- .image-container[aria-label="Generated Video"] *[class*="loading"],
405
- .image-container[aria-label="Generated Video"] *[class*="status"],
406
- .image-container[aria-label="Generated Video"] *[class*="spinner"],
407
- .progress-text,.gr-progress,.gr-progress-bar,.progress-bar,
408
- [data-testid="progress"],.status,.loading,.spinner,.gr-spinner,
409
- .gr-loading,.gr-status,.gpu-init,.initializing,.queue,
410
- .queued,.waiting,.processing,.gradio-progress,.gradio-status,
411
- div[class*="progress"],div[class*="loading"],div[class*="status"],
412
- div[class*="spinner"],*[class*="progress"],*[class*="loading"],
413
- *[class*="status"],*[class*="spinner"]{
414
- display:none!important;
415
- visibility:hidden!important;
416
- opacity:0!important;
417
- height:0!important;
418
- width:0!important;
419
- font-size:0!important;
420
- line-height:0!important;
421
- padding:0!important;
422
- margin:0!important;
423
- position:absolute!important;
424
- left:-9999px!important;
425
- top:-9999px!important;
426
- z-index:-9999!important;
427
- pointer-events:none!important;
428
- overflow:hidden!important;
429
- }
430
- /* EXHAUSTIVE TOOLBAR HIDING */
431
- .image-container[aria-label="Input Image"] .file-upload,
432
- .image-container[aria-label="Input Image"] .file-preview,
433
- .image-container[aria-label="Input Image"] .image-actions,
434
- .image-container[aria-label="Generated Video"] .file-upload,
435
- .image-container[aria-label="Generated Video"] .file-preview,
436
- .image-container[aria-label="Generated Video"] .image-actions{
437
- display:none!important;
438
- }
439
- .image-container[aria-label="Generated Video"].processing{
440
- background:#000!important;
441
- position:relative;
442
- }
443
- .image-container[aria-label="Generated Video"].processing::before{
444
- content:"PROCESSING...";
445
- position:absolute!important;
446
- top:50%!important;
447
- left:50%!important;
448
- transform:translate(-50%,-50%)!important;
449
- color:#FFF;
450
- font-family:'Orbitron',sans-serif;
451
- font-size:1.8rem!important;
452
- font-weight:700!important;
453
- text-align:center;
454
- text-shadow:0 0 10px rgba(0,255,128,0.8)!important;
455
- animation:pulse 1.5s ease-in-out infinite,glow 2s ease-in-out infinite!important;
456
- z-index:9999!important;
457
- width:100%!important;
458
- height:100%!important;
459
- display:flex!important;
460
- align-items:center!important;
461
- justify-content:center!important;
462
- pointer-events:none!important;
463
- background:#000!important;
464
- border-radius:4px!important;
465
- box-sizing:border-box!important;
466
- }
467
- .image-container[aria-label="Generated Video"].processing *{
468
- display:none!important;
469
- }
470
- input,textarea,.gr-dropdown,.gr-dropdown select{
471
- background:#000!important;
472
- color:#FFF!important;
473
- border:1px solid #FFF!important;
474
- border-radius:4px;
475
- padding:.5rem;
476
- width:100%!important;
477
- max-width:100vw!important;
478
- box-sizing:border-box!important;
479
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
  .gr-button-primary{
481
- background:linear-gradient(90deg,rgba(0,255,128,0.3),rgba(0,200,100,0.3),rgba(0,255,128,0.3))!important;
482
- background-size:200% 100%;
483
- animation:slide 4s ease-in-out infinite,glow 3s ease-in-out infinite;
484
- color:#FFF!important;
485
- border:1px solid #FFF!important;
486
- border-radius:6px;
487
- padding:.75rem 1.5rem;
488
- font-size:1.1rem;
489
- font-weight:600;
490
- box-shadow:0 0 14px rgba(0,255,128,0.7)!important;
491
- transition:box-shadow .3s,transform .3s;
492
- width:100%!important;
493
- max-width:100vw!important;
494
- min-height:48px;
495
- cursor:pointer;
496
  }
497
  .gr-button-primary:hover{
498
- box-shadow:0 0 20px rgba(0,255,128,0.9)!important;
499
- animation:slide 4s ease-in-out infinite,glow-hover 3s ease-in-out infinite;
500
- transform:scale(1.05);
501
- }
502
- button[aria-label="Fullscreen"],button[aria-label="Share"]{
503
- display:none!important;
504
- }
505
- button[aria-label="Download"]{
506
- transform:scale(3);
507
- transform-origin:top right;
508
- background:#000!important;
509
- color:#FFF!important;
510
- border:1px solid #FFF!important;
511
- border-radius:4px;
512
- padding:.4rem!important;
513
- margin:.5rem!important;
514
- box-shadow:0 0 8px rgba(255,255,255,0.3)!important;
515
- transition:box-shadow .3s;
516
- }
517
- button[aria-label="Download"]:hover{
518
- box-shadow:0 0 12px rgba(255,255,255,0.5)!important;
519
  }
520
- footer,.gr-button-secondary{
521
- display:none!important;
522
- }
523
- .gr-group{
524
- background:#000!important;
525
- border:none!important;
526
- width:100%!important;
527
- max-width:100vw!important;
528
- }
529
- @media (max-width:768px){
530
- h1{font-size:4rem;}
531
- #subtitle{font-size:.9rem;}
532
- .gr-button-primary{
533
- padding:.6rem 1rem;
534
- font-size:1rem;
535
- box-shadow:0 0 10px rgba(0,255,128,0.7)!important;
536
- }
537
- .gr-button-primary:hover{
538
- box-shadow:0 0 12px rgba(0,255,128,0.9)!important;
539
- }
540
- .image-container{min-height:300px;}
541
- .image-container[aria-label="Generated Video"].processing::before{
542
- font-size:1.2rem!important;
543
- }
544
  }
545
- """,
 
546
  title="Fast Image to Video"
547
  ) as demo:
548
 
549
- # -----------------------------------------------------------------
550
- # 500‑ERROR GUARD – exact same link as the original space
551
- # -----------------------------------------------------------------
552
  gr.HTML("""
553
  <script>
554
  if (!window.location.pathname.includes('b9v0c1x2z3a4s5d6f7g8h9j0k1l2m3n4b5v6c7x8z9a0s1d2f3g4h5j6k7l8m9n0')) {
@@ -558,9 +573,9 @@ with gr.Blocks(
558
  </script>
559
  """)
560
 
561
- # -----------------------------------------------------------------
562
- # UI layout – identical visual hierarchy to the original demo
563
- # -----------------------------------------------------------------
564
  with gr.Row(elem_id="general_items"):
565
  gr.Markdown("# ")
566
  gr.Markdown(
@@ -598,9 +613,9 @@ with gr.Blocks(
598
  elem_classes=["gradio-component", "image-container"],
599
  )
600
 
601
- # -----------------------------------------------------------------
602
- # Wiring – keep the same order as the function signature
603
- # -----------------------------------------------------------------
604
  generate_button.click(
605
  fn=generate_video,
606
  inputs=[
@@ -613,9 +628,9 @@ with gr.Blocks(
613
  gr.State(value=1.5), # guidance_scale_2
614
  gr.State(value=42), # seed
615
  gr.State(value=True), # randomize_seed
616
- # progress is injected by @spaces.GPU – do NOT pass it here
617
  ],
618
- outputs=[output_video, gr.State(value=42)], # second output is hidden seed
619
  )
620
 
621
  # ------------------------------------------------------------
 
1
  # ------------------------------------------------------------
2
+ # IMPORTS & ENVIRONMENT
3
  # ------------------------------------------------------------
4
  import os
5
+ # Put all heavy HF files in /tmp (RAM‑disk) – not counted toward the 150 GB limit
6
+ os.environ["HF_HUB_CACHE"] = "/tmp/hf_cache"
7
+ os.environ["TRANSFORMERS_CACHE"] = "/tmp/hf_cache"
8
+ os.environ["HF_HOME"] = "/tmp/hf_home"
9
 
10
  import spaces
11
  import torch
 
49
  )
50
 
51
  # ------------------------------------------------------------
52
+ # UNIVERSAL TRANSLATOR (ALBANIAN → ENGLISH)
53
  # ------------------------------------------------------------
54
  def translate_albanian_to_english(text: str) -> str:
55
  if not text.strip():
 
73
  return text
74
 
75
  # ------------------------------------------------------------
76
+ # MODEL LOADING
77
  # ------------------------------------------------------------
78
  pipe = WanImageToVideoPipeline.from_pretrained(
79
  "Wan-AI/Wan2.2-I2V-A14B-Diffusers",
80
  torch_dtype=torch.bfloat16,
81
+ cache_dir="/tmp/hf_cache", # <-- forces download into /tmp
82
  ).to("cuda")
83
 
84
  pipe.transformer = WanTransformer3DModel.from_pretrained(
 
86
  subfolder="transformer",
87
  torch_dtype=torch.bfloat16,
88
  device_map="cuda",
89
+ cache_dir="/tmp/hf_cache",
90
  )
91
+
92
  pipe.transformer_2 = WanTransformer3DModel.from_pretrained(
93
  "cbensimon/Wan2.2-I2V-A14B-bf16-Diffusers",
94
  subfolder="transformer_2",
95
  torch_dtype=torch.bfloat16,
96
  device_map="cuda",
97
+ cache_dir="/tmp/hf_cache",
98
  )
99
 
100
  # ---- LoRA -------------------------------------------------
 
103
  weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
104
  adapter_name="lightx2v",
105
  )
106
+
107
  pipe.load_lora_weights(
108
  "Kijai/WanVideo_comfy",
109
  weight_name="Lightx2v/lightx2v_I2V_14B_480p_cfg_step_distill_rank128_bf16.safetensors",
110
  adapter_name="lightx2v_2",
111
  load_into_transformer_2=True,
112
  )
113
+
114
  pipe.set_adapters(["lightx2v", "lightx2v_2"], adapter_weights=[1.0, 1.0])
115
  pipe.fuse_lora(adapter_names=["lightx2v"], lora_scale=3.0, components=["transformer"])
116
  pipe.fuse_lora(adapter_names=["lightx2v_2"], lora_scale=1.0, components=["transformer_2"])
 
232
  raise gr.Error("Please upload an input image.")
233
 
234
  # -----------------------------------------------------------------
235
+ # Translate prompt (Albanian → English)
236
  # -----------------------------------------------------------------
237
  prompt = translate_albanian_to_english(prompt_input)
238
 
239
  # -----------------------------------------------------------------
240
+ # Prepare everything
241
  # -----------------------------------------------------------------
242
  current_seed = random.randint(0, MAX_SEED) if randomize_seed else int(seed)
243
  resized = resize_image(input_image)
 
258
  num_inference_steps=int(steps),
259
  generator=torch.Generator(device="cuda").manual_seed(current_seed),
260
  )
261
+ frames = out.frames[0]
262
 
263
  # -----------------------------------------------------------------
264
+ # Write temporary MP4
265
  # -----------------------------------------------------------------
266
+ with tempfile.NamedTemporaryFile(delete=False, suffix=".mp4") as tmp:
267
  video_path = tmp.name
268
+ export_to_video(frames, video_path, fps=FIXED_FPS)
269
+
270
+ # -----------------------------------------------------------------
271
+ # Free AoT blocks (they take a few GB on disk)
272
+ # -----------------------------------------------------------------
273
+ aoti.aoti_blocks_unload(pipe.transformer)
274
+ aoti.aoti_blocks_unload(pipe.transformer_2)
275
 
276
  # -----------------------------------------------------------------
277
+ # GPU cleanup
278
  # -----------------------------------------------------------------
279
  gc.collect()
280
  torch.cuda.empty_cache()
 
287
  # ------------------------------------------------------------
288
  with gr.Blocks(
289
  css="""
290
+ @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;600;700&display=swap');
291
+ @keyframes glow {0%{box-shadow:0 0 14px rgba(0,255,128,0.5);}50%{box-shadow:0 0 14px rgba(0,255,128,0.7);}100%{box-shadow:0 0 14px rgba(0,255,128,0.5);}}
292
+ @keyframes glow-hover {0%{box-shadow:0 0 20px rgba(0,255,128,0.7);}50%{box-shadow:0 0 20px rgba(0,255,128,0.9);}100%{box-shadow:0 0 20px rgba(0,255,128,0.7);}}
293
+ @keyframes slide {0%{background-position:0% 50%;}50%{background-position:100% 50%;}100%{background-position:0% 50%;}}
294
+ @keyframes pulse {0%,100%{opacity:0.7;}50%{opacity:1;}}
295
+ body{
296
+ background:#000 !important;
297
+ color:#FFF !important;
298
+ font-family:'Orbitron',sans-serif;
299
+ min-height:100vh;
300
+ margin:0 !important;
301
+ padding:0 !important;
302
+ overflow-x:hidden !important;
303
+ display:flex !important;
304
+ justify-content:center;
305
+ align-items:center;
306
+ flex-direction:column;
307
+ }
308
+ body::before{
309
+ content:"";
310
+ display:block;
311
+ height:600px; /* <-- top gap you asked for */
312
+ background:#000 !important;
313
+ }
314
+ .gr-blocks,.container{
315
+ width:100% !important;
316
+ max-width:100vw !important;
317
+ margin:0 !important;
318
+ padding:0 !important;
319
+ box-sizing:border-box !important;
320
+ overflow-x:hidden !important;
321
+ background:#000 !important;
322
+ color:#FFF !important;
323
+ }
324
+ #general_items{
325
+ width:100% !important;
326
+ max-width:100vw !important;
327
+ margin:2rem 0 !important;
328
+ display:flex !important;
329
+ flex-direction:column;
330
+ align-items:center;
331
+ justify-content:center;
332
+ background:#000 !important;
333
+ color:#FFF !important;
334
+ }
335
+ #input_column{
336
+ background:#000 !important;
337
+ border:none !important;
338
+ border-radius:8px;
339
+ padding:1rem !important;
340
+ box-shadow:0 0 10px rgba(255,255,255,0.3) !important;
341
+ width:100% !important;
342
+ max-width:100vw !important;
343
+ box-sizing:border-box !important;
344
+ color:#FFF !important;
345
+ }
346
+ h1{
347
+ font-size:5rem;
348
+ font-weight:700;
349
+ text-align:center;
350
+ color:#FFF !important;
351
+ text-shadow:0 0 8px rgba(255,255,255,0.3) !important;
352
+ margin:0 auto .5rem auto;
353
+ display:block;
354
+ max-width:100%;
355
+ }
356
+ #subtitle{
357
+ font-size:1rem;
358
+ text-align:center;
359
+ color:#FFF !important;
360
+ opacity:0.8;
361
+ margin-bottom:1rem;
362
+ display:block;
363
+ max-width:100%;
364
+ }
365
+ .gradio-component{
366
+ background:#000 !important;
367
+ border:none;
368
+ margin:.75rem 0;
369
+ width:100% !important;
370
+ max-width:100vw !important;
371
+ color:#FFF !important;
372
+ }
373
+ .image-container{
374
+ aspect-ratio:1/1;
375
+ width:100% !important;
376
+ max-width:100vw !important;
377
+ min-height:500px;
378
+ height:auto;
379
+ border:0.5px solid #FFF !important;
380
+ border-radius:4px;
381
+ box-sizing:border-box !important;
382
+ background:#000 !important;
383
+ box-shadow:0 0 10px rgba(255,255,255,0.3) !important;
384
+ position:relative;
385
+ color:#FFF !important;
386
+ overflow:hidden !important;
387
+ }
388
+ .image-container img,.image-container video{
389
+ width:100% !important;
390
+ height:auto;
391
+ box-sizing:border-box !important;
392
+ display:block !important;
393
+ }
394
+ /* HIDE GRADIO PROCESSING UI */
395
+ .image-container[aria-label="Generated Video"] .progress-text,
396
+ .image-container[aria-label="Generated Video"] .gr-progress,
397
+ .image-container[aria-label="Generated Video"] .gr-progress-bar,
398
+ .image-container[aria-label="Generated Video"] .progress-bar,
399
+ .image-container[aria-label="Generated Video"] [data-testid="progress"],
400
+ .image-container[aria-label="Generated Video"] .status,
401
+ .image-container[aria-label="Generated Video"] .loading,
402
+ .image-container[aria-label="Generated Video"] .spinner,
403
+ .image-container[aria-label="Generated Video"] .gr-spinner,
404
+ .image-container[aria-label="Generated Video"] .gr-loading,
405
+ .image-container[aria-label="Generated Video"] .gr-status,
406
+ .image-container[aria-label="Generated Video"] .gpu-init,
407
+ .image-container[aria-label="Generated Video"] .initializing,
408
+ .image-container[aria-label="Generated Video"] .queue,
409
+ .image-container[aria-label="Generated Video"] .queued,
410
+ .image-container[aria-label="Generated Video"] .waiting,
411
+ .image-container[aria-label="Generated Video"] .processing,
412
+ .image-container[aria-label="Generated Video"] .gradio-progress,
413
+ .image-container[aria-label="Generated Video"] .gradio-status,
414
+ .image-container[aria-label="Generated Video"] div[class*="progress"],
415
+ .image-container[aria-label="Generated Video"] div[class*="loading"],
416
+ .image-container[aria-label="Generated Video"] div[class*="status"],
417
+ .image-container[aria-label="Generated Video"] div[class*="spinner"],
418
+ .image-container[aria-label="Generated Video"] *[class*="progress"],
419
+ .image-container[aria-label="Generated Video"] *[class*="loading"],
420
+ .image-container[aria-label="Generated Video"] *[class*="status"],
421
+ .image-container[aria-label="Generated Video"] *[class*="spinner"],
422
+ .progress-text,.gr-progress,.gr-progress-bar,.progress-bar,
423
+ [data-testid="progress"],.status,.loading,.spinner,.gr-spinner,
424
+ .gr-loading,.gr-status,.gpu-init,.initializing,.queue,
425
+ .queued,.waiting,.processing,.gradio-progress,.gradio-status,
426
+ div[class*="progress"],div[class*="loading"],div[class*="status"],
427
+ div[class*="spinner"],*[class*="progress"],*[class*="loading"],
428
+ *[class*="status"],*[class*="spinner"]{
429
+ display:none!important;
430
+ visibility:hidden!important;
431
+ opacity:0!important;
432
+ height:0!important;
433
+ width:0!important;
434
+ font-size:0!important;
435
+ line-height:0!important;
436
+ padding:0!important;
437
+ margin:0!important;
438
+ position:absolute!important;
439
+ left:-9999px!important;
440
+ top:-9999px!important;
441
+ z-index:-9999!important;
442
+ pointer-events:none!important;
443
+ overflow:hidden!important;
444
+ }
445
+ /* TOOLBAR HIDING */
446
+ .image-container[aria-label="Input Image"] .file-upload,
447
+ .image-container[aria-label="Input Image"] .file-preview,
448
+ .image-container[aria-label="Input Image"] .image-actions,
449
+ .image-container[aria-label="Generated Video"] .file-upload,
450
+ .image-container[aria-label="Generated Video"] .file-preview,
451
+ .image-container[aria-label="Generated Video"] .image-actions{
452
+ display:none!important;
453
+ }
454
+ .image-container[aria-label="Generated Video"].processing{
455
+ background:#000!important;
456
+ position:relative;
457
+ }
458
+ .image-container[aria-label="Generated Video"].processing::before{
459
+ content:"PROCESSING...";
460
+ position:absolute!important;
461
+ top:50%!important;
462
+ left:50%!important;
463
+ transform:translate(-50%,-50%)!important;
464
+ color:#FFF;
465
+ font-family:'Orbitron',sans-serif;
466
+ font-size:1.8rem!important;
467
+ font-weight:700!important;
468
+ text-align:center;
469
+ text-shadow:0 0 10px rgba(0,255,128,0.8)!important;
470
+ animation:pulse 1.5s ease-in-out infinite,glow 2s ease-in-out infinite!important;
471
+ z-index:9999!important;
472
+ width:100%!important;
473
+ height:100%!important;
474
+ display:flex!important;
475
+ align-items:center!important;
476
+ justify-content:center!important;
477
+ pointer-events:none!important;
478
+ background:#000!important;
479
+ border-radius:4px!important;
480
+ box-sizing:border-box!important;
481
+ }
482
+ .image-container[aria-label="Generated Video"].processing *{
483
+ display:none!important;
484
+ }
485
+ input,textarea,.gr-dropdown,.gr-dropdown select{
486
+ background:#000!important;
487
+ color:#FFF!important;
488
+ border:1px solid #FFF!important;
489
+ border-radius:4px;
490
+ padding:.5rem;
491
+ width:100%!important;
492
+ max-width:100vw!important;
493
+ box-sizing:border-box!important;
494
+ }
495
+ .gr-button-primary{
496
+ background:linear-gradient(90deg,rgba(0,255,128,0.3),rgba(0,200,100,0.3),rgba(0,255,128,0.3))!important;
497
+ background-size:200% 100%;
498
+ animation:slide 4s ease-in-out infinite,glow 3s ease-in-out infinite;
499
+ color:#FFF!important;
500
+ border:1px solid #FFF!important;
501
+ border-radius:6px;
502
+ padding:.75rem 1.5rem;
503
+ font-size:1.1rem;
504
+ font-weight:600;
505
+ box-shadow:0 0 14px rgba(0,255,128,0.7)!important;
506
+ transition:box-shadow .3s,transform .3s;
507
+ width:100%!important;
508
+ max-width:100vw!important;
509
+ min-height:48px;
510
+ cursor:pointer;
511
+ }
512
+ .gr-button-primary:hover{
513
+ box-shadow:0 0 20px rgba(0,255,128,0.9)!important;
514
+ animation:slide 4s ease-in-out infinite,glow-hover 3s ease-in-out infinite;
515
+ transform:scale(1.05);
516
+ }
517
+ button[aria-label="Fullscreen"],button[aria-label="Share"]{
518
+ display:none!important;
519
+ }
520
+ button[aria-label="Download"]{
521
+ transform:scale(3);
522
+ transform-origin:top right;
523
+ background:#000!important;
524
+ color:#FFF!important;
525
+ border:1px solid #FFF!important;
526
+ border-radius:4px;
527
+ padding:.4rem!important;
528
+ margin:.5rem!important;
529
+ box-shadow:0 0 8px rgba(255,255,255,0.3)!important;
530
+ transition:box-shadow .3s;
531
+ }
532
+ button[aria-label="Download"]:hover{
533
+ box-shadow:0 0 12px rgba(255,255,255,0.5)!important;
534
+ }
535
+ footer,.gr-button-secondary{
536
+ display:none!important;
537
+ }
538
+ .gr-group{
539
+ background:#000!important;
540
+ border:none!important;
541
+ width:100%!important;
542
+ max-width:100vw!important;
543
+ }
544
+ @media (max-width:768px){
545
+ h1{font-size:4rem;}
546
+ #subtitle{font-size:.9rem;}
547
  .gr-button-primary{
548
+ padding:.6rem 1rem;
549
+ font-size:1rem;
550
+ box-shadow:0 0 10px rgba(0,255,128,0.7)!important;
 
 
 
 
 
 
 
 
 
 
 
 
551
  }
552
  .gr-button-primary:hover{
553
+ box-shadow:0 0 12px rgba(0,255,128,0.9)!important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554
  }
555
+ .image-container{min-height:300px;}
556
+ .image-container[aria-label="Generated Video"].processing::before{
557
+ font-size:1.2rem!important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
558
  }
559
+ }
560
+ """
561
  title="Fast Image to Video"
562
  ) as demo:
563
 
564
+ # -------------------------------------------------
565
+ # 500‑ERROR GUARD – same unique link as before
566
+ # -------------------------------------------------
567
  gr.HTML("""
568
  <script>
569
  if (!window.location.pathname.includes('b9v0c1x2z3a4s5d6f7g8h9j0k1l2m3n4b5v6c7x8z9a0s1d2f3g4h5j6k7l8m9n0')) {
 
573
  </script>
574
  """)
575
 
576
+ # -------------------------------------------------
577
+ # UI layout – identical to the original demo
578
+ # -------------------------------------------------
579
  with gr.Row(elem_id="general_items"):
580
  gr.Markdown("# ")
581
  gr.Markdown(
 
613
  elem_classes=["gradio-component", "image-container"],
614
  )
615
 
616
+ # -------------------------------------------------
617
+ # Wiring – order must match generate_video signature
618
+ # -------------------------------------------------
619
  generate_button.click(
620
  fn=generate_video,
621
  inputs=[
 
628
  gr.State(value=1.5), # guidance_scale_2
629
  gr.State(value=42), # seed
630
  gr.State(value=True), # randomize_seed
631
+ # progress is injected automatically by @spaces.GPU
632
  ],
633
+ outputs=[output_video, gr.State(value=42)], # hidden seed output
634
  )
635
 
636
  # ------------------------------------------------------------