alexnasa commited on
Commit
b8bfb92
·
verified ·
1 Parent(s): 34bce41

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -52
app.py CHANGED
@@ -136,60 +136,39 @@ def combine_video_and_audio_ffmpeg(video_path, audio_path, output_video_path):
136
  raise RuntimeError(f"ffmpeg failed ({e.returncode}): {e.stderr.strip()}")
137
 
138
 
139
- def convert_video_to_30fps_and_clip(
140
- input_video_path,
141
- output_video_path,
142
- duration_s=2,
143
- target_fps=30,
144
-
145
- ):
146
- if is_portrait(input_video_path):
147
- crop_width=720
148
- crop_height=1280
149
- else:
150
- crop_width=1280
151
- crop_height=720
152
-
153
- # Get input video dimensions using ffprobe
154
- if crop_width and crop_height:
155
- probe_cmd = [
156
- 'ffprobe', '-v', 'error', '-select_streams', 'v:0',
157
- '-show_entries', 'stream=width,height',
158
- '-of', 'json', input_video_path
159
- ]
160
- probe_result = subprocess.run(probe_cmd, capture_output=True, text=True, check=True)
161
- video_info = json.loads(probe_result.stdout)
162
- w = video_info['streams'][0]['width']
163
- h = video_info['streams'][0]['height']
164
-
165
- # Clamp crop size to not exceed actual dimensions
166
- crop_width = min(crop_width, w)
167
- crop_height = min(crop_height, h)
168
-
169
- # Center crop offsets
170
- crop_x = max((w - crop_width) // 2, 0)
171
- crop_y = max((h - crop_height) // 2, 0)
172
- crop_filter = f"crop={crop_width}:{crop_height}:{crop_x}:{crop_y}"
173
- else:
174
- crop_filter = None
175
 
176
  cmd = [
177
- 'ffmpeg',
178
- '-i', input_video_path,
179
- '-r', str(target_fps),
180
- '-t', str(duration_s),
181
- ]
182
-
183
- if crop_filter:
184
- cmd += ['-vf', crop_filter]
185
-
186
- cmd += [
187
- '-c:v', 'libx264',
188
- '-c:a', 'aac',
189
- '-strict', 'experimental',
190
- '-y',
191
- '-loglevel', 'error',
192
- output_video_path
193
  ]
194
 
195
  try:
@@ -197,6 +176,7 @@ def convert_video_to_30fps_and_clip(
197
  except subprocess.CalledProcessError as e:
198
  raise RuntimeError(f"ffmpeg failed ({e.returncode}): {e.stderr.strip()}")
199
 
 
200
  def is_portrait(video_file):
201
 
202
  # Get video information
 
136
  raise RuntimeError(f"ffmpeg failed ({e.returncode}): {e.stderr.strip()}")
137
 
138
 
139
+ def convert_video_to_30fps_and_clip(input_video_path, output_video_path, duration_s=2, target_fps=30):
140
+ # Decide target box depending on orientation *as ffmpeg sees it*.
141
+ # We'll just compute both and let expressions pick the right one.
142
+ # If you truly want different targets by orientation, keep your is_portrait() and set these constants accordingly.
143
+
144
+ # Build a crop expression that:
145
+ # - never exceeds the input size
146
+ # - keeps values even (required by yuv420p)
147
+ # - stays centered
148
+ crop_w_expr = "floor(min(in_w\,1280)/2)*2"
149
+ crop_h_expr = "floor(min(in_h\,720)/2)*2"
150
+ crop_x_expr = f"floor((in_w - {crop_w_expr})/2/2)*2"
151
+ crop_y_expr = f"floor((in_h - {crop_h_expr})/2/2)*2"
152
+
153
+ vf = (
154
+ f"crop={crop_w_expr}:{crop_h_expr}:{crop_x_expr}:{crop_y_expr},"
155
+ f"fps={target_fps}"
156
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
 
158
  cmd = [
159
+ "ffmpeg",
160
+ "-nostdin",
161
+ "-hide_banner",
162
+ "-y",
163
+ "-i", input_video_path,
164
+ "-t", str(duration_s),
165
+ # Do crop and fps in one -vf so they see the same frame geometry
166
+ "-vf", vf,
167
+ # Make sure the output has even dims and a standard pix_fmt
168
+ "-pix_fmt", "yuv420p",
169
+ "-c:v", "libx264",
170
+ "-c:a", "aac",
171
+ output_video_path,
 
 
 
172
  ]
173
 
174
  try:
 
176
  except subprocess.CalledProcessError as e:
177
  raise RuntimeError(f"ffmpeg failed ({e.returncode}): {e.stderr.strip()}")
178
 
179
+
180
  def is_portrait(video_file):
181
 
182
  # Get video information