import os import uuid import zipfile import gradio as gr from tqdm import tqdm from datetime import datetime from pydub import AudioSegment from moviepy import VideoFileClip audio_formats = ["mp3", "wav", "flac", "ogg", "aac", "m4a", "aiff", "wma", "opus"] video_formats = ["mp4", "webm", "mkv", "avi", "mov", "flv"] # ---------- AUDIO PROCESSING ---------- 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) os.makedirs(session_id, exist_ok=True) for input_file in tqdm(input_files, desc="Converting audio files"): file_path = input_file if isinstance(input_file, str) else input_file.name audio = AudioSegment.from_file(file_path) base_name = os.path.splitext(os.path.basename(file_path))[0] output_filename = f"{base_name}.{output_format}" output_path = os.path.join(session_id, output_filename) 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 # ---------- ZIP CREATION ---------- 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 # ---------- AUDIO HANDLER ---------- 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 len(output_files) > 1: print("Creating ZIP archive...") zip_filename = create_zip(output_files, session_id) return zip_filename return output_files[0] # ---------- VIDEO HANDLER ---------- 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) input_path = input_video if isinstance(input_video, str) else input_video.name base_name = os.path.splitext(os.path.basename(input_path))[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_path) if conversion_type == "Video to Video": print("Converting video to video...") clip.write_videofile(output_path, codec='libx264', audio_codec='aac', logger=None) 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=None) 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 # ---------- FORMAT CHOICES ---------- 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") # ---------- UI ---------- with gr.Blocks(theme=gr.themes.Soft()) as demo: gr.HTML("

Universal Media Converter 🎧🎬

") with gr.Tabs(): # AUDIO TAB with gr.TabItem("🎶 Audio Converter"): gr.HTML("
Upload one or more audio files and select the output format. You can also merge all files into a single track.
") 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)") 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 ) # VIDEO TAB with gr.TabItem("🎬 Video Converter"): gr.HTML("
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.File(label="Upload Video File", file_types=["video"]) 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)