MySafeCode commited on
Commit
e9a1734
·
verified ·
1 Parent(s): f3130b6

Update app2.py

Browse files
Files changed (1) hide show
  1. app2.py +238 -88
app2.py CHANGED
@@ -6,18 +6,17 @@ from pydub import AudioSegment
6
  DOWNLOADS_FOLDER = "downloads"
7
  os.makedirs(DOWNLOADS_FOLDER, exist_ok=True)
8
 
9
- def download_audio(url, file_format, duration_sec):
10
- """
11
- Download audio from YouTube or SoundCloud and convert to desired format
12
- """
13
  try:
14
  # Download best audio available
15
  ydl_opts = {
16
  'format': 'bestaudio/best',
17
  'outtmpl': os.path.join(DOWNLOADS_FOLDER, '%(title)s.%(ext)s'),
18
- 'quiet': True,
19
- 'no_warnings': True,
20
  'extract_flat': False,
 
21
  }
22
 
23
  with YoutubeDL(ydl_opts) as ydl:
@@ -25,8 +24,9 @@ def download_audio(url, file_format, duration_sec):
25
 
26
  original_file = os.path.join(DOWNLOADS_FOLDER, f"{info['title']}.{info['ext']}")
27
 
28
- # Clean filename (remove special characters)
29
  safe_title = "".join(c for c in info['title'] if c.isalnum() or c in (' ', '-', '_')).rstrip()
 
30
  original_file_safe = os.path.join(DOWNLOADS_FOLDER, f"{safe_title}.{info['ext']}")
31
 
32
  # Rename if necessary
@@ -34,17 +34,17 @@ def download_audio(url, file_format, duration_sec):
34
  os.rename(original_file, original_file_safe)
35
  original_file = original_file_safe
36
 
37
- # Load audio and trim to duration
38
  audio = AudioSegment.from_file(original_file)
39
 
40
- # Handle duration parameter
41
  if duration_sec > 0:
42
  duration_ms = min(len(audio), int(duration_sec * 1000))
43
  trimmed_audio = audio[:duration_ms]
44
  else:
45
- trimmed_audio = audio # Full track if duration is 0
46
 
47
- # Determine output file path based on desired format
48
  base_name = os.path.splitext(original_file)[0]
49
 
50
  if file_format.lower() == "mp3":
@@ -63,103 +63,253 @@ def download_audio(url, file_format, duration_sec):
63
  output_file = base_name + ".m4a"
64
  trimmed_audio.export(output_file, format="ipod", codec="aac")
65
 
66
- else: # keep original format
67
  output_file = original_file
68
 
69
- # Optional: Remove original downloaded file to save space
70
  if output_file != original_file and os.path.exists(original_file):
71
  os.remove(original_file)
72
 
73
- return output_file
74
 
75
  except Exception as e:
76
- raise gr.Error(f"Error downloading audio: {str(e)}")
77
 
