File size: 5,636 Bytes
3ece626
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import gradio as gr
from yt_dlp import YoutubeDL
import os
from pydub import AudioSegment

DOWNLOADS_FOLDER = "downloads"
os.makedirs(DOWNLOADS_FOLDER, exist_ok=True)

def download_audio(url, file_format, duration_sec):
    """
    Download audio from YouTube or SoundCloud and convert to desired format
    """
    try:
        # Download best audio available
        ydl_opts = {
            'format': 'bestaudio/best',
            'outtmpl': os.path.join(DOWNLOADS_FOLDER, '%(title)s.%(ext)s'),
            'quiet': True,
            'no_warnings': True,
            'extract_flat': False,
        }
        
        with YoutubeDL(ydl_opts) as ydl:
            info = ydl.extract_info(url, download=True)
        
        original_file = os.path.join(DOWNLOADS_FOLDER, f"{info['title']}.{info['ext']}")
        
        # Clean filename (remove special characters)
        safe_title = "".join(c for c in info['title'] if c.isalnum() or c in (' ', '-', '_')).rstrip()
        original_file_safe = os.path.join(DOWNLOADS_FOLDER, f"{safe_title}.{info['ext']}")
        
        # Rename if necessary
        if original_file != original_file_safe:
            os.rename(original_file, original_file_safe)
            original_file = original_file_safe
        
        # Load audio and trim to duration
        audio = AudioSegment.from_file(original_file)
        duration_ms = min(len(audio), int(duration_sec * 1000))
        trimmed_audio = audio[:duration_ms]
        
        # Determine output file path based on desired format
        base_name = os.path.splitext(original_file)[0]
        
        if file_format.lower() == "mp3":
            output_file = base_name + ".mp3"
            trimmed_audio.export(output_file, format="mp3", bitrate="192k")
        
        elif file_format.lower() == "opus":
            output_file = base_name + ".opus"
            trimmed_audio.export(output_file, format="opus", bitrate="128k")
        
        elif file_format.lower() == "wav":
            output_file = base_name + ".wav"
            trimmed_audio.export(output_file, format="wav")
        
        elif file_format.lower() == "m4a":
            output_file = base_name + ".m4a"
            trimmed_audio.export(output_file, format="ipod", codec="aac")
        
        else:  # keep original format
            output_file = original_file
        
        # Optional: Remove original downloaded file to save space
        if output_file != original_file and os.path.exists(original_file):
            os.remove(original_file)
        
        return output_file
    
    except Exception as e:
        raise gr.Error(f"Error downloading audio: {str(e)}")

# Create Gradio interface
with gr.Blocks(title="Audio Downloader", theme=gr.themes.Soft()) as iface:
    gr.Markdown("# 🎵 YouTube & SoundCloud Audio Downloader")
    gr.Markdown("Download audio from YouTube or SoundCloud and convert to your preferred format")
    
    with gr.Row():
        url_input = gr.Textbox(
            label="Enter URL",
            placeholder="Paste YouTube or SoundCloud URL here...",
            scale=4
        )
    
    with gr.Row():
        with gr.Column(scale=1):
            format_choice = gr.Dropdown(
                choices=["mp3", "m4a", "opus", "wav"],
                value="mp3",
                label="Output Format"
            )
        
        with gr.Column(scale=3):
            duration_slider = gr.Slider(
                minimum=5,
                maximum=600,  # Increased to 10 minutes
                value=60,
                step=5,
                label="Duration (seconds)",
                info="Maximum duration to download (0 = full track)"
            )
    
    with gr.Row():
        download_button = gr.Button("Download Audio", variant="primary", size="lg")
    
    with gr.Row():
        download_file = gr.File(label="Download your audio", interactive=False)
    
    # Example URLs
    with gr.Accordion("Example URLs (click to use)", open=False):
        gr.Examples(
            examples=[
                ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
                ["https://soundcloud.com/antonio-antetomaso/mutiny-on-the-bounty-closing-titles-cover"],
                ["https://www.youtube.com/watch?v=JGwWNGJdvx8"],
                ["https://soundcloud.com/officialnikkig/kill-bill-sza-kill-bill-remix"]
            ],
            inputs=url_input,
            label=""
        )
    
    # Add instructions
    with gr.Accordion("Instructions", open=False):
        gr.Markdown("""
        ### How to use:
        1. Paste a YouTube or SoundCloud URL
        2. Choose your desired output format
        3. Set the maximum duration (or leave at 0 for full track)
        4. Click "Download Audio"
        
        ### Supported formats:
        - **MP3**: Most compatible, good quality
        - **M4A**: Apple format, smaller file size
        - **Opus**: Best quality at low bitrates
        - **WAV**: Lossless, large file size
        
        ### Notes:
        - Downloads are saved to a 'downloads' folder
        - Some tracks may have download restrictions
        - Very long videos may take time to process
        """)
    
    download_button.click(
        fn=download_audio,
        inputs=[url_input, format_choice, duration_slider],
        outputs=download_file,
        show_progress=True
    )

# Launch the interface
if __name__ == "__main__":
    iface.launch(
        show_error=True,
        share=False,  # Set to True to create a public link
        server_name="0.0.0.0" if os.getenv("GRADIO_SHARE") else "127.0.0.1",
        server_port=7860
    )