File size: 3,509 Bytes
4f02f65
 
 
 
 
 
 
 
 
 
 
 
 
ffd04f3
4f02f65
ffd04f3
 
 
4f02f65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ffd04f3
4f02f65
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ffd04f3
 
4f02f65
 
 
 
 
 
ffd04f3
4f02f65
 
ffd04f3
4f02f65
ffd04f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4f02f65
ffd04f3
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
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)