78
- # Create Gradio interface
79
- with gr.Blocks(title="Audio Downloader") as iface:
80
- gr.Markdown("# 🎵 YouTube & SoundCloud Audio Downloader")
81
- gr.Markdown("Download audio from YouTube or SoundCloud and convert to your preferred format")
82
-
83
- with gr.Row():
84
- url_input = gr.Textbox(
85
- label="Enter URL",
86
- placeholder="Paste YouTube or SoundCloud URL here...",
87
- scale=4
88
- )
89
-
90
- with gr.Row():
91
- with gr.Column(scale=1):
92
- format_choice = gr.Dropdown(
93
- choices=["mp3", "m4a", "opus", "wav"],
94
- value="mp3",
95
- label="Output Format"
96
- )
97
-
98
- with gr.Column(scale=3):
99
- duration_slider = gr.Slider(
100
- minimum=0,
101
- maximum=600, # Increased to 10 minutes
102
- value=60,
103
- step=5,
104
- label="Duration (seconds)",
105
- info="Maximum duration to download (0 = full track)"
106
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
- with gr.Row():
109
- download_button = gr.Button("Download Audio", variant="primary", size="lg")
 
 
 
 
 
 
 
110
 
111
- with gr.Row():
112
- download_file = gr.File(label="Download your audio", interactive=False)
113
 
114
- # Example URLs
115
- with gr.Accordion("Example URLs (click to use)", open=False):
116
- gr.Examples(
117
- examples=[
118
- ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
119
- ["https://soundcloud.com/antonio-antetomaso/mutiny-on-the-bounty-closing-titles-cover"],
120
- ["https://www.youtube.com/watch?v=JGwWNGJdvx8"],
121
- ["https://soundcloud.com/officialnikkig/kill-bill-sza-kill-bill-remix"]
122
- ],
123
- inputs=url_input,
124
- label=""
125
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
 
127
- # Add instructions
128
- with gr.Accordion("Instructions", open=False):
129
  gr.Markdown("""
130
- ### How to use:
131
- 1. Paste a YouTube or SoundCloud URL
132
- 2. Choose your desired output format
133
- 3. Set the maximum duration (or set to 0 for full track)
134
- 4. Click "Download Audio"
135
-
136
- ### Supported formats:
137
- - **MP3**: Most compatible, good quality
138
- - **M4A**: Apple format, smaller file size
139
- - **Opus**: Best quality at low bitrates
140
- - **WAV**: Lossless, large file size
 
 
141
 
142
  ### Notes:
143
- - Downloads are saved to a 'downloads' folder
144
- - Some tracks may have download restrictions
145
- - Very long videos may take time to process
146
- - Minimum duration is now 0 (for full tracks)
147
  """)
148
 
149
- download_button.click(
150
- fn=download_audio,
151
- inputs=[url_input, format_choice, duration_slider],
152
- outputs=download_file,
153
- show_progress=True
 
 
 
 
 
 
154
  )
155
 
156
- # Launch the interface
157
  if __name__ == "__main__":
158
  iface.launch(
159
- theme=gr.themes.Soft(),
160
- show_error=True,
161
- share=False, # Set to True to create a public link
162
- server_name="0.0.0.0" if os.getenv("GRADIO_SHARE") else "127.0.0.1",
163
  server_port=7860,
164
- ssr_mode=False # Disable SSR to avoid the warning
 
 
165
  )
 
6
  DOWNLOADS_FOLDER = "downloads"
7
  os.makedirs(DOWNLOADS_FOLDER, exist_ok=True)
8
 
9
+ def download_youtube_audio(url, file_format, duration_sec):
10
+ """Download and process audio from YouTube"""
 
 
11
  try:
12
  # Download best audio available
13
  ydl_opts = {
14
  'format': 'bestaudio/best',
15
  'outtmpl': os.path.join(DOWNLOADS_FOLDER, '%(title)s.%(ext)s'),
16
+ 'quiet': False,
17
+ 'no_warnings': False,
18
  'extract_flat': False,
19
+ 'noplaylist': True, # Don't download playlists
20
  }
21
 
22
  with YoutubeDL(ydl_opts) as ydl:
 
24
 
25
  original_file = os.path.join(DOWNLOADS_FOLDER, f"{info['title']}.{info['ext']}")
26
 
27
+ # Clean filename
28
  safe_title = "".join(c for c in info['title'] if c.isalnum() or c in (' ', '-', '_')).rstrip()
29
+ safe_title = safe_title[:100] # Limit filename length
30
  original_file_safe = os.path.join(DOWNLOADS_FOLDER, f"{safe_title}.{info['ext']}")
31
 
32
  # Rename if necessary
 
34
  os.rename(original_file, original_file_safe)
35
  original_file = original_file_safe
36
 
37
+ # Load audio
38
  audio = AudioSegment.from_file(original_file)
39
 
40
+ # Handle duration
41
  if duration_sec > 0:
42
  duration_ms = min(len(audio), int(duration_sec * 1000))
43
  trimmed_audio = audio[:duration_ms]
44
  else:
45
+ trimmed_audio = audio # Full track
46
 
47
+ # Determine output file
48
  base_name = os.path.splitext(original_file)[0]
49
 
50
  if file_format.lower() == "mp3":
 
63
  output_file = base_name + ".m4a"
64
  trimmed_audio.export(output_file, format="ipod", codec="aac")
65
 
66
+ else: # keep original
67
  output_file = original_file
68
 
69
+ # Clean up original if converted
70
  if output_file != original_file and os.path.exists(original_file):
71
  os.remove(original_file)
72
 
73
+ return output_file, f"✅ Downloaded: {os.path.basename(output_file)}"
74
 
75
  except Exception as e:
76
+ raise gr.Error(f"Error downloading from YouTube: {str(e)}")
77
 
78
+ def download_soundcloud_audio(url, file_format, duration_sec):
79
+ """Download and process audio from SoundCloud"""
80
+ try:
81
+ # SoundCloud specific options
82
+ ydl_opts = {
83
+ 'format': 'bestaudio/best',
84
+ 'outtmpl': os.path.join(DOWNLOADS_FOLDER, '%(title)s.%(ext)s'),
85
+ 'quiet': False,
86
+ 'no_warnings': False,
87
+ 'extract_flat': False,
88
+ }
89
+
90
+ with YoutubeDL(ydl_opts) as ydl:
91
+ info = ydl.extract_info(url, download=True)
92
+
93
+ original_file = os.path.join(DOWNLOADS_FOLDER, f"{info['title']}.{info['ext']}")
94
+
95
+ # Clean filename
96
+ safe_title = "".join(c for c in info['title'] if c.isalnum() or c in (' ', '-', '_')).rstrip()
97
+ safe_title = safe_title[:100]
98
+ original_file_safe = os.path.join(DOWNLOADS_FOLDER, f"{safe_title}.{info['ext']}")
99
+
100
+ if original_file != original_file_safe:
101
+ os.rename(original_file, original_file_safe)
102
+ original_file = original_file_safe
103
+
104
+ # Load and process audio
105
+ audio = AudioSegment.from_file(original_file)
106
+
107
+ if duration_sec > 0:
108
+ duration_ms = min(len(audio), int(duration_sec * 1000))
109
+ trimmed_audio = audio[:duration_ms]
110
+ else:
111
+ trimmed_audio = audio
112
+
113
+ # Convert to desired format
114
+ base_name = os.path.splitext(original_file)[0]
115
+
116
+ if file_format.lower() == "mp3":
117
+ output_file = base_name + ".mp3"
118
+ trimmed_audio.export(output_file, format="mp3", bitrate="192k")
119
+
120
+ elif file_format.lower() == "opus":
121
+ output_file = base_name + ".opus"
122
+ trimmed_audio.export(output_file, format="opus", bitrate="128k")
123
+
124
+ elif file_format.lower() == "wav":
125
+ output_file = base_name + ".wav"
126
+ trimmed_audio.export(output_file, format="wav")
127
+
128
+ elif file_format.lower() == "m4a":
129
+ output_file = base_name + ".m4a"
130
+ trimmed_audio.export(output_file, format="ipod", codec="aac")
131
+
132
+ else:
133
+ output_file = original_file
134
+
135
+ # Clean up
136
+ if output_file != original_file and os.path.exists(original_file):
137
+ os.remove(original_file)
138
+
139
+ return output_file, f"✅ Downloaded: {os.path.basename(output_file)}"
140
 
141
+ except Exception as e:
142
+ raise gr.Error(f"Error downloading from SoundCloud: {str(e)}")
143
+
144
+ # Create Gradio interface
145
+ with gr.Blocks(title="Audio Downloader", css="""
146
+ .tab-nav { background-color: #f0f0f0; }
147
+ .download-btn { margin-top: 20px; }
148
+ .status-box { margin-top: 10px; }
149
+ """) as iface:
150
 
151
+ gr.Markdown("# 🎵 Audio Downloader")
152
+ gr.Markdown("Download audio from YouTube or SoundCloud")
153
 
154
+ # Create tabs
155
+ with gr.Tabs():
156
+ # YouTube Tab
157
+ with gr.TabItem("YouTube", id="youtube"):
158
+ with gr.Row():
159
+ with gr.Column():
160
+ youtube_url = gr.Textbox(
161
+ label="YouTube URL",
162
+ placeholder="https://www.youtube.com/watch?v=...",
163
+ lines=1
164
+ )
165
+
166
+ with gr.Row():
167
+ youtube_format = gr.Dropdown(
168
+ choices=["mp3", "m4a", "opus", "wav"],
169
+ value="mp3",
170
+ label="Output Format"
171
+ )
172
+
173
+ youtube_duration = gr.Slider(
174
+ minimum=0,
175
+ maximum=1800, # 30 minutes max for YouTube
176
+ value=60,
177
+ step=5,
178
+ label="Duration (seconds)",
179
+ info="0 = full video"
180
+ )
181
+
182
+ youtube_btn = gr.Button(
183
+ "Download from YouTube",
184
+ variant="primary",
185
+ size="lg",
186
+ elem_classes="download-btn"
187
+ )
188
+
189
+ youtube_status = gr.Textbox(
190
+ label="Status",
191
+ interactive=False,
192
+ elem_classes="status-box"
193
+ )
194
+
195
+ youtube_output = gr.File(
196
+ label="Downloaded File",
197
+ interactive=False
198
+ )
199
+
200
+ # YouTube examples
201
+ with gr.Accordion("YouTube Examples", open=False):
202
+ gr.Examples(
203
+ examples=[
204
+ ["https://www.youtube.com/watch?v=dQw4w9WgXcQ"],
205
+ ["https://www.youtube.com/watch?v=JGwWNGJdvx8"],
206
+ ["https://www.youtube.com/watch?v=9bZkp7q19f0"],
207
+ ["https://www.youtube.com/watch?v=kJQP7kiw5Fk"]
208
+ ],
209
+ inputs=youtube_url,
210
+ label="Try these URLs:"
211
+ )
212
+
213
+ # SoundCloud Tab
214
+ with gr.TabItem("SoundCloud", id="soundcloud"):
215
+ with gr.Row():
216
+ with gr.Column():
217
+ soundcloud_url = gr.Textbox(
218
+ label="SoundCloud URL",
219
+ placeholder="https://soundcloud.com/...",
220
+ lines=1
221
+ )
222
+
223
+ with gr.Row():
224
+ soundcloud_format = gr.Dropdown(
225
+ choices=["mp3", "m4a", "opus", "wav"],
226
+ value="mp3",
227
+ label="Output Format"
228
+ )
229
+
230
+ soundcloud_duration = gr.Slider(
231
+ minimum=0,
232
+ maximum=600, # 10 minutes max for SoundCloud
233
+ value=60,
234
+ step=5,
235
+ label="Duration (seconds)",
236
+ info="0 = full track"
237
+ )
238
+
239
+ soundcloud_btn = gr.Button(
240
+ "Download from SoundCloud",
241
+ variant="primary",
242
+ size="lg",
243
+ elem_classes="download-btn"
244
+ )
245
+
246
+ soundcloud_status = gr.Textbox(
247
+ label="Status",
248
+ interactive=False,
249
+ elem_classes="status-box"
250
+ )
251
+
252
+ soundcloud_output = gr.File(
253
+ label="Downloaded File",
254
+ interactive=False
255
+ )
256
+
257
+ # SoundCloud examples
258
+ with gr.Accordion("SoundCloud Examples", open=False):
259
+ gr.Examples(
260
+ examples=[
261
+ ["https://soundcloud.com/antonio-antetomaso/mutiny-on-the-bounty-closing-titles-cover"],
262
+ ["https://soundcloud.com/officialnikkig/kill-bill-sza-kill-bill-remix"],
263
+ ["https://soundcloud.com/lofi-girl"],
264
+ ["https://soundcloud.com/user-123456789/sample-track"]
265
+ ],
266
+ inputs=soundcloud_url,
267
+ label="Try these URLs:"
268
+ )
269
 
270
+ # Instructions
271
+ with gr.Accordion("📖 Instructions & Info", open=False):
272
  gr.Markdown("""
273
+ ### How to Use:
274
+ 1. **Select the platform tab** (YouTube or SoundCloud)
275
+ 2. **Paste a URL** from the selected platform
276
+ 3. **Choose output format** (MP3, M4A, Opus, or WAV)
277
+ 4. **Set duration** (0 for full track, or specify seconds)
278
+ 5. **Click Download** button
279
+
280
+ ### Features:
281
+ - **YouTube**: Download audio from any YouTube video
282
+ - **SoundCloud**: Download tracks from SoundCloud
283
+ - **Format Conversion**: Convert to MP3, M4A, Opus, or WAV
284
+ - **Duration Control**: Extract specific segments or full tracks
285
+ - **Clean Interface**: Separate tabs for each platform
286
 
287
  ### Notes:
288
+ - Files are saved in the 'downloads' folder
289
+ - Some content may have download restrictions
290
+ - Long videos may take time to process
291
+ - Original files are deleted after conversion
292
  """)
293
 
294
+ # Connect button events
295
+ youtube_btn.click(
296
+ fn=download_youtube_audio,
297
+ inputs=[youtube_url, youtube_format, youtube_duration],
298
+ outputs=[youtube_output, youtube_status]
299
+ )
300
+
301
+ soundcloud_btn.click(
302
+ fn=download_soundcloud_audio,
303
+ inputs=[soundcloud_url, soundcloud_format, soundcloud_duration],
304
+ outputs=[soundcloud_output, soundcloud_status]
305
  )
306
 
307
+ # Launch the app
308
  if __name__ == "__main__":
309
  iface.launch(
310
+ server_name="127.0.0.1",
 
 
 
311
  server_port=7860,
312
+ show_error=True,
313
+ share=False,
314
+ theme=gr.themes.Soft()
315
  )