sam12345324 commited on
Commit
c0b7fb8
·
verified ·
1 Parent(s): 9485fa5

Update main.py

Browse files
Files changed (1) hide show
  1. main.py +18 -22
main.py CHANGED
@@ -13,6 +13,7 @@ from moviepy.editor import (
13
  concatenate_audioclips,
14
  )
15
  import io
 
16
 
17
  # Configure logging
18
  logging.basicConfig(level=logging.DEBUG)
@@ -30,6 +31,12 @@ def safe_video_clip(path):
30
  clip.close()
31
  raise ValueError(f"Invalid or empty video file: {os.path.basename(path)}")
32
  logger.debug(f"Loaded video: {path}, duration: {clip.duration}s")
 
 
 
 
 
 
33
  return clip
34
  except Exception as e:
35
  raise ValueError(f"Failed to load video file '{os.path.basename(path)}': {str(e)}")
@@ -54,8 +61,6 @@ def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, ori
54
  for vp in video_paths:
55
  try:
56
  clip = safe_video_clip(vp)
57
- # Resize to a common resolution (e.g., 1280x720) for compatibility
58
- clip = clip.resize((1280, 720))
59
  video_clips.append(clip)
60
  except Exception as e:
61
  logger.warning(f"Skipping invalid video file {vp}: {e}")
@@ -68,7 +73,7 @@ def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, ori
68
  for ap in audio_paths:
69
  try:
70
  clip = safe_audio_clip(ap)
71
- clip = clip.volumex(music_vol) # Apply volume adjustment
72
  audio_clips.append(clip)
73
  except Exception as e:
74
  logger.warning(f"Skipping invalid audio file {ap}: {e}")
@@ -87,13 +92,17 @@ def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, ori
87
  final_audio = None
88
  if audio_clips:
89
  if audio_mode == "concatenate":
90
- final_audio = concatenate_audioclips(audio_clips) # Play audios sequentially
91
  logger.debug(f"Concatenated audio duration: {final_audio.duration}s")
92
  else:
93
- final_audio = CompositeAudioClip(audio_clips) # Play audios simultaneously
94
  logger.debug(f"Composite audio duration: {final_audio.duration}s")
95
 
96
- # If original audio exists, combine it with uploaded audio
 
 
 
 
97
  if original_audio:
98
  final_audio = CompositeAudioClip([final_audio, original_audio])
99
  logger.debug(f"Combined audio (original + uploaded) duration: {final_audio.duration}s")
