alexnasa commited on
Commit
6a997f3
·
verified ·
1 Parent(s): d843a55

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -38
app.py CHANGED
@@ -249,19 +249,22 @@ class RadioAnimated(gr.HTML):
249
  if value is None:
250
  value = choices[0]
251
 
252
- # Build labels/inputs HTML
 
 
253
  inputs_html = "\n".join(
254
  f"""
255
- <input class="ra-input" type="radio" name="ra" id="ra-{i}" value="{c}">
256
- <label class="ra-label" for="ra-{i}">{c}</label>
257
  """
258
  for i, c in enumerate(choices)
259
  )
260
 
 
261
  html_template = f"""
262
- <div class="ra-wrap" id="ra-wrap">
263
- <div class="ra-inner" id="ra-inner">
264
- <div class="ra-highlight" id="ra-highlight"></div>
265
  {inputs_html}
266
  </div>
267
  </div>
@@ -269,11 +272,10 @@ class RadioAnimated(gr.HTML):
269
 
270
  js_on_load = r"""
271
  (() => {
272
- const wrap = element.querySelector('#ra-wrap');
273
- const inner = element.querySelector('#ra-inner');
274
- const highlight = element.querySelector('#ra-highlight');
275
  const inputs = Array.from(element.querySelectorAll('.ra-input'));
276
- const labels = Array.from(element.querySelectorAll('.ra-label'));
277
 
278
  if (!inputs.length) return;
279
 
@@ -291,7 +293,6 @@ class RadioAnimated(gr.HTML):
291
  inputs.forEach((inp, i) => { inp.checked = (i === idx); });
292
  setHighlightByIndex(idx);
293
 
294
- // Update props + fire change if requested
295
  props.value = choices[idx];
296
  if (shouldTrigger) trigger('change', props.value);
297
  }
@@ -299,7 +300,7 @@ class RadioAnimated(gr.HTML):
299
  // Init from props.value
300
  setCheckedByValue(props.value ?? choices[0], false);
301
 
302
- // Click handlers
303
  inputs.forEach((inp) => {
304
  inp.addEventListener('change', () => {
305
  setCheckedByValue(inp.value, true);
@@ -324,6 +325,10 @@ class RadioAnimated(gr.HTML):
324
  **kwargs
325
  )
326
 
 
 
 
 
327
 
328
  @spaces.GPU(duration=get_duration)
329
  def generate_video(
@@ -429,6 +434,10 @@ def apply_resolution(resolution: str):
429
  w, h = resolution.split("x")
430
  return int(w), int(h)
431
 
 
 
 
 
432
  css = """
433
  #col-container {
434
  margin: 0 auto;
@@ -610,13 +619,7 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
610
  max_lines=3,
611
  placeholder="Describe the motion and animation you want..."
612
  )
613
- duration = gr.Slider(
614
- label="Duration (seconds)",
615
- minimum=1.0,
616
- maximum=10.0,
617
- value=3.0,
618
- step=0.1
619
- )
620
  enhance_prompt = gr.Checkbox(
621
  label="Enhance Prompt",
622
  value=True,
@@ -634,25 +637,51 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
634
 
635
  randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
636
 
637
-
638
 
639
  with gr.Column(elem_id="step-column"):
640
  output_video = gr.Video(label="Generated Video", autoplay=True, height=512)
641
-
642
- radioanimated = RadioAnimated(
643
- choices=["768x512", "512x512", "512x768"],
644
- value=f"{DEFAULT_1_STAGE_WIDTH}x{DEFAULT_1_STAGE_HEIGHT}",
645
- elem_id="radioanimated"
646
- )
647
 
648
- width = gr.Number(label="Width", value=DEFAULT_1_STAGE_WIDTH, precision=0, visible=False)
649
- height = gr.Number(label="Height", value=DEFAULT_1_STAGE_HEIGHT, precision=0, visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
 
651
  generate_btn = gr.Button("🤩 Generate Video", variant="primary", elem_classes="button-gradient")
652
 
653
- radioanimated.change(
 
 
 
 
 
 
 
654
  fn=apply_resolution,
655
- inputs=radioanimated,
656
  outputs=[width, height],
657
  api_visibility="private"
658
  )
@@ -677,24 +706,25 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
677
  examples=[
678
  [
679
  "supergirl.png",
680
- "A fuzzy puppet superhero character resembling a female puppet with blonde hair and a blue superhero suit stands inside an icy cave made of frozen walls and icicles, she looks panicked and frantic, rapidly turning her head left and right and scanning the cave while waving her arms and shouting angrily and desperately, mouthing the words “where the hell is my dog,” her movements exaggerated and puppet-like with high energy and urgency, suddenly a second puppet dog bursts into frame from the side, jumping up excitedly and tackling her affectionately while licking her face repeatedly, she freezes in surprise and then breaks into relief and laughter as the dog continues licking her, the scene feels chaotic, comedic, and emotional with expressive puppet reactions, cinematic lighting, smooth camera motion, shallow depth of field, and high-quality puppet-style animation",
681
- 5.0,
 
 
 
682
  ],
683
  [
684
  "wednesday.png",
685
  "A cinematic close-up of Wednesday Addams frozen mid-dance on a dark, blue-lit ballroom floor as students move indistinctly behind her, their footsteps and muffled music reduced to a distant, underwater thrum; the audio foregrounds her steady breathing and the faint rustle of fabric as she slowly raises one arm, never breaking eye contact with the camera, then after a deliberately long silence she speaks in a flat, dry, perfectly controlled voice, “I don’t dance… I vibe code,” each word crisp and unemotional, followed by an abrupt cutoff of her voice as the background sound swells slightly, reinforcing the deadpan humor, with precise lip sync, minimal facial movement, stark gothic lighting, and cinematic realism.",
686
- 5.0,
687
  ],
688
  [
689
- "astronaut.jpg",
690
  "An astronaut hatches from a fragile egg on the surface of the Moon, the shell cracking and peeling apart in gentle low-gravity motion. Fine lunar dust lifts and drifts outward with each movement, floating in slow arcs before settling back onto the ground. The astronaut pushes free in a deliberate, weightless motion, small fragments of the egg tumbling and spinning through the air. In the background, the deep darkness of space subtly shifts as stars glide with the camera's movement, emphasizing vast depth and scale. The camera performs a smooth, cinematic slow push-in, with natural parallax between the foreground dust, the astronaut, and the distant starfield. Ultra-realistic detail, physically accurate low-gravity motion, cinematic lighting, and a breath-taking, movie-like shot.",
691
- 10.0,
692
  ]
693
 
694
  ],
695
- fn=generate_video,
696
- inputs=[input_image, prompt, duration],
697
- outputs = [output_video, seed],
698
  label="Example",
699
  cache_examples=True,
700
  )
 
249
  if value is None:
250
  value = choices[0]
251
 
252
+ uid = uuid.uuid4().hex[:8] # unique per instance
253
+ group_name = f"ra-{uid}"
254
+
255
  inputs_html = "\n".join(
256
  f"""
257
+ <input class="ra-input" type="radio" name="{group_name}" id="{group_name}-{i}" value="{c}">
258
+ <label class="ra-label" for="{group_name}-{i}">{c}</label>
259
  """
260
  for i, c in enumerate(choices)
261
  )
262
 
263
+ # NOTE: use classes instead of duplicate IDs
264
  html_template = f"""
265
+ <div class="ra-wrap" data-ra="{uid}">
266
+ <div class="ra-inner">
267
+ <div class="ra-highlight"></div>
268
  {inputs_html}
269
  </div>
270
  </div>
 
272
 
273
  js_on_load = r"""
274
  (() => {
275
+ const wrap = element.querySelector('.ra-wrap');
276
+ const inner = element.querySelector('.ra-inner');
277
+ const highlight = element.querySelector('.ra-highlight');
278
  const inputs = Array.from(element.querySelectorAll('.ra-input'));
 
279
 
280
  if (!inputs.length) return;
281
 
 
293
  inputs.forEach((inp, i) => { inp.checked = (i === idx); });
294
  setHighlightByIndex(idx);
295
 
 
296
  props.value = choices[idx];
297
  if (shouldTrigger) trigger('change', props.value);
298
  }
 
300
  // Init from props.value
301
  setCheckedByValue(props.value ?? choices[0], false);
302
 
303
+ // Input handlers
304
  inputs.forEach((inp) => {
305
  inp.addEventListener('change', () => {
306
  setCheckedByValue(inp.value, true);
 
325
  **kwargs
326
  )
327
 
328
+ def generate_video_example(input_image, prompt, duration, progress=gr.Progress(track_tqdm=True)):
329
+ output_video, seed = generate_video(input_image, prompt, 5, True, 42, True, DEFAULT_1_STAGE_HEIGHT, DEFAULT_1_STAGE_WIDTH, progress)
330
+
331
+ return output_video
332
 
333
  @spaces.GPU(duration=get_duration)
334
  def generate_video(
 
434
  w, h = resolution.split("x")
435
  return int(w), int(h)
436
 
437
+ def apply_duration(duration: str):
438
+ duration_s = int(duration[:-1])
439
+ return duration_s
440
+
441
  css = """
442
  #col-container {
443
  margin: 0 auto;
 
619
  max_lines=3,
620
  placeholder="Describe the motion and animation you want..."
621
  )
622
+
 
 
 
 
 
 
623
  enhance_prompt = gr.Checkbox(
624
  label="Enhance Prompt",
625
  value=True,
 
637
 
638
  randomize_seed = gr.Checkbox(label="Randomize Seed", value=True)
639
 
 
640
 
641
  with gr.Column(elem_id="step-column"):
642
  output_video = gr.Video(label="Generated Video", autoplay=True, height=512)
 
 
 
 
 
 
643
 
644
+ with gr.Row():
645
+
646
+ with gr.Column():
647
+ radioanimated_duration = RadioAnimated(
648
+ choices=["3s", "5s", "10s"],
649
+ value="3s",
650
+ elem_id="radioanimated_duration"
651
+ )
652
+
653
+ duration = gr.Slider(
654
+ label="Duration (seconds)",
655
+ minimum=1.0,
656
+ maximum=10.0,
657
+ value=3.0,
658
+ step=0.1,
659
+ visible=False
660
+ )
661
+
662
+ with gr.Column():
663
+ radioanimated_resolution = RadioAnimated(
664
+ choices=["768x512", "512x512", "512x768"],
665
+ value=f"{DEFAULT_1_STAGE_WIDTH}x{DEFAULT_1_STAGE_HEIGHT}",
666
+ elem_id="radioanimated_resolution"
667
+ )
668
+
669
+ width = gr.Number(label="Width", value=DEFAULT_1_STAGE_WIDTH, precision=0, visible=False)
670
+ height = gr.Number(label="Height", value=DEFAULT_1_STAGE_HEIGHT, precision=0, visible=False)
671
+
672
 
673
  generate_btn = gr.Button("🤩 Generate Video", variant="primary", elem_classes="button-gradient")
674
 
675
+
676
+ radioanimated_duration.change(
677
+ fn=apply_duration,
678
+ inputs=radioanimated_duration,
679
+ outputs=[duration],
680
+ api_visibility="private"
681
+ )
682
+ radioanimated_resolution.change(
683
  fn=apply_resolution,
684
+ inputs=radioanimated_resolution,
685
  outputs=[width, height],
686
  api_visibility="private"
687
  )
 
706
  examples=[
707
  [
708
  "supergirl.png",
709
+ "A fuzzy puppet superhero character resembling a female puppet with blonde hair and a blue superhero suit stands inside an icy cave made of frozen walls and icicles, she looks panicked and frantic, rapidly turning her head left and right and scanning the cave while waving her arms and shouting angrily and desperately, mouthing the words “where the hell is my dog,” her movements exaggerated and puppet-like with high energy and urgency, suddenly a second puppet dog bursts into frame from the side, jumping up excitedly and tackling her affectionately while licking her face repeatedly, she freezes in surprise and then breaks into relief and laughter as the dog continues licking her, the scene feels chaotic, comedic, and emotional with expressive puppet reactions, cinematic lighting, smooth camera motion, shallow depth of field, and high-quality puppet-style animation"
710
+ ],
711
+ [
712
+ "highland.png",
713
+ "Realistic POV selfie-style video in a snowy, foggy field. Two shaggy Highland cows with long curved horns stand ahead. The camera is handheld and slightly shaky. The woman filming talks nervously and excitedly in a vlog tone: \"Oh my god guys… look how big those horns are… I’m kinda scared.\" The cow on the left walks toward the camera in a cute, bouncy, hopping way, curious and gentle. Snow crunches under its hooves, breath visible in the cold air. The horns look massive from the POV. As the cow gets very close, its wet nose with slight dripping fills part of the frame. She laughs nervously but reaches out and pets the cow. The cow makes deep, soft, interesting mooing and snorting sounds, calm and friendly. Ultra-realistic, natural lighting, immersive audio, documentary-style realism.",
714
  ],
715
  [
716
  "wednesday.png",
717
  "A cinematic close-up of Wednesday Addams frozen mid-dance on a dark, blue-lit ballroom floor as students move indistinctly behind her, their footsteps and muffled music reduced to a distant, underwater thrum; the audio foregrounds her steady breathing and the faint rustle of fabric as she slowly raises one arm, never breaking eye contact with the camera, then after a deliberately long silence she speaks in a flat, dry, perfectly controlled voice, “I don’t dance… I vibe code,” each word crisp and unemotional, followed by an abrupt cutoff of her voice as the background sound swells slightly, reinforcing the deadpan humor, with precise lip sync, minimal facial movement, stark gothic lighting, and cinematic realism.",
 
718
  ],
719
  [
720
+ "astronaut.png",
721
  "An astronaut hatches from a fragile egg on the surface of the Moon, the shell cracking and peeling apart in gentle low-gravity motion. Fine lunar dust lifts and drifts outward with each movement, floating in slow arcs before settling back onto the ground. The astronaut pushes free in a deliberate, weightless motion, small fragments of the egg tumbling and spinning through the air. In the background, the deep darkness of space subtly shifts as stars glide with the camera's movement, emphasizing vast depth and scale. The camera performs a smooth, cinematic slow push-in, with natural parallax between the foreground dust, the astronaut, and the distant starfield. Ultra-realistic detail, physically accurate low-gravity motion, cinematic lighting, and a breath-taking, movie-like shot.",
 
722
  ]
723
 
724
  ],
725
+ fn=generate_video_example,
726
+ inputs=[input_image, prompt],
727
+ outputs = [output_video],
728
  label="Example",
729
  cache_examples=True,
730
  )