Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -637,27 +637,53 @@ class PromptBox(gr.HTML):
|
|
| 637 |
|
| 638 |
class CameraDropdown(gr.HTML):
|
| 639 |
"""
|
| 640 |
-
Custom dropdown (More-style).
|
| 641 |
-
Outputs: selected option string, e.g. "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 642 |
"""
|
| 643 |
-
def __init__(self, choices, value="None", title="
|
| 644 |
if not choices:
|
| 645 |
raise ValueError("CameraDropdown requires choices.")
|
| 646 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 647 |
uid = uuid.uuid4().hex[:8]
|
| 648 |
-
safe_choices = [str(c) for c in choices]
|
| 649 |
|
| 650 |
-
|
| 651 |
-
|
| 652 |
-
|
| 653 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 654 |
|
| 655 |
html_template = f"""
|
| 656 |
<div class="cd-wrap" data-cd="{uid}">
|
| 657 |
-
|
| 658 |
-
|
| 659 |
-
|
| 660 |
-
|
|
|
|
| 661 |
|
| 662 |
<div class="cd-menu" role="menu" aria-hidden="true">
|
| 663 |
<div class="cd-title">{title}</div>
|
|
@@ -668,94 +694,108 @@ class CameraDropdown(gr.HTML):
|
|
| 668 |
</div>
|
| 669 |
"""
|
| 670 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 671 |
js_on_load = r"""
|
| 672 |
(() => {
|
| 673 |
-
|
| 674 |
-
|
| 675 |
-
|
| 676 |
-
|
| 677 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 678 |
|
| 679 |
-
if (!wrap || !trigger || !menu || !items.length) return;
|
| 680 |
|
| 681 |
-
|
| 682 |
menu.classList.remove("open");
|
| 683 |
trigger.setAttribute("aria-expanded", "false");
|
| 684 |
menu.setAttribute("aria-hidden", "true");
|
| 685 |
-
|
| 686 |
|
| 687 |
-
|
| 688 |
menu.classList.add("open");
|
| 689 |
trigger.setAttribute("aria-expanded", "true");
|
| 690 |
menu.setAttribute("aria-hidden", "false");
|
| 691 |
-
|
| 692 |
|
| 693 |
-
|
| 694 |
-
|
| 695 |
-
|
| 696 |
-
|
| 697 |
-
|
| 698 |
-
|
| 699 |
-
|
| 700 |
-
|
| 701 |
-
|
| 702 |
-
|
| 703 |
-
if (shouldTrigger) trigger("change", props.value);
|
| 704 |
-
}
|
| 705 |
|
| 706 |
-
|
| 707 |
-
|
| 708 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 709 |
e.stopPropagation();
|
| 710 |
if (menu.classList.contains("open")) closeMenu();
|
| 711 |
else openMenu();
|
| 712 |
-
|
| 713 |
|
| 714 |
-
|
| 715 |
-
document.addEventListener("pointerdown", (e) => {
|
| 716 |
if (!wrap.contains(e.target)) closeMenu();
|
| 717 |
-
|
| 718 |
|
| 719 |
-
|
| 720 |
-
document.addEventListener("keydown", (e) => {
|
| 721 |
if (e.key === "Escape") closeMenu();
|
| 722 |
-
|
| 723 |
|
| 724 |
-
|
| 725 |
-
wrap.addEventListener("focusout", (e) => {
|
| 726 |
-
// if the newly-focused element isn't inside wrap, close
|
| 727 |
if (!wrap.contains(e.relatedTarget)) closeMenu();
|
| 728 |
-
|
| 729 |
|
| 730 |
-
|
| 731 |
-
items.forEach((btn) => {
|
| 732 |
btn.addEventListener("pointerdown", (e) => {
|
| 733 |
-
|
| 734 |
-
|
| 735 |
-
|
| 736 |
-
|
| 737 |
-
closeMenu();
|
| 738 |
-
setValue(btn.dataset.value, true);
|
| 739 |
});
|
| 740 |
-
|
| 741 |
|
| 742 |
-
|
| 743 |
-
|
| 744 |
|
| 745 |
-
|
| 746 |
-
|
| 747 |
-
|
| 748 |
if (props.value !== last) {
|
| 749 |
-
|
| 750 |
-
|
| 751 |
}
|
| 752 |
requestAnimationFrame(syncFromProps);
|
| 753 |
-
|
| 754 |
-
|
| 755 |
})();
|
| 756 |
-
|
| 757 |
"""
|
| 758 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 759 |
super().__init__(
|
| 760 |
value=value,
|
| 761 |
html_template=html_template,
|
|
@@ -763,47 +803,7 @@ class CameraDropdown(gr.HTML):
|
|
| 763 |
**kwargs
|
| 764 |
)
|
| 765 |
|
| 766 |
-
|
| 767 |
-
def generate_video_example(input_image, prompt, camera_lora, resolution, progress=gr.Progress(track_tqdm=True)):
|
| 768 |
-
|
| 769 |
-
w, h = apply_resolution(resolution)
|
| 770 |
-
|
| 771 |
-
output_video = generate_video(
|
| 772 |
-
input_image,
|
| 773 |
-
prompt,
|
| 774 |
-
10, # duration seconds
|
| 775 |
-
True, # enhance_prompt
|
| 776 |
-
42, # seed
|
| 777 |
-
True, # randomize_seed
|
| 778 |
-
h, # height
|
| 779 |
-
w, # width
|
| 780 |
-
camera_lora,
|
| 781 |
-
None,
|
| 782 |
-
progress
|
| 783 |
-
)
|
| 784 |
-
|
| 785 |
-
return output_video
|
| 786 |
-
|
| 787 |
-
def generate_video_example_t2v(prompt, camera_lora, resolution, progress=gr.Progress(track_tqdm=True)):
|
| 788 |
-
|
| 789 |
-
w, h = apply_resolution(resolution)
|
| 790 |
-
|
| 791 |
-
output_video = generate_video(
|
| 792 |
-
None,
|
| 793 |
-
prompt,
|
| 794 |
-
15, # duration seconds
|
| 795 |
-
True, # enhance_prompt
|
| 796 |
-
42, # seed
|
| 797 |
-
True, # randomize_seed
|
| 798 |
-
h, # height
|
| 799 |
-
w, # width
|
| 800 |
-
camera_lora,
|
| 801 |
-
None,
|
| 802 |
-
progress
|
| 803 |
-
)
|
| 804 |
-
return output_video
|
| 805 |
-
|
| 806 |
-
def generate_video_example_s2v(input_image, prompt, camera_lora, resolution, audio_path, progress=gr.Progress(track_tqdm=True)):
|
| 807 |
|
| 808 |
w, h = apply_resolution(resolution)
|
| 809 |
|
|
@@ -1123,6 +1123,23 @@ css = """
|
|
| 1123 |
}
|
| 1124 |
"""
|
| 1125 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1126 |
css += """
|
| 1127 |
/* ---- radioanimated ---- */
|
| 1128 |
.ra-wrap{
|
|
@@ -1170,6 +1187,18 @@ css += """
|
|
| 1170 |
}
|
| 1171 |
"""
|
| 1172 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1173 |
css += """
|
| 1174 |
/* --- prompt box --- */
|
| 1175 |
.ds-prompt{
|
|
@@ -1371,6 +1400,26 @@ css += """
|
|
| 1371 |
|
| 1372 |
"""
|
| 1373 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1374 |
|
| 1375 |
|
| 1376 |
with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
@@ -1465,12 +1514,30 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 1465 |
visible=False
|
| 1466 |
)
|
| 1467 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1468 |
radioanimated_resolution = CameraDropdown(
|
| 1469 |
-
choices=[
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1470 |
value="16:9",
|
| 1471 |
title="Resolution",
|
| 1472 |
elem_id="radioanimated_resolution"
|
| 1473 |
)
|
|
|
|
| 1474 |
|
| 1475 |
width = gr.Number(label="Width", value=DEFAULT_1_STAGE_WIDTH, precision=0, visible=False)
|
| 1476 |
height = gr.Number(label="Height", value=DEFAULT_1_STAGE_HEIGHT, precision=0, visible=False)
|
|
@@ -1492,28 +1559,6 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 1492 |
|
| 1493 |
generate_btn = gr.Button("🤩 Generate Video", variant="primary", elem_classes="button-gradient")
|
| 1494 |
|
| 1495 |
-
# with gr.Sidebar(width=280):
|
| 1496 |
-
# gr.Examples(
|
| 1497 |
-
# examples=[
|
| 1498 |
-
# [
|
| 1499 |
-
# "The video opens on a cake. A knife, held by a hand, is coming into frame and hovering over the cake. The knife then begins cutting into the cake to c4k3 cakeify it. As the knife slices the cake open, the inside of the cake is revealed to be cake with chocolate layers. The knife cuts through and the contents of the cake are revealed. Greek music playing in the background.",
|
| 1500 |
-
# "Cakify",
|
| 1501 |
-
# ],
|
| 1502 |
-
|
| 1503 |
-
# [
|
| 1504 |
-
# "The video showcases an item. The camera zooms out. Then infl4t3 inflates it, the item expanding into giant, inflated balloon against the landscape.",
|
| 1505 |
-
# "Inflate",
|
| 1506 |
-
# ],
|
| 1507 |
-
|
| 1508 |
-
# [
|
| 1509 |
-
# "The video begins with an item. A hydraulic press positioned above slowly descends towards the item. Upon contact, the hydraulic press c5us4 crushes it, deforming and flattening the item, causing the item to collapse inward until the item is no longer recognizable.",
|
| 1510 |
-
# "Hydraulic",
|
| 1511 |
-
# ],
|
| 1512 |
-
# ],
|
| 1513 |
-
# inputs=[prompt_ui, camera_lora_ui],
|
| 1514 |
-
# label="Example",
|
| 1515 |
-
# cache_examples=False,
|
| 1516 |
-
# )
|
| 1517 |
camera_lora_ui.change(
|
| 1518 |
fn=lambda x: x,
|
| 1519 |
inputs=camera_lora_ui,
|
|
@@ -1558,35 +1603,9 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 1558 |
outputs=[output_video]
|
| 1559 |
)
|
| 1560 |
|
| 1561 |
-
|
| 1562 |
-
|
| 1563 |
-
timestep_prompt = """Style: Realistic live-action, cinematic, shallow depth of field, 24 fps, natural and dramatic lighting
|
| 1564 |
-
|
| 1565 |
-
Environment: Interior of a space station module or realistic mock-up, metal panels, blinking lights, Earth visible through a large window
|
| 1566 |
-
|
| 1567 |
-
Character:
|
| 1568 |
-
|
| 1569 |
-
Woman: mid-30s, athletic build, wearing authentic-style futuristic space suit (real materials, fabric details, visible patches); calm, confident, precise movements; hair tucked or braided; expressive eyes visible through visor, reflecting focus and awe
|
| 1570 |
-
|
| 1571 |
-
Timestamps & action sequence:
|
| 1572 |
-
|
| 1573 |
-
0:00–0:05 — Close-up on her face through visor; soft reflections of Earth and panels in her eyes; she adjusts her gloves and glances around, calm and focused.
|
| 1574 |
-
|
| 1575 |
-
0:05–0:10 — Medium shot; she moves to the large window, gazes out as the sun begins to rise over Earth’s horizon; her expression shifts slightly, squinting at the bright sunlight.
|
| 1576 |
-
|
| 1577 |
-
0:10–0:15 — Close-up on her face; she squints, shading her eyes with a gloved hand, mutters with dry humor: “Damn thing is blinding.” Camera captures Earth glowing in the background with cinematic lens flare across the window edge.
|
| 1578 |
-
|
| 1579 |
-
Audio:
|
| 1580 |
-
|
| 1581 |
-
Woman: calm, soft-spoken, slight dry humor, low tone
|
| 1582 |
-
|
| 1583 |
-
Environment: soft hum of space station, faint beeps from panels
|
| 1584 |
-
|
| 1585 |
-
Music: subtle cinematic synth or ambient pad, futuristic and minimal, emphasizing awe and solitude"""
|
| 1586 |
-
|
| 1587 |
gr.Examples(
|
| 1588 |
examples=[
|
| 1589 |
-
|
| 1590 |
[
|
| 1591 |
"supergirl-2.png",
|
| 1592 |
"A fuzzy puppet superhero character resembling a female puppet with blonde hair and a blue superhero suit sleeping in bed and just waking up, she gradually gets up, rubbing her eyes and looking at her dog that just popped on the bed. 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",
|
|
@@ -1594,79 +1613,39 @@ with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
| 1594 |
"16:9",
|
| 1595 |
"supergirl.m4a"
|
| 1596 |
],
|
| 1597 |
-
|
| 1598 |
-
],
|
| 1599 |
-
fn=generate_video_example_s2v,
|
| 1600 |
-
inputs=[input_image, prompt_ui, camera_lora_ui, radioanimated_resolution, audio_input],
|
| 1601 |
-
outputs = [output_video],
|
| 1602 |
-
label="S2V Example",
|
| 1603 |
-
cache_examples=True,
|
| 1604 |
-
)
|
| 1605 |
-
|
| 1606 |
-
gr.Examples(
|
| 1607 |
-
examples=[
|
| 1608 |
-
|
| 1609 |
-
[
|
| 1610 |
-
timestep_prompt,
|
| 1611 |
-
"No LoRA",
|
| 1612 |
-
"16:9",
|
| 1613 |
-
],
|
| 1614 |
-
|
| 1615 |
-
],
|
| 1616 |
-
fn=generate_video_example_t2v,
|
| 1617 |
-
inputs=[prompt_ui, camera_lora_ui, radioanimated_resolution],
|
| 1618 |
-
outputs = [output_video],
|
| 1619 |
-
label="T2V Example",
|
| 1620 |
-
cache_examples=True,
|
| 1621 |
-
)
|
| 1622 |
-
|
| 1623 |
-
|
| 1624 |
-
# Add example
|
| 1625 |
-
gr.Examples(
|
| 1626 |
-
examples=[
|
| 1627 |
[
|
| 1628 |
"supergirl.png",
|
| 1629 |
"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",
|
| 1630 |
-
"
|
| 1631 |
"16:9",
|
|
|
|
| 1632 |
],
|
| 1633 |
[
|
| 1634 |
"highland.png",
|
| 1635 |
"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.",
|
| 1636 |
"No LoRA",
|
| 1637 |
"16:9",
|
|
|
|
| 1638 |
],
|
| 1639 |
[
|
| 1640 |
"wednesday.png",
|
| 1641 |
"A cinematic dolly out 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.",
|
| 1642 |
"Zoom Out",
|
| 1643 |
"16:9",
|
|
|
|
| 1644 |
],
|
| 1645 |
[
|
| 1646 |
"astronaut.png",
|
| 1647 |
"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.",
|
| 1648 |
"Static",
|
| 1649 |
"1:1",
|
|
|
|
| 1650 |
],
|
| 1651 |
-
|
| 1652 |
-
# "astronaut.png",
|
| 1653 |
-
# "The video opens on object. A knife, held by a hand, is coming into frame and hovering over the object. The knife then begins cutting into the object to c4k3 cakeify them. As the knife slices the object open, the insides of the object are revealed to be cakes with chocolate layers. The knife cuts through and the contents of object are revealed.",
|
| 1654 |
-
# "Cakify",
|
| 1655 |
-
# ],
|
| 1656 |
-
# [
|
| 1657 |
-
# "astronaut.png",
|
| 1658 |
-
# "The video showcases an item. The camera zooms out. Then infl4t3 inflates it, the item expanding into giant, inflated balloon against the landscape.",
|
| 1659 |
-
# "Inflate",
|
| 1660 |
-
# ],
|
| 1661 |
-
# [
|
| 1662 |
-
# "astronaut.png",
|
| 1663 |
-
# "The video begins with an item. A hydraulic press positioned above slowly descends towards the item. Upon contact, the hydraulic press c5us4 crushes it, deforming and flattening the item, causing the item to collapse inward until the item is no longer recognizable.",
|
| 1664 |
-
# "Hydraulic",
|
| 1665 |
-
# ],
|
| 1666 |
|
| 1667 |
],
|
| 1668 |
fn=generate_video_example,
|
| 1669 |
-
inputs=[input_image, prompt_ui, camera_lora_ui, radioanimated_resolution],
|
| 1670 |
outputs = [output_video],
|
| 1671 |
label="I2V Examples",
|
| 1672 |
cache_examples=True,
|
|
|
|
| 637 |
|
| 638 |
class CameraDropdown(gr.HTML):
|
| 639 |
"""
|
| 640 |
+
Custom dropdown (More-style) with optional icons per item.
|
| 641 |
+
Outputs: selected option string, e.g. "16:9"
|
| 642 |
+
|
| 643 |
+
choices can be:
|
| 644 |
+
- ["16:9", "1:1", "9:16"] (text only)
|
| 645 |
+
- [{"label":"16:9","value":"16:9","icon":"…"}, ...] (icon+text)
|
| 646 |
+
|
| 647 |
+
icon can be emoji or inline SVG/HTML.
|
| 648 |
"""
|
| 649 |
+
def __init__(self, choices, value="None", title="Dropdown", **kwargs):
|
| 650 |
if not choices:
|
| 651 |
raise ValueError("CameraDropdown requires choices.")
|
| 652 |
|
| 653 |
+
# Normalize choices -> list of dicts: {label, value, icon(optional)}
|
| 654 |
+
norm = []
|
| 655 |
+
for c in choices:
|
| 656 |
+
if isinstance(c, dict):
|
| 657 |
+
label = str(c.get("label", c.get("value", "")))
|
| 658 |
+
val = str(c.get("value", label))
|
| 659 |
+
icon = c.get("icon", None) # emoji or svg/html
|
| 660 |
+
norm.append({"label": label, "value": val, "icon": icon})
|
| 661 |
+
else:
|
| 662 |
+
s = str(c)
|
| 663 |
+
norm.append({"label": s, "value": s, "icon": None})
|
| 664 |
+
|
| 665 |
uid = uuid.uuid4().hex[:8]
|
|
|
|
| 666 |
|
| 667 |
+
def render_item(item):
|
| 668 |
+
icon_html = ""
|
| 669 |
+
if item["icon"]:
|
| 670 |
+
icon_html = f'<span class="cd-icn">{item["icon"]}</span>'
|
| 671 |
+
return (
|
| 672 |
+
f'<button type="button" class="cd-item" '
|
| 673 |
+
f'data-value="{item["value"]}">'
|
| 674 |
+
f'{icon_html}<span class="cd-label">{item["label"]}</span>'
|
| 675 |
+
f'</button>'
|
| 676 |
+
)
|
| 677 |
+
|
| 678 |
+
items_html = "\n".join(render_item(item) for item in norm)
|
| 679 |
|
| 680 |
html_template = f"""
|
| 681 |
<div class="cd-wrap" data-cd="{uid}">
|
| 682 |
+
<button type="button" class="cd-trigger" aria-haspopup="menu" aria-expanded="false">
|
| 683 |
+
<span class="cd-trigger-icon"></span>
|
| 684 |
+
<span class="cd-trigger-text"></span>
|
| 685 |
+
<span class="cd-caret">▾</span>
|
| 686 |
+
</button>
|
| 687 |
|
| 688 |
<div class="cd-menu" role="menu" aria-hidden="true">
|
| 689 |
<div class="cd-title">{title}</div>
|
|
|
|
| 694 |
</div>
|
| 695 |
"""
|
| 696 |
|
| 697 |
+
# Pass a mapping value->label so the trigger can show label text
|
| 698 |
+
# (and still output value to Python)
|
| 699 |
+
value_to_label = {it["value"]: it["label"] for it in norm}
|
| 700 |
+
value_to_icon = {it["value"]: (it["icon"] or "") for it in norm}
|
| 701 |
+
|
| 702 |
js_on_load = r"""
|
| 703 |
(() => {
|
| 704 |
+
const wrap = element.querySelector(".cd-wrap");
|
| 705 |
+
const trigger = element.querySelector(".cd-trigger");
|
| 706 |
+
const triggerIcon = element.querySelector(".cd-trigger-icon");
|
| 707 |
+
const triggerText = element.querySelector(".cd-trigger-text");
|
| 708 |
+
const menu = element.querySelector(".cd-menu");
|
| 709 |
+
const items = Array.from(element.querySelectorAll(".cd-item"));
|
| 710 |
+
if (!wrap || !trigger || !menu || !items.length) return;
|
| 711 |
+
|
| 712 |
+
const valueToLabel = __VALUE_TO_LABEL__;
|
| 713 |
+
const valueToIcon = __VALUE_TO_ICON__;
|
| 714 |
+
|
| 715 |
+
const safeLabel = (v) => (valueToLabel && valueToLabel[v]) ? valueToLabel[v] : (v ?? "None");
|
| 716 |
+
const safeIcon = (v) => (valueToIcon && valueToIcon[v]) ? valueToIcon[v] : "";
|
| 717 |
|
|
|
|
| 718 |
|
| 719 |
+
function closeMenu() {
|
| 720 |
menu.classList.remove("open");
|
| 721 |
trigger.setAttribute("aria-expanded", "false");
|
| 722 |
menu.setAttribute("aria-hidden", "true");
|
| 723 |
+
}
|
| 724 |
|
| 725 |
+
function openMenu() {
|
| 726 |
menu.classList.add("open");
|
| 727 |
trigger.setAttribute("aria-expanded", "true");
|
| 728 |
menu.setAttribute("aria-hidden", "false");
|
| 729 |
+
}
|
| 730 |
|
| 731 |
+
function setValue(val, shouldTrigger = false) {
|
| 732 |
+
const v = (val ?? "None");
|
| 733 |
+
props.value = v;
|
| 734 |
+
|
| 735 |
+
// Trigger shows LABEL only (icons stay in menu)
|
| 736 |
+
triggerText.textContent = safeLabel(v);
|
| 737 |
+
if (triggerIcon) {
|
| 738 |
+
triggerIcon.innerHTML = safeIcon(v);
|
| 739 |
+
triggerIcon.style.display = safeIcon(v) ? "inline-flex" : "none";
|
| 740 |
+
}
|
|
|
|
|
|
|
| 741 |
|
| 742 |
+
|
| 743 |
+
items.forEach(btn => {
|
| 744 |
+
btn.dataset.selected = (btn.dataset.value === v) ? "true" : "false";
|
| 745 |
+
});
|
| 746 |
+
|
| 747 |
+
if (shouldTrigger) trigger("change", props.value);
|
| 748 |
+
}
|
| 749 |
+
|
| 750 |
+
trigger.addEventListener("pointerdown", (e) => {
|
| 751 |
+
e.preventDefault();
|
| 752 |
e.stopPropagation();
|
| 753 |
if (menu.classList.contains("open")) closeMenu();
|
| 754 |
else openMenu();
|
| 755 |
+
});
|
| 756 |
|
| 757 |
+
document.addEventListener("pointerdown", (e) => {
|
|
|
|
| 758 |
if (!wrap.contains(e.target)) closeMenu();
|
| 759 |
+
}, true);
|
| 760 |
|
| 761 |
+
document.addEventListener("keydown", (e) => {
|
|
|
|
| 762 |
if (e.key === "Escape") closeMenu();
|
| 763 |
+
});
|
| 764 |
|
| 765 |
+
wrap.addEventListener("focusout", (e) => {
|
|
|
|
|
|
|
| 766 |
if (!wrap.contains(e.relatedTarget)) closeMenu();
|
| 767 |
+
});
|
| 768 |
|
| 769 |
+
items.forEach((btn) => {
|
|
|
|
| 770 |
btn.addEventListener("pointerdown", (e) => {
|
| 771 |
+
e.preventDefault();
|
| 772 |
+
e.stopPropagation();
|
| 773 |
+
closeMenu();
|
| 774 |
+
setValue(btn.dataset.value, true);
|
|
|
|
|
|
|
| 775 |
});
|
| 776 |
+
});
|
| 777 |
|
| 778 |
+
// init
|
| 779 |
+
setValue((props.value ?? "None"), false);
|
| 780 |
|
| 781 |
+
// sync from Python
|
| 782 |
+
let last = props.value;
|
| 783 |
+
const syncFromProps = () => {
|
| 784 |
if (props.value !== last) {
|
| 785 |
+
last = props.value;
|
| 786 |
+
setValue(last, false);
|
| 787 |
}
|
| 788 |
requestAnimationFrame(syncFromProps);
|
| 789 |
+
};
|
| 790 |
+
requestAnimationFrame(syncFromProps);
|
| 791 |
})();
|
|
|
|
| 792 |
"""
|
| 793 |
|
| 794 |
+
# Inject mapping into JS safely
|
| 795 |
+
import json
|
| 796 |
+
js_on_load = js_on_load.replace("__VALUE_TO_LABEL__", json.dumps(value_to_label))
|
| 797 |
+
js_on_load = js_on_load.replace("__VALUE_TO_ICON__", json.dumps(value_to_icon))
|
| 798 |
+
|
| 799 |
super().__init__(
|
| 800 |
value=value,
|
| 801 |
html_template=html_template,
|
|
|
|
| 803 |
**kwargs
|
| 804 |
)
|
| 805 |
|
| 806 |
+
def generate_video_example(input_image, prompt, camera_lora, resolution, audio_path = None, progress=gr.Progress(track_tqdm=True)):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 807 |
|
| 808 |
w, h = apply_resolution(resolution)
|
| 809 |
|
|
|
|
| 1123 |
}
|
| 1124 |
"""
|
| 1125 |
|
| 1126 |
+
css += """
|
| 1127 |
+
.cd-trigger-icon{
|
| 1128 |
+
color: rgba(255,255,255,0.9);
|
| 1129 |
+
display: inline-flex;
|
| 1130 |
+
align-items: center;
|
| 1131 |
+
justify-content: center;
|
| 1132 |
+
width: 18px;
|
| 1133 |
+
height: 18px;
|
| 1134 |
+
}
|
| 1135 |
+
.cd-trigger-icon svg {
|
| 1136 |
+
width: 18px;
|
| 1137 |
+
height: 18px;
|
| 1138 |
+
display: block;
|
| 1139 |
+
}
|
| 1140 |
+
"""
|
| 1141 |
+
|
| 1142 |
+
|
| 1143 |
css += """
|
| 1144 |
/* ---- radioanimated ---- */
|
| 1145 |
.ra-wrap{
|
|
|
|
| 1187 |
}
|
| 1188 |
"""
|
| 1189 |
|
| 1190 |
+
css += """
|
| 1191 |
+
.cd-icn svg{
|
| 1192 |
+
width: 18px;
|
| 1193 |
+
height: 18px;
|
| 1194 |
+
display: block;
|
| 1195 |
+
}
|
| 1196 |
+
.cd-icn svg *{
|
| 1197 |
+
stroke: rgba(255,255,255,0.9);
|
| 1198 |
+
}
|
| 1199 |
+
"""
|
| 1200 |
+
|
| 1201 |
+
|
| 1202 |
css += """
|
| 1203 |
/* --- prompt box --- */
|
| 1204 |
.ds-prompt{
|
|
|
|
| 1400 |
|
| 1401 |
"""
|
| 1402 |
|
| 1403 |
+
css += """
|
| 1404 |
+
/* icons in dropdown items */
|
| 1405 |
+
.cd-item{
|
| 1406 |
+
display: flex;
|
| 1407 |
+
align-items: center;
|
| 1408 |
+
gap: 10px;
|
| 1409 |
+
}
|
| 1410 |
+
.cd-icn{
|
| 1411 |
+
display: inline-flex;
|
| 1412 |
+
align-items: center;
|
| 1413 |
+
justify-content: center;
|
| 1414 |
+
width: 18px;
|
| 1415 |
+
height: 18px;
|
| 1416 |
+
flex: 0 0 18px;
|
| 1417 |
+
}
|
| 1418 |
+
.cd-label{
|
| 1419 |
+
flex: 1;
|
| 1420 |
+
}
|
| 1421 |
+
"""
|
| 1422 |
+
|
| 1423 |
|
| 1424 |
|
| 1425 |
with gr.Blocks(title="LTX-2 Video Distilled 🎥🔈") as demo:
|
|
|
|
| 1514 |
visible=False
|
| 1515 |
)
|
| 1516 |
|
| 1517 |
+
ICON_16_9 = """<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
| 1518 |
+
<rect x="3" y="7" width="18" height="10" rx="2" stroke="currentColor" stroke-width="2"/>
|
| 1519 |
+
</svg>"""
|
| 1520 |
+
|
| 1521 |
+
ICON_1_1 = """<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
| 1522 |
+
<rect x="6" y="6" width="12" height="12" rx="2" stroke="currentColor" stroke-width="2"/>
|
| 1523 |
+
</svg>"""
|
| 1524 |
+
|
| 1525 |
+
ICON_9_16 = """<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
| 1526 |
+
<rect x="7" y="3" width="10" height="18" rx="2" stroke="currentColor" stroke-width="2"/>
|
| 1527 |
+
</svg>"""
|
| 1528 |
+
|
| 1529 |
+
|
| 1530 |
radioanimated_resolution = CameraDropdown(
|
| 1531 |
+
choices=[
|
| 1532 |
+
{"label": "16:9", "value": "16:9", "icon": ICON_16_9},
|
| 1533 |
+
{"label": "1:1", "value": "1:1", "icon": ICON_1_1},
|
| 1534 |
+
{"label": "9:16", "value": "9:16", "icon": ICON_9_16},
|
| 1535 |
+
],
|
| 1536 |
value="16:9",
|
| 1537 |
title="Resolution",
|
| 1538 |
elem_id="radioanimated_resolution"
|
| 1539 |
)
|
| 1540 |
+
|
| 1541 |
|
| 1542 |
width = gr.Number(label="Width", value=DEFAULT_1_STAGE_WIDTH, precision=0, visible=False)
|
| 1543 |
height = gr.Number(label="Height", value=DEFAULT_1_STAGE_HEIGHT, precision=0, visible=False)
|
|
|
|
| 1559 |
|
| 1560 |
generate_btn = gr.Button("🤩 Generate Video", variant="primary", elem_classes="button-gradient")
|
| 1561 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1562 |
camera_lora_ui.change(
|
| 1563 |
fn=lambda x: x,
|
| 1564 |
inputs=camera_lora_ui,
|
|
|
|
| 1603 |
outputs=[output_video]
|
| 1604 |
)
|
| 1605 |
|
| 1606 |
+
# Add example
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1607 |
gr.Examples(
|
| 1608 |
examples=[
|
|
|
|
| 1609 |
[
|
| 1610 |
"supergirl-2.png",
|
| 1611 |
"A fuzzy puppet superhero character resembling a female puppet with blonde hair and a blue superhero suit sleeping in bed and just waking up, she gradually gets up, rubbing her eyes and looking at her dog that just popped on the bed. 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",
|
|
|
|
| 1613 |
"16:9",
|
| 1614 |
"supergirl.m4a"
|
| 1615 |
],
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1616 |
[
|
| 1617 |
"supergirl.png",
|
| 1618 |
"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",
|
| 1619 |
+
"No LoRA",
|
| 1620 |
"16:9",
|
| 1621 |
+
None,
|
| 1622 |
],
|
| 1623 |
[
|
| 1624 |
"highland.png",
|
| 1625 |
"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.",
|
| 1626 |
"No LoRA",
|
| 1627 |
"16:9",
|
| 1628 |
+
None,
|
| 1629 |
],
|
| 1630 |
[
|
| 1631 |
"wednesday.png",
|
| 1632 |
"A cinematic dolly out 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.",
|
| 1633 |
"Zoom Out",
|
| 1634 |
"16:9",
|
| 1635 |
+
None,
|
| 1636 |
],
|
| 1637 |
[
|
| 1638 |
"astronaut.png",
|
| 1639 |
"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.",
|
| 1640 |
"Static",
|
| 1641 |
"1:1",
|
| 1642 |
+
None,
|
| 1643 |
],
|
| 1644 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1645 |
|
| 1646 |
],
|
| 1647 |
fn=generate_video_example,
|
| 1648 |
+
inputs=[input_image, prompt_ui, camera_lora_ui, radioanimated_resolution, audio_input],
|
| 1649 |
outputs = [output_video],
|
| 1650 |
label="I2V Examples",
|
| 1651 |
cache_examples=True,
|