sam12345324 commited on
Commit
a3e025c
·
verified ·
1 Parent(s): 34decfe

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -2
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import gradio as gr
2
  import tempfile
3
  import os
 
4
  from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip, concatenate_audioclips
5
  import numpy as np
6
  import logging
@@ -26,6 +27,46 @@ def check_port(port):
26
  except socket.error:
27
  return False
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  def trim_silence(audio_clip, threshold=0.005):
30
  """
31
  Trim silence from the start and end of an audio clip.
@@ -77,6 +118,7 @@ def merge_videos_and_audios(video_files=None, audio_files=None, orig_vol=1.0, mu
77
  - If only video_files: Merge videos, retaining their original audio.
78
  - If only audio_files: Merge audio files into a single audio file.
79
  - If both: Merge videos and overlay the concatenated audio.
 
80
  Args:
81
  video_files: List of video file paths (optional)
82
  audio_files: List of audio file paths (optional)
@@ -86,6 +128,14 @@ def merge_videos_and_audios(video_files=None, audio_files=None, orig_vol=1.0, mu
86
  Path to the merged file (video or audio) or error message.
87
  """
88
  try:
 
 
 
 
 
 
 
 
89
  # Ensure at least two files are provided (videos, audios, or combination)
90
  video_count = len(video_files) if video_files else 0
91
  audio_count = len(audio_files) if audio_files else 0
@@ -103,7 +153,8 @@ def merge_videos_and_audios(video_files=None, audio_files=None, orig_vol=1.0, mu
103
 
104
  # Case 1: Audio only
105
  if audio_count >= 2 and video_count == 0:
106
- output_path = os.path.join(temp_dir, "merged_output.mp3")
 
107
  logger.info("Merging audio files only")
108
 
109
  # Load, normalize, and trim audio clips
@@ -153,7 +204,11 @@ def merge_videos_and_audios(video_files=None, audio_files=None, orig_vol=1.0, mu
153
  return output_path
154
 
155
  # Case 2: Video only or Video with Audio
156
- output_path = os.path.join(temp_dir, "merged_output.mp4")
 
 
 
 
157
 
158
  # Load and concatenate video clips
159
  video_clips = [VideoFileClip(video) for video in video_files]
@@ -304,6 +359,7 @@ if __name__ == "__main__":
304
  with gr.Blocks(title="Video and Audio Merger API") as app:
305
  gr.Markdown("## Video and Audio Merger API")
306
  gr.Markdown("Upload at least 2 files total (videos, audios, or a combination) to merge them. Videos and audios are optional.")
 
307
 
308
  with gr.Row():
309
  video_input = gr.File(label="Video Files (Optional, at least 2 if no audio)", type="filepath", file_count="multiple")
 
1
  import gradio as gr
2
  import tempfile
3
  import os
4
+ import re
5
  from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip, concatenate_audioclips
6
  import numpy as np
7
  import logging
 
27
  except socket.error:
28
  return False
29
 
30
+ def sort_files_by_index(file_list, prefix_pattern):
31
+ """
32
+ Sort files based on their numerical index in the filename.
33
+ Args:
34
+ file_list: List of file paths (e.g., ['file2.mp4', 'file1.mp4', 'file3.mp4'])
35
+ prefix_pattern: Regex pattern to match the prefix and number (e.g., r'file(\d+)\.mp4')
36
+ Returns:
37
+ Sorted list of file paths
38
+ """
39
+ if not file_list:
40
+ return []
41
+
42
+ def extract_index(filename):
43
+ match = re.match(prefix_pattern, os.path.basename(filename))
44
+ if match:
45
+ return int(match.group(1))
46
+ return float('inf') # Invalid filenames go to the end
47
+
48
+ sorted_files = sorted(file_list, key=extract_index)
49
+ logger.info(f"Sorted files: {sorted_files}")
50
+ return sorted_files
51
+
52
+ def get_indices_string(file_list, prefix_pattern):
53
+ """
54
+ Extract the numerical indices from filenames and return as a string.
55
+ Args:
56
+ file_list: List of file paths
57
+ prefix_pattern: Regex pattern to match the prefix and number
58
+ Returns:
59
+ String of indices (e.g., '123' for ['file1.mp4', 'file2.mp4', 'file3.mp4'])
60
+ """
61
+ if not file_list:
62
+ return ""
63
+ indices = []
64
+ for filename in file_list:
65
+ match = re.match(prefix_pattern, os.path.basename(filename))
66
+ if match:
67
+ indices.append(match.group(1))
68
+ return "".join(indices)
69
+
70
  def trim_silence(audio_clip, threshold=0.005):
71
  """
72
  Trim silence from the start and end of an audio clip.
 
118
  - If only video_files: Merge videos, retaining their original audio.
119
  - If only audio_files: Merge audio files into a single audio file.
120
  - If both: Merge videos and overlay the concatenated audio.
121
+ Files are sorted by numerical index in their filenames (e.g., file1.mp4, file2.mp4).
122
  Args:
123
  video_files: List of video file paths (optional)
124
  audio_files: List of audio file paths (optional)
 
128
  Path to the merged file (video or audio) or error message.
129
  """
130
  try:
131
+ # Sort files by numerical index
132
+ video_files = sort_files_by_index(video_files, r'file(\d+)\.mp4')
133
+ audio_files = sort_files_by_index(audio_files, r'audio(\d+)\.mp4')
134
+
135
+ # Get indices for output naming
136
+ video_indices = get_indices_string(video_files, r'file(\d+)\.mp4')
137
+ audio_indices = get_indices_string(audio_files, r'audio(\d+)\.mp4')
138
+
139
  # Ensure at least two files are provided (videos, audios, or combination)
140
  video_count = len(video_files) if video_files else 0
141
  audio_count = len(audio_files) if audio_files else 0
 
153
 
154
  # Case 1: Audio only
155
  if audio_count >= 2 and video_count == 0:
156
+ output_filename = f"combined_audio_{audio_indices}.mp3"
157
+ output_path = os.path.join(temp_dir, output_filename)
158
  logger.info("Merging audio files only")
159
 
160
  # Load, normalize, and trim audio clips
 
204
  return output_path
205
 
206
  # Case 2: Video only or Video with Audio
207
+ if audio_indices:
208
+ output_filename = f"combined_video_{video_indices}_with_audio_{audio_indices}.mp4"
209
+ else:
210
+ output_filename = f"combined_video_{video_indices}.mp4"
211
+ output_path = os.path.join(temp_dir, output_filename)
212
 
213
  # Load and concatenate video clips
214
  video_clips = [VideoFileClip(video) for video in video_files]
 
359
  with gr.Blocks(title="Video and Audio Merger API") as app:
360
  gr.Markdown("## Video and Audio Merger API")
361
  gr.Markdown("Upload at least 2 files total (videos, audios, or a combination) to merge them. Videos and audios are optional.")
362
+ gr.Markdown("For API usage, name videos as file1.mp4, file2.mp4, etc., and audios as audio1.mp4, audio2.mp4, etc.")
363
 
364
  with gr.Row():
365
  video_input = gr.File(label="Video Files (Optional, at least 2 if no audio)", type="filepath", file_count="multiple")