sam12345324 commited on
Commit
d7332ba
·
verified ·
1 Parent(s): 822e0d5

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +34 -11
main.py CHANGED
@@ -11,7 +11,7 @@ from moviepy.editor import (
11
  AudioFileClip,
12
  CompositeAudioClip,
13
  concatenate_audioclips,
14
- vfx, # Import vfx for looping
15
  )
16
  import io
17
  from PIL import Image
@@ -25,20 +25,37 @@ from moviepy.config import change_settings
25
  change_settings({"VERBOSE": True})
26
 
27
  # Safe video clip loader
28
- def safe_video_clip(path):
29
  try:
30
  clip = VideoFileClip(path)
31
  if clip.reader is None or clip.duration is None or clip.duration <= 0:
32
  clip.close()
33
  raise ValueError(f"Invalid or empty video file: {os.path.basename(path)}")
34
- logger.debug(f"Loaded video: {path}, duration: {clip.duration}s")
35
- # Resize without resample keyword
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  try:
37
- clip = clip.resize((1280, 720)) # Use default resampling
 
38
  except Exception as e:
39
  logger.warning(f"Failed to resize video {path}: {e}")
40
- # Continue without resizing if it fails
41
- return clip
 
42
  except Exception as e:
43
  raise ValueError(f"Failed to load video file '{os.path.basename(path)}': {str(e)}")
44
 
@@ -54,14 +71,17 @@ def safe_audio_clip(path):
54
  except Exception as e:
55
  raise ValueError(f"Failed to load audio file '{os.path.basename(path)}': {str(e)}")
56
 
57
- def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, orig_vol=1.0, music_vol=0.5, audio_mode="composite"):
58
  logger.debug(f"Merging {len(video_paths)} videos and {len(audio_paths)} audios to {output_path}")
59
 
60
  # Load video clips
61
  video_clips = []
 
62
  for vp in video_paths:
63
  try:
64
- clip = safe_video_clip(vp)
 
 
65
  video_clips.append(clip)
66
  except Exception as e:
67
  logger.warning(f"Skipping invalid video file {vp}: {e}")
@@ -81,7 +101,7 @@ def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, ori
81
 
82
  # Concatenate video clips
83
  final_video = concatenate_videoclips(video_clips, method="compose")
84
- logger.debug(f"Concatenated video duration: {final_video.duration}s")
85
 
86
  # Handle original video audio
87
  original_audio = None
@@ -103,6 +123,9 @@ def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, ori
103
  if final_audio and final_audio.duration < final_video.duration:
104
  logger.debug(f"Looping audio to match video duration: {final_video.duration}s")
105
  final_audio = final_audio.fx(vfx.loop, duration=final_video.duration)
 
 
 
106
 
107
  if original_audio:
108
  final_audio = CompositeAudioClip([final_audio, original_audio])
@@ -148,7 +171,7 @@ async def merge_endpoint(
148
  files: list[UploadFile] = File(...),
149
  orig_vol: float = Form(1.0),
150
  music_vol: float = Form(0.5),
151
- audio_mode: str = Form("composite"),
152
  background_tasks: BackgroundTasks = BackgroundTasks(),
153
  ):
154
  temp_dir = tempfile.mkdtemp()
 
11
  AudioFileClip,
12
  CompositeAudioClip,
13
  concatenate_audioclips,
14
+ vfx,
15
  )
16
  import io
17
  from PIL import Image
 
25
  change_settings({"VERBOSE": True})
26
 
27
  # Safe video clip loader
28
+ def safe_video_clip(path, target_width=1280, reference_aspect_ratio=None):
29
  try:
30
  clip = VideoFileClip(path)
31
  if clip.reader is None or clip.duration is None or clip.duration <= 0:
32
  clip.close()
33
  raise ValueError(f"Invalid or empty video file: {os.path.basename(path)}")
34
+ logger.debug(f"Loaded video: {path}, duration: {clip.duration}s, resolution: {clip.size}, aspect ratio: {clip.w / clip.h}")
35
+
36
+ # Get video aspect ratio
37
+ current_aspect_ratio = clip.w / clip.h
38
+
39
+ # Use reference aspect ratio if provided, else use current video's aspect ratio
40
+ target_aspect_ratio = reference_aspect_ratio if reference_aspect_ratio else current_aspect_ratio
41
+
42
+ # Check if aspect ratios are compatible (within a small tolerance)
43
+ if reference_aspect_ratio and abs(current_aspect_ratio - target_aspect_ratio) > 0.05:
44
+ logger.warning(f"Video {path} has different aspect ratio ({current_aspect_ratio:.2f}) than reference ({target_aspect_ratio:.2f}). Adjusting to match.")
45
+
46
+ # Calculate target resolution to preserve aspect ratio
47
+ target_height = int(target_width / target_aspect_ratio)
48
+ # Ensure height is even (required by libx264 codec)
49
+ target_height = target_height if target_height % 2 == 0 else target_height + 1
50
+
51
  try:
52
+ clip = clip.resize((target_width, target_height))
53
+ logger.debug(f"Resized video {path} to {target_width}x{target_height}, aspect ratio: {target_width / target_height}")
54
  except Exception as e:
55
  logger.warning(f"Failed to resize video {path}: {e}")
56
+ # Continue without resizing if it fails (may cause concatenation issues)
57
+
58
+ return clip, target_aspect_ratio
59
  except Exception as e:
60
  raise ValueError(f"Failed to load video file '{os.path.basename(path)}': {str(e)}")
61
 
 
71
  except Exception as e:
72
  raise ValueError(f"Failed to load audio file '{os.path.basename(path)}': {str(e)}")
73
 
74
+ def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, orig_vol=1.0, music_vol=0.5, audio_mode="concatenate"):
75
  logger.debug(f"Merging {len(video_paths)} videos and {len(audio_paths)} audios to {output_path}")
76
 
77
  # Load video clips
78
  video_clips = []
79
+ reference_aspect_ratio = None
80
  for vp in video_paths:
81
  try:
82
+ clip, aspect_ratio = safe_video_clip(vp, reference_aspect_ratio=reference_aspect_ratio)
83
+ if reference_aspect_ratio is None:
84
+ reference_aspect_ratio = aspect_ratio # Set reference from first valid video
85
  video_clips.append(clip)
86
  except Exception as e:
87
  logger.warning(f"Skipping invalid video file {vp}: {e}")
 
101
 
102
  # Concatenate video clips
103
  final_video = concatenate_videoclips(video_clips, method="compose")
104
+ logger.debug(f"Concatenated video duration: {final_video.duration}s, resolution: {final_video.size}")
105
 
106
  # Handle original video audio
107
  original_audio = None
 
123
  if final_audio and final_audio.duration < final_video.duration:
124
  logger.debug(f"Looping audio to match video duration: {final_video.duration}s")
125
  final_audio = final_audio.fx(vfx.loop, duration=final_video.duration)
126
+ elif final_audio and final_audio.duration > final_video.duration:
127
+ logger.debug(f"Trimming audio to match video duration: {final_video.duration}s")
128
+ final_audio = final_audio.subclip(0, final_video.duration)
129
 
130
  if original_audio:
131
  final_audio = CompositeAudioClip([final_audio, original_audio])
 
171
  files: list[UploadFile] = File(...),
172
  orig_vol: float = Form(1.0),
173
  music_vol: float = Form(0.5),
174
+ audio_mode: str = Form("concatenate"),
175
  background_tasks: BackgroundTasks = BackgroundTasks(),
176
  ):
177
  temp_dir = tempfile.mkdtemp()