Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from yt_dlp import YoutubeDL | |
| import os | |
| from pydub import AudioSegment | |
| import re | |
| DOWNLOADS_FOLDER = "downloads" | |
| os.makedirs(DOWNLOADS_FOLDER, exist_ok=True) | |
| def sanitize_filename(filename): | |
| """Remove invalid characters from filename""" | |
| return re.sub(r'[<>:"/\\|?*]', '', filename) | |
| def download_audio(url, file_format): | |
| try: | |
| if not url or not url.strip(): | |
| return None, "Error: Please enter a URL" | |
| # Set download options | |
| ydl_opts = { | |
| 'format': 'bestaudio/best', | |
| 'outtmpl': os.path.join(DOWNLOADS_FOLDER, '%(title)s.%(ext)s'), | |
| 'quiet': True, | |
| 'no_warnings': True | |
| } | |
| with YoutubeDL(ydl_opts) as ydl: | |
| info = ydl.extract_info(url, download=True) | |
| original_filename = ydl.prepare_filename(info) | |
| # Get the actual downloaded filename | |
| if os.path.exists(original_filename): | |
| downloaded_file = original_filename | |
| else: | |
| # Sometimes the extension might be different | |
| base_name = os.path.splitext(original_filename)[0] | |
| for ext in ['.m4a', '.webm', '.mp3', '.opus', '.flac', '.wav']: | |
| possible_file = base_name + ext | |
| if os.path.exists(possible_file): | |
| downloaded_file = possible_file | |
| break | |
| else: | |
| downloaded_file = original_filename | |
| # If user wants specific format, convert if needed | |
| if file_format.lower() != "original": | |
| target_ext = f".{file_format.lower()}" | |
| current_ext = os.path.splitext(downloaded_file)[1].lower() | |
| if current_ext != target_ext: | |
| # Create sanitized output filename | |
| base_name = os.path.splitext(downloaded_file)[0] | |
| sanitized_base = sanitize_filename(os.path.basename(base_name)) | |
| output_file = os.path.join(DOWNLOADS_FOLDER, sanitized_base + target_ext) | |
| try: | |
| # Convert audio format | |
| audio = AudioSegment.from_file(downloaded_file) | |
| audio.export(output_file, format=file_format.lower()) | |
| # Optionally remove original file after conversion | |
| # os.remove(downloaded_file) | |
| downloaded_file = output_file | |
| except Exception as e: | |
| print(f"Conversion failed: {e}") | |
| # Return original file if conversion fails | |
| pass | |
| return downloaded_file, "Download completed successfully!" | |
| except Exception as e: | |
| return None, f"Error: {str(e)}" | |
| # Create Gradio interface | |
| iface = gr.Interface( | |
| fn=download_audio, | |
| inputs=[ | |
| gr.Textbox(label="YouTube or SoundCloud URL", placeholder="Enter URL here..."), | |
| gr.Dropdown(["original", "mp3", "m4a", "wav"], value="mp3", label="Output Format") | |
| ], | |
| outputs=[ | |
| gr.File(label="Download Audio"), | |
| gr.Textbox(label="Status") | |
| ], | |
| title="🎵 Audio Downloader", | |
| description="Download audio from YouTube or SoundCloud. Supports MP3, M4A, WAV formats.", | |
| examples=[ | |
| ["https://www.youtube.com/watch?v=dQw4w9WgXcQ", "mp3"], | |
| ["https://soundcloud.com/aviciiofficial/levels", "mp3"], | |
| ] | |
| ) | |
| # Launch the interface | |
| if __name__ == "__main__": | |
| iface.launch(share=False, show_error=True) |