Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -67,6 +67,26 @@ def get_indices_string(file_list, prefix_pattern):
|
|
| 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.
|
|
@@ -130,11 +150,11 @@ def merge_videos_and_audios(video_files=None, audio_files=None, orig_vol=1.0, mu
|
|
| 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+)\.
|
| 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+)\.
|
| 138 |
|
| 139 |
# Ensure at least two files are provided (videos, audios, or combination)
|
| 140 |
video_count = len(video_files) if video_files else 0
|
|
@@ -302,21 +322,28 @@ def merge_videos_and_audios(video_files=None, audio_files=None, orig_vol=1.0, mu
|
|
| 302 |
|
| 303 |
# --- Gradio App Using Blocks ---
|
| 304 |
|
| 305 |
-
def
|
| 306 |
"""
|
| 307 |
Gradio endpoint to merge videos and/or audio.
|
| 308 |
Args:
|
| 309 |
-
|
| 310 |
-
audio_files: List of audio file paths (optional)
|
| 311 |
orig_vol: Volume for original video audio (0.0 to 1.0)
|
| 312 |
music_vol: Volume for background audio (0.0 to 1.0)
|
| 313 |
Returns:
|
| 314 |
Path to the merged file (video or audio) or error message
|
| 315 |
"""
|
| 316 |
-
logger.info(f"Received {len(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
|
| 318 |
result = merge_videos_and_audios(
|
| 319 |
-
video_files
|
|
|
|
|
|
|
|
|
|
| 320 |
)
|
| 321 |
|
| 322 |
if isinstance(result, str) and result.startswith("Error"):
|
|
@@ -358,12 +385,11 @@ if __name__ == "__main__":
|
|
| 358 |
|
| 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.
|
| 362 |
-
gr.Markdown("For API usage, name videos as file1.mp4, file2.mp4, etc., and audios as audio1.
|
| 363 |
|
| 364 |
with gr.Row():
|
| 365 |
-
|
| 366 |
-
audio_input = gr.File(label="Audio Files (Optional, at least 2 if no video)", type="filepath", file_count="multiple")
|
| 367 |
|
| 368 |
with gr.Row():
|
| 369 |
orig_vol_input = gr.Slider(minimum=0.0, maximum=1.0, value=1.0, step=0.05, label="Original Video Audio Volume")
|
|
@@ -374,8 +400,8 @@ if __name__ == "__main__":
|
|
| 374 |
merge_button = gr.Button("Merge Files")
|
| 375 |
|
| 376 |
merge_button.click(
|
| 377 |
-
fn=
|
| 378 |
-
inputs=[
|
| 379 |
outputs=[output_video, output_audio]
|
| 380 |
)
|
| 381 |
|
|
|
|
| 67 |
indices.append(match.group(1))
|
| 68 |
return "".join(indices)
|
| 69 |
|
| 70 |
+
def split_files_by_extension(all_files):
|
| 71 |
+
"""
|
| 72 |
+
Split a list of files into videos (.mp4) and audios (.mp3, .wav) based on extensions.
|
| 73 |
+
Args:
|
| 74 |
+
all_files: List of file paths (e.g., ['file1.mp4', 'audio1.mp3', 'file2.mp4', 'audio2.mp3'])
|
| 75 |
+
Returns:
|
| 76 |
+
Tuple of (video_files, audio_files)
|
| 77 |
+
"""
|
| 78 |
+
video_files = []
|
| 79 |
+
audio_files = []
|
| 80 |
+
for file_path in all_files:
|
| 81 |
+
filename = os.path.basename(file_path).lower()
|
| 82 |
+
if filename.endswith('.mp4'):
|
| 83 |
+
video_files.append(file_path)
|
| 84 |
+
elif filename.endswith(('.mp3', '.wav')):
|
| 85 |
+
audio_files.append(file_path)
|
| 86 |
+
else:
|
| 87 |
+
logger.warning(f"Unsupported file extension for {file_path}; skipping")
|
| 88 |
+
return video_files, audio_files
|
| 89 |
+
|
| 90 |
def trim_silence(audio_clip, threshold=0.005):
|
| 91 |
"""
|
| 92 |
Trim silence from the start and end of an audio clip.
|
|
|
|
| 150 |
try:
|
| 151 |
# Sort files by numerical index
|
| 152 |
video_files = sort_files_by_index(video_files, r'file(\d+)\.mp4')
|
| 153 |
+
audio_files = sort_files_by_index(audio_files, r'audio(\d+)\.(mp3|wav)')
|
| 154 |
|
| 155 |
# Get indices for output naming
|
| 156 |
video_indices = get_indices_string(video_files, r'file(\d+)\.mp4')
|
| 157 |
+
audio_indices = get_indices_string(audio_files, r'audio(\d+)\.(mp3|wav)')
|
| 158 |
|
| 159 |
# Ensure at least two files are provided (videos, audios, or combination)
|
| 160 |
video_count = len(video_files) if video_files else 0
|
|
|
|
| 322 |
|
| 323 |
# --- Gradio App Using Blocks ---
|
| 324 |
|
| 325 |
+
def gradio_merge_files(all_files, orig_vol, music_vol):
|
| 326 |
"""
|
| 327 |
Gradio endpoint to merge videos and/or audio.
|
| 328 |
Args:
|
| 329 |
+
all_files: List of file paths (mixed videos and audios, e.g., ['file1.mp4', 'audio1.mp3', 'file2.mp4'])
|
|
|
|
| 330 |
orig_vol: Volume for original video audio (0.0 to 1.0)
|
| 331 |
music_vol: Volume for background audio (0.0 to 1.0)
|
| 332 |
Returns:
|
| 333 |
Path to the merged file (video or audio) or error message
|
| 334 |
"""
|
| 335 |
+
logger.info(f"Received {len(all_files) if all_files else 0} files: {all_files}")
|
| 336 |
+
|
| 337 |
+
# Split files into videos and audios based on extensions
|
| 338 |
+
video_files, audio_files = split_files_by_extension(all_files)
|
| 339 |
+
logger.info(f"Identified {len(video_files)} video files: {video_files}")
|
| 340 |
+
logger.info(f"Identified {len(audio_files)} audio files: {audio_files}")
|
| 341 |
|
| 342 |
result = merge_videos_and_audios(
|
| 343 |
+
video_files=video_files,
|
| 344 |
+
audio_files=audio_files,
|
| 345 |
+
orig_vol=orig_vol,
|
| 346 |
+
music_vol=music_vol
|
| 347 |
)
|
| 348 |
|
| 349 |
if isinstance(result, str) and result.startswith("Error"):
|
|
|
|
| 385 |
|
| 386 |
with gr.Blocks(title="Video and Audio Merger API") as app:
|
| 387 |
gr.Markdown("## Video and Audio Merger API")
|
| 388 |
+
gr.Markdown("Upload at least 2 files total (videos, audios, or a combination) to merge them.")
|
| 389 |
+
gr.Markdown("For API usage, name videos as file1.mp4, file2.mp4, etc., and audios as audio1.mp3, audio2.mp3, etc. Files can be sent in a single list; the app will distinguish them by extension (.mp4 for videos, .mp3/.wav for audios).")
|
| 390 |
|
| 391 |
with gr.Row():
|
| 392 |
+
file_input = gr.File(label="Upload Files (Videos: .mp4, Audios: .mp3/.wav)", type="filepath", file_count="multiple")
|
|
|
|
| 393 |
|
| 394 |
with gr.Row():
|
| 395 |
orig_vol_input = gr.Slider(minimum=0.0, maximum=1.0, value=1.0, step=0.05, label="Original Video Audio Volume")
|
|
|
|
| 400 |
merge_button = gr.Button("Merge Files")
|
| 401 |
|
| 402 |
merge_button.click(
|
| 403 |
+
fn=gradio_merge_files,
|
| 404 |
+
inputs=[file_input, orig_vol_input, music_vol_input],
|
| 405 |
outputs=[output_video, output_audio]
|
| 406 |
)
|
| 407 |
|