problaze28 commited on
Commit
bb5707e
·
verified ·
1 Parent(s): f4249f7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -0
app.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import os
3
+ import time
4
+ import gradio as gr
5
+ from typing import Dict, Any, Tuple
6
+
7
+ # Sample prompt templates based on joeygambino/MiniMax-H3-Multishot-Workflow rules
8
+ DEFAULT_SHOTS = """[Shot 1] A detective in a dark trenchcoat walks down a dimly lit, rain-slicked alleyway in Neo-Tokyo. Neon signs reflect off the wet asphalt.
9
+ ---
10
+ [Shot 2] The detective stops under a blue neon bar sign, reaches into his coat pocket, and pulls out a brass lighter.
11
+ ---
12
+ [Shot 3] He flicks the lighter open. The flame briefly illuminates his sharp jawline and worn facial expression before a loud thunder crack echoes in the background."""
13
+
14
+ def parse_shot_script(script_text: str) -> list[str]:
15
+ """Splits multi-shot prompt scripts delimited by '---'."""
16
+ shots = [shot.strip() for shot in script_text.split("---") if shot.strip()]
17
+ return shots if shots else ["A cinematic scene with continuous motion."]
18
+
19
+ def generate_multishot_video(
20
+ prompts: str,
21
+ resolution: str = "1280x736",
22
+ continuity_mode: str = "first_frame",
23
+ take_seconds: int = 15,
24
+ fps: int = 24,
25
+ steps: int = 30,
26
+ ) -> Tuple[str, str, Dict[str, Any]]:
27
+ """
28
+ Main function for multi-shot video generation.
29
+ Exposed as an agent-callable API via Gradio.
30
+ """
31
+ shots = parse_shot_script(prompts)
32
+ width, height = map(int, resolution.split("x"))
33
+
34
+ # Payload structured according to MiniMax-H3-Multishot node spec
35
+ pipeline_payload = {
36
+ "workflow_version": "2.7.0",
37
+ "shots_count": len(shots),
38
+ "shots": shots,
39
+ "master_controls": {
40
+ "width": width,
41
+ "height": height,
42
+ "fps": fps,
43
+ "steps": steps,
44
+ "take_seconds": take_seconds,
45
+ "continuity": continuity_mode,
46
+ }
47
+ }
48
+
49
+ # Simulated execution pipeline (connects to backend GPU ComfyUI instance/Inference Endpoint)
50
+ time.sleep(2) # Pipeline latency placeholder
51
+
52
+ # Summary response
53
+ execution_summary = {
54
+ "status": "success",
55
+ "processed_shots": len(shots),
56
+ "total_duration_sec": take_seconds,
57
+ "resolution": resolution,
58
+ "continuity_applied": continuity_mode,
59
+ "payload": pipeline_payload
60
+ }
61
+
62
+ # Dummy video path output for demo structure
63
+ output_video = None # Replace with actual output file path when backend runner is attached
64
+ audio_track = None
65
+
66
+ return output_video, audio_track, execution_summary
67
+
68
+
69
+ # Gradio UI Design
70
+ with gr.Blocks(title="MiniMax-H3 Multi-Shot Studio", theme=gr.themes.Soft()) as demo:
71
+ gr.Markdown(
72
+ """
73
+ # 🎬 MiniMax-H3 Seamless Multi-Shot Studio
74
+ Create continuous, multi-shot video takes with unified audio and character continuity using the **MiniMax-H3-Multishot** workflow.
75
+ """
76
+ )
77
+
78
+ with gr.Row():
79
+ with gr.Column(scale=2):
80
+ prompts_input = gr.Textbox(
81
+ label="Multi-Shot Script (Separate shots with '---')",
82
+ value=DEFAULT_SHOTS,
83
+ lines=10,
84
+ placeholder="Write Shot 1...\n---\nWrite Shot 2...",
85
+ )
86
+
87
+ with gr.Accordion("⚙️ Master Controls & Parameters", open=True):
88
+ with gr.Row():
89
+ resolution_dropdown = gr.Dropdown(
90
+ choices=["1280x736", "1024x576", "768x512"],
91
+ value="1280x736",
92
+ label="Resolution"
93
+ )
94
+ continuity_radio = gr.Radio(
95
+ choices=["first_frame", "context_pin"],
96
+ value="first_frame",
97
+ label="Continuity Mode",
98
+ info="first_frame = zero extra deps | context_pin = latent memory alignment"
99
+ )
100
+
101
+ with gr.Row():
102
+ take_sec_slider = gr.Slider(
103
+ minimum=5, maximum=60, value=15, step=5, label="Take Duration (Seconds)"
104
+ )
105
+ steps_slider = gr.Slider(
106
+ minimum=15, maximum=50, value=30, step=1, label="Sampling Steps"
107
+ )
108
+
109
+ generate_btn = gr.Button("🚀 Generate Multi-Shot Take", variant="primary")
110
+
111
+ with gr.Column(scale=2):
112
+ video_output = gr.Video(label="Generated Master Video")
113
+ audio_output = gr.Audio(label="Master Audio Track")
114
+ status_json = gr.JSON(label="Pipeline Execution & Agent Metadata")
115
+
116
+ # Wire up the Gradio button action & API endpoint
117
+ generate_btn.click(
118
+ fn=generate_multishot_video,
119
+ inputs=[
120
+ prompts_input,
121
+ resolution_dropdown,
122
+ continuity_radio,
123
+ take_sec_slider,
124
+ steps_slider
125
+ ],
126
+ outputs=[video_output, audio_output, status_json],
127
+ api_name="generate_multishot_video" # Exposed for AI Agents
128
+ )
129
+
130
+ gr.Markdown(
131
+ """
132
+ ---
133
+ ### 🤖 For AI Agents
134
+ Access the automated `/agents.md` endpoint of this Space or query `/info` to retrieve JSON signatures.
135
+ """
136
+ )
137
+
138
+ if __name__ == "__main__":
139
+ demo.launch()