@@ -122,7 +131,7 @@ def merge_videos_and_audios(video_paths, audio_paths, output_path, temp_dir, ori
122
  logger.error(f"MoviePy failed to write output: {str(e)}")
123
  raise
124
 
125
- # Close clips to release resources
126
  final_video.close()
127
  for vc in video_clips:
128
  vc.close()
@@ -138,7 +147,7 @@ async def merge_endpoint(
138
  files: list[UploadFile] = File(...),
139
  orig_vol: float = Form(1.0),
140
  music_vol: float = Form(0.5),
141
- audio_mode: str = Form("composite"), # New parameter: "composite" or "concatenate"
142
  background_tasks: BackgroundTasks = BackgroundTasks(),
143
  ):
144
  temp_dir = tempfile.mkdtemp()
@@ -146,8 +155,6 @@ async def merge_endpoint(
146
 
147
  try:
148
  saved_files = []
149
-
150
- # Save uploaded files
151
  for uploaded_file in files:
152
  if not uploaded_file.filename:
153
  logger.warning("Skipping file with no filename")
@@ -162,29 +169,21 @@ async def merge_endpoint(
162
  saved_files.append(file_path)
163
  logger.debug(f"Saved file: {file_path}")
164
 
165
- # Separate video and audio files
166
  video_files = [f for f in saved_files if f.lower().endswith(".mp4")]
167
- audio_files = [
168
- f for f in saved_files if f.lower().endswith((".mp3", ".wav", ".aac", ".m4a", ".ogg"))
169
- ]
170
  logger.debug(f"Video files: {video_files}")
171
  logger.debug(f"Audio files: {audio_files}")
172
 
173
  if len(video_files) < 1:
174
  raise HTTPException(status_code=400, detail="Please upload at least one valid video file")
175
 
176
- # Prepare output path
177
  output_path = os.path.join(temp_dir, "merged_output.mp4")
178
-
179
- # Merge videos and audios
180
  merge_videos_and_audios(video_files, audio_files, output_path, temp_dir, orig_vol, music_vol, audio_mode)
181
 
182
- # Verify the output file exists
183
  if not os.path.exists(output_path):
184
  logger.error(f"Output file not found: {output_path}")
185
  raise HTTPException(status_code=500, detail="Failed to create merged video file")
186
 
187
- # Read the file into memory
188
  logger.debug(f"Reading output file: {output_path}")
189
  with open(output_path, "rb") as file:
190
  content = file.read()
@@ -192,10 +191,7 @@ async def merge_endpoint(
192
  logger.error(f"Output file is empty: {output_path}")
193
  raise HTTPException(status_code=500, detail="Output file is empty")
194
 
195
- # Schedule cleanup
196
  background_tasks.add_task(shutil.rmtree, temp_dir, ignore_errors=True)
197
-
198
- # Return the file
199
  logger.debug("Sending streaming response")
200
  return StreamingResponse(
201
  io.BytesIO(content),
 
13
  concatenate_audioclips,
14
  )
15
  import io
16
+ from PIL import Image
17
 
18
  # Configure logging
19
  logging.basicConfig(level=logging.DEBUG)
 
31
  clip.close()
32
  raise ValueError(f"Invalid or empty video file: {os.path.basename(path)}")
33
  logger.debug(f"Loaded video: {path}, duration: {clip.duration}s")
34
+ # Resize with compatible resampling method
35
+ try:
36
+ clip = clip.resize((1280, 720), resample=Image.Resampling.LANCZOS)
37
+ except Exception as e:
38
+ logger.warning(f"Failed to resize video {path}: {e}")
39
+ clip = clip.resize((1280, 720)) # Fallback without explicit resampling
40
  return clip
41
  except Exception as e:
42
  raise ValueError(f"Failed to load video file '{os.path.basename(path)}': {str(e)}")
 
61
  for vp in video_paths:
62
  try:
63
  clip = safe_video_clip(vp)
 
 
64
  video_clips.append(clip)
65
  except Exception as e:
66
  logger.warning(f"Skipping invalid video file {vp}: {e}")
 
73
  for ap in audio_paths:
74
  try:
75
  clip = safe_audio_clip(ap)
76
+ clip = clip.volumex(music_vol)
77
  audio_clips.append(clip)
78
  except Exception as e:
79
  logger.warning(f"Skipping invalid audio file {ap}: {e}")
 
92
  final_audio = None
93
  if audio_clips:
94
  if audio_mode == "concatenate":
95
+ final_audio = concatenate_audioclips(audio_clips)
96
  logger.debug(f"Concatenated audio duration: {final_audio.duration}s")
97
  else:
98
+ final_audio = CompositeAudioClip(audio_clips)
99
  logger.debug(f"Composite audio duration: {final_audio.duration}s")
100
 
101
+ # Match audio duration to video
102
+ if final_audio.duration < final_video.duration:
103
+ logger.debug(f"Looping audio to match video duration: {final_video.duration}s")
104
+ final_audio = final_audio.fx(vfx.loop, duration=final_video.duration)
105
+
106
  if original_audio:
107
  final_audio = CompositeAudioClip([final_audio, original_audio])
108
  logger.debug(f"Combined audio (original + uploaded) duration: {final_audio.duration}s")
 
131
  logger.error(f"MoviePy failed to write output: {str(e)}")
132
  raise
133
 
134
+ # Close clips
135
  final_video.close()
136
  for vc in video_clips:
137
  vc.close()
 
147
  files: list[UploadFile] = File(...),
148
  orig_vol: float = Form(1.0),
149
  music_vol: float = Form(0.5),
150
+ audio_mode: str = Form("composite"),
151
  background_tasks: BackgroundTasks = BackgroundTasks(),
152
  ):
153
  temp_dir = tempfile.mkdtemp()
 
155
 
156
  try:
157
  saved_files = []
 
 
158
  for uploaded_file in files:
159
  if not uploaded_file.filename:
160
  logger.warning("Skipping file with no filename")
 
169
  saved_files.append(file_path)
170
  logger.debug(f"Saved file: {file_path}")
171
 
 
172
  video_files = [f for f in saved_files if f.lower().endswith(".mp4")]
173
+ audio_files = [f for f in saved_files if f.lower().endswith((".mp3", ".wav", ".aac", ".m4a", ".ogg"))]
 
 
174
  logger.debug(f"Video files: {video_files}")
175
  logger.debug(f"Audio files: {audio_files}")
176
 
177
  if len(video_files) < 1:
178
  raise HTTPException(status_code=400, detail="Please upload at least one valid video file")
179
 
 
180
  output_path = os.path.join(temp_dir, "merged_output.mp4")
 
 
181
  merge_videos_and_audios(video_files, audio_files, output_path, temp_dir, orig_vol, music_vol, audio_mode)
182
 
 
183
  if not os.path.exists(output_path):
184
  logger.error(f"Output file not found: {output_path}")
185
  raise HTTPException(status_code=500, detail="Failed to create merged video file")
186
 
 
187
  logger.debug(f"Reading output file: {output_path}")
188
  with open(output_path, "rb") as file:
189
  content = file.read()
 
191
  logger.error(f"Output file is empty: {output_path}")
192
  raise HTTPException(status_code=500, detail="Output file is empty")
193
 
 
194
  background_tasks.add_task(shutil.rmtree, temp_dir, ignore_errors=True)
 
 
195
  logger.debug("Sending streaming response")
196
  return StreamingResponse(
197
  io.BytesIO(content),