1inkusFace commited on
Commit
140a4b8
·
verified ·
1 Parent(s): 205f29e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +33 -11
app.py CHANGED
@@ -63,7 +63,7 @@ def setup_environment():
63
 
64
  setup_environment()
65
 
66
- @spaces.GPU(requires=True)
67
  def interpolate_video(input_video_path, multi_factor):
68
  if input_video_path is None: return None
69
  factor = str(multi_factor).replace("x", "").strip()
@@ -89,10 +89,20 @@ def interpolate_video(input_video_path, multi_factor):
89
  os.chdir(BASE_DIR)
90
 
91
  # --- Stitching Logic ---
92
- def stitch_videos(video_files):
93
  if not video_files: return None
94
 
95
- print(f"Stitching {len(video_files)} videos...")
 
 
 
 
 
 
 
 
 
 
96
  stitch_list_path = os.path.join(BASE_DIR, "stitch_list.txt")
97
  output_stitched = os.path.join(BASE_DIR, "final_stitched.mp4")
98
  temp_dir = os.path.join(BASE_DIR, "temp_stitch")
@@ -100,18 +110,21 @@ def stitch_videos(video_files):
100
  if os.path.exists(temp_dir): shutil.rmtree(temp_dir)
101
  os.makedirs(temp_dir)
102
 
103
- # 1. Normalize Step: Convert all inputs to same Codec, FPS (60), and Scale
104
- # This prevents the "glitch" when combining different framerates
105
  normalized_files = []
106
  for i, vid_path in enumerate(video_files):
107
  temp_filepath = os.path.join(temp_dir, f"norm_{i}.mp4")
108
  print(f"Normalizing clip {i+1}...")
109
 
110
- # We force 60fps (-r 60) and 1080p scale to ensure they match
 
 
 
 
111
  cmd = [
112
  'ffmpeg', '-i', vid_path,
113
- '-r', '60', # Force Framerate
114
- '-vf', 'scale=1920:1080:force_original_aspect_ratio=decrease,pad=1920:1080:(ow-iw)/2:(oh-ih)/2', # Fit to 1080p box
115
  '-c:v', 'libx264', '-crf', '23',
116
  '-c:a', 'aac', # Force Audio Codec
117
  '-ar', '44100', # Force Audio Rate
@@ -152,14 +165,23 @@ with gr.Blocks() as demo:
152
 
153
  # TAB 2: Stitch
154
  with gr.TabItem("2. Stitch Videos"):
155
- gr.Markdown("Upload multiple videos. They will be **normalized to 60fps 1080p** and joined together.")
156
  with gr.Row():
157
  with gr.Column():
158
- # file_count="multiple" allows selecting multiple files
159
  stitch_inputs = gr.File(label="Upload Clips", file_count="multiple")
 
 
 
 
 
 
 
 
160
  stitch_btn = gr.Button("Stitch Videos", variant="primary")
161
  with gr.Column():
162
  stitch_output = gr.Video(label="Stitched Result")
163
- stitch_btn.click(stitch_videos, inputs=stitch_inputs, outputs=stitch_output)
 
 
164
 
165
  demo.launch()
 
63
 
64
  setup_environment()
65
 
66
+ @spaces.GPU(required=True)
67
  def interpolate_video(input_video_path, multi_factor):
68
  if input_video_path is None: return None
69
  factor = str(multi_factor).replace("x", "").strip()
 
89
  os.chdir(BASE_DIR)
90
 
91
  # --- Stitching Logic ---
92
+ def stitch_videos(video_files, resolution_choice):
93
  if not video_files: return None
94
 
95
+ # Parse resolution (e.g., "1024x1024" -> w=1024, h=1024)
96
+ try:
97
+ target_w, target_h = resolution_choice.split("x")
98
+ target_w = target_w.strip()
99
+ target_h = target_h.strip()
100
+ except:
101
+ # Fallback default
102
+ target_w, target_h = "1920", "1080"
103
+
104
+ print(f"Stitching {len(video_files)} videos into {target_w}x{target_h}...")
105
+
106
  stitch_list_path = os.path.join(BASE_DIR, "stitch_list.txt")
107
  output_stitched = os.path.join(BASE_DIR, "final_stitched.mp4")
108
  temp_dir = os.path.join(BASE_DIR, "temp_stitch")
 
110
  if os.path.exists(temp_dir): shutil.rmtree(temp_dir)
111
  os.makedirs(temp_dir)
112
 
113
+ # 1. Normalize Step: Convert all inputs to same Codec, FPS (60), and User-Selected Scale
 
114
  normalized_files = []
115
  for i, vid_path in enumerate(video_files):
116
  temp_filepath = os.path.join(temp_dir, f"norm_{i}.mp4")
117
  print(f"Normalizing clip {i+1}...")
118
 
119
+ # FFmpeg Filter Breakdown:
120
+ # scale=W:H:force_original_aspect_ratio=decrease -> Resize video to FIT inside the box
121
+ # pad=W:H:(ow-iw)/2:(oh-ih)/2 -> Create the box and center the video (adding black bars)
122
+ scale_filter = f"scale={target_w}:{target_h}:force_original_aspect_ratio=decrease,pad={target_w}:{target_h}:(ow-iw)/2:(oh-ih)/2"
123
+
124
  cmd = [
125
  'ffmpeg', '-i', vid_path,
126
+ '-r', '60', # Force Framerate to 60
127
+ '-vf', scale_filter, # Apply Dynamic Scaling
128
  '-c:v', 'libx264', '-crf', '23',
129
  '-c:a', 'aac', # Force Audio Codec
130
  '-ar', '44100', # Force Audio Rate
 
165
 
166
  # TAB 2: Stitch
167
  with gr.TabItem("2. Stitch Videos"):
168
+ gr.Markdown("Upload multiple videos. They will be normalized to **60fps** and your selected resolution.")
169
  with gr.Row():
170
  with gr.Column():
 
171
  stitch_inputs = gr.File(label="Upload Clips", file_count="multiple")
172
+
173
+ # New Resolution Dropdown
174
+ res_select = gr.Dropdown(
175
+ choices=["1920x1080", "1280x1280", "1024x1024"],
176
+ value="1920x1080",
177
+ label="Output Resolution"
178
+ )
179
+
180
  stitch_btn = gr.Button("Stitch Videos", variant="primary")
181
  with gr.Column():
182
  stitch_output = gr.Video(label="Stitched Result")
183
+
184
+ # Updated click event passing the resolution choice
185
+ stitch_btn.click(stitch_videos, inputs=[stitch_inputs, res_select], outputs=stitch_output)
186
 
187
  demo.launch()