Spaces:
Sleeping
Sleeping
| import os | |
| import uuid | |
| import zipfile | |
| import gradio as gr | |
| from tqdm import tqdm | |
| from datetime import datetime | |
| from pydub import AudioSegment | |
| from moviepy.editor import VideoFileClip | |
| def convert_audio(input_files, output_format, session_id, merge_files, gap_duration): | |
| """Converts or merges a list of audio files.""" | |
| output_files = [] | |
| merged_audio = AudioSegment.silent(duration=0) | |
| for input_file in tqdm(input_files, desc="Converting audio files"): | |
| audio = AudioSegment.from_file(input_file.name) | |
| base_name = os.path.splitext(os.path.basename(input_file.name))[0] | |
| output_filename = f"{base_name}.{output_format}" | |
| output_path = os.path.join(session_id, output_filename) | |
| os.makedirs(session_id, exist_ok=True) | |
| audio.export(output_path, format=output_format) | |
| if merge_files: | |
| merged_audio += audio + AudioSegment.silent(duration=gap_duration) | |
| else: | |
| output_files.append(output_path) | |
| if merge_files: | |
| merged_output_path = os.path.join(session_id, f"merged_output.{output_format}") | |
| merged_audio.export(merged_output_path, format=output_format) | |
| return merged_output_path | |
| return output_files | |
| def create_zip(files_to_zip, session_id): | |
| """Creates a ZIP archive from a list of files.""" | |
| zip_filename = f"{session_id}.zip" | |
| with zipfile.ZipFile(zip_filename, 'w') as zipf: | |
| for file in tqdm(files_to_zip, desc="Creating ZIP archive"): | |
| zipf.write(file, os.path.basename(file)) | |
| return zip_filename | |
| def process_audio_files(files, output_format, merge_files, gap_duration, progress=gr.Progress(track_tqdm=True)): | |
| """Main handler function for audio processing.""" | |
| if not files: | |
| raise gr.Error("Please upload at least one audio file!") | |
| session_id = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + "_" + str(uuid.uuid4())[:8] | |
| print(f"\nStarting audio session: {session_id}") | |
| print(f"Files to convert: {len(files)} to format {output_format}") | |
| output_files = convert_audio(files, output_format, session_id, merge_files, gap_duration) | |
| if merge_files: | |
| print("Merging complete!") | |
| return output_files | |
| print("Conversion complete! Creating ZIP archive...") | |
| zip_filename = create_zip(output_files, session_id) | |
| print("Zipping complete!") | |
| return zip_filename | |
| def process_video(input_video, conversion_type, output_format, progress=gr.Progress(track_tqdm=True)): | |
| """Converts a video to another format or extracts its audio.""" | |
| if not input_video: | |
| raise gr.Error("Please upload a video file first!") | |
| session_id = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + "_" + str(uuid.uuid4())[:8] | |
| os.makedirs(session_id, exist_ok=True) | |
| base_name = os.path.splitext(os.path.basename(input_video))[0] | |
| output_filename = f"{base_name}_converted.{output_format}" | |
| output_path = os.path.join(session_id, output_filename) | |
| print(f"\nStarting video session: {session_id}") | |
| print(f"Conversion type: {conversion_type}, Output format: {output_format}") | |
| try: | |
| clip = VideoFileClip(input_video) | |
| if conversion_type == "Video to Video": | |
| print("Converting video to video...") | |
| clip.write_videofile(output_path, codec='libx264', audio_codec='aac', logger='bar') | |
| elif conversion_type == "Video to Audio": | |
| print("Extracting audio from video...") | |
| if clip.audio is None: | |
| raise gr.Error("The uploaded video file does not contain an audio track.") | |
| audio_clip = clip.audio | |
| audio_clip.write_audiofile(output_path, logger='bar') | |
| audio_clip.close() | |
| clip.close() | |
| except Exception as e: | |
| print(f"An error occurred: {e}") | |
| raise gr.Error(f"An error occurred during processing: {e}") | |
| print("Video processing complete!") | |
| return output_path | |
| def update_format_choices(conversion_type): | |
| """Dynamically updates the format dropdown based on the conversion type.""" | |
| if conversion_type == "Video to Video": | |
| return gr.Dropdown(choices=video_formats, value="mp4", label="Output Video Format") | |
| else: | |
| return gr.Dropdown(choices=audio_formats, value="mp3", label="Output Audio Format") | |
| audio_formats = ["mp3", "wav", "flac", "ogg", "aac", "m4a", "aiff", "wma", "opus"] | |
| video_formats = ["mp4", "webm", "mkv", "avi", "mov", "flv"] | |
| with gr.Blocks(theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# Universal Media Converter π§π¬") | |
| gr.Markdown("Use the tabs below to switch between the Audio and Video converters.") | |
| with gr.Tabs(): | |
| with gr.TabItem("πΆ Audio Converter"): | |
| gr.Markdown("## Convert and Merge Audio Files") | |
| gr.Markdown("Upload one or more audio files and select the output format. You can also merge all files into a single track by checking the box.") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| audio_file_input = gr.Files(label="Upload Audio Files", file_types=["audio"]) | |
| with gr.Column(scale=1): | |
| audio_format_choice = gr.Dropdown(choices=audio_formats, label="Output Format", value="mp3") | |
| merge_files_checkbox = gr.Checkbox(label="Merge all files into one") | |
| gap_slider = gr.Slider(minimum=0, maximum=5000, step=100, value=500, label="Gap between files (ms)", info="Only used when merging") | |
| audio_submit_button = gr.Button("π Convert", variant="primary") | |
| audio_output_file = gr.File(label="Download Result") | |
| audio_submit_button.click( | |
| fn=process_audio_files, | |
| inputs=[audio_file_input, audio_format_choice, merge_files_checkbox, gap_slider], | |
| outputs=audio_output_file | |
| ) | |
| with gr.TabItem("π¬ Video Converter"): | |
| gr.Markdown("## Convert Video and Extract Audio") | |
| gr.Markdown("Upload a video file, then choose whether to convert it to another video format or to extract its audio track.") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| video_input = gr.Video(label="Upload Video File") | |
| with gr.Column(scale=1): | |
| conversion_type_radio = gr.Radio( | |
| choices=["Video to Video", "Video to Audio"], | |
| label="Conversion Type", | |
| value="Video to Video" | |
| ) | |
| video_format_dropdown = gr.Dropdown( | |
| choices=video_formats, | |
| label="Output Video Format", | |
| value="mp4" | |
| ) | |
| video_submit_button = gr.Button("π Convert", variant="primary") | |
| video_output_file = gr.File(label="Download Result") | |
| conversion_type_radio.change( | |
| fn=update_format_choices, | |
| inputs=conversion_type_radio, | |
| outputs=video_format_dropdown | |
| ) | |
| video_submit_button.click( | |
| fn=process_video, | |
| inputs=[video_input, conversion_type_radio, video_format_dropdown], | |
| outputs=video_output_file | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch(debug=True) |